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