1*9298Smckusick static char *sccsid = "@(#)icheck.c 2.4 (Berkeley) 11/18/82"; 24410Smckusic 34240Smckusick /* 44240Smckusick * icheck 54240Smckusick */ 64240Smckusick #define NB 500 74240Smckusick #define MAXFN 500 85349Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) 94240Smckusick 104240Smckusick #ifndef STANDALONE 114240Smckusick #include <stdio.h> 124240Smckusick #endif 136490Smckusick #ifndef SIMFS 146490Smckusick #include <sys/param.h> 156490Smckusick #include <sys/inode.h> 166490Smckusick #include <sys/fs.h> 176490Smckusick #else 184240Smckusick #include "../h/param.h" 194240Smckusick #include "../h/inode.h" 204240Smckusick #include "../h/fs.h" 216490Smckusick #endif 224240Smckusick 234240Smckusick union { 244240Smckusick struct fs sb; 255326Smckusic char pad[MAXBSIZE]; 264240Smckusick } sbun; 274240Smckusick #define sblock sbun.sb 284240Smckusick 294240Smckusick union { 304240Smckusick struct cg cg; 315326Smckusic char pad[MAXBSIZE]; 324240Smckusick } cgun; 334240Smckusick #define cgrp cgun.cg 344240Smckusick 354240Smckusick struct dinode itab[MAXIPG]; 364240Smckusick daddr_t blist[NB]; 37*9298Smckusick daddr_t fsblist[NB]; 384240Smckusick char *bmap; 394240Smckusick 404240Smckusick int mflg; 415098Smckusic int sflg; 424240Smckusick int dflg; 434240Smckusick int fi; 444240Smckusick ino_t ino; 454240Smckusick int cginit; 464240Smckusick 474240Smckusick ino_t nrfile; 484240Smckusick ino_t ndfile; 494240Smckusick ino_t nbfile; 504240Smckusick ino_t ncfile; 516286Smckusick ino_t nlfile; 524240Smckusick 534240Smckusick daddr_t nblock; 544240Smckusick daddr_t nfrag; 554240Smckusick daddr_t nindir; 564240Smckusick daddr_t niindir; 574240Smckusick 584240Smckusick daddr_t nffree; 594240Smckusick daddr_t nbfree; 604240Smckusick 614240Smckusick daddr_t ndup; 624240Smckusick 634240Smckusick int nerror; 644240Smckusick 655098Smckusic extern int inside[], around[]; 665326Smckusic extern unsigned char *fragtbl[]; 675098Smckusic 684240Smckusick long atol(); 694240Smckusick #ifndef STANDALONE 704240Smckusick char *malloc(); 715098Smckusic char *calloc(); 724240Smckusick #endif 734240Smckusick 744240Smckusick main(argc, argv) 755098Smckusic int argc; 765098Smckusic char *argv[]; 774240Smckusick { 784240Smckusick register i; 794240Smckusick long n; 804240Smckusick 814240Smckusick blist[0] = -1; 824240Smckusick #ifndef STANDALONE 834240Smckusick while (--argc) { 844240Smckusick argv++; 854240Smckusick if (**argv=='-') 864240Smckusick switch ((*argv)[1]) { 874240Smckusick case 'd': 884240Smckusick dflg++; 894240Smckusick continue; 904240Smckusick 914240Smckusick case 'm': 924240Smckusick mflg++; 934240Smckusick continue; 944240Smckusick 955098Smckusic case 's': 965098Smckusic sflg++; 975098Smckusic continue; 985098Smckusic 994240Smckusick case 'b': 1004240Smckusick for(i=0; i<NB; i++) { 1014240Smckusick n = atol(argv[1]); 1024240Smckusick if(n == 0) 1034240Smckusick break; 1044240Smckusick blist[i] = n; 1054240Smckusick argv++; 1064240Smckusick argc--; 1074240Smckusick } 1084240Smckusick blist[i] = -1; 1094240Smckusick continue; 1104240Smckusick 1114240Smckusick default: 1124240Smckusick printf("Bad flag\n"); 1134240Smckusick } 1144240Smckusick check(*argv); 1154240Smckusick } 1164240Smckusick #else 1174240Smckusick { 1184240Smckusick static char fname[128]; 1194240Smckusick 1204240Smckusick printf("File: "); 1214240Smckusick gets(fname); 1224240Smckusick check(fname); 1234240Smckusick } 1244240Smckusick #endif 1254240Smckusick return(nerror); 1264240Smckusick } 1274240Smckusick 1284240Smckusick check(file) 1295098Smckusic char *file; 1304240Smckusick { 1314240Smckusick register i, j, c; 1324240Smckusick daddr_t d, cgd, cbase, b; 1334240Smckusick long n; 134*9298Smckusick char buf[BUFSIZ]; 1354240Smckusick 1365098Smckusic fi = open(file, sflg ? 2 : 0); 1374240Smckusick if (fi < 0) { 1385098Smckusic perror(file); 1394240Smckusick nerror |= 04; 1404240Smckusick return; 1414240Smckusick } 1424240Smckusick printf("%s:\n", file); 1434240Smckusick nrfile = 0; 1444240Smckusick ndfile = 0; 1454240Smckusick ncfile = 0; 1464240Smckusick nbfile = 0; 1476286Smckusick nlfile = 0; 1484240Smckusick 1494240Smckusick nblock = 0; 1504240Smckusick nfrag = 0; 1514240Smckusick nindir = 0; 1524240Smckusick niindir = 0; 1534240Smckusick 1544240Smckusick ndup = 0; 1554240Smckusick #ifndef STANDALONE 1564240Smckusick sync(); 1574240Smckusick #endif 1585326Smckusic getsb(&sblock, file); 1595326Smckusic if (nerror) 1604240Smckusick return; 161*9298Smckusick for (n=0; blist[n] != -1; n++) 162*9298Smckusick fsblist[n] = dbtofsb(&sblock, blist[n]); 1634240Smckusick ino = 0; 1645098Smckusic n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short)); 1654240Smckusick #ifdef STANDALONE 1664240Smckusick bmap = NULL; 1674240Smckusick #else 1684240Smckusick bmap = malloc((unsigned)n); 1694240Smckusick #endif 1704240Smckusick if (bmap==NULL) { 1714240Smckusick printf("Not enough core; duplicates unchecked\n"); 1724240Smckusick dflg++; 1735098Smckusic if (sflg) { 1745098Smckusic printf("No Updates\n"); 1755098Smckusic sflg = 0; 1765098Smckusic } 1774240Smckusick } 1784240Smckusick ino = 0; 1794240Smckusick cginit = 1; 1806534Smckusick if (!dflg) { 1816534Smckusick for (i = 0; i < (unsigned)n; i++) 1824240Smckusick bmap[i] = 0; 1836534Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1845382Smckusic cgd = cgtod(&sblock, c); 1856534Smckusick if (c == 0) 1866534Smckusick d = cgbase(&sblock, c); 1876534Smckusick else 1886534Smckusick d = cgsblock(&sblock, c); 189*9298Smckusick sprintf(buf, "spare super block %d", c); 1906534Smckusick for (; d < cgd; d += sblock.fs_frag) 191*9298Smckusick chk(d, buf, sblock.fs_bsize); 1925382Smckusic d = cgimin(&sblock, c); 193*9298Smckusick sprintf(buf, "cylinder group %d", c); 1944240Smckusick while (cgd < d) { 195*9298Smckusick chk(cgd, buf, sblock.fs_bsize); 1965326Smckusic cgd += sblock.fs_frag; 1974240Smckusick } 1985382Smckusic d = cgdmin(&sblock, c); 199*9298Smckusick i = INOPB(&sblock); 200*9298Smckusick for (; cgd < d; cgd += sblock.fs_frag) { 201*9298Smckusick sprintf(buf, "inodes %d-%d", ino, ino + i); 202*9298Smckusick chk(cgd, buf, sblock.fs_bsize); 203*9298Smckusick ino += i; 204*9298Smckusick } 2054240Smckusick if (c == 0) { 2066534Smckusick d += howmany(sblock.fs_cssize, sblock.fs_fsize); 2076534Smckusick for (; cgd < d; cgd++) 2086534Smckusick chk(cgd, "csum", sblock.fs_fsize); 2094240Smckusick } 2104240Smckusick } 2114240Smckusick } 212*9298Smckusick ino = 0; 2134240Smckusick cginit = 0; 2144240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2155382Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 2164240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 2174240Smckusick for (j=0; j < sblock.fs_ipg; j++) { 2184240Smckusick pass1(&itab[j]); 2194240Smckusick ino++; 2204240Smckusick } 2214240Smckusick } 2224240Smckusick ino = 0; 2234240Smckusick #ifndef STANDALONE 2244240Smckusick sync(); 2254240Smckusick #endif 2265098Smckusic if (sflg) { 2275098Smckusic makecg(); 2285098Smckusic close(fi); 2295098Smckusic #ifndef STANDALONE 2305098Smckusic if (bmap) 2315098Smckusic free(bmap); 2325098Smckusic #endif 2335098Smckusic return; 2345098Smckusic } 2354240Smckusick nffree = 0; 2364240Smckusick nbfree = 0; 2374240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2385382Smckusic cbase = cgbase(&sblock, c); 2395382Smckusic bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp, 2405326Smckusic sblock.fs_cgsize); 2416534Smckusick if (cgrp.cg_magic != CG_MAGIC) 2426534Smckusick printf("cg %d: bad magic number\n", c); 2435326Smckusic for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { 2445326Smckusic if (isblock(&sblock, cgrp.cg_free, 2455326Smckusic b / sblock.fs_frag)) { 2464240Smckusick nbfree++; 247*9298Smckusick chk(cbase+b, "free block", sblock.fs_bsize); 2484240Smckusick } else { 2495326Smckusic for (d = 0; d < sblock.fs_frag; d++) 2504240Smckusick if (isset(cgrp.cg_free, b+d)) { 251*9298Smckusick chk(cbase+b+d, "free frag", sblock.fs_fsize); 2524240Smckusick nffree++; 2534240Smckusick } 2544240Smckusick } 2554240Smckusick } 2564240Smckusick } 2574240Smckusick close(fi); 2584240Smckusick #ifndef STANDALONE 2594240Smckusick if (bmap) 2604240Smckusick free(bmap); 2614240Smckusick #endif 2624240Smckusick 2636286Smckusick i = nrfile + ndfile + ncfile + nbfile + nlfile; 2644240Smckusick #ifndef STANDALONE 2656286Smckusick printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", 2666286Smckusick i, nrfile, ndfile, nbfile, ncfile, nlfile); 2674240Smckusick #else 2686286Smckusick printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", 2696286Smckusick i, nrfile, ndfile, nbfile, ncfile, nlfile); 2704240Smckusick #endif 2715326Smckusic n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag; 2724240Smckusick #ifdef STANDALONE 2734240Smckusick printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2744240Smckusick n, nindir, niindir, nblock, nfrag); 2755326Smckusic printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, 2764240Smckusick nbfree, nffree); 2774240Smckusick #else 2784240Smckusick printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2794240Smckusick n, nindir, niindir, nblock, nfrag); 2805326Smckusic printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, 2814240Smckusick nbfree, nffree); 2824240Smckusick #endif 2834240Smckusick if(!dflg) { 2844240Smckusick n = 0; 2854410Smckusic for (d = 0; d < sblock.fs_size; d++) 2865326Smckusic if(!duped(d, sblock.fs_fsize)) { 2874240Smckusick if(mflg) 2884240Smckusick printf("%ld missing\n", d); 2894240Smckusick n++; 2904240Smckusick } 2914240Smckusick printf("missing%5ld\n", n); 2924240Smckusick } 2934240Smckusick } 2944240Smckusick 2954240Smckusick pass1(ip) 2964410Smckusic register struct dinode *ip; 2974240Smckusick { 2985326Smckusic daddr_t ind1[MAXNINDIR]; 2995326Smckusic daddr_t ind2[MAXNINDIR]; 3004429Smckusic daddr_t db, ib; 3014429Smckusic register int i, j, k, siz; 302*9298Smckusick int lbn; 303*9298Smckusick char buf[BUFSIZ]; 3044240Smckusick 3054240Smckusick i = ip->di_mode & IFMT; 3064790Smckusic if(i == 0) 3074240Smckusick return; 3084240Smckusick switch (i) { 3094240Smckusick case IFCHR: 3104240Smckusick ncfile++; 3114240Smckusick return; 3124240Smckusick case IFBLK: 3134240Smckusick nbfile++; 3144240Smckusick return; 3154240Smckusick case IFDIR: 3164240Smckusick ndfile++; 3174240Smckusick break; 3184240Smckusick case IFREG: 3194240Smckusick nrfile++; 3204240Smckusick break; 3216286Smckusick case IFLNK: 3226286Smckusick nlfile++; 3236286Smckusick break; 3244240Smckusick default: 3254240Smckusick printf("bad mode %u\n", ino); 3264240Smckusick return; 3274240Smckusick } 3284410Smckusic for (i = 0; i < NDADDR; i++) { 3294410Smckusic db = ip->di_db[i]; 3304410Smckusic if (db == 0) 3314240Smckusick continue; 3325326Smckusic siz = dblksize(&sblock, ip, i); 333*9298Smckusick sprintf(buf, "logical data block %d", i); 334*9298Smckusick chk(db, buf, siz); 3355326Smckusic if (siz == sblock.fs_bsize) 3364429Smckusic nblock++; 3374429Smckusic else 3385326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3394240Smckusick } 3404410Smckusic for(i = 0; i < NIADDR; i++) { 3414410Smckusic ib = ip->di_ib[i]; 342*9298Smckusick if (ib == 0) 3434240Smckusick continue; 3445326Smckusic if (chk(ib, "1st indirect", sblock.fs_bsize)) 3454410Smckusic continue; 3465326Smckusic bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize); 3474240Smckusick nindir++; 3485326Smckusic for (j = 0; j < NINDIR(&sblock); j++) { 3494410Smckusic ib = ind1[j]; 3504410Smckusic if (ib == 0) 3514240Smckusick continue; 3524410Smckusic if (i == 0) { 353*9298Smckusick lbn = NDADDR + j; 354*9298Smckusick siz = dblksize(&sblock, ip, lbn); 355*9298Smckusick sprintf(buf, "logical data block %d", lbn); 356*9298Smckusick chk(ib, buf, siz); 3575326Smckusic if (siz == sblock.fs_bsize) 3584429Smckusic nblock++; 3594429Smckusic else 3605326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3614240Smckusick continue; 3624240Smckusick } 3635326Smckusic if (chk(ib, "2nd indirect", sblock.fs_bsize)) 3644410Smckusic continue; 3655326Smckusic bread(fsbtodb(&sblock, ib), (char *)ind2, 3665326Smckusic sblock.fs_bsize); 3674240Smckusick niindir++; 3685326Smckusic for (k = 0; k < NINDIR(&sblock); k++) { 3694410Smckusic ib = ind2[k]; 3704410Smckusic if (ib == 0) 3714240Smckusick continue; 372*9298Smckusick lbn = NDADDR + NINDIR(&sblock) * (i + j) + k; 373*9298Smckusick siz = dblksize(&sblock, ip, lbn); 374*9298Smckusick sprintf(buf, "logical data block %d", lbn); 375*9298Smckusick chk(ib, buf, siz); 3765326Smckusic if (siz == sblock.fs_bsize) 3774429Smckusic nblock++; 3784429Smckusic else 3795326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3804240Smckusick } 3814240Smckusick } 3824240Smckusick } 3834240Smckusick } 3844240Smckusick 3854429Smckusic chk(bno, s, size) 3864410Smckusic daddr_t bno; 3874410Smckusic char *s; 3884429Smckusic int size; 3894240Smckusick { 3904240Smckusick register n, cg; 3915957Smckusic int frags; 3924240Smckusick 3935382Smckusic cg = dtog(&sblock, bno); 3946534Smckusick if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) { 3954240Smckusick printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 3964240Smckusick return(1); 3974240Smckusick } 398*9298Smckusick frags = numfrags(&sblock, size); 399*9298Smckusick if (frags == sblock.fs_frag) { 4004429Smckusic if (duped(bno, size)) { 4014429Smckusic printf("%ld dup block; inode=%u, class=%s\n", 4024429Smckusic bno, ino, s); 4035326Smckusic ndup += sblock.fs_frag; 4044429Smckusic } 4054429Smckusic } else { 4065957Smckusic for (n = 0; n < frags; n++) { 4075326Smckusic if (duped(bno + n, sblock.fs_fsize)) { 4084429Smckusic printf("%ld dup frag; inode=%u, class=%s\n", 4094429Smckusic bno, ino, s); 4104429Smckusic ndup++; 4114429Smckusic } 4124429Smckusic } 4134240Smckusick } 4144240Smckusick for (n=0; blist[n] != -1; n++) 415*9298Smckusick if (fsblist[n] >= bno && fsblist[n] < bno + frags) 416*9298Smckusick printf("%ld arg; frag %d of %d, inode=%u, class=%s\n", 417*9298Smckusick blist[n], fsblist[n] - bno, frags, ino, s); 4184240Smckusick return(0); 4194240Smckusick } 4204240Smckusick 4214429Smckusic duped(bno, size) 4224410Smckusic daddr_t bno; 4234429Smckusic int size; 4244240Smckusick { 4254240Smckusick if(dflg) 4264240Smckusick return(0); 4275326Smckusic if (size != sblock.fs_fsize && size != sblock.fs_bsize) 4284429Smckusic printf("bad size %d to duped\n", size); 4295326Smckusic if (size == sblock.fs_fsize) { 4304410Smckusic if (isset(bmap, bno)) 4314410Smckusic return(1); 4324410Smckusic setbit(bmap, bno); 4334410Smckusic return (0); 4344410Smckusic } 4355326Smckusic if (bno % sblock.fs_frag != 0) 4364410Smckusic printf("bad bno %d to duped\n", bno); 4375326Smckusic if (isblock(&sblock, bmap, bno/sblock.fs_frag)) 4384410Smckusic return (1); 4395326Smckusic setblock(&sblock, bmap, bno/sblock.fs_frag); 4404240Smckusick return(0); 4414240Smckusick } 4424240Smckusick 4435098Smckusic makecg() 4445098Smckusic { 4455098Smckusic int c, blk; 4466534Smckusick daddr_t dbase, d, dlower, dupper, dmax; 4475098Smckusic long i, j, s; 4485098Smckusic register struct csum *cs; 4495098Smckusic register struct dinode *dp; 4505098Smckusic 4515098Smckusic sblock.fs_cstotal.cs_nbfree = 0; 4525098Smckusic sblock.fs_cstotal.cs_nffree = 0; 4535098Smckusic sblock.fs_cstotal.cs_nifree = 0; 4545098Smckusic sblock.fs_cstotal.cs_ndir = 0; 4555098Smckusic for (c = 0; c < sblock.fs_ncg; c++) { 4565382Smckusic dbase = cgbase(&sblock, c); 4575098Smckusic dmax = dbase + sblock.fs_fpg; 4585410Smckusic if (dmax > sblock.fs_size) { 4595410Smckusic for ( ; dmax >= sblock.fs_size; dmax--) 4605400Smckusic clrbit(cgrp.cg_free, dmax - dbase); 4615410Smckusic dmax++; 4625410Smckusic } 4636534Smckusick dlower = cgsblock(&sblock, c) - dbase; 4646534Smckusick dupper = cgdmin(&sblock, c) - dbase; 4655326Smckusic cs = &sblock.fs_cs(&sblock, c); 4665098Smckusic cgrp.cg_time = time(0); 4675098Smckusic cgrp.cg_magic = CG_MAGIC; 4685098Smckusic cgrp.cg_cgx = c; 4698143Smckusick if (c == sblock.fs_ncg - 1) 4708143Smckusick cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 4718143Smckusick else 4728143Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 4735098Smckusic cgrp.cg_niblk = sblock.fs_ipg; 4745098Smckusic cgrp.cg_ndblk = dmax - dbase; 4755098Smckusic cgrp.cg_cs.cs_ndir = 0; 4765098Smckusic cgrp.cg_cs.cs_nffree = 0; 4775098Smckusic cgrp.cg_cs.cs_nbfree = 0; 4785098Smckusic cgrp.cg_cs.cs_nifree = 0; 4796534Smckusick cgrp.cg_rotor = 0; 4806534Smckusick cgrp.cg_frotor = 0; 4815098Smckusic cgrp.cg_irotor = 0; 4825326Smckusic for (i = 0; i < sblock.fs_frag; i++) 4835098Smckusic cgrp.cg_frsum[i] = 0; 4845382Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 4855098Smckusic sblock.fs_ipg * sizeof(struct dinode)); 4865098Smckusic for (i = 0; i < sblock.fs_ipg; i++) { 4875945Smckusic cgrp.cg_cs.cs_nifree++; 4885945Smckusic clrbit(cgrp.cg_iused, i); 4895098Smckusic dp = &itab[i]; 4905098Smckusic if ((dp->di_mode & IFMT) != 0) { 4915098Smckusic if ((dp->di_mode & IFMT) == IFDIR) 4925098Smckusic cgrp.cg_cs.cs_ndir++; 4935945Smckusic cgrp.cg_cs.cs_nifree--; 4945098Smckusic setbit(cgrp.cg_iused, i); 4955098Smckusic continue; 4965098Smckusic } 4975098Smckusic } 4985098Smckusic while (i < MAXIPG) { 4995098Smckusic clrbit(cgrp.cg_iused, i); 5005098Smckusic i++; 5015098Smckusic } 5025338Smckusic if (c == 0) 5035338Smckusic for (i = 0; i < ROOTINO; i++) { 5045338Smckusic setbit(cgrp.cg_iused, i); 5055338Smckusic cgrp.cg_cs.cs_nifree--; 5065338Smckusic } 5075372Smckusic for (s = 0; s < MAXCPG; s++) { 5085372Smckusic cgrp.cg_btot[s] = 0; 5095098Smckusic for (i = 0; i < NRPOS; i++) 5105098Smckusic cgrp.cg_b[s][i] = 0; 5115372Smckusic } 5125098Smckusic if (c == 0) { 5136534Smckusick dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 5145098Smckusic } 5156534Smckusick for (d = dlower; d < dupper; d++) 5165098Smckusic clrbit(cgrp.cg_free, d); 5176534Smckusick for (d = 0; (d + sblock.fs_frag) <= dmax - dbase; 5186534Smckusick d += sblock.fs_frag) { 5195098Smckusic j = 0; 5205326Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5216534Smckusick if (!isset(bmap, dbase + d + i)) { 5226534Smckusick setbit(cgrp.cg_free, d + i); 5235098Smckusic j++; 5245098Smckusic } else 5255098Smckusic clrbit(cgrp.cg_free, d+i); 5265098Smckusic } 5275326Smckusic if (j == sblock.fs_frag) { 5285098Smckusic cgrp.cg_cs.cs_nbfree++; 5295372Smckusic cgrp.cg_btot[cbtocylno(&sblock, d)]++; 5305364Smckusic cgrp.cg_b[cbtocylno(&sblock, d)] 5315364Smckusic [cbtorpos(&sblock, d)]++; 5325098Smckusic } else if (j > 0) { 5335098Smckusic cgrp.cg_cs.cs_nffree += j; 5346534Smckusick blk = blkmap(&sblock, cgrp.cg_free, d); 5355326Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 5365098Smckusic } 5375098Smckusic } 5385098Smckusic for (j = d; d < dmax - dbase; d++) { 5396534Smckusick if (!isset(bmap, dbase + d)) { 5405098Smckusic setbit(cgrp.cg_free, d); 5415098Smckusic cgrp.cg_cs.cs_nffree++; 5425098Smckusic } else 5435098Smckusic clrbit(cgrp.cg_free, d); 5445098Smckusic } 5458143Smckusick for (; d % sblock.fs_frag != 0; d++) 5468143Smckusick clrbit(cgrp.cg_free, d); 5475098Smckusic if (j != d) { 5486534Smckusick blk = blkmap(&sblock, cgrp.cg_free, j); 5495326Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 5505098Smckusic } 5518143Smckusick for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++) 5528143Smckusick clrblock(&sblock, cgrp.cg_free, d); 5535098Smckusic sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree; 5545098Smckusic sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree; 5555098Smckusic sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree; 5565098Smckusic sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir; 5575098Smckusic *cs = cgrp.cg_cs; 5585382Smckusic bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp, 5595326Smckusic sblock.fs_cgsize); 5605098Smckusic } 5616534Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 5626534Smckusick bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 5636534Smckusick (char *)sblock.fs_csp[j], 5646534Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 5656534Smckusick sblock.fs_cssize - i : sblock.fs_bsize); 5665098Smckusic } 5675098Smckusic sblock.fs_ronly = 0; 5685098Smckusic sblock.fs_fmod = 0; 5695349Smckusic bwrite(SBLOCK, (char *)&sblock, SBSIZE); 5705098Smckusic } 5715098Smckusic 5725098Smckusic /* 5735098Smckusic * update the frsum fields to reflect addition or deletion 5745098Smckusic * of some frags 5755098Smckusic */ 5765326Smckusic fragacct(fs, fragmap, fraglist, cnt) 5775326Smckusic struct fs *fs; 5785098Smckusic int fragmap; 5795098Smckusic long fraglist[]; 5805098Smckusic int cnt; 5815098Smckusic { 5825098Smckusic int inblk; 5835098Smckusic register int field, subfield; 5845098Smckusic register int siz, pos; 5855098Smckusic 5865326Smckusic inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1); 5875098Smckusic fragmap <<= 1; 5885326Smckusic for (siz = 1; siz < fs->fs_frag; siz++) { 5896291Smckusick if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 5905098Smckusic continue; 5915098Smckusic field = around[siz]; 5925098Smckusic subfield = inside[siz]; 5935326Smckusic for (pos = siz; pos <= fs->fs_frag; pos++) { 5945098Smckusic if ((fragmap & field) == subfield) { 5955098Smckusic fraglist[siz] += cnt; 5965098Smckusic pos += siz; 5975098Smckusic field <<= siz; 5985098Smckusic subfield <<= siz; 5995098Smckusic } 6005098Smckusic field <<= 1; 6015098Smckusic subfield <<= 1; 6025098Smckusic } 6035098Smckusic } 6045098Smckusic } 6055098Smckusic 6065326Smckusic getsb(fs, file) 6075326Smckusic register struct fs *fs; 6085326Smckusic char *file; 6095326Smckusic { 6106534Smckusick int i, j, size; 6115326Smckusic 6125349Smckusic if (bread(SBLOCK, fs, SBSIZE)) { 6135326Smckusic printf("bad super block"); 6145326Smckusic perror(file); 6155326Smckusic nerror |= 04; 6165326Smckusic return; 6175326Smckusic } 6185326Smckusic if (fs->fs_magic != FS_MAGIC) { 6195326Smckusic printf("%s: bad magic number\n", file); 6205326Smckusic nerror |= 04; 6215326Smckusic return; 6225326Smckusic } 6236534Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 6246534Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 6256534Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 6266534Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, size); 6276534Smckusick bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)), 6286534Smckusick (char *)fs->fs_csp[j], size); 6295326Smckusic } 6305326Smckusic } 6315326Smckusic 6325098Smckusic bwrite(blk, buf, size) 6335098Smckusic char *buf; 6345098Smckusic daddr_t blk; 6355098Smckusic register size; 6365098Smckusic { 6375326Smckusic if (lseek(fi, blk * DEV_BSIZE, 0) < 0) { 6385098Smckusic perror("FS SEEK"); 6395098Smckusic return(1); 6405098Smckusic } 6415098Smckusic if (write(fi, buf, size) != size) { 6425098Smckusic perror("FS WRITE"); 6435098Smckusic return(1); 6445098Smckusic } 6455326Smckusic return (0); 6465098Smckusic } 6475098Smckusic 6484240Smckusick bread(bno, buf, cnt) 6494410Smckusic daddr_t bno; 6504410Smckusic char *buf; 6514240Smckusick { 6524240Smckusick register i; 6534240Smckusick 6545326Smckusic lseek(fi, bno * DEV_BSIZE, 0); 6554240Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 6565098Smckusic if (sflg) { 6575098Smckusic printf("No Update\n"); 6585098Smckusic sflg = 0; 6595098Smckusic } 6605326Smckusic for(i=0; i<sblock.fs_bsize; i++) 6614240Smckusick buf[i] = 0; 6625326Smckusic return (1); 6634240Smckusick } 6645326Smckusic return (0); 6654240Smckusick } 6665326Smckusic 6675326Smckusic /* 6688143Smckusick * check if a block is available 6695326Smckusic */ 6705326Smckusic isblock(fs, cp, h) 6715326Smckusic struct fs *fs; 6725326Smckusic unsigned char *cp; 6735326Smckusic int h; 6745326Smckusic { 6755326Smckusic unsigned char mask; 6765326Smckusic 6775326Smckusic switch (fs->fs_frag) { 6785326Smckusic case 8: 6795326Smckusic return (cp[h] == 0xff); 6805326Smckusic case 4: 6815326Smckusic mask = 0x0f << ((h & 0x1) << 2); 6825326Smckusic return ((cp[h >> 1] & mask) == mask); 6835326Smckusic case 2: 6845326Smckusic mask = 0x03 << ((h & 0x3) << 1); 6855326Smckusic return ((cp[h >> 2] & mask) == mask); 6865326Smckusic case 1: 6875326Smckusic mask = 0x01 << (h & 0x7); 6885326Smckusic return ((cp[h >> 3] & mask) == mask); 6895326Smckusic default: 6908143Smckusick #ifdef STANDALONE 6918143Smckusick printf("isblock bad fs_frag %d\n", fs->fs_frag); 6928143Smckusick #else 6935326Smckusic fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 6948143Smckusick #endif 6955326Smckusic return; 6965326Smckusic } 6975326Smckusic } 6985326Smckusic 6998143Smckusick /* 7008143Smckusick * take a block out of the map 7018143Smckusick */ 7028143Smckusick clrblock(fs, cp, h) 7038143Smckusick struct fs *fs; 7048143Smckusick unsigned char *cp; 7058143Smckusick int h; 7068143Smckusick { 7078143Smckusick switch ((fs)->fs_frag) { 7088143Smckusick case 8: 7098143Smckusick cp[h] = 0; 7108143Smckusick return; 7118143Smckusick case 4: 7128143Smckusick cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 7138143Smckusick return; 7148143Smckusick case 2: 7158143Smckusick cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 7168143Smckusick return; 7178143Smckusick case 1: 7188143Smckusick cp[h >> 3] &= ~(0x01 << (h & 0x7)); 7198143Smckusick return; 7208143Smckusick default: 7218143Smckusick #ifdef STANDALONE 7228143Smckusick printf("clrblock bad fs_frag %d\n", fs->fs_frag); 7238143Smckusick #else 7248143Smckusick fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); 7258143Smckusick #endif 7268143Smckusick return; 7278143Smckusick } 7288143Smckusick } 7298143Smckusick 7308143Smckusick /* 7318143Smckusick * put a block into the map 7328143Smckusick */ 7335326Smckusic setblock(fs, cp, h) 7345326Smckusic struct fs *fs; 7355326Smckusic unsigned char *cp; 7365326Smckusic int h; 7375326Smckusic { 7385326Smckusic switch (fs->fs_frag) { 7395326Smckusic case 8: 7405326Smckusic cp[h] = 0xff; 7415326Smckusic return; 7425326Smckusic case 4: 7435326Smckusic cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 7445326Smckusic return; 7455326Smckusic case 2: 7465326Smckusic cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 7475326Smckusic return; 7485326Smckusic case 1: 7495326Smckusic cp[h >> 3] |= (0x01 << (h & 0x7)); 7505326Smckusic return; 7515326Smckusic default: 7528143Smckusick #ifdef STANDALONE 7538143Smckusick printf("setblock bad fs_frag %d\n", fs->fs_frag); 7548143Smckusick #else 7555326Smckusic fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); 7568143Smckusick #endif 7575326Smckusic return; 7585326Smckusic } 7595326Smckusic } 7606490Smckusick 7616490Smckusick /* tables.c 4.1 82/03/25 */ 7626490Smckusick 7636490Smckusick /* merged into kernel: tables.c 2.1 3/25/82 */ 7646490Smckusick 7656490Smckusick /* last monet version: partab.c 4.2 81/03/08 */ 7666490Smckusick 7676490Smckusick /* 7686490Smckusick * bit patterns for identifying fragments in the block map 7696490Smckusick * used as ((map & around) == inside) 7706490Smckusick */ 7716490Smckusick int around[9] = { 7726490Smckusick 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff 7736490Smckusick }; 7746490Smckusick int inside[9] = { 7756490Smckusick 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe 7766490Smckusick }; 7776490Smckusick 7786490Smckusick /* 7796490Smckusick * given a block map bit pattern, the frag tables tell whether a 7806490Smckusick * particular size fragment is available. 7816490Smckusick * 7826490Smckusick * used as: 7836490Smckusick * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { 7846490Smckusick * at least one fragment of the indicated size is available 7856490Smckusick * } 7866490Smckusick * 7876490Smckusick * These tables are used by the scanc instruction on the VAX to 7886490Smckusick * quickly find an appropriate fragment. 7896490Smckusick */ 7906490Smckusick 7916490Smckusick unsigned char fragtbl124[256] = { 7926490Smckusick 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, 7936490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, 7946490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7956490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7966490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7976490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7986490Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 7996490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 8006490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8016490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8026490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8036490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8046490Smckusick 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, 8056490Smckusick 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, 8066490Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 8076490Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 8086490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8096490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8106490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8116490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8126490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8136490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8146490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 8156490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 8166490Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 8176490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 8186490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 8196490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 8206490Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 8216490Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 8226490Smckusick 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, 8236490Smckusick 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, 8246490Smckusick }; 8256490Smckusick 8266490Smckusick unsigned char fragtbl8[256] = { 8276490Smckusick 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 8286490Smckusick 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, 8296490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8306490Smckusick 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, 8316490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8326490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8336490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8346490Smckusick 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, 8356490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8366490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8376490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8386490Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 8396490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8406490Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 8416490Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 8426490Smckusick 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, 8436490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8446490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8456490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8466490Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 8476490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8486490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8496490Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 8506490Smckusick 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, 8516490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8526490Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 8536490Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 8546490Smckusick 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, 8556490Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 8566490Smckusick 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, 8576490Smckusick 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, 8586490Smckusick 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, 8596490Smckusick }; 8606490Smckusick 8616490Smckusick /* 8626490Smckusick * the actual fragtbl array 8636490Smckusick */ 8646490Smckusick unsigned char *fragtbl[MAXFRAG + 1] = { 8656490Smckusick 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, 8666490Smckusick }; 867