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: #if !defined(lint) && defined(DOSCCS)
   8: /* static char sccsid[] = "@(#)pass1.c	5.3 (Berkeley) 5/13/86"; */
   9: static char sccsid[] = "@(#)pass1.c	1.0 (2.11BSD) 9/13/90";
  10: #endif not lint
  11: 
  12: #include <sys/param.h>
  13: #include <sys/inode.h>
  14: #include <sys/fs.h>
  15: #include "fsck.h"
  16: 
  17: int pass1check();
  18: 
  19: pass1()
  20: {
  21:     register int j;
  22:     register DINODE *dp;
  23:     daddr_t ndb, lj;
  24:     struct inodesc idesc;
  25:     register ino_t inumber;
  26: 
  27:     /*
  28: 	 * Set file system reserved blocks in used block map.
  29: 	 */
  30:     for (j = 0; j < fmin; j++)
  31:         setbmap((daddr_t)j);
  32:     /*
  33: 	 * Find all allocated blocks.
  34: 	 */
  35:     bzero((char *)&idesc, sizeof(struct inodesc));
  36:     idesc.id_type = ADDR;
  37:     idesc.id_func = pass1check;
  38:     n_files = n_blks = n_free = 0;
  39:     for (inumber = ROOTINO; inumber < imax; inumber++) {
  40:         dp = ginode(inumber);
  41:         if (!ALLOC(dp)) {
  42:             if (bcmp((char *)dp->di_addr, (char *)zino.di_addr,
  43:                 NADDR * sizeof(daddr_t)) ||
  44:                 dp->di_mode || dp->di_size) {
  45:                 pfatal("PARTIALLY ALLOCATED INODE I=%u",
  46:                     inumber);
  47:                 if (reply("CLEAR") == 1) {
  48:                     zapino(dp);
  49:                     inodirty();
  50:                 }
  51:             }
  52:             setstate(inumber, USTATE);
  53:             continue;
  54:         }
  55:         lastino = inumber;
  56:         if (dp->di_size < 0) {
  57:             printf("bad size %ld:", dp->di_size);
  58:             goto unknown;
  59:         }
  60:         if (!preen && (dp->di_mode & IFMT) == IFMT &&
  61:             reply("HOLD BAD BLOCK") == 1) {
  62:             dp->di_size = sblock.fs_fsize;
  63:             dp->di_mode = IFREG|0600;
  64:             inodirty();
  65:         }
  66:         ndb = howmany(dp->di_size, DEV_BSIZE);
  67:         if (SPECIAL(dp))
  68:             ndb++;
  69: /*
  70:  * This check is not in 4.3BSD and is due to the fact that pipes in 2.11BSD
  71:  * are still implemented using the filesystem.  Zero length files with blocks
  72:  * (typically only the first direct block) allocated are the symptom.  It is
  73:  * safe to clear the inode as the blocks will end up missing and be reclaimed
  74:  * in pass5.
  75: */
  76:         else if (dp->di_size == 0 && bcmp(dp->di_addr,
  77:                 zino.di_addr,NADDR* sizeof (daddr_t))) {
  78:             pwarn("SIZE=0 FILE HAS ALLOCATED BLOCKS. I=%u",inumber);
  79:             if (preen)
  80:                 printf(" (CLEARED)\n");
  81:             if (preen || reply("CLEAR") == 1) {
  82:                 setstate(inumber, USTATE);
  83:                 zapino(dp);
  84:                 inodirty();
  85:                 continue;
  86:             }
  87:         }
  88:         for (lj = ndb; lj < NDADDR; lj++) {
  89:             j = lj;
  90:             if (dp->di_addr[j] != 0) {
  91:                 if (debug)
  92:                     printf("bad direct di_addr[%d]: %ld\n",
  93:                         j, dp->di_addr[j]);
  94:                 goto unknown;
  95:             }
  96:         }
  97:         for (j = 0, ndb -= NDADDR; ndb > 0; j++)
  98:             ndb /= NINDIR;
  99:         for (; j < NIADDR; j++)
 100:             if (dp->di_addr[NDADDR + j] != 0) {
 101:                 if (debug)
 102:                     printf("bad indirect addr: %ld\n",
 103:                         dp->di_addr[NDADDR + j]);
 104:                 goto unknown;
 105:             }
 106:         if (ftypeok(dp) == 0)
 107:             goto unknown;
 108:         n_files++;
 109:         setlncnt(inumber, dp->di_nlink);
 110:         if (dp->di_nlink <= 0) {
 111:             if (zlnp >= &zlnlist[MAXLNCNT]) {
 112:                 pfatal("LINK COUNT TABLE OVERFLOW");
 113:                 if (reply("CONTINUE") == 0)
 114:                     errexit("");
 115:             } else
 116:                 *zlnp++ = inumber;
 117:         }
 118:         setstate(inumber, DIRCT(dp) ? DSTATE : FSTATE);
 119:         badblk = dupblk = 0;
 120:         idesc.id_number = inumber;
 121:         (void)ckinode(dp, &idesc);
 122:         continue;
 123: unknown:
 124:         pfatal("UNKNOWN FILE TYPE I=%u mode: %o", inumber, dp->di_mode);
 125:         setstate(inumber, FCLEAR);
 126:         if (reply("CLEAR") == 1) {
 127:             setstate(inumber, USTATE);
 128:             zapino(dp);
 129:             inodirty();
 130:         }
 131:     }
 132: }
 133: 
 134: pass1check(idesc)
 135:     register struct inodesc *idesc;
 136: {
 137:     int res = KEEPON;
 138:     daddr_t blkno = idesc->id_blkno;
 139:     register daddr_t *dlp;
 140: 
 141:     if (outrange(blkno)) {
 142:         blkerr(idesc->id_number, "BAD", blkno);
 143:         if (++badblk >= MAXBAD) {
 144:             pwarn("EXCESSIVE BAD BLKS I=%u", idesc->id_number);
 145:             if (preen)
 146:                 printf(" (SKIPPING)\n");
 147:             else if (reply("CONTINUE") == 0)
 148:                 errexit("");
 149:             return (STOP);
 150:         }
 151:     return (SKIP);
 152:     }
 153:     if (!getbmap(blkno)) {
 154:             n_blks++;
 155:             setbmap(blkno);
 156:     } else {
 157:         blkerr(idesc->id_number, "DUP", blkno);
 158:         if (++dupblk >= MAXDUP) {
 159:             pwarn("EXCESSIVE DUP 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:         if (enddup >= &duplist[DUPTBLSIZE]) {
 168:             pfatal("DUP TABLE OVERFLOW");
 169:             if (reply("CONTINUE") == 0)
 170:                 errexit("");
 171:             return(STOP);
 172:         }
 173:         for (dlp = duplist; dlp < muldup; dlp++) {
 174:             if (*dlp == blkno) {
 175:                 *enddup++ = blkno;
 176:                 break;
 177:             }
 178:         }
 179:         if ( dlp >= muldup) {
 180:             *enddup++ = *muldup;
 181:             *muldup++ = blkno;
 182:         }
 183:     }
 184:         /*
 185: 		 * count the number of blocks found in id_entryno
 186: 		 */
 187:     idesc->id_entryno++;
 188:     return (res);
 189: }

Defined functions

pass1 defined in line 19; used 1 times
pass1check defined in line 134; used 4 times

Defined variables

sccsid defined in line 9; never used
Last modified: 1992-02-27
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2654
Valid CSS Valid XHTML 1.0 Strict