1*4790Smckusic static char *sccsid = "@(#)icheck.c 1.8 (Berkeley) 11/07/81"; 24410Smckusic 34240Smckusick /* 44240Smckusick * icheck 54240Smckusick */ 64240Smckusick #define NB 500 74240Smckusick #define BITS 8 84240Smckusick #define MAXFN 500 94240Smckusick 104240Smckusick #ifndef STANDALONE 114240Smckusick #include <stdio.h> 124240Smckusick #endif 134240Smckusick #include "../h/param.h" 144240Smckusick #include "../h/inode.h" 154240Smckusick #include "../h/fs.h" 164240Smckusick 174240Smckusick union { 184240Smckusick struct fs sb; 194240Smckusick char pad[BSIZE]; 204240Smckusick } sbun; 214240Smckusick #define sblock sbun.sb 224240Smckusick 234240Smckusick union { 244240Smckusick struct cg cg; 254240Smckusick char pad[BSIZE]; 264240Smckusick } cgun; 274240Smckusick #define cgrp cgun.cg 284240Smckusick 294240Smckusick struct dinode itab[MAXIPG]; 304240Smckusick daddr_t blist[NB]; 314240Smckusick char *bmap; 324240Smckusick 334240Smckusick int mflg; 344240Smckusick int dflg; 354240Smckusick int fi; 364240Smckusick ino_t ino; 374240Smckusick int cginit; 384240Smckusick 394240Smckusick ino_t nrfile; 404240Smckusick ino_t ndfile; 414240Smckusick ino_t nbfile; 424240Smckusick ino_t ncfile; 434240Smckusick ino_t nmcfile; 444240Smckusick 454240Smckusick daddr_t nblock; 464240Smckusick daddr_t nfrag; 474240Smckusick daddr_t nindir; 484240Smckusick daddr_t niindir; 494240Smckusick 504240Smckusick daddr_t nffree; 514240Smckusick daddr_t nbfree; 524240Smckusick 534240Smckusick daddr_t ndup; 544240Smckusick 554240Smckusick int nerror; 564240Smckusick 574240Smckusick long atol(); 584240Smckusick daddr_t alloc(); 594240Smckusick #ifndef STANDALONE 604240Smckusick char *malloc(); 614240Smckusick #endif 624240Smckusick 634240Smckusick main(argc, argv) 644240Smckusick char *argv[]; 654240Smckusick { 664240Smckusick register i; 674240Smckusick long n; 684240Smckusick 694240Smckusick blist[0] = -1; 704240Smckusick #ifndef STANDALONE 714240Smckusick while (--argc) { 724240Smckusick argv++; 734240Smckusick if (**argv=='-') 744240Smckusick switch ((*argv)[1]) { 754240Smckusick case 'd': 764240Smckusick dflg++; 774240Smckusick continue; 784240Smckusick 794240Smckusick case 'm': 804240Smckusick mflg++; 814240Smckusick continue; 824240Smckusick 834240Smckusick case 'b': 844240Smckusick for(i=0; i<NB; i++) { 854240Smckusick n = atol(argv[1]); 864240Smckusick if(n == 0) 874240Smckusick break; 884240Smckusick blist[i] = n; 894240Smckusick argv++; 904240Smckusick argc--; 914240Smckusick } 924240Smckusick blist[i] = -1; 934240Smckusick continue; 944240Smckusick 954240Smckusick default: 964240Smckusick printf("Bad flag\n"); 974240Smckusick } 984240Smckusick check(*argv); 994240Smckusick } 1004240Smckusick #else 1014240Smckusick { 1024240Smckusick static char fname[128]; 1034240Smckusick 1044240Smckusick printf("File: "); 1054240Smckusick gets(fname); 1064240Smckusick check(fname); 1074240Smckusick } 1084240Smckusick #endif 1094240Smckusick return(nerror); 1104240Smckusick } 1114240Smckusick 1124240Smckusick check(file) 1134240Smckusick char *file; 1144240Smckusick { 1154240Smckusick register i, j, c; 1164240Smckusick daddr_t d, cgd, cbase, b; 1174240Smckusick long n; 1184240Smckusick 1194773Smckusic fi = open(file, 0); 1204240Smckusick if (fi < 0) { 1214240Smckusick printf("cannot open %s\n", file); 1224240Smckusick nerror |= 04; 1234240Smckusick return; 1244240Smckusick } 1254240Smckusick printf("%s:\n", file); 1264240Smckusick nrfile = 0; 1274240Smckusick ndfile = 0; 1284240Smckusick ncfile = 0; 1294240Smckusick nbfile = 0; 1304240Smckusick nmcfile = 0; 1314240Smckusick 1324240Smckusick nblock = 0; 1334240Smckusick nfrag = 0; 1344240Smckusick nindir = 0; 1354240Smckusick niindir = 0; 1364240Smckusick 1374240Smckusick ndup = 0; 1384240Smckusick #ifndef STANDALONE 1394240Smckusick sync(); 1404240Smckusick #endif 1414240Smckusick bread(SBLOCK, (char *)&sblock, BSIZE); 1424240Smckusick if (sblock.fs_magic != FS_MAGIC) { 1434240Smckusick printf("%s: bad magic number\n", file); 1444240Smckusick nerror |= 04; 1454240Smckusick return; 1464240Smckusick } 1474654Smckusic for (n = 0; n < howmany(cssize(&sblock), BSIZE); n++) { 1484654Smckusic sblock.fs_csp[n] = (struct csum *)calloc(1, BSIZE); 1494654Smckusic bread(csaddr(&sblock) + (n * FRAG), 1504654Smckusic (char *)sblock.fs_csp[n], BSIZE); 1514654Smckusic } 1524240Smckusick ino = 0; 1534240Smckusick n = (sblock.fs_size*FRAG + BITS-1) / BITS; 1544240Smckusick #ifdef STANDALONE 1554240Smckusick bmap = NULL; 1564240Smckusick #else 1574240Smckusick bmap = malloc((unsigned)n); 1584240Smckusick #endif 1594240Smckusick if (bmap==NULL) { 1604240Smckusick printf("Not enough core; duplicates unchecked\n"); 1614240Smckusick dflg++; 1624240Smckusick } 1634240Smckusick ino = 0; 1644240Smckusick cginit = 1; 1654240Smckusick if(!dflg) { 1664240Smckusick for (i=0; i<(unsigned)n; i++) 1674240Smckusick bmap[i] = 0; 1684240Smckusick for (c=0; c < sblock.fs_ncg; c++) { 1694240Smckusick cgd = cgtod(c, &sblock); 1704410Smckusic for (d = cgbase(c, &sblock); d < cgd; d += FRAG) 1714429Smckusic chk(d, "badcg", BSIZE); 1724240Smckusick d = cgimin(c, &sblock); 1734240Smckusick while (cgd < d) { 1744429Smckusic chk(cgd, "cg", BSIZE); 1754410Smckusic cgd += FRAG; 1764240Smckusick } 1774240Smckusick d = cgdmin(c, &sblock); 1784410Smckusic for (; cgd < d; cgd += FRAG) 1794429Smckusic chk(cgd, "inode", BSIZE); 1804240Smckusick if (c == 0) { 1814410Smckusic d += howmany(cssize(&sblock), FSIZE); 1824410Smckusic for (; cgd < d; cgd += FRAG) 1834429Smckusic chk(cgd, "csum", BSIZE); 1844240Smckusick } 1854240Smckusick } 1864240Smckusick } 1874240Smckusick cginit = 0; 1884240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1894240Smckusick bread(cgimin(c,&sblock), (char *)itab, 1904240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1914240Smckusick for (j=0; j < sblock.fs_ipg; j++) { 1924240Smckusick pass1(&itab[j]); 1934240Smckusick ino++; 1944240Smckusick } 1954240Smckusick } 1964240Smckusick ino = 0; 1974240Smckusick #ifndef STANDALONE 1984240Smckusick sync(); 1994240Smckusick #endif 2004240Smckusick bread(SBLOCK, (char *)&sblock, sizeof(sblock)); 2014240Smckusick nffree = 0; 2024240Smckusick nbfree = 0; 2034240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2044240Smckusick cbase = cgbase(c,&sblock); 2054240Smckusick bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize); 2064240Smckusick for (b = 0; b < sblock.fs_fpg; b += FRAG) { 2074240Smckusick if (isblock(cgrp.cg_free, b / FRAG)) { 2084240Smckusick nbfree++; 2094429Smckusic chk(cbase+b, "block", BSIZE); 2104240Smckusick } else { 2114240Smckusick for (d = 0; d < FRAG; d++) 2124240Smckusick if (isset(cgrp.cg_free, b+d)) { 2134429Smckusic chk(cbase+b+d, "frag", FSIZE); 2144240Smckusick nffree++; 2154240Smckusick } 2164240Smckusick } 2174240Smckusick } 2184240Smckusick } 2194240Smckusick close(fi); 2204240Smckusick #ifndef STANDALONE 2214240Smckusick if (bmap) 2224240Smckusick free(bmap); 2234240Smckusick #endif 2244240Smckusick 2254240Smckusick i = nrfile + ndfile + ncfile + nbfile + nmcfile; 2264240Smckusick #ifndef STANDALONE 2274240Smckusick printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 2284240Smckusick i, nrfile, ndfile, nbfile, ncfile, nmcfile); 2294240Smckusick #else 2304240Smckusick printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 2314240Smckusick i, nrfile, ndfile, nbfile, ncfile, nmcfile); 2324240Smckusick #endif 2334429Smckusic n = (nblock + nindir + niindir) * FRAG + nfrag; 2344240Smckusick #ifdef STANDALONE 2354240Smckusick printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2364240Smckusick n, nindir, niindir, nblock, nfrag); 2374429Smckusic printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 2384240Smckusick nbfree, nffree); 2394240Smckusick #else 2404240Smckusick printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2414240Smckusick n, nindir, niindir, nblock, nfrag); 2424429Smckusic printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 2434240Smckusick nbfree, nffree); 2444240Smckusick #endif 2454240Smckusick if(!dflg) { 2464240Smckusick n = 0; 2474410Smckusic for (d = 0; d < sblock.fs_size; d++) 2484429Smckusic if(!duped(d, FSIZE)) { 2494240Smckusick if(mflg) 2504240Smckusick printf("%ld missing\n", d); 2514240Smckusick n++; 2524240Smckusick } 2534240Smckusick printf("missing%5ld\n", n); 2544240Smckusick } 2554240Smckusick } 2564240Smckusick 2574240Smckusick pass1(ip) 2584410Smckusic register struct dinode *ip; 2594240Smckusick { 2604429Smckusic daddr_t ind1[NINDIR]; 2614429Smckusic daddr_t ind2[NINDIR]; 2624429Smckusic daddr_t db, ib; 2634429Smckusic register int i, j, k, siz; 2644240Smckusick 2654240Smckusick i = ip->di_mode & IFMT; 266*4790Smckusic if(i == 0) 2674240Smckusick return; 2684240Smckusick switch (i) { 2694240Smckusick case IFCHR: 2704240Smckusick ncfile++; 2714240Smckusick return; 2724240Smckusick case IFBLK: 2734240Smckusick nbfile++; 2744240Smckusick return; 2754240Smckusick case IFDIR: 2764240Smckusick ndfile++; 2774240Smckusick break; 2784240Smckusick case IFREG: 2794240Smckusick nrfile++; 2804240Smckusick break; 2814240Smckusick default: 2824240Smckusick printf("bad mode %u\n", ino); 2834240Smckusick return; 2844240Smckusick } 2854410Smckusic for (i = 0; i < NDADDR; i++) { 2864410Smckusic db = ip->di_db[i]; 2874410Smckusic if (db == 0) 2884240Smckusick continue; 2894429Smckusic siz = dblksize(ip, i); 2904429Smckusic chk(db, "data (block)", siz); 2914429Smckusic if (siz == BSIZE) 2924429Smckusic nblock++; 2934429Smckusic else 2944429Smckusic nfrag += howmany(siz, FSIZE); 2954240Smckusick } 2964410Smckusic for(i = 0; i < NIADDR; i++) { 2974410Smckusic ib = ip->di_ib[i]; 2984410Smckusic if(ib == 0) 2994240Smckusick continue; 3004429Smckusic if (chk(ib, "1st indirect", BSIZE)) 3014410Smckusic continue; 3024429Smckusic bread(ib, (char *)ind1, BSIZE); 3034240Smckusick nindir++; 3044410Smckusic for (j = 0; j < NINDIR; j++) { 3054410Smckusic ib = ind1[j]; 3064410Smckusic if (ib == 0) 3074240Smckusick continue; 3084410Smckusic if (i == 0) { 3094429Smckusic siz = dblksize(ip, NDADDR + j); 3104429Smckusic chk(ib, "data (large)", siz); 3114429Smckusic if (siz == BSIZE) 3124429Smckusic nblock++; 3134429Smckusic else 3144429Smckusic nfrag += howmany(siz, FSIZE); 3154240Smckusick continue; 3164240Smckusick } 3174429Smckusic if (chk(ib, "2nd indirect", BSIZE)) 3184410Smckusic continue; 3194429Smckusic bread(ib, (char *)ind2, BSIZE); 3204240Smckusick niindir++; 3214410Smckusic for (k = 0; k < NINDIR; k++) { 3224410Smckusic ib = ind2[k]; 3234410Smckusic if (ib == 0) 3244240Smckusick continue; 3254429Smckusic siz = dblksize(ip, 3264429Smckusic NDADDR + NINDIR * (i + j) + k); 3274429Smckusic chk(ib, "data (huge)", siz); 3284429Smckusic if (siz == BSIZE) 3294429Smckusic nblock++; 3304429Smckusic else 3314429Smckusic nfrag += howmany(siz, FSIZE); 3324240Smckusick } 3334240Smckusick } 3344240Smckusick } 3354240Smckusick } 3364240Smckusick 3374429Smckusic chk(bno, s, size) 3384410Smckusic daddr_t bno; 3394410Smckusic char *s; 3404429Smckusic int size; 3414240Smckusick { 3424240Smckusick register n, cg; 3434240Smckusick 3444240Smckusick cg = dtog(bno, &sblock); 3454429Smckusic if (cginit==0 && 3464429Smckusic bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) { 3474240Smckusick printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 3484240Smckusick return(1); 3494240Smckusick } 3504429Smckusic if (size == BSIZE) { 3514429Smckusic if (duped(bno, size)) { 3524429Smckusic printf("%ld dup block; inode=%u, class=%s\n", 3534429Smckusic bno, ino, s); 3544429Smckusic ndup += FRAG; 3554429Smckusic } 3564429Smckusic } else { 3574429Smckusic for (n = 0; n < size / FSIZE; n++) { 3584429Smckusic if (duped(bno + n, FSIZE)) { 3594429Smckusic printf("%ld dup frag; inode=%u, class=%s\n", 3604429Smckusic bno, ino, s); 3614429Smckusic ndup++; 3624429Smckusic } 3634429Smckusic } 3644240Smckusick } 3654240Smckusick for (n=0; blist[n] != -1; n++) 3664240Smckusick if (bno == blist[n]) 3674240Smckusick printf("%ld arg; inode=%u, class=%s\n", bno, ino, s); 3684240Smckusick return(0); 3694240Smckusick } 3704240Smckusick 3714429Smckusic duped(bno, size) 3724410Smckusic daddr_t bno; 3734429Smckusic int size; 3744240Smckusick { 3754240Smckusick if(dflg) 3764240Smckusick return(0); 3774429Smckusic if (size != FSIZE && size != BSIZE) 3784429Smckusic printf("bad size %d to duped\n", size); 3794429Smckusic if (size == FSIZE) { 3804410Smckusic if (isset(bmap, bno)) 3814410Smckusic return(1); 3824410Smckusic setbit(bmap, bno); 3834410Smckusic return (0); 3844410Smckusic } 3854410Smckusic if (bno % FRAG != 0) 3864410Smckusic printf("bad bno %d to duped\n", bno); 3874410Smckusic if (isblock(bmap, bno/FRAG)) 3884410Smckusic return (1); 3894410Smckusic setblock(bmap, bno/FRAG); 3904240Smckusick return(0); 3914240Smckusick } 3924240Smckusick 3934240Smckusick bread(bno, buf, cnt) 3944410Smckusic daddr_t bno; 3954410Smckusic char *buf; 3964240Smckusick { 3974240Smckusick register i; 3984240Smckusick 3994240Smckusick lseek(fi, bno*FSIZE, 0); 4004240Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 4014240Smckusick for(i=0; i<BSIZE; i++) 4024240Smckusick buf[i] = 0; 4034240Smckusick } 4044240Smckusick } 405