1*4410Smckusic static char *sccsid = "@(#)icheck.c 1.4 (Berkeley) 09/19/81"; 2*4410Smckusic 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 long szfrag; 494240Smckusick daddr_t nindir; 504240Smckusick long szindir; 514240Smckusick daddr_t niindir; 524240Smckusick 534240Smckusick daddr_t nffree; 544240Smckusick long szffree; 554240Smckusick daddr_t nbfree; 564240Smckusick 574240Smckusick daddr_t ndup; 584240Smckusick 594240Smckusick int nerror; 604240Smckusick 614240Smckusick long atol(); 624240Smckusick daddr_t alloc(); 634240Smckusick #ifndef STANDALONE 644240Smckusick char *malloc(); 654240Smckusick #endif 664240Smckusick 674240Smckusick main(argc, argv) 684240Smckusick char *argv[]; 694240Smckusick { 704240Smckusick register i; 714240Smckusick long n; 724240Smckusick 734240Smckusick blist[0] = -1; 744240Smckusick #ifndef STANDALONE 754240Smckusick while (--argc) { 764240Smckusick argv++; 774240Smckusick if (**argv=='-') 784240Smckusick switch ((*argv)[1]) { 794240Smckusick case 'd': 804240Smckusick dflg++; 814240Smckusick continue; 824240Smckusick 834240Smckusick case 'm': 844240Smckusick mflg++; 854240Smckusick continue; 864240Smckusick 874240Smckusick case 's': 884240Smckusick sflg++; 894240Smckusick continue; 904240Smckusick 914240Smckusick case 'b': 924240Smckusick for(i=0; i<NB; i++) { 934240Smckusick n = atol(argv[1]); 944240Smckusick if(n == 0) 954240Smckusick break; 964240Smckusick blist[i] = n; 974240Smckusick argv++; 984240Smckusick argc--; 994240Smckusick } 1004240Smckusick blist[i] = -1; 1014240Smckusick continue; 1024240Smckusick 1034240Smckusick default: 1044240Smckusick printf("Bad flag\n"); 1054240Smckusick } 1064240Smckusick check(*argv); 1074240Smckusick } 1084240Smckusick #else 1094240Smckusick { 1104240Smckusick static char fname[128]; 1114240Smckusick 1124240Smckusick printf("File: "); 1134240Smckusick gets(fname); 1144240Smckusick check(fname); 1154240Smckusick } 1164240Smckusick #endif 1174240Smckusick return(nerror); 1184240Smckusick } 1194240Smckusick 1204240Smckusick check(file) 1214240Smckusick char *file; 1224240Smckusick { 1234240Smckusick register i, j, c; 1244240Smckusick daddr_t d, cgd, cbase, b; 1254240Smckusick long n; 1264240Smckusick 1274240Smckusick fi = open(file, sflg?2:0); 1284240Smckusick if (fi < 0) { 1294240Smckusick printf("cannot open %s\n", file); 1304240Smckusick nerror |= 04; 1314240Smckusick return; 1324240Smckusick } 1334240Smckusick printf("%s:\n", file); 1344240Smckusick nrfile = 0; 1354240Smckusick ndfile = 0; 1364240Smckusick ncfile = 0; 1374240Smckusick nbfile = 0; 1384240Smckusick nmcfile = 0; 1394240Smckusick 1404240Smckusick nblock = 0; 1414240Smckusick nfrag = 0; 1424240Smckusick szfrag = 0; 1434240Smckusick nindir = 0; 1444240Smckusick szindir = 0; 1454240Smckusick niindir = 0; 1464240Smckusick 1474240Smckusick ndup = 0; 1484240Smckusick #ifndef STANDALONE 1494240Smckusick sync(); 1504240Smckusick #endif 1514240Smckusick bread(SBLOCK, (char *)&sblock, BSIZE); 1524240Smckusick if (sblock.fs_magic != FS_MAGIC) { 1534240Smckusick printf("%s: bad magic number\n", file); 1544240Smckusick nerror |= 04; 1554240Smckusick return; 1564240Smckusick } 1574240Smckusick sblock.fs_cs = 1584240Smckusick (struct csum *)calloc(howmany(cssize(&sblock), BSIZE), BSIZE); 1594240Smckusick lseek(fi, csaddr(&sblock)*FSIZE, 0); 1604240Smckusick read(fi, (char *)sblock.fs_cs, cssize(&sblock)); 1614240Smckusick ino = 0; 1624240Smckusick n = (sblock.fs_size*FRAG + BITS-1) / BITS; 1634240Smckusick #ifdef STANDALONE 1644240Smckusick bmap = NULL; 1654240Smckusick #else 1664240Smckusick bmap = malloc((unsigned)n); 1674240Smckusick #endif 1684240Smckusick if (bmap==NULL) { 1694240Smckusick printf("Not enough core; duplicates unchecked\n"); 1704240Smckusick dflg++; 1714240Smckusick sflg = 0; 1724240Smckusick } 1734240Smckusick ino = 0; 1744240Smckusick cginit = 1; 1754240Smckusick if(!dflg) { 1764240Smckusick for (i=0; i<(unsigned)n; i++) 1774240Smckusick bmap[i] = 0; 1784240Smckusick for (c=0; c < sblock.fs_ncg; c++) { 1794240Smckusick cgd = cgtod(c, &sblock); 180*4410Smckusic for (d = cgbase(c, &sblock); d < cgd; d += FRAG) 181*4410Smckusic chk(d, "badcg", 0); 1824240Smckusick d = cgimin(c, &sblock); 1834240Smckusick while (cgd < d) { 184*4410Smckusic chk(cgd, "cg", 0); 185*4410Smckusic cgd += FRAG; 1864240Smckusick } 1874240Smckusick d = cgdmin(c, &sblock); 188*4410Smckusic for (; cgd < d; cgd += FRAG) 189*4410Smckusic chk(cgd, "inode", 0); 1904240Smckusick if (c == 0) { 191*4410Smckusic d += howmany(cssize(&sblock), FSIZE); 192*4410Smckusic for (; cgd < d; cgd += FRAG) 193*4410Smckusic chk(cgd, "csum", 0); 1944240Smckusick } 1954240Smckusick } 1964240Smckusick } 1974240Smckusick cginit = 0; 1984240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1994240Smckusick bread(cgimin(c,&sblock), (char *)itab, 2004240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 2014240Smckusick for (j=0; j < sblock.fs_ipg; j++) { 2024240Smckusick pass1(&itab[j]); 2034240Smckusick ino++; 2044240Smckusick } 2054240Smckusick } 2064240Smckusick ino = 0; 2074240Smckusick #ifndef STANDALONE 2084240Smckusick sync(); 2094240Smckusick #endif 2104240Smckusick bread(SBLOCK, (char *)&sblock, sizeof(sblock)); 2114240Smckusick if (sflg) { 2124240Smckusick makecg(); 2134240Smckusick close(fi); 2144240Smckusick #ifndef STANDALONE 2154240Smckusick if (bmap) 2164240Smckusick free(bmap); 2174240Smckusick #endif 2184240Smckusick return; 2194240Smckusick } 2204240Smckusick nffree = 0; 2214240Smckusick szffree = 0; 2224240Smckusick nbfree = 0; 2234240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2244240Smckusick cbase = cgbase(c,&sblock); 2254240Smckusick bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize); 2264240Smckusick for (b = 0; b < sblock.fs_fpg; b += FRAG) { 2274240Smckusick if (isblock(cgrp.cg_free, b / FRAG)) { 2284240Smckusick nbfree++; 229*4410Smckusic chk(cbase+b, "block", 0); 2304240Smckusick } else { 2314240Smckusick for (d = 0; d < FRAG; d++) 2324240Smckusick if (isset(cgrp.cg_free, b+d)) { 233*4410Smckusic chk(cbase+b+d, "frag", 1); 2344240Smckusick nffree++; 2354240Smckusick szffree++; 2364240Smckusick } 2374240Smckusick } 2384240Smckusick } 2394240Smckusick } 2404240Smckusick close(fi); 2414240Smckusick #ifndef STANDALONE 2424240Smckusick if (bmap) 2434240Smckusick free(bmap); 2444240Smckusick #endif 2454240Smckusick 2464240Smckusick i = nrfile + ndfile + ncfile + nbfile + nmcfile; 2474240Smckusick #ifndef STANDALONE 2484240Smckusick printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 2494240Smckusick i, nrfile, ndfile, nbfile, ncfile, nmcfile); 2504240Smckusick #else 2514240Smckusick printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 2524240Smckusick i, nrfile, ndfile, nbfile, ncfile, nmcfile); 2534240Smckusick #endif 254*4410Smckusic n = (nblock + nindir + niindir) * FRAG + szfrag + szindir; 2554240Smckusick #ifdef STANDALONE 2564240Smckusick printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2574240Smckusick n, nindir, niindir, nblock, nfrag); 2584240Smckusick printf("free %ld (b=%ld,f=%ld)\n", szffree + FRAG * nbfree, 2594240Smckusick nbfree, nffree); 2604240Smckusick #else 2614240Smckusick printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2624240Smckusick n, nindir, niindir, nblock, nfrag); 2634240Smckusick printf("free %7ld (b=%ld,f=%ld)\n", szffree + FRAG * nbfree, 2644240Smckusick nbfree, nffree); 2654240Smckusick #endif 2664240Smckusick if(!dflg) { 2674240Smckusick n = 0; 268*4410Smckusic for (d = 0; d < sblock.fs_size; d++) 269*4410Smckusic if(!duped(d, 1)) { 2704240Smckusick if(mflg) 2714240Smckusick printf("%ld missing\n", d); 2724240Smckusick n++; 2734240Smckusick } 2744240Smckusick printf("missing%5ld\n", n); 2754240Smckusick } 2764240Smckusick } 2774240Smckusick 2784240Smckusick pass1(ip) 279*4410Smckusic register struct dinode *ip; 2804240Smckusick { 281*4410Smckusic fsbaddr_t ind1[NINDIR]; 282*4410Smckusic fsbaddr_t ind2[NINDIR]; 283*4410Smckusic fsbaddr_t db, ib; 284*4410Smckusic register i, j, k; 2854240Smckusick 2864240Smckusick i = ip->di_mode & IFMT; 2874240Smckusick if(i == 0) { 2884240Smckusick sblock.fs_nifree++; 2894240Smckusick return; 2904240Smckusick } 2914240Smckusick switch (i) { 2924240Smckusick case IFCHR: 2934240Smckusick ncfile++; 2944240Smckusick return; 2954240Smckusick case IFBLK: 2964240Smckusick nbfile++; 2974240Smckusick return; 2984240Smckusick case IFDIR: 2994240Smckusick ndfile++; 3004240Smckusick break; 3014240Smckusick case IFREG: 3024240Smckusick nrfile++; 3034240Smckusick break; 3044240Smckusick default: 3054240Smckusick printf("bad mode %u\n", ino); 3064240Smckusick return; 3074240Smckusick } 308*4410Smckusic for (i = 0; i < NDADDR; i++) { 309*4410Smckusic db = ip->di_db[i]; 310*4410Smckusic if (db == 0) 3114240Smckusick continue; 312*4410Smckusic chk(fsbtodb(db), "data (block)", isfrag(db)); 313*4410Smckusic nblock++; 3144240Smckusick } 315*4410Smckusic for(i = 0; i < NIADDR; i++) { 316*4410Smckusic ib = ip->di_ib[i]; 317*4410Smckusic if(ib == 0) 3184240Smckusick continue; 319*4410Smckusic if (chk(fsbtodb(ib), "1st indirect", 0)) 320*4410Smckusic continue; 321*4410Smckusic bread(fsbtodb(ib), (char *)ind1, BSIZE); 3224240Smckusick nindir++; 323*4410Smckusic for (j = 0; j < NINDIR; j++) { 324*4410Smckusic ib = ind1[j]; 325*4410Smckusic if (ib == 0) 3264240Smckusick continue; 327*4410Smckusic if (i == 0) { 328*4410Smckusic chk(fsbtodb(ib), "data (large)", isfrag(ib)); 3294240Smckusick nblock++; 3304240Smckusick continue; 3314240Smckusick } 332*4410Smckusic if (chk(fsbtodb(ib), "2nd indirect", 0)) 333*4410Smckusic continue; 334*4410Smckusic bread(fsbtodb(ib), (char *)ind2, BSIZE); 3354240Smckusick niindir++; 336*4410Smckusic for (k = 0; k < NINDIR; k++) { 337*4410Smckusic ib = ind2[k]; 338*4410Smckusic if (ib == 0) 3394240Smckusick continue; 340*4410Smckusic chk(fsbtodb(ib), "data (huge)", isfrag(ib)); 3414240Smckusick nblock++; 3424240Smckusick } 3434240Smckusick } 3444240Smckusick } 3454240Smckusick } 3464240Smckusick 347*4410Smckusic chk(bno, s, fragflg) 348*4410Smckusic daddr_t bno; 349*4410Smckusic char *s; 350*4410Smckusic int fragflg; 3514240Smckusick { 3524240Smckusick register n, cg; 3534240Smckusick 3544240Smckusick cg = dtog(bno, &sblock); 3554240Smckusick if (cginit==0 && bno<cgdmin(cg,&sblock) || bno>=FRAG*sblock.fs_size) { 3564240Smckusick printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 3574240Smckusick return(1); 3584240Smckusick } 359*4410Smckusic if (duped(bno, fragflg)) { 3604240Smckusick printf("%ld dup; inode=%u, class=%s\n", bno, ino, s); 3614240Smckusick ndup++; 3624240Smckusick } 3634240Smckusick for (n=0; blist[n] != -1; n++) 3644240Smckusick if (bno == blist[n]) 3654240Smckusick printf("%ld arg; inode=%u, class=%s\n", bno, ino, s); 3664240Smckusick return(0); 3674240Smckusick } 3684240Smckusick 369*4410Smckusic duped(bno, fragflg) 370*4410Smckusic daddr_t bno; 371*4410Smckusic int fragflg; 3724240Smckusick { 3734240Smckusick if(dflg) 3744240Smckusick return(0); 375*4410Smckusic if (fragflg) { 376*4410Smckusic if (isset(bmap, bno)) 377*4410Smckusic return(1); 378*4410Smckusic setbit(bmap, bno); 379*4410Smckusic return (0); 380*4410Smckusic } 381*4410Smckusic if (bno % FRAG != 0) 382*4410Smckusic printf("bad bno %d to duped\n", bno); 383*4410Smckusic if (isblock(bmap, bno/FRAG)) 384*4410Smckusic return (1); 385*4410Smckusic setblock(bmap, bno/FRAG); 3864240Smckusick return(0); 3874240Smckusick } 3884240Smckusick 3894240Smckusick bread(bno, buf, cnt) 390*4410Smckusic daddr_t bno; 391*4410Smckusic char *buf; 3924240Smckusick { 3934240Smckusick register i; 3944240Smckusick 3954240Smckusick lseek(fi, bno*FSIZE, 0); 3964240Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 3974240Smckusick if (sflg) { 3984240Smckusick printf("No update\n"); 3994240Smckusick sflg = 0; 4004240Smckusick } 4014240Smckusick for(i=0; i<BSIZE; i++) 4024240Smckusick buf[i] = 0; 4034240Smckusick } 4044240Smckusick } 4054240Smckusick 4064240Smckusick bwrite(bno, buf, cnt) 407*4410Smckusic daddr_t bno; 408*4410Smckusic char *buf; 4094240Smckusick { 4104240Smckusick lseek(fi, bno*FSIZE, 0); 4114240Smckusick if (write(fi, buf, cnt) != cnt) 4124240Smckusick printf("write error %d\n", tell(fi)/BSIZE); 4134240Smckusick } 4144240Smckusick 4154240Smckusick makecg() 4164240Smckusick { 4174240Smckusick int c; 4184240Smckusick daddr_t dbase, d, dmin, dmax; 4194240Smckusick long i, j, s; 4204240Smckusick register struct csum *cs; 4214240Smckusick 4224240Smckusick sblock.fs_nbfree = 0; 4234240Smckusick sblock.fs_nffree = 0; 4244240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 4254240Smckusick bread(cgimin(c,&sblock), (char *)itab, 4264240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 4274240Smckusick dbase = cgbase(c, &sblock); 4284240Smckusick dmax = dbase + sblock.fs_fpg; 4294240Smckusick if (dmax > sblock.fs_size) 4304240Smckusick dmax = sblock.fs_size; 4314240Smckusick cs = &sblock.fs_cs[c]; 432*4410Smckusic cgrp.cg_time = time((long)0); 4334240Smckusick cgrp.cg_magic = CG_MAGIC; 4344240Smckusick cgrp.cg_cgx = c; 4354240Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 4364240Smckusick cgrp.cg_niblk = sblock.fs_ipg; 4374240Smckusick cgrp.cg_ndblk = dmax - dbase; 4384240Smckusick cgrp.cg_ndir = 0; 4394240Smckusick cgrp.cg_nffree = 0; 4404240Smckusick cgrp.cg_nbfree = 0; 4414240Smckusick cgrp.cg_nifree = 0; 4424240Smckusick for (i = 0; i < sblock.fs_ipg; i++) 4434240Smckusick switch (itab[i].di_mode&IFMT) { 4444240Smckusick 4454240Smckusick case 0: 4464240Smckusick cgrp.cg_nifree++; 4474240Smckusick clrbit(cgrp.cg_iused, i); 4484240Smckusick continue; 4494240Smckusick 4504240Smckusick case IFDIR: 4514240Smckusick cgrp.cg_ndir++; 4524240Smckusick /* fall into ... */ 4534240Smckusick 4544240Smckusick default: 4554240Smckusick setbit(cgrp.cg_iused, i); 4564240Smckusick continue; 4574240Smckusick } 4584240Smckusick while (i < MAXIPG) { 4594240Smckusick clrbit(cgrp.cg_iused, i); 4604240Smckusick i++; 4614240Smckusick } 4624240Smckusick for (s = 0; s < MAXCPG; s++) 4634240Smckusick for (i = 0; i < NRPOS; i++) 4644240Smckusick cgrp.cg_b[s][i] = 0; 4654240Smckusick dmin = cgdmin(c, &sblock) - dbase; 4664240Smckusick if (c == 0) 4674240Smckusick dmin += howmany(cssize(&sblock), BSIZE) * FRAG; 4684240Smckusick for (d = 0; d < dmin; d++) 4694240Smckusick clrbit(cgrp.cg_free, d); 4704240Smckusick #define getbmap(i) isset(bmap, i) 4714240Smckusick for (; (d + FRAG) <= dmax - dbase; d += FRAG) { 4724240Smckusick j = 0; 4734240Smckusick for (i = 0; i < FRAG; i++) { 4744240Smckusick if (!getbmap(dbase+d+i)) { 4754240Smckusick setbit(cgrp.cg_free, d+i); 4764240Smckusick j++; 4774240Smckusick } else 4784240Smckusick clrbit(cgrp.cg_free, d+i); 4794240Smckusick } 4804240Smckusick if (j == FRAG) { 4814240Smckusick cgrp.cg_nbfree++; 4824240Smckusick s = d * NSPF; 4834240Smckusick cgrp.cg_b[s/sblock.fs_spc] 4844240Smckusick [s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]++; 4854240Smckusick } else 4864240Smckusick cgrp.cg_nffree += j; 4874240Smckusick } 4884240Smckusick for (; d < dmax - dbase; d++) { 4894240Smckusick if (!getbmap(dbase+d)) { 4904240Smckusick setbit(cgrp.cg_free, d); 4914240Smckusick cgrp.cg_nffree++; 4924240Smckusick } else 4934240Smckusick clrbit(cgrp.cg_free, d); 4944240Smckusick } 4954240Smckusick for (; d < MAXBPG; d++) 4964240Smckusick clrbit(cgrp.cg_free, d); 4974240Smckusick sblock.fs_nffree += cgrp.cg_nffree; 4984240Smckusick sblock.fs_nbfree += cgrp.cg_nbfree; 4994240Smckusick cs->cs_ndir = cgrp.cg_ndir; 5004240Smckusick cs->cs_nifree = cgrp.cg_nifree; 5014240Smckusick cs->cs_nbfree = cgrp.cg_nbfree; 5024240Smckusick bwrite(cgtod(c, &sblock), (char *)&cgrp, sblock.fs_cgsize); 5034240Smckusick } 5044240Smckusick sblock.fs_ronly = 0; 5054240Smckusick sblock.fs_fmod = 0; 5064240Smckusick bwrite(SBLOCK, (char *)&sblock, sizeof (sblock)); 507*4410Smckusic lseek(fi, csaddr(&sblock) * FSIZE, 0); 5084240Smckusick if (write(fi,(char *)sblock.fs_cs,cssize(&sblock)) != cssize(&sblock)) 5094240Smckusick printf("write error %d\n", tell(fi)/BSIZE); 5104240Smckusick } 511