# struct {int INT;}; char *dargv[] { "/dev/rrp0", 0 }; #define NINODE 16*16 #define NB 10 #include "ino.h" #include "filsys.h" struct inode inode[NINODE]; struct filsys sblock; int sflg; int fi; int nifiles; int nfile; int nspcl; int nlarg; int nindir; int ndir; int nused; int nfree; int ino; int ndup; int blist[10] { -1}; int nerror; int bmap[4096]; int mod; int cylsiz; main(argc, argv) char **argv; { register char **p; register int n, *lp; if (argc == 1) { for (p = dargv; *p;) check(*p++); return(nerror); } while (--argc) { argv++; if (**argv=='-') switch ((*argv)[1]) { case 's': sflg++; *argv =+ 2; if ((*argv)[1] == 0) { if (**argv == '3') { cylsiz = 200; mod = 5; continue; } if (**argv == '4') { cylsiz = 418; mod = 9; continue; } } if ((cylsiz = number(*argv)) <= 0) goto error; while(**argv != ':') if (*(*argv)++ == 0) goto error; ++*argv; if ((mod = number(*argv)) <= 0) goto error; if (mod >= cylsiz) goto error; continue; error: cylsiz = mod = 1; continue; continue; case 'b': lp = blist; while (lp < &blist[NB-1] && (n = number(argv[1]))) { *lp++ = n; argv++; argc--; } *lp++ = -1; continue; default: printf("Bad flag\n"); } check(*argv); } return(nerror); } check(file) char *file; { register *ip, i, j; fi = open(file, sflg?2:0); if (fi < 0) { printf("cannot open %s\n", file); nerror =| 04; return; } printf("%s:\n", file); nfile = 0; nspcl = 0; nlarg = 0; nindir = 0; ndir = 0; nused = 0; nfree = 0; ndup = 0; for (ip = bmap; ip < &bmap[4096];) *ip++ = 0; sync(); bread(1, &sblock, 512); nifiles = sblock.s_isize*16; for(i=0; ino < nifiles; i =+ NINODE/16) { bread(i+2, inode, sizeof inode); for(j=0; j<NINODE && ino<nifiles; j++) { ino++; pass1(&inode[j]); } } ino = 0; sync(); bread(1, &sblock, 512); if (sflg) { makefree(); return; } while(i = alloc()) { if (chk(i, "free")) break; nfree++; } if (ndup) { printf("%l dups in free\n", ndup); nerror =| 02; } j = 0; for (ip = bmap; ip < &bmap[4096];) { i = *ip++; while (i) { if (i<0) j--; i =<< 1; } } j =+ sblock.s_fsize - sblock.s_isize - 2; if (j) printf("missing%5l\n", j); printf("spcl %6l\n", nspcl); printf("files %6l\n", nfile); printf("large %6l\n", nlarg); printf("direc %6l\n", ndir); printf("indir %6l\n", nindir); printf("used %6l\n", nused); printf("free %6l\n", nfree); close(fi); } pass1(aip) struct inode *aip; { int buf[256]; register i, j, *ip; ip = aip; if ((ip->i_mode&IALLOC) == 0) return; if ((ip->i_mode&IFCHR&IFBLK) != 0) { nspcl++; return; } if ((ip->i_mode&IFMT) == IFDIR) ndir++; else nfile++; if ((ip->i_mode&ILARG) != 0) { nlarg++; for(i=0; i<8; i++) if (ip->i_addr[i] != 0) { nindir++; if (chk(ip->i_addr[i], "indirect")) continue; bread(ip->i_addr[i], buf, 512); for(j=0; j<256; j++) if (buf[j] != 0) chk(buf[j], "data (large)"); } return; } for(i=0; i<8; i++) { if (ip->i_addr[i] != 0) chk(ip->i_addr[i], "data (small)"); } } chk(ab, s) char *ab; { register char *b; register n, m; b = ab; if (ino) nused++; if (b<sblock.s_isize+2 || b>=sblock.s_fsize) { printf("%l bad; inode=%l, class=%s\n", b, ino, s); return(1); } m = 1 << (b&017); n = (b>>4) & 07777; if (bmap[n]&m) { printf("%l dup; inode=%l, class=%s\n", b, ino, s); ndup++; } bmap[n] =| m; for (n=0; blist[n] != -1; n++) if (b == blist[n]) printf("%l arg; inode=%l, class=%s\n", b, ino, s); return(0); } alloc() { register b, i; int buf[256]; i = --sblock.s_nfree; if (i<0 || i>=100) { printf("bad freeblock\n"); return(0); } b = sblock.s_free[i]; if (b == 0) return(0); if (sblock.s_nfree <= 0) { bread(b, buf, 512); sblock.s_nfree = buf[0]; for(i=0; i<100; i++) sblock.s_free[i] = buf[i+1]; } return(b); } bread(bno, buf, cnt) int *buf; { register *ip; seek(fi, bno, 3); if (read(fi, buf, cnt) != cnt) { printf("read error %d\n", bno); if (sflg) { printf("No update\n"); sflg = 0; } for (ip = buf; ip < &buf[256];) *ip++ = 0; } } free(in) { register i; int buf[256]; if (sblock.s_nfree >= 100) { buf[0] = sblock.s_nfree; for(i=0; i<100; i++) buf[i+1] = sblock.s_free[i]; sblock.s_nfree = 0; bwrite(in, buf); } sblock.s_free[sblock.s_nfree++] = in; if (in) sblock.s_tfree++; } bwrite(bno, buf) { seek(fi, bno, 3); if (write(fi, buf, 512) != 512) printf("write error %d\n", bno); } number(as) char *as; { register n, c; register char *s; s = as; n = 0; while ((c = *s++) >= '0' && c <= '9') { n = n*10+c-'0'; } return(n); } makefree() { char *k,*first,*last; register i,j; char *cyl; int x,y,z; sblock.s_nfree = 0; sblock.s_ninode = 0; sblock.s_flock = 0; sblock.s_ilock = 0; sblock.s_fmod = 0; sblock.s_tfree = 0; sblock.s_tinode = nifiles - (nspcl + ndir + nfile); free(0); last = sblock.s_fsize-1; first = sblock.s_isize+2; cyl = 0; while (((cyl =+ cylsiz) <= last) && (cyl>=cylsiz)); do { cyl =- cylsiz; i = cylsiz - mod; x = 0; y = -1; while(1) { k = i + cyl; if (k<=last && k>=first) { j = k; if ((bmap[(j>>4)&07777] & (1<<(j&017)))==0) free(j); } if ((i =- mod) < 0) i =+ cylsiz; x++; if (i == cylsiz - mod) if (y == -1) { z = x; y = (cylsiz / z) - 1; } if (z == x) { x = 0; if (y-- == 0) break; i--; } } } while (cyl != 0); bwrite(1, &sblock); close(fi); sync(); return; }