1*4773Smckusic /*###1 [lint] static variable sccsid unused%%%*/ 2*4773Smckusic /*###1 [lint] sccsid defined( icheck.c(1) ), but never used%%%*/ 3*4773Smckusic static char *sccsid = "@(#)icheck.c 1.7 (Berkeley) 11/07/81"; 44410Smckusic 54240Smckusick /* 64240Smckusick * icheck 74240Smckusick */ 84240Smckusick #define NB 500 94240Smckusick #define BITS 8 104240Smckusick #define MAXFN 500 114240Smckusick 124240Smckusick #ifndef STANDALONE 134240Smckusick #include <stdio.h> 144240Smckusick #endif 154240Smckusick #include "../h/param.h" 164240Smckusick #include "../h/inode.h" 174240Smckusick #include "../h/fs.h" 184240Smckusick 194240Smckusick union { 204240Smckusick struct fs sb; 214240Smckusick char pad[BSIZE]; 224240Smckusick } sbun; 234240Smckusick #define sblock sbun.sb 244240Smckusick 254240Smckusick union { 264240Smckusick struct cg cg; 274240Smckusick char pad[BSIZE]; 284240Smckusick } cgun; 294240Smckusick #define cgrp cgun.cg 304240Smckusick 314240Smckusick struct dinode itab[MAXIPG]; 324240Smckusick daddr_t blist[NB]; 334240Smckusick char *bmap; 344240Smckusick 354240Smckusick int mflg; 364240Smckusick int dflg; 374240Smckusick int fi; 384240Smckusick ino_t ino; 394240Smckusick int cginit; 404240Smckusick 414240Smckusick ino_t nrfile; 424240Smckusick ino_t ndfile; 434240Smckusick ino_t nbfile; 444240Smckusick ino_t ncfile; 454240Smckusick ino_t nmcfile; 464240Smckusick 474240Smckusick daddr_t nblock; 484240Smckusick daddr_t nfrag; 494240Smckusick daddr_t nindir; 504240Smckusick daddr_t niindir; 514240Smckusick 524240Smckusick daddr_t nffree; 534240Smckusick daddr_t nbfree; 544240Smckusick 554240Smckusick daddr_t ndup; 564240Smckusick 574240Smckusick int nerror; 584240Smckusick 594240Smckusick long atol(); 604240Smckusick daddr_t alloc(); 614240Smckusick #ifndef STANDALONE 624240Smckusick char *malloc(); 634240Smckusick #endif 644240Smckusick 654240Smckusick main(argc, argv) 664240Smckusick char *argv[]; 674240Smckusick { 684240Smckusick register i; 694240Smckusick long n; 704240Smckusick 714240Smckusick blist[0] = -1; 724240Smckusick #ifndef STANDALONE 734240Smckusick while (--argc) { 744240Smckusick argv++; 754240Smckusick if (**argv=='-') 764240Smckusick switch ((*argv)[1]) { 774240Smckusick case 'd': 784240Smckusick dflg++; 794240Smckusick continue; 804240Smckusick 814240Smckusick case 'm': 824240Smckusick mflg++; 834240Smckusick continue; 844240Smckusick 854240Smckusick case 'b': 864240Smckusick for(i=0; i<NB; i++) { 874240Smckusick n = atol(argv[1]); 884240Smckusick if(n == 0) 894240Smckusick break; 904240Smckusick blist[i] = n; 914240Smckusick argv++; 924240Smckusick argc--; 934240Smckusick } 944240Smckusick blist[i] = -1; 954240Smckusick continue; 964240Smckusick 974240Smckusick default: 984240Smckusick printf("Bad flag\n"); 994240Smckusick } 1004240Smckusick check(*argv); 1014240Smckusick } 1024240Smckusick #else 1034240Smckusick { 1044240Smckusick static char fname[128]; 1054240Smckusick 1064240Smckusick printf("File: "); 1074240Smckusick gets(fname); 1084240Smckusick check(fname); 1094240Smckusick } 1104240Smckusick #endif 1114240Smckusick return(nerror); 1124240Smckusick } 1134240Smckusick 1144240Smckusick check(file) 1154240Smckusick char *file; 1164240Smckusick { 1174240Smckusick register i, j, c; 1184240Smckusick daddr_t d, cgd, cbase, b; 1194240Smckusick long n; 1204240Smckusick 121*4773Smckusic fi = open(file, 0); 1224240Smckusick if (fi < 0) { 1234240Smckusick printf("cannot open %s\n", file); 1244240Smckusick nerror |= 04; 1254240Smckusick return; 1264240Smckusick } 1274240Smckusick printf("%s:\n", file); 1284240Smckusick nrfile = 0; 1294240Smckusick ndfile = 0; 1304240Smckusick ncfile = 0; 1314240Smckusick nbfile = 0; 1324240Smckusick nmcfile = 0; 1334240Smckusick 1344240Smckusick nblock = 0; 1354240Smckusick nfrag = 0; 1364240Smckusick nindir = 0; 1374240Smckusick niindir = 0; 1384240Smckusick 1394240Smckusick ndup = 0; 1404240Smckusick #ifndef STANDALONE 1414240Smckusick sync(); 1424240Smckusick #endif 1434240Smckusick bread(SBLOCK, (char *)&sblock, BSIZE); 1444240Smckusick if (sblock.fs_magic != FS_MAGIC) { 1454240Smckusick printf("%s: bad magic number\n", file); 1464240Smckusick nerror |= 04; 1474240Smckusick return; 1484240Smckusick } 1494654Smckusic for (n = 0; n < howmany(cssize(&sblock), BSIZE); n++) { 150*4773Smckusic /*###148 [lint] calloc value declared inconsistently llib-lc(58) :: icheck.c(148)%%%*/ 151*4773Smckusic /*###148 [lint] calloc value used inconsistently llib-lc(58) :: icheck.c(148)%%%*/ 1524654Smckusic sblock.fs_csp[n] = (struct csum *)calloc(1, BSIZE); 1534654Smckusic bread(csaddr(&sblock) + (n * FRAG), 1544654Smckusic (char *)sblock.fs_csp[n], BSIZE); 1554654Smckusic } 1564240Smckusick ino = 0; 1574240Smckusick n = (sblock.fs_size*FRAG + BITS-1) / BITS; 1584240Smckusick #ifdef STANDALONE 1594240Smckusick bmap = NULL; 1604240Smckusick #else 1614240Smckusick bmap = malloc((unsigned)n); 1624240Smckusick #endif 1634240Smckusick if (bmap==NULL) { 1644240Smckusick printf("Not enough core; duplicates unchecked\n"); 1654240Smckusick dflg++; 1664240Smckusick } 1674240Smckusick ino = 0; 1684240Smckusick cginit = 1; 1694240Smckusick if(!dflg) { 1704240Smckusick for (i=0; i<(unsigned)n; i++) 1714240Smckusick bmap[i] = 0; 1724240Smckusick for (c=0; c < sblock.fs_ncg; c++) { 1734240Smckusick cgd = cgtod(c, &sblock); 1744410Smckusic for (d = cgbase(c, &sblock); d < cgd; d += FRAG) 1754429Smckusic chk(d, "badcg", BSIZE); 1764240Smckusick d = cgimin(c, &sblock); 1774240Smckusick while (cgd < d) { 1784429Smckusic chk(cgd, "cg", BSIZE); 1794410Smckusic cgd += FRAG; 1804240Smckusick } 1814240Smckusick d = cgdmin(c, &sblock); 1824410Smckusic for (; cgd < d; cgd += FRAG) 1834429Smckusic chk(cgd, "inode", BSIZE); 1844240Smckusick if (c == 0) { 1854410Smckusic d += howmany(cssize(&sblock), FSIZE); 1864410Smckusic for (; cgd < d; cgd += FRAG) 1874429Smckusic chk(cgd, "csum", BSIZE); 1884240Smckusick } 1894240Smckusick } 1904240Smckusick } 1914240Smckusick cginit = 0; 1924240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1934240Smckusick bread(cgimin(c,&sblock), (char *)itab, 1944240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1954240Smckusick for (j=0; j < sblock.fs_ipg; j++) { 1964240Smckusick pass1(&itab[j]); 1974240Smckusick ino++; 1984240Smckusick } 1994240Smckusick } 2004240Smckusick ino = 0; 2014240Smckusick #ifndef STANDALONE 2024240Smckusick sync(); 2034240Smckusick #endif 2044240Smckusick bread(SBLOCK, (char *)&sblock, sizeof(sblock)); 2054240Smckusick nffree = 0; 2064240Smckusick nbfree = 0; 2074240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2084240Smckusick cbase = cgbase(c,&sblock); 2094240Smckusick bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize); 2104240Smckusick for (b = 0; b < sblock.fs_fpg; b += FRAG) { 2114240Smckusick if (isblock(cgrp.cg_free, b / FRAG)) { 2124240Smckusick nbfree++; 2134429Smckusic chk(cbase+b, "block", BSIZE); 2144240Smckusick } else { 2154240Smckusick for (d = 0; d < FRAG; d++) 2164240Smckusick if (isset(cgrp.cg_free, b+d)) { 2174429Smckusic chk(cbase+b+d, "frag", FSIZE); 2184240Smckusick nffree++; 2194240Smckusick } 2204240Smckusick } 2214240Smckusick } 2224240Smckusick } 2234240Smckusick close(fi); 2244240Smckusick #ifndef STANDALONE 2254240Smckusick if (bmap) 2264240Smckusick free(bmap); 2274240Smckusick #endif 2284240Smckusick 2294240Smckusick i = nrfile + ndfile + ncfile + nbfile + nmcfile; 2304240Smckusick #ifndef STANDALONE 2314240Smckusick printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 2324240Smckusick i, nrfile, ndfile, nbfile, ncfile, nmcfile); 2334240Smckusick #else 2344240Smckusick printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 2354240Smckusick i, nrfile, ndfile, nbfile, ncfile, nmcfile); 2364240Smckusick #endif 2374429Smckusic n = (nblock + nindir + niindir) * FRAG + nfrag; 2384240Smckusick #ifdef STANDALONE 2394240Smckusick printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2404240Smckusick n, nindir, niindir, nblock, nfrag); 2414429Smckusic printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 2424240Smckusick nbfree, nffree); 2434240Smckusick #else 2444240Smckusick printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2454240Smckusick n, nindir, niindir, nblock, nfrag); 2464429Smckusic printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 2474240Smckusick nbfree, nffree); 2484240Smckusick #endif 2494240Smckusick if(!dflg) { 2504240Smckusick n = 0; 2514410Smckusic for (d = 0; d < sblock.fs_size; d++) 2524429Smckusic if(!duped(d, FSIZE)) { 2534240Smckusick if(mflg) 2544240Smckusick printf("%ld missing\n", d); 2554240Smckusick n++; 2564240Smckusick } 2574240Smckusick printf("missing%5ld\n", n); 2584240Smckusick } 2594240Smckusick } 2604240Smckusick 2614240Smckusick pass1(ip) 2624410Smckusic register struct dinode *ip; 2634240Smckusick { 2644429Smckusic daddr_t ind1[NINDIR]; 2654429Smckusic daddr_t ind2[NINDIR]; 2664429Smckusic daddr_t db, ib; 2674429Smckusic register int i, j, k, siz; 2684240Smckusick 2694240Smckusick i = ip->di_mode & IFMT; 2704240Smckusick if(i == 0) { 2714240Smckusick sblock.fs_nifree++; 2724240Smckusick return; 2734240Smckusick } 2744240Smckusick switch (i) { 2754240Smckusick case IFCHR: 2764240Smckusick ncfile++; 2774240Smckusick return; 2784240Smckusick case IFBLK: 2794240Smckusick nbfile++; 2804240Smckusick return; 2814240Smckusick case IFDIR: 2824240Smckusick ndfile++; 2834240Smckusick break; 2844240Smckusick case IFREG: 2854240Smckusick nrfile++; 2864240Smckusick break; 2874240Smckusick default: 2884240Smckusick printf("bad mode %u\n", ino); 2894240Smckusick return; 2904240Smckusick } 2914410Smckusic for (i = 0; i < NDADDR; i++) { 2924410Smckusic db = ip->di_db[i]; 2934410Smckusic if (db == 0) 2944240Smckusick continue; 2954429Smckusic siz = dblksize(ip, i); 2964429Smckusic chk(db, "data (block)", siz); 2974429Smckusic if (siz == BSIZE) 2984429Smckusic nblock++; 2994429Smckusic else 3004429Smckusic nfrag += howmany(siz, FSIZE); 3014240Smckusick } 3024410Smckusic for(i = 0; i < NIADDR; i++) { 3034410Smckusic ib = ip->di_ib[i]; 3044410Smckusic if(ib == 0) 3054240Smckusick continue; 3064429Smckusic if (chk(ib, "1st indirect", BSIZE)) 3074410Smckusic continue; 3084429Smckusic bread(ib, (char *)ind1, BSIZE); 3094240Smckusick nindir++; 3104410Smckusic for (j = 0; j < NINDIR; j++) { 3114410Smckusic ib = ind1[j]; 3124410Smckusic if (ib == 0) 3134240Smckusick continue; 3144410Smckusic if (i == 0) { 3154429Smckusic siz = dblksize(ip, NDADDR + j); 3164429Smckusic chk(ib, "data (large)", siz); 3174429Smckusic if (siz == BSIZE) 3184429Smckusic nblock++; 3194429Smckusic else 3204429Smckusic nfrag += howmany(siz, FSIZE); 3214240Smckusick continue; 3224240Smckusick } 3234429Smckusic if (chk(ib, "2nd indirect", BSIZE)) 3244410Smckusic continue; 3254429Smckusic bread(ib, (char *)ind2, BSIZE); 3264240Smckusick niindir++; 3274410Smckusic for (k = 0; k < NINDIR; k++) { 3284410Smckusic ib = ind2[k]; 3294410Smckusic if (ib == 0) 3304240Smckusick continue; 3314429Smckusic siz = dblksize(ip, 3324429Smckusic NDADDR + NINDIR * (i + j) + k); 3334429Smckusic chk(ib, "data (huge)", siz); 3344429Smckusic if (siz == BSIZE) 3354429Smckusic nblock++; 3364429Smckusic else 3374429Smckusic nfrag += howmany(siz, FSIZE); 3384240Smckusick } 3394240Smckusick } 3404240Smckusick } 3414240Smckusick } 3424240Smckusick 3434429Smckusic chk(bno, s, size) 3444410Smckusic daddr_t bno; 3454410Smckusic char *s; 3464429Smckusic int size; 3474240Smckusick { 3484240Smckusick register n, cg; 3494240Smckusick 3504240Smckusick cg = dtog(bno, &sblock); 3514429Smckusic if (cginit==0 && 3524429Smckusic bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) { 3534240Smckusick printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 3544240Smckusick return(1); 3554240Smckusick } 3564429Smckusic if (size == BSIZE) { 3574429Smckusic if (duped(bno, size)) { 3584429Smckusic printf("%ld dup block; inode=%u, class=%s\n", 3594429Smckusic bno, ino, s); 3604429Smckusic ndup += FRAG; 3614429Smckusic } 3624429Smckusic } else { 3634429Smckusic for (n = 0; n < size / FSIZE; n++) { 3644429Smckusic if (duped(bno + n, FSIZE)) { 3654429Smckusic printf("%ld dup frag; inode=%u, class=%s\n", 3664429Smckusic bno, ino, s); 3674429Smckusic ndup++; 3684429Smckusic } 3694429Smckusic } 3704240Smckusick } 3714240Smckusick for (n=0; blist[n] != -1; n++) 3724240Smckusick if (bno == blist[n]) 3734240Smckusick printf("%ld arg; inode=%u, class=%s\n", bno, ino, s); 3744240Smckusick return(0); 3754240Smckusick } 3764240Smckusick 3774429Smckusic duped(bno, size) 3784410Smckusic daddr_t bno; 3794429Smckusic int size; 3804240Smckusick { 3814240Smckusick if(dflg) 3824240Smckusick return(0); 3834429Smckusic if (size != FSIZE && size != BSIZE) 3844429Smckusic printf("bad size %d to duped\n", size); 3854429Smckusic if (size == FSIZE) { 3864410Smckusic if (isset(bmap, bno)) 3874410Smckusic return(1); 3884410Smckusic setbit(bmap, bno); 3894410Smckusic return (0); 3904410Smckusic } 3914410Smckusic if (bno % FRAG != 0) 3924410Smckusic printf("bad bno %d to duped\n", bno); 3934410Smckusic if (isblock(bmap, bno/FRAG)) 3944410Smckusic return (1); 3954410Smckusic setblock(bmap, bno/FRAG); 3964240Smckusick return(0); 3974240Smckusick } 3984240Smckusick 3994240Smckusick bread(bno, buf, cnt) 4004410Smckusic daddr_t bno; 4014410Smckusic char *buf; 4024240Smckusick { 4034240Smckusick register i; 4044240Smckusick 4054240Smckusick lseek(fi, bno*FSIZE, 0); 406*4773Smckusic /*###402 [lint] lseek value declared inconsistently llib-lc(31) :: icheck.c(402)%%%*/ 4074240Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 4084240Smckusick for(i=0; i<BSIZE; i++) 4094240Smckusick buf[i] = 0; 4104240Smckusick } 4114240Smckusick } 412