|
|
1.1 root 1: #define NI 4
2: #define NB 500
3: #define BITS 8
4: #define MAXFN 500
5:
6: #include <stdio.h>
7: #include <sys/param.h>
8: #include <sys/inode.h>
9: #include <sys/ino.h>
10: #include <sys/fblk.h>
11: #include <sys/filsys.h>
12: #include <sys/stat.h>
13:
14: #define BITFSBIT 64 /* should be in param.h */
15: #define BIGINOPB INOPB(BITFSBIT)
16: #define BIGBSIZE BSIZE(BITFSBIT)
17: #define BIGNINDIR NINDIR(BITFSBIT)
18:
19: struct filsys sblock;
20: struct stat status;
21: #define dev status.st_rdev
22: struct dinode itab[BIGINOPB*NI];
23: daddr_t iaddr[NADDR];
24: daddr_t blist[NB];
25: char *bmap;
26:
27: int sflg;
28: int mflg;
29: int dflg;
30: int eflg;
31: int fi;
32: long ino;
33: int bigflag;
34:
35: ino_t nrfile;
36: ino_t ndfile;
37: ino_t nbfile;
38: ino_t ncfile;
39: ino_t nlfile;
40:
41: daddr_t ndirect;
42: daddr_t nindir;
43: daddr_t niindir;
44: daddr_t niiindir;
45: daddr_t nfree;
46: daddr_t ndup;
47: daddr_t maxblk;
48:
49: int nerror;
50:
51: long atol();
52: daddr_t alloc();
53: char *malloc();
54: char *memset();
55: time_t time();
56: long lseek();
57: void sync();
58:
59: main(argc, argv)
60: char *argv[];
61: {
62: register i;
63: long n;
64:
65: setbuf(stdout, (char *)NULL);
66: blist[0] = -1;
67: while (--argc) {
68: argv++;
69: if (**argv=='-')
70: switch ((*argv)[1]) {
71: case 'd':
72: dflg++;
73: continue;
74:
75: case 'e':
76: eflg++;
77: continue;
78:
79: case 'm':
80: mflg++;
81: continue;
82:
83: case 's':
84: sflg++;
85: continue;
86:
87: case 'b':
88: for(i=0; i<NB; i++) {
89: n = atol(argv[1]);
90: if(n == 0)
91: break;
92: blist[i] = n;
93: argv++;
94: argc--;
95: }
96: blist[i] = -1;
97: continue;
98:
99: case 'B':
100: bigflag = BITFSBIT;
101: continue;
102:
103: default:
104: fprintf(stderr, "Bad flag\n");
105: }
106: check(*argv);
107: }
108: return(nerror);
109: }
110:
111: check(file)
112: char *file;
113: {
114: register i, j;
115: long mino;
116: daddr_t d;
117: long n;
118:
119: fi = open(file, sflg?2:0);
120: if (fi < 0) {
121: fprintf(stderr, "cannot open %s\n", file);
122: nerror |= 04;
123: return;
124: }
125: if (fstat(fi, &status) < 0) {
126: fprintf(stderr, "cannot fstat %s\n", file);
127: nerror |= 04;
128: close(fi);
129: return;
130: }
131: if ((status.st_mode & S_IFMT) == S_IFREG)
132: dev = makedev(0, bigflag);
133: printf("%s:\n", file);
134: nrfile = 0;
135: ndfile = 0;
136: ncfile = 0;
137: nbfile = 0;
138: nlfile = 0;
139:
140: ndirect = 0;
141: nindir = 0;
142: niindir = 0;
143: niiindir = 0;
144:
145: ndup = 0;
146: sync();
147: bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
148: mino = ((int)sblock.s_isize-2) * INOPB(dev);
149: ino = 0;
150: maxblk = sblock.s_fsize;
151: /*
152: * fudge for new bitmapped filesystems
153: * this should be isolated somewhere
154: */
155: if (BITFS(dev) && sblock.U.N.S_flag) {
156: n = (sblock.s_fsize+sblock.U.N.S_bsize-1)/sblock.U.N.S_bsize;
157: maxblk -= n;
158: }
159: n = (maxblk - (int)sblock.s_isize + BITS-1) / BITS;
160: if (n != (unsigned)n) {
161: fprintf(stderr, "Check fsize and isize: %ld, %u\n",
162: maxblk, (int)sblock.s_isize);
163: }
164: bmap = malloc((unsigned)n);
165: if (bmap==NULL) {
166: fprintf(stderr, "Not enough core; duplicates unchecked\n");
167: dflg++;
168: sflg = 0;
169: }
170: if(!dflg)
171: for(i=0; i<(unsigned)n; i++)
172: bmap[i] = 0;
173: for(i=2;; i+=NI) {
174: if(ino >= mino)
175: break;
176: bread((daddr_t)i, (char *)itab, BSIZE(dev)*NI);
177: for(j=0; j<INOPB(dev)*NI; j++) {
178: if(ino >= mino)
179: break;
180: ino++;
181: pass1(&itab[j]);
182: }
183: }
184: ino = 0;
185: sync();
186: bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
187: if (sflg) {
188: makefree();
189: close(fi);
190: if (bmap)
191: free(bmap);
192: return;
193: }
194: nfree = 0;
195: while(n = alloc()) {
196: if (chk(0, n, "free"))
197: break;
198: nfree++;
199: }
200: close(fi);
201:
202: i = nrfile + ndfile + ncfile + nbfile + nlfile;
203: printf("files %6u (r=%u,d=%u,b=%u,c=%u,l=%u)\n",
204: i, nrfile, ndfile, nbfile, ncfile, nlfile);
205: n = ndirect + nindir + niindir + niiindir;
206: printf("used %7ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
207: n, nindir, niindir, niiindir, ndirect);
208: printf("free %7ld\n", nfree);
209: if(!dflg) {
210: n = 0;
211: for(d=(int)sblock.s_isize; d<maxblk; d++)
212: if(!duped(d)) {
213: if(mflg)
214: printf("%ld missing\n", d);
215: n++;
216: }
217: printf("missing%5ld\n", n);
218: }
219: if (bmap)
220: free(bmap);
221: }
222:
223: pass1(ip)
224: register struct dinode *ip;
225: {
226: daddr_t ind1[BIGNINDIR];
227: daddr_t ind2[BIGNINDIR];
228: daddr_t ind3[BIGNINDIR];
229: register i, j;
230: int k, l;
231: int squawked = 0;
232:
233: i = ip->di_mode & IFMT;
234: if(i == 0) {
235: sblock.s_tinode++;
236: return;
237: }
238: if(i == IFCHR) {
239: ncfile++;
240: return;
241: }
242: if(i == IFBLK) {
243: nbfile++;
244: return;
245: }
246: if(i == IFDIR)
247: ndfile++;
248: else if(i == IFREG)
249: nrfile++;
250: else if(i == IFLNK)
251: nlfile++;
252: else {
253: printf("bad mode %u\n", ino);
254: return;
255: }
256: l3tol(iaddr, ip->di_addr, NADDR);
257: for(i=0; i<NADDR; i++) {
258: if(iaddr[i] == 0)
259: continue;
260: if(i < NADDR-3) {
261: ndirect++;
262: chk(squawked++, iaddr[i], "data (small)");
263: continue;
264: }
265: nindir++;
266: if (chk(squawked++, iaddr[i], "1st indirect"))
267: continue;
268: bread(iaddr[i], (char *)ind1, BSIZE(dev));
269: for(j=0; j<NINDIR(dev); j++) {
270: if(ind1[j] == 0)
271: continue;
272: if(i == NADDR-3) {
273: ndirect++;
274: chk(squawked++, ind1[j], "data (large)");
275: continue;
276: }
277: niindir++;
278: if(chk(squawked++, ind1[j], "2nd indirect"))
279: continue;
280: bread(ind1[j], (char *)ind2, BSIZE(dev));
281: for(k=0; k<NINDIR(dev); k++) {
282: if(ind2[k] == 0)
283: continue;
284: if(i == NADDR-2) {
285: ndirect++;
286: chk(squawked++, ind2[k], "data (huge)");
287: continue;
288: }
289: niiindir++;
290: if(chk(squawked++, ind2[k], "3rd indirect"))
291: continue;
292: bread(ind2[k], (char *)ind3, BSIZE(dev));
293: for(l=0; l<NINDIR(dev); l++)
294: if(ind3[l]) {
295: ndirect++;
296: chk(squawked++, ind3[l], "data (garg)");
297: }
298: }
299: }
300: }
301: }
302:
303: chk(loud, bno, s)
304: daddr_t bno;
305: char *s;
306: {
307: register n;
308:
309: for (n=0; blist[n] != -1; n++)
310: if (bno == blist[n])
311: printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
312: if (bno<(int)sblock.s_isize || bno>=maxblk) {
313: if (loud == 0 || eflg == 0)
314: printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
315: return(1);
316: }
317: if(duped(bno)) {
318: if (loud == 0)
319: printf("%ld dup; inode=%u, class=%s\n", bno, ino, s);
320: ndup++;
321: }
322: return(0);
323: }
324:
325: duped(bno)
326: daddr_t bno;
327: {
328: daddr_t d;
329: register m, n;
330:
331: if(dflg)
332: return(0);
333: d = bno - (int)sblock.s_isize;
334: m = 1 << (d%BITS);
335: n = (d/BITS);
336: if(bmap[n] & m)
337: return(1);
338: bmap[n] |= m;
339: return(0);
340: }
341:
342: daddr_t bitfsalloc(), bigfsalloc();
343:
344: daddr_t
345: alloc()
346: {
347: daddr_t bno;
348: union {
349: char data[BIGBSIZE];
350: struct fblk fb;
351: } buf;
352: register int i;
353:
354: sblock.s_tfree--;
355: if (BITFS(dev)) {
356: if (sblock.U.N.S_flag)
357: return (bigfsalloc());
358: return (bitfsalloc());
359: }
360: if (sblock.s_nfree<=0)
361: return(0);
362: if (sblock.s_nfree>NICFREE) {
363: fprintf(stderr, "Bad free list, s.b. count = %d\n", sblock.s_nfree);
364: return(0);
365: }
366: bno = sblock.s_free[--sblock.s_nfree];
367: sblock.s_free[sblock.s_nfree] = (daddr_t)0;
368: if(bno == 0)
369: return(bno);
370: if(sblock.s_nfree <= 0) {
371: bread(bno, buf.data, BSIZE(dev));
372: sblock.s_nfree = buf.fb.df_nfree;
373: if (sblock.s_nfree<0 || sblock.s_nfree>NICFREE) {
374: fprintf(stderr, "Bad free list, entry count of block %ld = %d\n",
375: bno, sblock.s_nfree);
376: sblock.s_nfree = 0;
377: return(0);
378: }
379: for(i=0; i<NICFREE; i++)
380: sblock.s_free[i] = buf.fb.df_free[i];
381: }
382: return(bno);
383: }
384:
385: daddr_t
386: bitfsalloc()
387: {
388: daddr_t bno;
389: register long *p;
390: register int i, j;
391:
392: p = sblock.s_bfree;
393: for(i = 0; i < BITMAP && *p == 0; i++, p++)
394: ;
395: if(i >= BITMAP)
396: return (0);
397: bno = sblock.s_isize + BITCELL * i;
398: for(j = 0; j < BITCELL; j++)
399: if(*p & (1 << j))
400: break;
401: if(j >= BITCELL)
402: return (0);
403: bno += j;
404: if(bno >= sblock.s_fsize)
405: return (0);
406: *p &= ~(1 << j);
407: return (bno);
408: }
409:
410: daddr_t
411: bigfsalloc()
412: {
413: register long *p;
414: register int i;
415: int nblk;
416: static long *flist, *fend;
417: daddr_t bno;
418:
419: if (flist == NULL) {
420: if (sblock.U.N.S_bsize == 0) /* unlikely */
421: sblock.U.N.S_bsize = BIGBSIZE*NBBY;
422: nblk = (sblock.s_fsize+sblock.U.N.S_bsize-1)/sblock.U.N.S_bsize;
423: if ((flist = (long *)malloc(nblk*BIGBSIZE)) == NULL) {
424: fprintf(stderr, "no mem for free bitmap\n");
425: return (0);
426: }
427: bno = sblock.s_fsize - nblk;
428: fend = flist;
429: for (i = 0; i < nblk; i++, bno++, fend += BIGBSIZE/sizeof(long))
430: bread(bno, (char *)fend, BIGBSIZE);
431: }
432: for (p = flist; p < fend && *p == 0; p++)
433: ;
434: if (p >= fend)
435: return (0);
436: for (i = 0; i < BITCELL; i++)
437: if (*p & (1<<i))
438: break;
439: if (i >= BITCELL)
440: return (0); /* shouldn't happen */
441: bno = i + (p - flist)*BITCELL;
442: if (bno >= maxblk)
443: return (0);
444: *p &=~ (1<<i);
445: return (bno);
446: }
447:
448:
449: bread(bno, buf, cnt)
450: daddr_t bno;
451: char *buf;
452: {
453: register i;
454:
455: lseek(fi, bno*BSIZE(dev), 0);
456: if (read(fi, buf, cnt) != cnt) {
457: fprintf(stderr, "read error %ld\n", bno);
458: if (sflg) {
459: fprintf(stderr, "No update\n");
460: sflg = 0;
461: }
462: for(i=0; i<BSIZE(dev); i++)
463: buf[i] = 0;
464: }
465: }
466:
467: bwrite(bno, buf)
468: daddr_t bno;
469: char *buf;
470: {
471:
472: lseek(fi, bno*BSIZE(dev), 0);
473: if (write(fi, buf, BSIZE(dev)) != BSIZE(dev))
474: fprintf(stderr, "write error %ld\n", bno);
475: }
476:
477: makefree()
478: {
479:
480: if (!BITFS(dev))
481: makeoldfree();
482: else if (sblock.U.N.S_flag == 0)
483: makesbitfree();
484: else
485: makebbitfree();
486: }
487:
488: makeoldfree()
489: {
490: char flg[MAXFN];
491: int adr[MAXFN];
492: register i, j;
493: daddr_t f, d;
494: int m, n;
495:
496: n = sblock.s_n;
497: if(n <= 0 || n > MAXFN)
498: n = MAXFN;
499: sblock.s_n = n;
500: m = sblock.s_m;
501: if(m <= 0 || m > sblock.s_n)
502: m = 3;
503: sblock.s_m = m;
504:
505: for(i=0; i<n; i++)
506: flg[i] = 0;
507: i = 0;
508: for(j=0; j<n; j++) {
509: while(flg[i])
510: i = (i+1)%n;
511: adr[j] = i+1;
512: flg[i]++;
513: i = (i+m)%n;
514: }
515:
516: sblock.s_nfree = 0;
517: sblock.s_ninode = 0;
518: sblock.s_flock = 0;
519: sblock.s_ilock = 0;
520: sblock.s_fmod = 0;
521: sblock.s_ronly = 0;
522: time(&sblock.s_time);
523:
524: bfree((daddr_t)0);
525: sblock.s_tfree = 0;
526: sblock.s_tinode = 0;
527: d = maxblk-1;
528: while(d%sblock.s_n)
529: d++;
530: for(; d > 0; d -= sblock.s_n)
531: for(i=0; i<sblock.s_n; i++) {
532: f = d - adr[i];
533: if(f < maxblk && f >= (int)sblock.s_isize)
534: if(!duped(f))
535: bfree(f);
536: }
537: bwrite((daddr_t)1, (char *)&sblock);
538: sync();
539: }
540:
541: bfree(bno)
542: daddr_t bno;
543: {
544: union {
545: char data[BIGBSIZE];
546: struct fblk fb;
547: } buf;
548: int i;
549:
550: sblock.s_tfree++;
551: if(sblock.s_nfree >= NICFREE) {
552: for(i=0; i<BSIZE(dev); i++)
553: buf.data[i] = 0;
554: buf.fb.df_nfree = sblock.s_nfree;
555: for(i=0; i<NICFREE; i++)
556: buf.fb.df_free[i] = sblock.s_free[i];
557: bwrite(bno, buf.data);
558: sblock.s_nfree = 0;
559: }
560: sblock.s_free[sblock.s_nfree] = bno;
561: sblock.s_nfree++;
562: }
563:
564: makesbitfree()
565: {
566: register daddr_t bno;
567:
568: memset((char *)sblock.s_bfree, 0, BITMAP);
569: sblock.s_tfree = 0;
570: for (bno = sblock.s_isize; bno < maxblk; bno++)
571: if (!duped(bno)) {
572: BITFREE(sblock.s_bfree, bno-sblock.s_isize);
573: sblock.s_tfree++;
574: }
575: sblock.s_valid = 1;
576: bwrite((daddr_t)1, (char *)&sblock);
577: }
578:
579: makebbitfree()
580: {
581: register daddr_t bno;
582: register long *flist;
583: register int nblk, i;
584:
585: nblk = (sblock.s_fsize+sblock.U.N.S_bsize-1)/sblock.U.N.S_bsize;
586: if ((flist = (long *)malloc(nblk*BIGBSIZE)) == NULL) {
587: fprintf(stderr, "no mem for free bitmap\n");
588: exit(1); /* eh? */
589: }
590: memset((char *)flist, 0, nblk*BIGBSIZE);
591: sblock.s_tfree = 0;
592: for (bno = sblock.s_isize; bno < maxblk; bno++)
593: if (!duped(bno)) {
594: BITFREE(flist, bno);
595: sblock.s_tfree++;
596: }
597: for (i = 0; i < nblk; i++)
598: bwrite(sblock.s_fsize - nblk + i, ((char *)flist)+(i*BIGBSIZE));
599: free((char *)flist);
600: sblock.s_valid = 1;
601: bwrite((daddr_t)1, (char *)&sblock);
602: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.