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