|
|
1.1 root 1: static char *sccsid = "@(#)icheck.c 4.1 (Berkeley) 10/1/80";
2: #define NI 16
3: #define NB 500
4: #define BITS 8
5: #define MAXFN 500
6:
7: #ifndef STANDALONE
8: #include <stdio.h>
9: #endif
10: #include <sys/param.h>
11: #include <sys/inode.h>
12: #include <sys/ino.h>
13: #include <sys/fblk.h>
14: #include <sys/filsys.h>
15:
16: struct filsys sblock;
17: struct dinode itab[INOPB*NI];
18: daddr_t iaddr[NADDR];
19: daddr_t blist[NB];
20: char *bmap;
21:
22: int sflg;
23: int mflg;
24: int dflg;
25: int fi;
26: ino_t ino;
27:
28: ino_t nrfile;
29: ino_t ndfile;
30: ino_t nbfile;
31: ino_t ncfile;
32:
33: daddr_t ndirect;
34: daddr_t nindir;
35: daddr_t niindir;
36: daddr_t niiindir;
37: daddr_t nfree;
38: daddr_t ndup;
39:
40: int nerror;
41:
42: long atol();
43: daddr_t alloc();
44: #ifndef STANDALONE
45: char *malloc();
46: #endif
47:
48: main(argc, argv)
49: char *argv[];
50: {
51: register i;
52: long n;
53:
54: blist[0] = -1;
55: #ifndef STANDALONE
56: while (--argc) {
57: argv++;
58: if (**argv=='-')
59: switch ((*argv)[1]) {
60: case 'd':
61: dflg++;
62: continue;
63:
64:
65: case 'm':
66: mflg++;
67: continue;
68:
69: case 's':
70: sflg++;
71: continue;
72:
73: case 'b':
74: for(i=0; i<NB; i++) {
75: n = atol(argv[1]);
76: if(n == 0)
77: break;
78: blist[i] = n;
79: argv++;
80: argc--;
81: }
82: blist[i] = -1;
83: continue;
84:
85: default:
86: printf("Bad flag\n");
87: }
88: check(*argv);
89: }
90: #else
91: {
92: static char fname[128];
93:
94: printf("File: ");
95: gets(fname);
96: check(fname);
97: }
98: #endif
99: return(nerror);
100: }
101:
102: check(file)
103: char *file;
104: {
105: register i, j;
106: ino_t mino;
107: daddr_t d;
108: long n;
109:
110: fi = open(file, sflg?2:0);
111: if (fi < 0) {
112: printf("cannot open %s\n", file);
113: nerror |= 04;
114: return;
115: }
116: printf("%s:\n", file);
117: nrfile = 0;
118: ndfile = 0;
119: ncfile = 0;
120: nbfile = 0;
121:
122: ndirect = 0;
123: nindir = 0;
124: niindir = 0;
125: niiindir = 0;
126:
127: ndup = 0;
128: #ifndef STANDALONE
129: sync();
130: #endif
131: bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
132: mino = ((int)sblock.s_isize-2) * INOPB;
133: ino = 0;
134: n = (sblock.s_fsize - (int)sblock.s_isize + BITS-1) / BITS;
135: if (n != (unsigned)n) {
136: printf("Check fsize and isize: %ld, %u\n",
137: sblock.s_fsize, (int)sblock.s_isize);
138: }
139: #ifdef STANDALONE
140: bmap = NULL;
141: #else
142: bmap = malloc((unsigned)n);
143: #endif
144: if (bmap==NULL) {
145: printf("Not enough core; duplicates unchecked\n");
146: dflg++;
147: sflg = 0;
148: }
149: if(!dflg)
150: for(i=0; i<(unsigned)n; i++)
151: bmap[i] = 0;
152: for(i=2;; i+=NI) {
153: if(ino >= mino)
154: break;
155: bread((daddr_t)i, (char *)itab, sizeof(itab));
156: for(j=0; j<INOPB*NI; j++) {
157: if(ino >= mino)
158: break;
159: ino++;
160: pass1(&itab[j]);
161: }
162: }
163: ino = 0;
164: #ifndef STANDALONE
165: sync();
166: #endif
167: bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
168: if (sflg) {
169: makefree();
170: close(fi);
171: #ifndef STANDALONE
172: if (bmap)
173: free(bmap);
174: #endif
175: return;
176: }
177: nfree = 0;
178: while(n = alloc()) {
179: if (chk(n, "free"))
180: break;
181: nfree++;
182: }
183: close(fi);
184: #ifndef STANDALONE
185: if (bmap)
186: free(bmap);
187: #endif
188:
189: i = nrfile + ndfile + ncfile + nbfile;
190: #ifndef STANDALONE
191: printf("files %6u (r=%u,d=%u,b=%u,c=%u)\n",
192: i, nrfile, ndfile, nbfile, ncfile);
193: #else
194: printf("files %u (r=%u,d=%u,b=%u,c=%u)\n",
195: i, nrfile, ndfile, nbfile, ncfile);
196: #endif
197: n = ndirect + nindir + niindir + niiindir;
198: #ifdef STANDALONE
199: printf("used %ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
200: n, nindir, niindir, niiindir, ndirect);
201: printf("free %ld\n", nfree);
202: #else
203: printf("used %7ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
204: n, nindir, niindir, niiindir, ndirect);
205: printf("free %7ld\n", nfree);
206: #endif
207: if(!dflg) {
208: n = 0;
209: for(d=(int)sblock.s_isize; d<sblock.s_fsize; d++)
210: if(!duped(d)) {
211: if(mflg)
212: printf("%ld missing\n", d);
213: n++;
214: }
215: printf("missing%5ld\n", n);
216: }
217: }
218:
219: pass1(ip)
220: register struct dinode *ip;
221: {
222: daddr_t ind1[NINDIR];
223: daddr_t ind2[NINDIR];
224: daddr_t ind3[NINDIR];
225: register i, j;
226: int k, l;
227:
228: i = ip->di_mode & IFMT;
229: if(i == 0) {
230: sblock.s_tinode++;
231: return;
232: }
233: if(i == IFCHR) {
234: ncfile++;
235: return;
236: }
237: if(i == IFBLK) {
238: nbfile++;
239: return;
240: }
241: if(i == IFDIR)
242: ndfile++; else
243: if(i == IFREG)
244: nrfile++;
245: else {
246: printf("bad mode %u\n", ino);
247: return;
248: }
249: l3tol(iaddr, ip->di_addr, NADDR);
250: for(i=0; i<NADDR; i++) {
251: if(iaddr[i] == 0)
252: continue;
253: if(i < NADDR-3) {
254: ndirect++;
255: chk(iaddr[i], "data (small)");
256: continue;
257: }
258: nindir++;
259: if (chk(iaddr[i], "1st indirect"))
260: continue;
261: bread(iaddr[i], (char *)ind1, BSIZE);
262: for(j=0; j<NINDIR; j++) {
263: if(ind1[j] == 0)
264: continue;
265: if(i == NADDR-3) {
266: ndirect++;
267: chk(ind1[j], "data (large)");
268: continue;
269: }
270: niindir++;
271: if(chk(ind1[j], "2nd indirect"))
272: continue;
273: bread(ind1[j], (char *)ind2, BSIZE);
274: for(k=0; k<NINDIR; k++) {
275: if(ind2[k] == 0)
276: continue;
277: if(i == NADDR-2) {
278: ndirect++;
279: chk(ind2[k], "data (huge)");
280: continue;
281: }
282: niiindir++;
283: if(chk(ind2[k], "3rd indirect"))
284: continue;
285: bread(ind2[k], (char *)ind3, BSIZE);
286: for(l=0; l<NINDIR; l++)
287: if(ind3[l]) {
288: ndirect++;
289: chk(ind3[l], "data (garg)");
290: }
291: }
292: }
293: }
294: }
295:
296: chk(bno, s)
297: daddr_t bno;
298: char *s;
299: {
300: register n;
301:
302: if (bno<(int)sblock.s_isize || bno>=sblock.s_fsize) {
303: printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
304: return(1);
305: }
306: if(duped(bno)) {
307: printf("%ld dup; inode=%u, class=%s\n", bno, ino, s);
308: ndup++;
309: }
310: for (n=0; blist[n] != -1; n++)
311: if (bno == blist[n])
312: printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
313: return(0);
314: }
315:
316: duped(bno)
317: daddr_t bno;
318: {
319: daddr_t d;
320: register m, n;
321:
322: if(dflg)
323: return(0);
324: d = bno - (int)sblock.s_isize;
325: m = 1 << (d%BITS);
326: n = (d/BITS);
327: if(bmap[n] & m)
328: return(1);
329: bmap[n] |= m;
330: return(0);
331: }
332:
333: daddr_t
334: alloc()
335: {
336: int i;
337: daddr_t bno;
338: union {
339: char data[BSIZE];
340: struct fblk fb;
341: } buf;
342:
343: sblock.s_tfree--;
344: if (sblock.s_nfree<=0)
345: return(0);
346: if (sblock.s_nfree>NICFREE) {
347: printf("Bad free list, s.b. count = %d\n", sblock.s_nfree);
348: return(0);
349: }
350: bno = sblock.s_free[--sblock.s_nfree];
351: sblock.s_free[sblock.s_nfree] = (daddr_t)0;
352: if(bno == 0)
353: return(bno);
354: if(sblock.s_nfree <= 0) {
355: bread(bno, buf.data, BSIZE);
356: sblock.s_nfree = buf.df_nfree;
357: if (sblock.s_nfree<0 || sblock.s_nfree>NICFREE) {
358: printf("Bad free list, entry count of block %ld = %d\n",
359: bno, sblock.s_nfree);
360: sblock.s_nfree = 0;
361: return(0);
362: }
363: for(i=0; i<NICFREE; i++)
364: sblock.s_free[i] = buf.df_free[i];
365: }
366: return(bno);
367: }
368:
369: bfree(bno)
370: daddr_t bno;
371: {
372: union {
373: char data[BSIZE];
374: struct fblk fb;
375: } buf;
376: int i;
377:
378: sblock.s_tfree++;
379: if(sblock.s_nfree >= NICFREE) {
380: for(i=0; i<BSIZE; i++)
381: buf.data[i] = 0;
382: buf.df_nfree = sblock.s_nfree;
383: for(i=0; i<NICFREE; i++)
384: buf.df_free[i] = sblock.s_free[i];
385: bwrite(bno, buf.data);
386: sblock.s_nfree = 0;
387: }
388: sblock.s_free[sblock.s_nfree] = bno;
389: sblock.s_nfree++;
390: }
391:
392: bread(bno, buf, cnt)
393: daddr_t bno;
394: char *buf;
395: {
396: register i;
397:
398: lseek(fi, bno*BSIZE, 0);
399: if (read(fi, buf, cnt) != cnt) {
400: printf("read error %ld\n", bno);
401: if (sflg) {
402: printf("No update\n");
403: sflg = 0;
404: }
405: for(i=0; i<BSIZE; i++)
406: buf[i] = 0;
407: }
408: }
409:
410: bwrite(bno, buf)
411: daddr_t bno;
412: char *buf;
413: {
414:
415: lseek(fi, bno*BSIZE, 0);
416: if (write(fi, buf, BSIZE) != BSIZE)
417: printf("write error %ld\n", bno);
418: }
419:
420: makefree()
421: {
422: char flg[MAXFN];
423: int adr[MAXFN];
424: register i, j;
425: daddr_t f, d;
426: int m, n;
427:
428: n = sblock.s_n;
429: if(n <= 0 || n > MAXFN)
430: n = MAXFN;
431: sblock.s_n = n;
432: m = sblock.s_m;
433: if(m <= 0 || m > sblock.s_n)
434: m = 3;
435: sblock.s_m = m;
436:
437: for(i=0; i<n; i++)
438: flg[i] = 0;
439: i = 0;
440: for(j=0; j<n; j++) {
441: while(flg[i])
442: i = (i+1)%n;
443: adr[j] = i+1;
444: flg[i]++;
445: i = (i+m)%n;
446: }
447:
448: sblock.s_nfree = 0;
449: sblock.s_ninode = 0;
450: sblock.s_flock = 0;
451: sblock.s_ilock = 0;
452: sblock.s_fmod = 0;
453: sblock.s_ronly = 0;
454: #ifndef STANDALONE
455: time(&sblock.s_time);
456: #endif
457: sblock.s_tfree = 0;
458: sblock.s_tinode = 0;
459:
460: bfree((daddr_t)0);
461: d = sblock.s_fsize-1;
462: while(d%sblock.s_n)
463: d++;
464: for(; d > 0; d -= sblock.s_n)
465: for(i=0; i<sblock.s_n; i++) {
466: f = d - adr[i];
467: if(f < sblock.s_fsize && f >= (int)sblock.s_isize)
468: if(!duped(f))
469: bfree(f);
470: }
471: bwrite((daddr_t)1, (char *)&sblock);
472: #ifndef STANDALONE
473: sync();
474: #endif
475: return;
476: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.