new include file locations engendered by vnodes
[unix-history] / usr / src / sbin / fsck / pass1.c
CommitLineData
76797561
DF
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
19052d90 7#ifndef lint
4d7f4685 8static char sccsid[] = "@(#)pass1.c 5.6 (Berkeley) %G%";
76797561 9#endif not lint
19052d90
KM
10
11#include <sys/param.h>
4d7f4685
KM
12#include <sys/time.h>
13#include <sys/vnode.h>
14#include <ufs/inode.h>
15#include <ufs/fs.h>
19052d90
KM
16#include "fsck.h"
17
993a756c
KM
18static daddr_t badblk;
19static daddr_t dupblk;
20int pass1check();
19052d90
KM
21
22pass1()
23{
993a756c 24 register int c, i, j;
19052d90 25 register DINODE *dp;
82dc9a9e 26 struct zlncnt *zlnp;
7718c0e6 27 int ndb, partial, cgd;
19052d90
KM
28 struct inodesc idesc;
29 ino_t inumber;
30
7718c0e6
KM
31 /*
32 * Set file system reserved blocks in used block map.
33 */
34 for (c = 0; c < sblock.fs_ncg; c++) {
35 cgd = cgdmin(&sblock, c);
36 if (c == 0) {
37 i = cgbase(&sblock, c);
38 cgd += howmany(sblock.fs_cssize, sblock.fs_fsize);
39 } else
40 i = cgsblock(&sblock, c);
41 for (; i < cgd; i++)
42 setbmap(i);
43 }
44 /*
45 * Find all allocated blocks.
46 */
19052d90
KM
47 bzero((char *)&idesc, sizeof(struct inodesc));
48 idesc.id_type = ADDR;
49 idesc.id_func = pass1check;
50 inumber = 0;
993a756c 51 n_files = n_blks = 0;
19052d90 52 for (c = 0; c < sblock.fs_ncg; c++) {
19052d90 53 for (i = 0; i < sblock.fs_ipg; i++, inumber++) {
993a756c 54 if (inumber < ROOTINO)
19052d90 55 continue;
39c18287 56 dp = ginode(inumber);
993a756c
KM
57 if (!ALLOC(dp)) {
58 if (bcmp((char *)dp->di_db, (char *)zino.di_db,
59 NDADDR * sizeof(daddr_t)) ||
60 bcmp((char *)dp->di_ib, (char *)zino.di_ib,
61 NIADDR * sizeof(daddr_t)) ||
62 dp->di_mode || dp->di_size) {
19052d90
KM
63 pfatal("PARTIALLY ALLOCATED INODE I=%u",
64 inumber);
65 if (reply("CLEAR") == 1) {
66 zapino(dp);
67 inodirty();
19052d90
KM
68 }
69 }
993a756c
KM
70 statemap[inumber] = USTATE;
71 continue;
72 }
73 lastino = inumber;
98061440
KM
74 if (dp->di_size < 0 ||
75 dp->di_size + sblock.fs_bsize - 1 < 0) {
993a756c
KM
76 if (debug)
77 printf("bad size %d:", dp->di_size);
78 goto unknown;
79 }
958be3d3
KM
80 if (!preen && (dp->di_mode & IFMT) == IFMT &&
81 reply("HOLD BAD BLOCK") == 1) {
82 dp->di_size = sblock.fs_fsize;
83 dp->di_mode = IFREG|0600;
84 inodirty();
85 }
993a756c 86 ndb = howmany(dp->di_size, sblock.fs_bsize);
dad05901
KM
87 if (ndb < 0) {
88 if (debug)
89 printf("bad size %d ndb %d:",
90 dp->di_size, ndb);
91 goto unknown;
92 }
993a756c
KM
93 if (SPECIAL(dp))
94 ndb++;
95 for (j = ndb; j < NDADDR; j++)
96 if (dp->di_db[j] != 0) {
97 if (debug)
98 printf("bad direct addr: %d\n",
99 dp->di_db[j]);
100 goto unknown;
101 }
102 for (j = 0, ndb -= NDADDR; ndb > 0; j++)
103 ndb /= NINDIR(&sblock);
104 for (; j < NIADDR; j++)
105 if (dp->di_ib[j] != 0) {
106 if (debug)
107 printf("bad indirect addr: %d\n",
108 dp->di_ib[j]);
109 goto unknown;
110 }
958be3d3 111 if (ftypeok(dp) == 0)
993a756c
KM
112 goto unknown;
113 n_files++;
114 lncntp[inumber] = dp->di_nlink;
115 if (dp->di_nlink <= 0) {
82dc9a9e
KM
116 zlnp = (struct zlncnt *)malloc(sizeof *zlnp);
117 if (zlnp == NULL) {
993a756c
KM
118 pfatal("LINK COUNT TABLE OVERFLOW");
119 if (reply("CONTINUE") == 0)
120 errexit("");
82dc9a9e
KM
121 } else {
122 zlnp->zlncnt = inumber;
123 zlnp->next = zlnhead;
124 zlnhead = zlnp;
993a756c
KM
125 }
126 }
127 statemap[inumber] = DIRCT(dp) ? DSTATE : FSTATE;
128 badblk = dupblk = 0; maxblk = 0;
129 idesc.id_number = inumber;
993a756c 130 (void)ckinode(dp, &idesc);
f0ed004a
KM
131 idesc.id_entryno *= btodb(sblock.fs_fsize);
132 if (dp->di_blocks != idesc.id_entryno) {
993a756c 133 pwarn("INCORRECT BLOCK COUNT I=%u (%ld should be %ld)",
f0ed004a 134 inumber, dp->di_blocks, idesc.id_entryno);
993a756c
KM
135 if (preen)
136 printf(" (CORRECTED)\n");
137 else if (reply("CORRECT") == 0)
138 continue;
f0ed004a 139 dp->di_blocks = idesc.id_entryno;
993a756c
KM
140 inodirty();
141 }
142 continue;
143 unknown:
144 pfatal("UNKNOWN FILE TYPE I=%u", inumber);
7b9b1d1f 145 statemap[inumber] = FCLEAR;
993a756c 146 if (reply("CLEAR") == 1) {
7b9b1d1f 147 statemap[inumber] = USTATE;
993a756c
KM
148 zapino(dp);
149 inodirty();
19052d90
KM
150 }
151 }
19052d90
KM
152 }
153}
154
155pass1check(idesc)
156 register struct inodesc *idesc;
157{
19052d90
KM
158 int res = KEEPON;
159 int anyout, nfrags;
160 daddr_t blkno = idesc->id_blkno;
62e6c152
KM
161 register struct dups *dlp;
162 struct dups *new;
19052d90 163
7718c0e6
KM
164 if ((anyout = outrange(blkno, idesc->id_numfrags)) != 0) {
165 blkerr(idesc->id_number, "BAD", blkno);
166 if (++badblk >= MAXBAD) {
167 pwarn("EXCESSIVE BAD BLKS I=%u",
168 idesc->id_number);
169 if (preen)
170 printf(" (SKIPPING)\n");
171 else if (reply("CONTINUE") == 0)
172 errexit("");
173 return (STOP);
174 }
175 }
19052d90
KM
176 for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
177 if (anyout && outrange(blkno, 1)) {
19052d90 178 res = SKIP;
7718c0e6
KM
179 } else if (!getbmap(blkno)) {
180 n_blks++;
181 setbmap(blkno);
182 } else {
19052d90
KM
183 blkerr(idesc->id_number, "DUP", blkno);
184 if (++dupblk >= MAXDUP) {
185 pwarn("EXCESSIVE DUP BLKS I=%u",
186 idesc->id_number);
187 if (preen)
188 printf(" (SKIPPING)\n");
189 else if (reply("CONTINUE") == 0)
190 errexit("");
191 return (STOP);
192 }
62e6c152
KM
193 new = (struct dups *)malloc(sizeof(struct dups));
194 if (new == NULL) {
19052d90
KM
195 pfatal("DUP TABLE OVERFLOW.");
196 if (reply("CONTINUE") == 0)
197 errexit("");
198 return (STOP);
199 }
62e6c152
KM
200 new->dup = blkno;
201 if (muldup == 0) {
202 duplist = muldup = new;
203 new->next = 0;
204 } else {
205 new->next = muldup->next;
206 muldup->next = new;
19052d90 207 }
62e6c152
KM
208 for (dlp = duplist; dlp != muldup; dlp = dlp->next)
209 if (dlp->dup == blkno)
210 break;
211 if (dlp == muldup && dlp->dup != blkno)
212 muldup = new;
19052d90 213 }
f0ed004a
KM
214 /*
215 * count the number of blocks found in id_entryno
216 */
217 idesc->id_entryno++;
19052d90
KM
218 }
219 return (res);
220}