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
Defined variables
sccsid
defined in line
9;
never used