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