1*16262Smckusick #ifndef lint 2*16262Smckusick static char version[] = "@(#)pass1.c 3.1 (Berkeley) 03/31/84"; 3*16262Smckusick #endif 4*16262Smckusick 5*16262Smckusick #include <sys/param.h> 6*16262Smckusick #include <sys/inode.h> 7*16262Smckusick #include <sys/fs.h> 8*16262Smckusick #include "fsck.h" 9*16262Smckusick 10*16262Smckusick int pass1check(); 11*16262Smckusick 12*16262Smckusick pass1() 13*16262Smckusick { 14*16262Smckusick register int c, i, n, j; 15*16262Smckusick register DINODE *dp; 16*16262Smckusick int ndb, partial; 17*16262Smckusick struct inodesc idesc; 18*16262Smckusick ino_t inumber; 19*16262Smckusick 20*16262Smckusick bzero((char *)&idesc, sizeof(struct inodesc)); 21*16262Smckusick idesc.id_type = ADDR; 22*16262Smckusick idesc.id_func = pass1check; 23*16262Smckusick inumber = 0; 24*16262Smckusick n_blks += howmany(sblock.fs_cssize, sblock.fs_fsize); 25*16262Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 26*16262Smckusick if (getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize) == 0) 27*16262Smckusick continue; 28*16262Smckusick if (cgrp.cg_magic != CG_MAGIC) { 29*16262Smckusick pfatal("CG %d: BAD MAGIC NUMBER\n", c); 30*16262Smckusick bzero((char *)&cgrp, (int)sblock.fs_cgsize); 31*16262Smckusick } 32*16262Smckusick n = 0; 33*16262Smckusick for (i = 0; i < sblock.fs_ipg; i++, inumber++) { 34*16262Smckusick dp = ginode(inumber); 35*16262Smckusick if (dp == NULL) 36*16262Smckusick continue; 37*16262Smckusick n++; 38*16262Smckusick if (ALLOC) { 39*16262Smckusick if (!isset(cgrp.cg_iused, i)) { 40*16262Smckusick if (debug) 41*16262Smckusick printf("%d bad, not used\n", 42*16262Smckusick inumber); 43*16262Smckusick inosumbad++; 44*16262Smckusick } 45*16262Smckusick n--; 46*16262Smckusick lastino = inumber; 47*16262Smckusick if (!preen && (dp->di_mode & IFMT) == IFMT && 48*16262Smckusick reply("HOLD BAD BLOCK") == 1) { 49*16262Smckusick dp->di_size = sblock.fs_fsize; 50*16262Smckusick dp->di_mode = IFREG|0600; 51*16262Smckusick inodirty(); 52*16262Smckusick } else if (ftypeok(dp) == 0) 53*16262Smckusick goto unknown; 54*16262Smckusick if (dp->di_size < 0) { 55*16262Smckusick if (debug) 56*16262Smckusick printf("bad size %d:", 57*16262Smckusick dp->di_size); 58*16262Smckusick goto unknown; 59*16262Smckusick } 60*16262Smckusick ndb = howmany(dp->di_size, sblock.fs_bsize); 61*16262Smckusick if (SPECIAL) 62*16262Smckusick ndb++; 63*16262Smckusick for (j = ndb; j < NDADDR; j++) 64*16262Smckusick if (dp->di_db[j] != 0) { 65*16262Smckusick if (debug) 66*16262Smckusick printf("bad direct addr: %d\n", 67*16262Smckusick dp->di_db[j]); 68*16262Smckusick goto unknown; 69*16262Smckusick } 70*16262Smckusick for (j = 0, ndb -= NDADDR; ndb > 0; j++) 71*16262Smckusick ndb /= NINDIR(&sblock); 72*16262Smckusick for (; j < NIADDR; j++) 73*16262Smckusick if (dp->di_ib[j] != 0) { 74*16262Smckusick if (debug) 75*16262Smckusick printf("bad indirect addr: %d\n", 76*16262Smckusick dp->di_ib[j]); 77*16262Smckusick goto unknown; 78*16262Smckusick } 79*16262Smckusick n_files++; 80*16262Smckusick lncntp[inumber] = dp->di_nlink; 81*16262Smckusick if (dp->di_nlink <= 0) { 82*16262Smckusick if (badlnp < &badlncnt[MAXLNCNT]) 83*16262Smckusick *badlnp++ = inumber; 84*16262Smckusick else { 85*16262Smckusick pfatal("LINK COUNT TABLE OVERFLOW"); 86*16262Smckusick if (reply("CONTINUE") == 0) 87*16262Smckusick errexit(""); 88*16262Smckusick } 89*16262Smckusick } 90*16262Smckusick statemap[inumber] = DIRCT ? DSTATE : FSTATE; 91*16262Smckusick badblk = dupblk = 0; maxblk = 0; 92*16262Smckusick idesc.id_number = inumber; 93*16262Smckusick idesc.id_filesize = 0; 94*16262Smckusick (void)ckinode(dp, &idesc); 95*16262Smckusick idesc.id_filesize *= btodb(sblock.fs_fsize); 96*16262Smckusick if (dp->di_blocks != idesc.id_filesize) { 97*16262Smckusick pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)", 98*16262Smckusick inumber, dp->di_blocks, 99*16262Smckusick idesc.id_filesize); 100*16262Smckusick if (preen) 101*16262Smckusick printf(" (CORRECTED)\n"); 102*16262Smckusick else if (reply("CORRECT") == 0) 103*16262Smckusick continue; 104*16262Smckusick dp->di_blocks = idesc.id_filesize; 105*16262Smckusick inodirty(); 106*16262Smckusick } 107*16262Smckusick continue; 108*16262Smckusick unknown: 109*16262Smckusick pfatal("UNKNOWN FILE TYPE I=%u", inumber); 110*16262Smckusick if (reply("CLEAR") == 1) { 111*16262Smckusick zapino(dp); 112*16262Smckusick inodirty(); 113*16262Smckusick inosumbad++; 114*16262Smckusick } 115*16262Smckusick } else { 116*16262Smckusick if (isset(cgrp.cg_iused, i)) { 117*16262Smckusick if (debug) 118*16262Smckusick printf("%d bad, marked used\n", 119*16262Smckusick inumber); 120*16262Smckusick inosumbad++; 121*16262Smckusick n--; 122*16262Smckusick } 123*16262Smckusick partial = 0; 124*16262Smckusick for (j = 0; j < NDADDR; j++) 125*16262Smckusick if (dp->di_db[j] != 0) 126*16262Smckusick partial++; 127*16262Smckusick for (j = 0; j < NIADDR; j++) 128*16262Smckusick if (dp->di_ib[j] != 0) 129*16262Smckusick partial++; 130*16262Smckusick if (partial || dp->di_mode != 0 || 131*16262Smckusick dp->di_size != 0) { 132*16262Smckusick pfatal("PARTIALLY ALLOCATED INODE I=%u", 133*16262Smckusick inumber); 134*16262Smckusick if (reply("CLEAR") == 1) { 135*16262Smckusick zapino(dp); 136*16262Smckusick inodirty(); 137*16262Smckusick inosumbad++; 138*16262Smckusick } 139*16262Smckusick } 140*16262Smckusick } 141*16262Smckusick } 142*16262Smckusick if (n != cgrp.cg_cs.cs_nifree) { 143*16262Smckusick if (debug) 144*16262Smckusick printf("cg[%d].cg_cs.cs_nifree is %d; calc %d\n", 145*16262Smckusick c, cgrp.cg_cs.cs_nifree, n); 146*16262Smckusick inosumbad++; 147*16262Smckusick } 148*16262Smckusick if (cgrp.cg_cs.cs_nbfree != sblock.fs_cs(&sblock, c).cs_nbfree 149*16262Smckusick || cgrp.cg_cs.cs_nffree != sblock.fs_cs(&sblock, c).cs_nffree 150*16262Smckusick || cgrp.cg_cs.cs_nifree != sblock.fs_cs(&sblock, c).cs_nifree 151*16262Smckusick || cgrp.cg_cs.cs_ndir != sblock.fs_cs(&sblock, c).cs_ndir) 152*16262Smckusick sbsumbad++; 153*16262Smckusick } 154*16262Smckusick } 155*16262Smckusick 156*16262Smckusick pass1check(idesc) 157*16262Smckusick register struct inodesc *idesc; 158*16262Smckusick { 159*16262Smckusick register daddr_t *dlp; 160*16262Smckusick int res = KEEPON; 161*16262Smckusick int anyout, nfrags; 162*16262Smckusick daddr_t blkno = idesc->id_blkno; 163*16262Smckusick 164*16262Smckusick anyout = outrange(blkno, idesc->id_numfrags); 165*16262Smckusick for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) { 166*16262Smckusick if (anyout && outrange(blkno, 1)) { 167*16262Smckusick blkerr(idesc->id_number, "BAD", blkno); 168*16262Smckusick if (++badblk >= MAXBAD) { 169*16262Smckusick pwarn("EXCESSIVE BAD BLKS I=%u", 170*16262Smckusick idesc->id_number); 171*16262Smckusick if (preen) 172*16262Smckusick printf(" (SKIPPING)\n"); 173*16262Smckusick else if (reply("CONTINUE") == 0) 174*16262Smckusick errexit(""); 175*16262Smckusick return (STOP); 176*16262Smckusick } 177*16262Smckusick res = SKIP; 178*16262Smckusick } else if (getbmap(blkno)) { 179*16262Smckusick blkerr(idesc->id_number, "DUP", blkno); 180*16262Smckusick if (++dupblk >= MAXDUP) { 181*16262Smckusick pwarn("EXCESSIVE DUP BLKS I=%u", 182*16262Smckusick idesc->id_number); 183*16262Smckusick if (preen) 184*16262Smckusick printf(" (SKIPPING)\n"); 185*16262Smckusick else if (reply("CONTINUE") == 0) 186*16262Smckusick errexit(""); 187*16262Smckusick return (STOP); 188*16262Smckusick } 189*16262Smckusick if (enddup >= &duplist[DUPTBLSIZE]) { 190*16262Smckusick pfatal("DUP TABLE OVERFLOW."); 191*16262Smckusick if (reply("CONTINUE") == 0) 192*16262Smckusick errexit(""); 193*16262Smckusick return (STOP); 194*16262Smckusick } 195*16262Smckusick for (dlp = duplist; dlp < muldup; dlp++) 196*16262Smckusick if (*dlp == blkno) { 197*16262Smckusick *enddup++ = blkno; 198*16262Smckusick break; 199*16262Smckusick } 200*16262Smckusick if (dlp >= muldup) { 201*16262Smckusick *enddup++ = *muldup; 202*16262Smckusick *muldup++ = blkno; 203*16262Smckusick } 204*16262Smckusick } else { 205*16262Smckusick n_blks++; 206*16262Smckusick setbmap(blkno); 207*16262Smckusick } 208*16262Smckusick idesc->id_filesize++; 209*16262Smckusick } 210*16262Smckusick return (res); 211*16262Smckusick } 212