minor fixups pre tcp<->spec coordination
[unix-history] / usr / src / sbin / icheck / icheck.c
CommitLineData
0947395d 1static char *sccsid = "@(#)icheck.c 1.8 (Berkeley) %G%";
955f6ff8 2
b42940ce
KM
3/*
4 * icheck
5 */
6#define NB 500
7#define BITS 8
8#define MAXFN 500
9
10#ifndef STANDALONE
11#include <stdio.h>
12#endif
13#include "../h/param.h"
14#include "../h/inode.h"
b42940ce
KM
15#include "../h/fs.h"
16
b42940ce
KM
17union {
18 struct fs sb;
19 char pad[BSIZE];
20} sbun;
21#define sblock sbun.sb
22
23union {
24 struct cg cg;
25 char pad[BSIZE];
26} cgun;
27#define cgrp cgun.cg
28
29struct dinode itab[MAXIPG];
b42940ce
KM
30daddr_t blist[NB];
31char *bmap;
32
b42940ce
KM
33int mflg;
34int dflg;
35int fi;
36ino_t ino;
37int cginit;
38
39ino_t nrfile;
40ino_t ndfile;
41ino_t nbfile;
42ino_t ncfile;
43ino_t nmcfile;
44
45daddr_t nblock;
46daddr_t nfrag;
b42940ce 47daddr_t nindir;
b42940ce
KM
48daddr_t niindir;
49
50daddr_t nffree;
b42940ce
KM
51daddr_t nbfree;
52
53daddr_t ndup;
54
55int nerror;
56
57long atol();
58daddr_t alloc();
59#ifndef STANDALONE
60char *malloc();
61#endif
62
63main(argc, argv)
64char *argv[];
65{
66 register i;
67 long n;
68
69 blist[0] = -1;
70#ifndef STANDALONE
71 while (--argc) {
72 argv++;
73 if (**argv=='-')
74 switch ((*argv)[1]) {
75 case 'd':
76 dflg++;
77 continue;
78
79 case 'm':
80 mflg++;
81 continue;
82
b42940ce
KM
83 case 'b':
84 for(i=0; i<NB; i++) {
85 n = atol(argv[1]);
86 if(n == 0)
87 break;
88 blist[i] = n;
89 argv++;
90 argc--;
91 }
92 blist[i] = -1;
93 continue;
94
95 default:
96 printf("Bad flag\n");
97 }
98 check(*argv);
99 }
100#else
101 {
102 static char fname[128];
103
104 printf("File: ");
105 gets(fname);
106 check(fname);
107 }
108#endif
109 return(nerror);
110}
111
112check(file)
113char *file;
114{
115 register i, j, c;
116 daddr_t d, cgd, cbase, b;
117 long n;
118
c27f32bc 119 fi = open(file, 0);
b42940ce
KM
120 if (fi < 0) {
121 printf("cannot open %s\n", file);
122 nerror |= 04;
123 return;
124 }
125 printf("%s:\n", file);
126 nrfile = 0;
127 ndfile = 0;
128 ncfile = 0;
129 nbfile = 0;
130 nmcfile = 0;
131
132 nblock = 0;
133 nfrag = 0;
b42940ce 134 nindir = 0;
b42940ce
KM
135 niindir = 0;
136
137 ndup = 0;
138#ifndef STANDALONE
139 sync();
140#endif
141 bread(SBLOCK, (char *)&sblock, BSIZE);
142 if (sblock.fs_magic != FS_MAGIC) {
143 printf("%s: bad magic number\n", file);
144 nerror |= 04;
145 return;
146 }
743f1ef7
KM
147 for (n = 0; n < howmany(cssize(&sblock), BSIZE); n++) {
148 sblock.fs_csp[n] = (struct csum *)calloc(1, BSIZE);
149 bread(csaddr(&sblock) + (n * FRAG),
150 (char *)sblock.fs_csp[n], BSIZE);
151 }
b42940ce
KM
152 ino = 0;
153 n = (sblock.fs_size*FRAG + BITS-1) / BITS;
154#ifdef STANDALONE
155 bmap = NULL;
156#else
157 bmap = malloc((unsigned)n);
158#endif
159 if (bmap==NULL) {
160 printf("Not enough core; duplicates unchecked\n");
161 dflg++;
b42940ce
KM
162 }
163 ino = 0;
164 cginit = 1;
165 if(!dflg) {
166 for (i=0; i<(unsigned)n; i++)
167 bmap[i] = 0;
168 for (c=0; c < sblock.fs_ncg; c++) {
169 cgd = cgtod(c, &sblock);
955f6ff8 170 for (d = cgbase(c, &sblock); d < cgd; d += FRAG)
07670f7d 171 chk(d, "badcg", BSIZE);
b42940ce
KM
172 d = cgimin(c, &sblock);
173 while (cgd < d) {
07670f7d 174 chk(cgd, "cg", BSIZE);
955f6ff8 175 cgd += FRAG;
b42940ce
KM
176 }
177 d = cgdmin(c, &sblock);
955f6ff8 178 for (; cgd < d; cgd += FRAG)
07670f7d 179 chk(cgd, "inode", BSIZE);
b42940ce 180 if (c == 0) {
955f6ff8
KM
181 d += howmany(cssize(&sblock), FSIZE);
182 for (; cgd < d; cgd += FRAG)
07670f7d 183 chk(cgd, "csum", BSIZE);
b42940ce
KM
184 }
185 }
186 }
187 cginit = 0;
188 for (c = 0; c < sblock.fs_ncg; c++) {
189 bread(cgimin(c,&sblock), (char *)itab,
190 sblock.fs_ipg * sizeof (struct dinode));
191 for (j=0; j < sblock.fs_ipg; j++) {
192 pass1(&itab[j]);
193 ino++;
194 }
195 }
196 ino = 0;
197#ifndef STANDALONE
198 sync();
199#endif
200 bread(SBLOCK, (char *)&sblock, sizeof(sblock));
b42940ce 201 nffree = 0;
b42940ce
KM
202 nbfree = 0;
203 for (c = 0; c < sblock.fs_ncg; c++) {
204 cbase = cgbase(c,&sblock);
205 bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize);
206 for (b = 0; b < sblock.fs_fpg; b += FRAG) {
207 if (isblock(cgrp.cg_free, b / FRAG)) {
208 nbfree++;
07670f7d 209 chk(cbase+b, "block", BSIZE);
b42940ce
KM
210 } else {
211 for (d = 0; d < FRAG; d++)
212 if (isset(cgrp.cg_free, b+d)) {
07670f7d 213 chk(cbase+b+d, "frag", FSIZE);
b42940ce 214 nffree++;
b42940ce
KM
215 }
216 }
217 }
218 }
219 close(fi);
220#ifndef STANDALONE
221 if (bmap)
222 free(bmap);
223#endif
224
225 i = nrfile + ndfile + ncfile + nbfile + nmcfile;
226#ifndef STANDALONE
227 printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
228 i, nrfile, ndfile, nbfile, ncfile, nmcfile);
229#else
230 printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n",
231 i, nrfile, ndfile, nbfile, ncfile, nmcfile);
232#endif
07670f7d 233 n = (nblock + nindir + niindir) * FRAG + nfrag;
b42940ce
KM
234#ifdef STANDALONE
235 printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
236 n, nindir, niindir, nblock, nfrag);
07670f7d 237 printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree,
b42940ce
KM
238 nbfree, nffree);
239#else
240 printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n",
241 n, nindir, niindir, nblock, nfrag);
07670f7d 242 printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree,
b42940ce
KM
243 nbfree, nffree);
244#endif
245 if(!dflg) {
246 n = 0;
955f6ff8 247 for (d = 0; d < sblock.fs_size; d++)
07670f7d 248 if(!duped(d, FSIZE)) {
b42940ce
KM
249 if(mflg)
250 printf("%ld missing\n", d);
251 n++;
252 }
253 printf("missing%5ld\n", n);
254 }
255}
256
257pass1(ip)
955f6ff8 258 register struct dinode *ip;
b42940ce 259{
07670f7d
KM
260 daddr_t ind1[NINDIR];
261 daddr_t ind2[NINDIR];
262 daddr_t db, ib;
263 register int i, j, k, siz;
b42940ce
KM
264
265 i = ip->di_mode & IFMT;
0947395d 266 if(i == 0)
b42940ce 267 return;
b42940ce
KM
268 switch (i) {
269 case IFCHR:
270 ncfile++;
271 return;
272 case IFBLK:
273 nbfile++;
274 return;
275 case IFDIR:
276 ndfile++;
277 break;
278 case IFREG:
279 nrfile++;
280 break;
281 default:
282 printf("bad mode %u\n", ino);
283 return;
284 }
955f6ff8
KM
285 for (i = 0; i < NDADDR; i++) {
286 db = ip->di_db[i];
287 if (db == 0)
b42940ce 288 continue;
07670f7d
KM
289 siz = dblksize(ip, i);
290 chk(db, "data (block)", siz);
291 if (siz == BSIZE)
292 nblock++;
293 else
294 nfrag += howmany(siz, FSIZE);
b42940ce 295 }
955f6ff8
KM
296 for(i = 0; i < NIADDR; i++) {
297 ib = ip->di_ib[i];
298 if(ib == 0)
299 continue;
07670f7d 300 if (chk(ib, "1st indirect", BSIZE))
b42940ce 301 continue;
07670f7d 302 bread(ib, (char *)ind1, BSIZE);
b42940ce 303 nindir++;
955f6ff8
KM
304 for (j = 0; j < NINDIR; j++) {
305 ib = ind1[j];
306 if (ib == 0)
b42940ce 307 continue;
955f6ff8 308 if (i == 0) {
07670f7d
KM
309 siz = dblksize(ip, NDADDR + j);
310 chk(ib, "data (large)", siz);
311 if (siz == BSIZE)
312 nblock++;
313 else
314 nfrag += howmany(siz, FSIZE);
b42940ce
KM
315 continue;
316 }
07670f7d 317 if (chk(ib, "2nd indirect", BSIZE))
955f6ff8 318 continue;
07670f7d 319 bread(ib, (char *)ind2, BSIZE);
b42940ce 320 niindir++;
955f6ff8
KM
321 for (k = 0; k < NINDIR; k++) {
322 ib = ind2[k];
323 if (ib == 0)
b42940ce 324 continue;
07670f7d
KM
325 siz = dblksize(ip,
326 NDADDR + NINDIR * (i + j) + k);
327 chk(ib, "data (huge)", siz);
328 if (siz == BSIZE)
329 nblock++;
330 else
331 nfrag += howmany(siz, FSIZE);
b42940ce 332 }
b42940ce
KM
333 }
334 }
335}
336
07670f7d 337chk(bno, s, size)
955f6ff8
KM
338 daddr_t bno;
339 char *s;
07670f7d 340 int size;
b42940ce
KM
341{
342 register n, cg;
343
344 cg = dtog(bno, &sblock);
07670f7d
KM
345 if (cginit==0 &&
346 bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) {
b42940ce
KM
347 printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
348 return(1);
349 }
07670f7d
KM
350 if (size == BSIZE) {
351 if (duped(bno, size)) {
352 printf("%ld dup block; inode=%u, class=%s\n",
353 bno, ino, s);
354 ndup += FRAG;
355 }
356 } else {
357 for (n = 0; n < size / FSIZE; n++) {
358 if (duped(bno + n, FSIZE)) {
359 printf("%ld dup frag; inode=%u, class=%s\n",
360 bno, ino, s);
361 ndup++;
362 }
363 }
b42940ce
KM
364 }
365 for (n=0; blist[n] != -1; n++)
366 if (bno == blist[n])
367 printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
368 return(0);
369}
370
07670f7d 371duped(bno, size)
955f6ff8 372 daddr_t bno;
07670f7d 373 int size;
b42940ce 374{
b42940ce
KM
375 if(dflg)
376 return(0);
07670f7d
KM
377 if (size != FSIZE && size != BSIZE)
378 printf("bad size %d to duped\n", size);
379 if (size == FSIZE) {
955f6ff8
KM
380 if (isset(bmap, bno))
381 return(1);
382 setbit(bmap, bno);
383 return (0);
384 }
385 if (bno % FRAG != 0)
386 printf("bad bno %d to duped\n", bno);
387 if (isblock(bmap, bno/FRAG))
388 return (1);
389 setblock(bmap, bno/FRAG);
b42940ce
KM
390 return(0);
391}
392
393bread(bno, buf, cnt)
955f6ff8
KM
394 daddr_t bno;
395 char *buf;
b42940ce
KM
396{
397 register i;
398
399 lseek(fi, bno*FSIZE, 0);
400 if ((i = read(fi, buf, cnt)) != cnt) {
b42940ce
KM
401 for(i=0; i<BSIZE; i++)
402 buf[i] = 0;
403 }
404}