1*4429Smckusic static char *sccsid = "@(#)icheck.c 1.5 (Berkeley) 09/22/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 sflg; 344240Smckusick int mflg; 354240Smckusick int dflg; 364240Smckusick int fi; 374240Smckusick ino_t ino; 384240Smckusick int cginit; 394240Smckusick 404240Smckusick ino_t nrfile; 414240Smckusick ino_t ndfile; 424240Smckusick ino_t nbfile; 434240Smckusick ino_t ncfile; 444240Smckusick ino_t nmcfile; 454240Smckusick 464240Smckusick daddr_t nblock; 474240Smckusick daddr_t nfrag; 484240Smckusick daddr_t nindir; 494240Smckusick daddr_t niindir; 504240Smckusick 514240Smckusick daddr_t nffree; 524240Smckusick daddr_t nbfree; 534240Smckusick 544240Smckusick daddr_t ndup; 554240Smckusick 564240Smckusick int nerror; 574240Smckusick 584240Smckusick long atol(); 594240Smckusick daddr_t alloc(); 604240Smckusick #ifndef STANDALONE 614240Smckusick char *malloc(); 624240Smckusick #endif 634240Smckusick 644240Smckusick main(argc, argv) 654240Smckusick char *argv[]; 664240Smckusick { 674240Smckusick register i; 684240Smckusick long n; 694240Smckusick 704240Smckusick blist[0] = -1; 714240Smckusick #ifndef STANDALONE 724240Smckusick while (--argc) { 734240Smckusick argv++; 744240Smckusick if (**argv=='-') 754240Smckusick switch ((*argv)[1]) { 764240Smckusick case 'd': 774240Smckusick dflg++; 784240Smckusick continue; 794240Smckusick 804240Smckusick case 'm': 814240Smckusick mflg++; 824240Smckusick continue; 834240Smckusick 844240Smckusick case 's': 854240Smckusick sflg++; 864240Smckusick continue; 874240Smckusick 884240Smckusick case 'b': 894240Smckusick for(i=0; i<NB; i++) { 904240Smckusick n = atol(argv[1]); 914240Smckusick if(n == 0) 924240Smckusick break; 934240Smckusick blist[i] = n; 944240Smckusick argv++; 954240Smckusick argc--; 964240Smckusick } 974240Smckusick blist[i] = -1; 984240Smckusick continue; 994240Smckusick 1004240Smckusick default: 1014240Smckusick printf("Bad flag\n"); 1024240Smckusick } 1034240Smckusick check(*argv); 1044240Smckusick } 1054240Smckusick #else 1064240Smckusick { 1074240Smckusick static char fname[128]; 1084240Smckusick 1094240Smckusick printf("File: "); 1104240Smckusick gets(fname); 1114240Smckusick check(fname); 1124240Smckusick } 1134240Smckusick #endif 1144240Smckusick return(nerror); 1154240Smckusick } 1164240Smckusick 1174240Smckusick check(file) 1184240Smckusick char *file; 1194240Smckusick { 1204240Smckusick register i, j, c; 1214240Smckusick daddr_t d, cgd, cbase, b; 1224240Smckusick long n; 1234240Smckusick 1244240Smckusick fi = open(file, sflg?2:0); 1254240Smckusick if (fi < 0) { 1264240Smckusick printf("cannot open %s\n", file); 1274240Smckusick nerror |= 04; 1284240Smckusick return; 1294240Smckusick } 1304240Smckusick printf("%s:\n", file); 1314240Smckusick nrfile = 0; 1324240Smckusick ndfile = 0; 1334240Smckusick ncfile = 0; 1344240Smckusick nbfile = 0; 1354240Smckusick nmcfile = 0; 1364240Smckusick 1374240Smckusick nblock = 0; 1384240Smckusick nfrag = 0; 1394240Smckusick nindir = 0; 1404240Smckusick niindir = 0; 1414240Smckusick 1424240Smckusick ndup = 0; 1434240Smckusick #ifndef STANDALONE 1444240Smckusick sync(); 1454240Smckusick #endif 1464240Smckusick bread(SBLOCK, (char *)&sblock, BSIZE); 1474240Smckusick if (sblock.fs_magic != FS_MAGIC) { 1484240Smckusick printf("%s: bad magic number\n", file); 1494240Smckusick nerror |= 04; 1504240Smckusick return; 1514240Smckusick } 1524240Smckusick sblock.fs_cs = 1534240Smckusick (struct csum *)calloc(howmany(cssize(&sblock), BSIZE), BSIZE); 1544240Smckusick lseek(fi, csaddr(&sblock)*FSIZE, 0); 1554240Smckusick read(fi, (char *)sblock.fs_cs, cssize(&sblock)); 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 sflg = 0; 1674240Smckusick } 1684240Smckusick ino = 0; 1694240Smckusick cginit = 1; 1704240Smckusick if(!dflg) { 1714240Smckusick for (i=0; i<(unsigned)n; i++) 1724240Smckusick bmap[i] = 0; 1734240Smckusick for (c=0; c < sblock.fs_ncg; c++) { 1744240Smckusick cgd = cgtod(c, &sblock); 1754410Smckusic for (d = cgbase(c, &sblock); d < cgd; d += FRAG) 176*4429Smckusic chk(d, "badcg", BSIZE); 1774240Smckusick d = cgimin(c, &sblock); 1784240Smckusick while (cgd < d) { 179*4429Smckusic chk(cgd, "cg", BSIZE); 1804410Smckusic cgd += FRAG; 1814240Smckusick } 1824240Smckusick d = cgdmin(c, &sblock); 1834410Smckusic for (; cgd < d; cgd += FRAG) 184*4429Smckusic chk(cgd, "inode", BSIZE); 1854240Smckusick if (c == 0) { 1864410Smckusic d += howmany(cssize(&sblock), FSIZE); 1874410Smckusic for (; cgd < d; cgd += FRAG) 188*4429Smckusic chk(cgd, "csum", BSIZE); 1894240Smckusick } 1904240Smckusick } 1914240Smckusick } 1924240Smckusick cginit = 0; 1934240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1944240Smckusick bread(cgimin(c,&sblock), (char *)itab, 1954240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1964240Smckusick for (j=0; j < sblock.fs_ipg; j++) { 1974240Smckusick pass1(&itab[j]); 1984240Smckusick ino++; 1994240Smckusick } 2004240Smckusick } 2014240Smckusick ino = 0; 2024240Smckusick #ifndef STANDALONE 2034240Smckusick sync(); 2044240Smckusick #endif 2054240Smckusick bread(SBLOCK, (char *)&sblock, sizeof(sblock)); 2064240Smckusick if (sflg) { 2074240Smckusick makecg(); 2084240Smckusick close(fi); 2094240Smckusick #ifndef STANDALONE 2104240Smckusick if (bmap) 2114240Smckusick free(bmap); 2124240Smckusick #endif 2134240Smckusick return; 2144240Smckusick } 2154240Smckusick nffree = 0; 2164240Smckusick nbfree = 0; 2174240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2184240Smckusick cbase = cgbase(c,&sblock); 2194240Smckusick bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize); 2204240Smckusick for (b = 0; b < sblock.fs_fpg; b += FRAG) { 2214240Smckusick if (isblock(cgrp.cg_free, b / FRAG)) { 2224240Smckusick nbfree++; 223*4429Smckusic chk(cbase+b, "block", BSIZE); 2244240Smckusick } else { 2254240Smckusick for (d = 0; d < FRAG; d++) 2264240Smckusick if (isset(cgrp.cg_free, b+d)) { 227*4429Smckusic chk(cbase+b+d, "frag", FSIZE); 2284240Smckusick nffree++; 2294240Smckusick } 2304240Smckusick } 2314240Smckusick } 2324240Smckusick } 2334240Smckusick close(fi); 2344240Smckusick #ifndef STANDALONE 2354240Smckusick if (bmap) 2364240Smckusick free(bmap); 2374240Smckusick #endif 2384240Smckusick 2394240Smckusick i = nrfile + ndfile + ncfile + nbfile + nmcfile; 2404240Smckusick #ifndef STANDALONE 2414240Smckusick printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 2424240Smckusick i, nrfile, ndfile, nbfile, ncfile, nmcfile); 2434240Smckusick #else 2444240Smckusick printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 2454240Smckusick i, nrfile, ndfile, nbfile, ncfile, nmcfile); 2464240Smckusick #endif 247*4429Smckusic n = (nblock + nindir + niindir) * FRAG + nfrag; 2484240Smckusick #ifdef STANDALONE 2494240Smckusick printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2504240Smckusick n, nindir, niindir, nblock, nfrag); 251*4429Smckusic printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 2524240Smckusick nbfree, nffree); 2534240Smckusick #else 2544240Smckusick printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2554240Smckusick n, nindir, niindir, nblock, nfrag); 256*4429Smckusic printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 2574240Smckusick nbfree, nffree); 2584240Smckusick #endif 2594240Smckusick if(!dflg) { 2604240Smckusick n = 0; 2614410Smckusic for (d = 0; d < sblock.fs_size; d++) 262*4429Smckusic if(!duped(d, FSIZE)) { 2634240Smckusick if(mflg) 2644240Smckusick printf("%ld missing\n", d); 2654240Smckusick n++; 2664240Smckusick } 2674240Smckusick printf("missing%5ld\n", n); 2684240Smckusick } 2694240Smckusick } 2704240Smckusick 2714240Smckusick pass1(ip) 2724410Smckusic register struct dinode *ip; 2734240Smckusick { 274*4429Smckusic daddr_t ind1[NINDIR]; 275*4429Smckusic daddr_t ind2[NINDIR]; 276*4429Smckusic daddr_t db, ib; 277*4429Smckusic register int i, j, k, siz; 2784240Smckusick 2794240Smckusick i = ip->di_mode & IFMT; 2804240Smckusick if(i == 0) { 2814240Smckusick sblock.fs_nifree++; 2824240Smckusick return; 2834240Smckusick } 2844240Smckusick switch (i) { 2854240Smckusick case IFCHR: 2864240Smckusick ncfile++; 2874240Smckusick return; 2884240Smckusick case IFBLK: 2894240Smckusick nbfile++; 2904240Smckusick return; 2914240Smckusick case IFDIR: 2924240Smckusick ndfile++; 2934240Smckusick break; 2944240Smckusick case IFREG: 2954240Smckusick nrfile++; 2964240Smckusick break; 2974240Smckusick default: 2984240Smckusick printf("bad mode %u\n", ino); 2994240Smckusick return; 3004240Smckusick } 3014410Smckusic for (i = 0; i < NDADDR; i++) { 3024410Smckusic db = ip->di_db[i]; 3034410Smckusic if (db == 0) 3044240Smckusick continue; 305*4429Smckusic siz = dblksize(ip, i); 306*4429Smckusic chk(db, "data (block)", siz); 307*4429Smckusic if (siz == BSIZE) 308*4429Smckusic nblock++; 309*4429Smckusic else 310*4429Smckusic nfrag += howmany(siz, FSIZE); 3114240Smckusick } 3124410Smckusic for(i = 0; i < NIADDR; i++) { 3134410Smckusic ib = ip->di_ib[i]; 3144410Smckusic if(ib == 0) 3154240Smckusick continue; 316*4429Smckusic if (chk(ib, "1st indirect", BSIZE)) 3174410Smckusic continue; 318*4429Smckusic bread(ib, (char *)ind1, BSIZE); 3194240Smckusick nindir++; 3204410Smckusic for (j = 0; j < NINDIR; j++) { 3214410Smckusic ib = ind1[j]; 3224410Smckusic if (ib == 0) 3234240Smckusick continue; 3244410Smckusic if (i == 0) { 325*4429Smckusic siz = dblksize(ip, NDADDR + j); 326*4429Smckusic chk(ib, "data (large)", siz); 327*4429Smckusic if (siz == BSIZE) 328*4429Smckusic nblock++; 329*4429Smckusic else 330*4429Smckusic nfrag += howmany(siz, FSIZE); 3314240Smckusick continue; 3324240Smckusick } 333*4429Smckusic if (chk(ib, "2nd indirect", BSIZE)) 3344410Smckusic continue; 335*4429Smckusic bread(ib, (char *)ind2, BSIZE); 3364240Smckusick niindir++; 3374410Smckusic for (k = 0; k < NINDIR; k++) { 3384410Smckusic ib = ind2[k]; 3394410Smckusic if (ib == 0) 3404240Smckusick continue; 341*4429Smckusic siz = dblksize(ip, 342*4429Smckusic NDADDR + NINDIR * (i + j) + k); 343*4429Smckusic chk(ib, "data (huge)", siz); 344*4429Smckusic if (siz == BSIZE) 345*4429Smckusic nblock++; 346*4429Smckusic else 347*4429Smckusic nfrag += howmany(siz, FSIZE); 3484240Smckusick } 3494240Smckusick } 3504240Smckusick } 3514240Smckusick } 3524240Smckusick 353*4429Smckusic chk(bno, s, size) 3544410Smckusic daddr_t bno; 3554410Smckusic char *s; 356*4429Smckusic int size; 3574240Smckusick { 3584240Smckusick register n, cg; 3594240Smckusick 3604240Smckusick cg = dtog(bno, &sblock); 361*4429Smckusic if (cginit==0 && 362*4429Smckusic bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) { 3634240Smckusick printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 3644240Smckusick return(1); 3654240Smckusick } 366*4429Smckusic if (size == BSIZE) { 367*4429Smckusic if (duped(bno, size)) { 368*4429Smckusic printf("%ld dup block; inode=%u, class=%s\n", 369*4429Smckusic bno, ino, s); 370*4429Smckusic ndup += FRAG; 371*4429Smckusic } 372*4429Smckusic } else { 373*4429Smckusic for (n = 0; n < size / FSIZE; n++) { 374*4429Smckusic if (duped(bno + n, FSIZE)) { 375*4429Smckusic printf("%ld dup frag; inode=%u, class=%s\n", 376*4429Smckusic bno, ino, s); 377*4429Smckusic ndup++; 378*4429Smckusic } 379*4429Smckusic } 3804240Smckusick } 3814240Smckusick for (n=0; blist[n] != -1; n++) 3824240Smckusick if (bno == blist[n]) 3834240Smckusick printf("%ld arg; inode=%u, class=%s\n", bno, ino, s); 3844240Smckusick return(0); 3854240Smckusick } 3864240Smckusick 387*4429Smckusic duped(bno, size) 3884410Smckusic daddr_t bno; 389*4429Smckusic int size; 3904240Smckusick { 3914240Smckusick if(dflg) 3924240Smckusick return(0); 393*4429Smckusic if (size != FSIZE && size != BSIZE) 394*4429Smckusic printf("bad size %d to duped\n", size); 395*4429Smckusic if (size == FSIZE) { 3964410Smckusic if (isset(bmap, bno)) 3974410Smckusic return(1); 3984410Smckusic setbit(bmap, bno); 3994410Smckusic return (0); 4004410Smckusic } 4014410Smckusic if (bno % FRAG != 0) 4024410Smckusic printf("bad bno %d to duped\n", bno); 4034410Smckusic if (isblock(bmap, bno/FRAG)) 4044410Smckusic return (1); 4054410Smckusic setblock(bmap, bno/FRAG); 4064240Smckusick return(0); 4074240Smckusick } 4084240Smckusick 4094240Smckusick bread(bno, buf, cnt) 4104410Smckusic daddr_t bno; 4114410Smckusic char *buf; 4124240Smckusick { 4134240Smckusick register i; 4144240Smckusick 4154240Smckusick lseek(fi, bno*FSIZE, 0); 4164240Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 4174240Smckusick if (sflg) { 4184240Smckusick printf("No update\n"); 4194240Smckusick sflg = 0; 4204240Smckusick } 4214240Smckusick for(i=0; i<BSIZE; i++) 4224240Smckusick buf[i] = 0; 4234240Smckusick } 4244240Smckusick } 4254240Smckusick 4264240Smckusick bwrite(bno, buf, cnt) 4274410Smckusic daddr_t bno; 4284410Smckusic char *buf; 4294240Smckusick { 4304240Smckusick lseek(fi, bno*FSIZE, 0); 4314240Smckusick if (write(fi, buf, cnt) != cnt) 4324240Smckusick printf("write error %d\n", tell(fi)/BSIZE); 4334240Smckusick } 4344240Smckusick 4354240Smckusick makecg() 4364240Smckusick { 4374240Smckusick int c; 4384240Smckusick daddr_t dbase, d, dmin, dmax; 4394240Smckusick long i, j, s; 4404240Smckusick register struct csum *cs; 4414240Smckusick 4424240Smckusick sblock.fs_nbfree = 0; 4434240Smckusick sblock.fs_nffree = 0; 4444240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 4454240Smckusick bread(cgimin(c,&sblock), (char *)itab, 4464240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 4474240Smckusick dbase = cgbase(c, &sblock); 4484240Smckusick dmax = dbase + sblock.fs_fpg; 4494240Smckusick if (dmax > sblock.fs_size) 4504240Smckusick dmax = sblock.fs_size; 4514240Smckusick cs = &sblock.fs_cs[c]; 4524410Smckusic cgrp.cg_time = time((long)0); 4534240Smckusick cgrp.cg_magic = CG_MAGIC; 4544240Smckusick cgrp.cg_cgx = c; 4554240Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 4564240Smckusick cgrp.cg_niblk = sblock.fs_ipg; 4574240Smckusick cgrp.cg_ndblk = dmax - dbase; 4584240Smckusick cgrp.cg_ndir = 0; 4594240Smckusick cgrp.cg_nffree = 0; 4604240Smckusick cgrp.cg_nbfree = 0; 4614240Smckusick cgrp.cg_nifree = 0; 4624240Smckusick for (i = 0; i < sblock.fs_ipg; i++) 4634240Smckusick switch (itab[i].di_mode&IFMT) { 4644240Smckusick 4654240Smckusick case 0: 4664240Smckusick cgrp.cg_nifree++; 4674240Smckusick clrbit(cgrp.cg_iused, i); 4684240Smckusick continue; 4694240Smckusick 4704240Smckusick case IFDIR: 4714240Smckusick cgrp.cg_ndir++; 4724240Smckusick /* fall into ... */ 4734240Smckusick 4744240Smckusick default: 4754240Smckusick setbit(cgrp.cg_iused, i); 4764240Smckusick continue; 4774240Smckusick } 4784240Smckusick while (i < MAXIPG) { 4794240Smckusick clrbit(cgrp.cg_iused, i); 4804240Smckusick i++; 4814240Smckusick } 4824240Smckusick for (s = 0; s < MAXCPG; s++) 4834240Smckusick for (i = 0; i < NRPOS; i++) 4844240Smckusick cgrp.cg_b[s][i] = 0; 4854240Smckusick dmin = cgdmin(c, &sblock) - dbase; 4864240Smckusick if (c == 0) 4874240Smckusick dmin += howmany(cssize(&sblock), BSIZE) * FRAG; 4884240Smckusick for (d = 0; d < dmin; d++) 4894240Smckusick clrbit(cgrp.cg_free, d); 4904240Smckusick #define getbmap(i) isset(bmap, i) 4914240Smckusick for (; (d + FRAG) <= dmax - dbase; d += FRAG) { 4924240Smckusick j = 0; 4934240Smckusick for (i = 0; i < FRAG; i++) { 4944240Smckusick if (!getbmap(dbase+d+i)) { 4954240Smckusick setbit(cgrp.cg_free, d+i); 4964240Smckusick j++; 4974240Smckusick } else 4984240Smckusick clrbit(cgrp.cg_free, d+i); 4994240Smckusick } 5004240Smckusick if (j == FRAG) { 5014240Smckusick cgrp.cg_nbfree++; 5024240Smckusick s = d * NSPF; 5034240Smckusick cgrp.cg_b[s/sblock.fs_spc] 5044240Smckusick [s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]++; 5054240Smckusick } else 5064240Smckusick cgrp.cg_nffree += j; 5074240Smckusick } 5084240Smckusick for (; d < dmax - dbase; d++) { 5094240Smckusick if (!getbmap(dbase+d)) { 5104240Smckusick setbit(cgrp.cg_free, d); 5114240Smckusick cgrp.cg_nffree++; 5124240Smckusick } else 5134240Smckusick clrbit(cgrp.cg_free, d); 5144240Smckusick } 5154240Smckusick for (; d < MAXBPG; d++) 5164240Smckusick clrbit(cgrp.cg_free, d); 5174240Smckusick sblock.fs_nffree += cgrp.cg_nffree; 5184240Smckusick sblock.fs_nbfree += cgrp.cg_nbfree; 5194240Smckusick cs->cs_ndir = cgrp.cg_ndir; 5204240Smckusick cs->cs_nifree = cgrp.cg_nifree; 5214240Smckusick cs->cs_nbfree = cgrp.cg_nbfree; 5224240Smckusick bwrite(cgtod(c, &sblock), (char *)&cgrp, sblock.fs_cgsize); 5234240Smckusick } 5244240Smckusick sblock.fs_ronly = 0; 5254240Smckusick sblock.fs_fmod = 0; 5264240Smckusick bwrite(SBLOCK, (char *)&sblock, sizeof (sblock)); 5274410Smckusic lseek(fi, csaddr(&sblock) * FSIZE, 0); 5284240Smckusick if (write(fi,(char *)sblock.fs_cs,cssize(&sblock)) != cssize(&sblock)) 5294240Smckusick printf("write error %d\n", tell(fi)/BSIZE); 5304240Smckusick } 531