1*8143Smckusick static char *sccsid = "@(#)icheck.c 2.3 (Berkeley) 09/10/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]; 374240Smckusick char *bmap; 384240Smckusick 394240Smckusick int mflg; 405098Smckusic int sflg; 414240Smckusick int dflg; 424240Smckusick int fi; 434240Smckusick ino_t ino; 444240Smckusick int cginit; 454240Smckusick 464240Smckusick ino_t nrfile; 474240Smckusick ino_t ndfile; 484240Smckusick ino_t nbfile; 494240Smckusick ino_t ncfile; 506286Smckusick ino_t nlfile; 514240Smckusick 524240Smckusick daddr_t nblock; 534240Smckusick daddr_t nfrag; 544240Smckusick daddr_t nindir; 554240Smckusick daddr_t niindir; 564240Smckusick 574240Smckusick daddr_t nffree; 584240Smckusick daddr_t nbfree; 594240Smckusick 604240Smckusick daddr_t ndup; 614240Smckusick 624240Smckusick int nerror; 634240Smckusick 645098Smckusic extern int inside[], around[]; 655326Smckusic extern unsigned char *fragtbl[]; 665098Smckusic 674240Smckusick long atol(); 684240Smckusick #ifndef STANDALONE 694240Smckusick char *malloc(); 705098Smckusic char *calloc(); 714240Smckusick #endif 724240Smckusick 734240Smckusick main(argc, argv) 745098Smckusic int argc; 755098Smckusic char *argv[]; 764240Smckusick { 774240Smckusick register i; 784240Smckusick long n; 794240Smckusick 804240Smckusick blist[0] = -1; 814240Smckusick #ifndef STANDALONE 824240Smckusick while (--argc) { 834240Smckusick argv++; 844240Smckusick if (**argv=='-') 854240Smckusick switch ((*argv)[1]) { 864240Smckusick case 'd': 874240Smckusick dflg++; 884240Smckusick continue; 894240Smckusick 904240Smckusick case 'm': 914240Smckusick mflg++; 924240Smckusick continue; 934240Smckusick 945098Smckusic case 's': 955098Smckusic sflg++; 965098Smckusic continue; 975098Smckusic 984240Smckusick case 'b': 994240Smckusick for(i=0; i<NB; i++) { 1004240Smckusick n = atol(argv[1]); 1014240Smckusick if(n == 0) 1024240Smckusick break; 1034240Smckusick blist[i] = n; 1044240Smckusick argv++; 1054240Smckusick argc--; 1064240Smckusick } 1074240Smckusick blist[i] = -1; 1084240Smckusick continue; 1094240Smckusick 1104240Smckusick default: 1114240Smckusick printf("Bad flag\n"); 1124240Smckusick } 1134240Smckusick check(*argv); 1144240Smckusick } 1154240Smckusick #else 1164240Smckusick { 1174240Smckusick static char fname[128]; 1184240Smckusick 1194240Smckusick printf("File: "); 1204240Smckusick gets(fname); 1214240Smckusick check(fname); 1224240Smckusick } 1234240Smckusick #endif 1244240Smckusick return(nerror); 1254240Smckusick } 1264240Smckusick 1274240Smckusick check(file) 1285098Smckusic char *file; 1294240Smckusick { 1304240Smckusick register i, j, c; 1314240Smckusick daddr_t d, cgd, cbase, b; 1324240Smckusick long n; 1334240Smckusick 1345098Smckusic fi = open(file, sflg ? 2 : 0); 1354240Smckusick if (fi < 0) { 1365098Smckusic perror(file); 1374240Smckusick nerror |= 04; 1384240Smckusick return; 1394240Smckusick } 1404240Smckusick printf("%s:\n", file); 1414240Smckusick nrfile = 0; 1424240Smckusick ndfile = 0; 1434240Smckusick ncfile = 0; 1444240Smckusick nbfile = 0; 1456286Smckusick nlfile = 0; 1464240Smckusick 1474240Smckusick nblock = 0; 1484240Smckusick nfrag = 0; 1494240Smckusick nindir = 0; 1504240Smckusick niindir = 0; 1514240Smckusick 1524240Smckusick ndup = 0; 1534240Smckusick #ifndef STANDALONE 1544240Smckusick sync(); 1554240Smckusick #endif 1565326Smckusic getsb(&sblock, file); 1575326Smckusic if (nerror) 1584240Smckusick return; 1594240Smckusick ino = 0; 1605098Smckusic n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short)); 1614240Smckusick #ifdef STANDALONE 1624240Smckusick bmap = NULL; 1634240Smckusick #else 1644240Smckusick bmap = malloc((unsigned)n); 1654240Smckusick #endif 1664240Smckusick if (bmap==NULL) { 1674240Smckusick printf("Not enough core; duplicates unchecked\n"); 1684240Smckusick dflg++; 1695098Smckusic if (sflg) { 1705098Smckusic printf("No Updates\n"); 1715098Smckusic sflg = 0; 1725098Smckusic } 1734240Smckusick } 1744240Smckusick ino = 0; 1754240Smckusick cginit = 1; 1766534Smckusick if (!dflg) { 1776534Smckusick for (i = 0; i < (unsigned)n; i++) 1784240Smckusick bmap[i] = 0; 1796534Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1805382Smckusic cgd = cgtod(&sblock, c); 1816534Smckusick if (c == 0) 1826534Smckusick d = cgbase(&sblock, c); 1836534Smckusick else 1846534Smckusick d = cgsblock(&sblock, c); 1856534Smckusick for (; d < cgd; d += sblock.fs_frag) 1865326Smckusic chk(d, "badcg", sblock.fs_bsize); 1875382Smckusic d = cgimin(&sblock, c); 1884240Smckusick while (cgd < d) { 1895326Smckusic chk(cgd, "cg", sblock.fs_bsize); 1905326Smckusic cgd += sblock.fs_frag; 1914240Smckusick } 1925382Smckusic d = cgdmin(&sblock, c); 1935326Smckusic for (; cgd < d; cgd += sblock.fs_frag) 1945326Smckusic chk(cgd, "inode", sblock.fs_bsize); 1954240Smckusick if (c == 0) { 1966534Smckusick d += howmany(sblock.fs_cssize, sblock.fs_fsize); 1976534Smckusick for (; cgd < d; cgd++) 1986534Smckusick chk(cgd, "csum", sblock.fs_fsize); 1994240Smckusick } 2004240Smckusick } 2014240Smckusick } 2024240Smckusick cginit = 0; 2034240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2045382Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 2054240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 2064240Smckusick for (j=0; j < sblock.fs_ipg; j++) { 2074240Smckusick pass1(&itab[j]); 2084240Smckusick ino++; 2094240Smckusick } 2104240Smckusick } 2114240Smckusick ino = 0; 2124240Smckusick #ifndef STANDALONE 2134240Smckusick sync(); 2144240Smckusick #endif 2155098Smckusic if (sflg) { 2165098Smckusic makecg(); 2175098Smckusic close(fi); 2185098Smckusic #ifndef STANDALONE 2195098Smckusic if (bmap) 2205098Smckusic free(bmap); 2215098Smckusic #endif 2225098Smckusic return; 2235098Smckusic } 2244240Smckusick nffree = 0; 2254240Smckusick nbfree = 0; 2264240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2275382Smckusic cbase = cgbase(&sblock, c); 2285382Smckusic bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp, 2295326Smckusic sblock.fs_cgsize); 2306534Smckusick if (cgrp.cg_magic != CG_MAGIC) 2316534Smckusick printf("cg %d: bad magic number\n", c); 2325326Smckusic for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { 2335326Smckusic if (isblock(&sblock, cgrp.cg_free, 2345326Smckusic b / sblock.fs_frag)) { 2354240Smckusick nbfree++; 2365326Smckusic chk(cbase+b, "block", sblock.fs_bsize); 2374240Smckusick } else { 2385326Smckusic for (d = 0; d < sblock.fs_frag; d++) 2394240Smckusick if (isset(cgrp.cg_free, b+d)) { 2405326Smckusic chk(cbase+b+d, "frag", sblock.fs_fsize); 2414240Smckusick nffree++; 2424240Smckusick } 2434240Smckusick } 2444240Smckusick } 2454240Smckusick } 2464240Smckusick close(fi); 2474240Smckusick #ifndef STANDALONE 2484240Smckusick if (bmap) 2494240Smckusick free(bmap); 2504240Smckusick #endif 2514240Smckusick 2526286Smckusick i = nrfile + ndfile + ncfile + nbfile + nlfile; 2534240Smckusick #ifndef STANDALONE 2546286Smckusick printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", 2556286Smckusick i, nrfile, ndfile, nbfile, ncfile, nlfile); 2564240Smckusick #else 2576286Smckusick printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", 2586286Smckusick i, nrfile, ndfile, nbfile, ncfile, nlfile); 2594240Smckusick #endif 2605326Smckusic n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag; 2614240Smckusick #ifdef STANDALONE 2624240Smckusick printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2634240Smckusick n, nindir, niindir, nblock, nfrag); 2645326Smckusic printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, 2654240Smckusick nbfree, nffree); 2664240Smckusick #else 2674240Smckusick printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2684240Smckusick n, nindir, niindir, nblock, nfrag); 2695326Smckusic printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, 2704240Smckusick nbfree, nffree); 2714240Smckusick #endif 2724240Smckusick if(!dflg) { 2734240Smckusick n = 0; 2744410Smckusic for (d = 0; d < sblock.fs_size; d++) 2755326Smckusic if(!duped(d, sblock.fs_fsize)) { 2764240Smckusick if(mflg) 2774240Smckusick printf("%ld missing\n", d); 2784240Smckusick n++; 2794240Smckusick } 2804240Smckusick printf("missing%5ld\n", n); 2814240Smckusick } 2824240Smckusick } 2834240Smckusick 2844240Smckusick pass1(ip) 2854410Smckusic register struct dinode *ip; 2864240Smckusick { 2875326Smckusic daddr_t ind1[MAXNINDIR]; 2885326Smckusic daddr_t ind2[MAXNINDIR]; 2894429Smckusic daddr_t db, ib; 2904429Smckusic register int i, j, k, siz; 2914240Smckusick 2924240Smckusick i = ip->di_mode & IFMT; 2934790Smckusic if(i == 0) 2944240Smckusick return; 2954240Smckusick switch (i) { 2964240Smckusick case IFCHR: 2974240Smckusick ncfile++; 2984240Smckusick return; 2994240Smckusick case IFBLK: 3004240Smckusick nbfile++; 3014240Smckusick return; 3024240Smckusick case IFDIR: 3034240Smckusick ndfile++; 3044240Smckusick break; 3054240Smckusick case IFREG: 3064240Smckusick nrfile++; 3074240Smckusick break; 3086286Smckusick case IFLNK: 3096286Smckusick nlfile++; 3106286Smckusick break; 3114240Smckusick default: 3124240Smckusick printf("bad mode %u\n", ino); 3134240Smckusick return; 3144240Smckusick } 3154410Smckusic for (i = 0; i < NDADDR; i++) { 3164410Smckusic db = ip->di_db[i]; 3174410Smckusic if (db == 0) 3184240Smckusick continue; 3195326Smckusic siz = dblksize(&sblock, ip, i); 3204429Smckusic chk(db, "data (block)", siz); 3215326Smckusic if (siz == sblock.fs_bsize) 3224429Smckusic nblock++; 3234429Smckusic else 3245326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3254240Smckusick } 3264410Smckusic for(i = 0; i < NIADDR; i++) { 3274410Smckusic ib = ip->di_ib[i]; 3284410Smckusic if(ib == 0) 3294240Smckusick continue; 3305326Smckusic if (chk(ib, "1st indirect", sblock.fs_bsize)) 3314410Smckusic continue; 3325326Smckusic bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize); 3334240Smckusick nindir++; 3345326Smckusic for (j = 0; j < NINDIR(&sblock); j++) { 3354410Smckusic ib = ind1[j]; 3364410Smckusic if (ib == 0) 3374240Smckusick continue; 3384410Smckusic if (i == 0) { 3395326Smckusic siz = dblksize(&sblock, ip, NDADDR + j); 3404429Smckusic chk(ib, "data (large)", siz); 3415326Smckusic if (siz == sblock.fs_bsize) 3424429Smckusic nblock++; 3434429Smckusic else 3445326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3454240Smckusick continue; 3464240Smckusick } 3475326Smckusic if (chk(ib, "2nd indirect", sblock.fs_bsize)) 3484410Smckusic continue; 3495326Smckusic bread(fsbtodb(&sblock, ib), (char *)ind2, 3505326Smckusic sblock.fs_bsize); 3514240Smckusick niindir++; 3525326Smckusic for (k = 0; k < NINDIR(&sblock); k++) { 3534410Smckusic ib = ind2[k]; 3544410Smckusic if (ib == 0) 3554240Smckusick continue; 3565326Smckusic siz = dblksize(&sblock, ip, 3575326Smckusic NDADDR + NINDIR(&sblock) * (i + j) + k); 3584429Smckusic chk(ib, "data (huge)", siz); 3595326Smckusic if (siz == sblock.fs_bsize) 3604429Smckusic nblock++; 3614429Smckusic else 3625326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3634240Smckusick } 3644240Smckusick } 3654240Smckusick } 3664240Smckusick } 3674240Smckusick 3684429Smckusic chk(bno, s, size) 3694410Smckusic daddr_t bno; 3704410Smckusic char *s; 3714429Smckusic int size; 3724240Smckusick { 3734240Smckusick register n, cg; 3745957Smckusic int frags; 3754240Smckusick 3765382Smckusic cg = dtog(&sblock, bno); 3776534Smckusick if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) { 3784240Smckusick printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 3794240Smckusick return(1); 3804240Smckusick } 3815326Smckusic if (size == sblock.fs_bsize) { 3824429Smckusic if (duped(bno, size)) { 3834429Smckusic printf("%ld dup block; inode=%u, class=%s\n", 3844429Smckusic bno, ino, s); 3855326Smckusic ndup += sblock.fs_frag; 3864429Smckusic } 3874429Smckusic } else { 3885957Smckusic frags = numfrags(&sblock, size); 3895957Smckusic for (n = 0; n < frags; n++) { 3905326Smckusic if (duped(bno + n, sblock.fs_fsize)) { 3914429Smckusic printf("%ld dup frag; inode=%u, class=%s\n", 3924429Smckusic bno, ino, s); 3934429Smckusic ndup++; 3944429Smckusic } 3954429Smckusic } 3964240Smckusick } 3974240Smckusick for (n=0; blist[n] != -1; n++) 3984240Smckusick if (bno == blist[n]) 3994240Smckusick printf("%ld arg; inode=%u, class=%s\n", bno, ino, s); 4004240Smckusick return(0); 4014240Smckusick } 4024240Smckusick 4034429Smckusic duped(bno, size) 4044410Smckusic daddr_t bno; 4054429Smckusic int size; 4064240Smckusick { 4074240Smckusick if(dflg) 4084240Smckusick return(0); 4095326Smckusic if (size != sblock.fs_fsize && size != sblock.fs_bsize) 4104429Smckusic printf("bad size %d to duped\n", size); 4115326Smckusic if (size == sblock.fs_fsize) { 4124410Smckusic if (isset(bmap, bno)) 4134410Smckusic return(1); 4144410Smckusic setbit(bmap, bno); 4154410Smckusic return (0); 4164410Smckusic } 4175326Smckusic if (bno % sblock.fs_frag != 0) 4184410Smckusic printf("bad bno %d to duped\n", bno); 4195326Smckusic if (isblock(&sblock, bmap, bno/sblock.fs_frag)) 4204410Smckusic return (1); 4215326Smckusic setblock(&sblock, bmap, bno/sblock.fs_frag); 4224240Smckusick return(0); 4234240Smckusick } 4244240Smckusick 4255098Smckusic makecg() 4265098Smckusic { 4275098Smckusic int c, blk; 4286534Smckusick daddr_t dbase, d, dlower, dupper, dmax; 4295098Smckusic long i, j, s; 4305098Smckusic register struct csum *cs; 4315098Smckusic register struct dinode *dp; 4325098Smckusic 4335098Smckusic sblock.fs_cstotal.cs_nbfree = 0; 4345098Smckusic sblock.fs_cstotal.cs_nffree = 0; 4355098Smckusic sblock.fs_cstotal.cs_nifree = 0; 4365098Smckusic sblock.fs_cstotal.cs_ndir = 0; 4375098Smckusic for (c = 0; c < sblock.fs_ncg; c++) { 4385382Smckusic dbase = cgbase(&sblock, c); 4395098Smckusic dmax = dbase + sblock.fs_fpg; 4405410Smckusic if (dmax > sblock.fs_size) { 4415410Smckusic for ( ; dmax >= sblock.fs_size; dmax--) 4425400Smckusic clrbit(cgrp.cg_free, dmax - dbase); 4435410Smckusic dmax++; 4445410Smckusic } 4456534Smckusick dlower = cgsblock(&sblock, c) - dbase; 4466534Smckusick dupper = cgdmin(&sblock, c) - dbase; 4475326Smckusic cs = &sblock.fs_cs(&sblock, c); 4485098Smckusic cgrp.cg_time = time(0); 4495098Smckusic cgrp.cg_magic = CG_MAGIC; 4505098Smckusic cgrp.cg_cgx = c; 451*8143Smckusick if (c == sblock.fs_ncg - 1) 452*8143Smckusick cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 453*8143Smckusick else 454*8143Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 4555098Smckusic cgrp.cg_niblk = sblock.fs_ipg; 4565098Smckusic cgrp.cg_ndblk = dmax - dbase; 4575098Smckusic cgrp.cg_cs.cs_ndir = 0; 4585098Smckusic cgrp.cg_cs.cs_nffree = 0; 4595098Smckusic cgrp.cg_cs.cs_nbfree = 0; 4605098Smckusic cgrp.cg_cs.cs_nifree = 0; 4616534Smckusick cgrp.cg_rotor = 0; 4626534Smckusick cgrp.cg_frotor = 0; 4635098Smckusic cgrp.cg_irotor = 0; 4645326Smckusic for (i = 0; i < sblock.fs_frag; i++) 4655098Smckusic cgrp.cg_frsum[i] = 0; 4665382Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 4675098Smckusic sblock.fs_ipg * sizeof(struct dinode)); 4685098Smckusic for (i = 0; i < sblock.fs_ipg; i++) { 4695945Smckusic cgrp.cg_cs.cs_nifree++; 4705945Smckusic clrbit(cgrp.cg_iused, i); 4715098Smckusic dp = &itab[i]; 4725098Smckusic if ((dp->di_mode & IFMT) != 0) { 4735098Smckusic if ((dp->di_mode & IFMT) == IFDIR) 4745098Smckusic cgrp.cg_cs.cs_ndir++; 4755945Smckusic cgrp.cg_cs.cs_nifree--; 4765098Smckusic setbit(cgrp.cg_iused, i); 4775098Smckusic continue; 4785098Smckusic } 4795098Smckusic } 4805098Smckusic while (i < MAXIPG) { 4815098Smckusic clrbit(cgrp.cg_iused, i); 4825098Smckusic i++; 4835098Smckusic } 4845338Smckusic if (c == 0) 4855338Smckusic for (i = 0; i < ROOTINO; i++) { 4865338Smckusic setbit(cgrp.cg_iused, i); 4875338Smckusic cgrp.cg_cs.cs_nifree--; 4885338Smckusic } 4895372Smckusic for (s = 0; s < MAXCPG; s++) { 4905372Smckusic cgrp.cg_btot[s] = 0; 4915098Smckusic for (i = 0; i < NRPOS; i++) 4925098Smckusic cgrp.cg_b[s][i] = 0; 4935372Smckusic } 4945098Smckusic if (c == 0) { 4956534Smckusick dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 4965098Smckusic } 4976534Smckusick for (d = dlower; d < dupper; d++) 4985098Smckusic clrbit(cgrp.cg_free, d); 4996534Smckusick for (d = 0; (d + sblock.fs_frag) <= dmax - dbase; 5006534Smckusick d += sblock.fs_frag) { 5015098Smckusic j = 0; 5025326Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5036534Smckusick if (!isset(bmap, dbase + d + i)) { 5046534Smckusick setbit(cgrp.cg_free, d + i); 5055098Smckusic j++; 5065098Smckusic } else 5075098Smckusic clrbit(cgrp.cg_free, d+i); 5085098Smckusic } 5095326Smckusic if (j == sblock.fs_frag) { 5105098Smckusic cgrp.cg_cs.cs_nbfree++; 5115372Smckusic cgrp.cg_btot[cbtocylno(&sblock, d)]++; 5125364Smckusic cgrp.cg_b[cbtocylno(&sblock, d)] 5135364Smckusic [cbtorpos(&sblock, d)]++; 5145098Smckusic } else if (j > 0) { 5155098Smckusic cgrp.cg_cs.cs_nffree += j; 5166534Smckusick blk = blkmap(&sblock, cgrp.cg_free, d); 5175326Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 5185098Smckusic } 5195098Smckusic } 5205098Smckusic for (j = d; d < dmax - dbase; d++) { 5216534Smckusick if (!isset(bmap, dbase + d)) { 5225098Smckusic setbit(cgrp.cg_free, d); 5235098Smckusic cgrp.cg_cs.cs_nffree++; 5245098Smckusic } else 5255098Smckusic clrbit(cgrp.cg_free, d); 5265098Smckusic } 527*8143Smckusick for (; d % sblock.fs_frag != 0; d++) 528*8143Smckusick clrbit(cgrp.cg_free, d); 5295098Smckusic if (j != d) { 5306534Smckusick blk = blkmap(&sblock, cgrp.cg_free, j); 5315326Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 5325098Smckusic } 533*8143Smckusick for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++) 534*8143Smckusick clrblock(&sblock, cgrp.cg_free, d); 5355098Smckusic sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree; 5365098Smckusic sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree; 5375098Smckusic sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree; 5385098Smckusic sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir; 5395098Smckusic *cs = cgrp.cg_cs; 5405382Smckusic bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp, 5415326Smckusic sblock.fs_cgsize); 5425098Smckusic } 5436534Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 5446534Smckusick bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 5456534Smckusick (char *)sblock.fs_csp[j], 5466534Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 5476534Smckusick sblock.fs_cssize - i : sblock.fs_bsize); 5485098Smckusic } 5495098Smckusic sblock.fs_ronly = 0; 5505098Smckusic sblock.fs_fmod = 0; 5515349Smckusic bwrite(SBLOCK, (char *)&sblock, SBSIZE); 5525098Smckusic } 5535098Smckusic 5545098Smckusic /* 5555098Smckusic * update the frsum fields to reflect addition or deletion 5565098Smckusic * of some frags 5575098Smckusic */ 5585326Smckusic fragacct(fs, fragmap, fraglist, cnt) 5595326Smckusic struct fs *fs; 5605098Smckusic int fragmap; 5615098Smckusic long fraglist[]; 5625098Smckusic int cnt; 5635098Smckusic { 5645098Smckusic int inblk; 5655098Smckusic register int field, subfield; 5665098Smckusic register int siz, pos; 5675098Smckusic 5685326Smckusic inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1); 5695098Smckusic fragmap <<= 1; 5705326Smckusic for (siz = 1; siz < fs->fs_frag; siz++) { 5716291Smckusick if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 5725098Smckusic continue; 5735098Smckusic field = around[siz]; 5745098Smckusic subfield = inside[siz]; 5755326Smckusic for (pos = siz; pos <= fs->fs_frag; pos++) { 5765098Smckusic if ((fragmap & field) == subfield) { 5775098Smckusic fraglist[siz] += cnt; 5785098Smckusic pos += siz; 5795098Smckusic field <<= siz; 5805098Smckusic subfield <<= siz; 5815098Smckusic } 5825098Smckusic field <<= 1; 5835098Smckusic subfield <<= 1; 5845098Smckusic } 5855098Smckusic } 5865098Smckusic } 5875098Smckusic 5885326Smckusic getsb(fs, file) 5895326Smckusic register struct fs *fs; 5905326Smckusic char *file; 5915326Smckusic { 5926534Smckusick int i, j, size; 5935326Smckusic 5945349Smckusic if (bread(SBLOCK, fs, SBSIZE)) { 5955326Smckusic printf("bad super block"); 5965326Smckusic perror(file); 5975326Smckusic nerror |= 04; 5985326Smckusic return; 5995326Smckusic } 6005326Smckusic if (fs->fs_magic != FS_MAGIC) { 6015326Smckusic printf("%s: bad magic number\n", file); 6025326Smckusic nerror |= 04; 6035326Smckusic return; 6045326Smckusic } 6056534Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 6066534Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 6076534Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 6086534Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, size); 6096534Smckusick bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)), 6106534Smckusick (char *)fs->fs_csp[j], size); 6115326Smckusic } 6125326Smckusic } 6135326Smckusic 6145098Smckusic bwrite(blk, buf, size) 6155098Smckusic char *buf; 6165098Smckusic daddr_t blk; 6175098Smckusic register size; 6185098Smckusic { 6195326Smckusic if (lseek(fi, blk * DEV_BSIZE, 0) < 0) { 6205098Smckusic perror("FS SEEK"); 6215098Smckusic return(1); 6225098Smckusic } 6235098Smckusic if (write(fi, buf, size) != size) { 6245098Smckusic perror("FS WRITE"); 6255098Smckusic return(1); 6265098Smckusic } 6275326Smckusic return (0); 6285098Smckusic } 6295098Smckusic 6304240Smckusick bread(bno, buf, cnt) 6314410Smckusic daddr_t bno; 6324410Smckusic char *buf; 6334240Smckusick { 6344240Smckusick register i; 6354240Smckusick 6365326Smckusic lseek(fi, bno * DEV_BSIZE, 0); 6374240Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 6385098Smckusic if (sflg) { 6395098Smckusic printf("No Update\n"); 6405098Smckusic sflg = 0; 6415098Smckusic } 6425326Smckusic for(i=0; i<sblock.fs_bsize; i++) 6434240Smckusick buf[i] = 0; 6445326Smckusic return (1); 6454240Smckusick } 6465326Smckusic return (0); 6474240Smckusick } 6485326Smckusic 6495326Smckusic /* 650*8143Smckusick * check if a block is available 6515326Smckusic */ 6525326Smckusic isblock(fs, cp, h) 6535326Smckusic struct fs *fs; 6545326Smckusic unsigned char *cp; 6555326Smckusic int h; 6565326Smckusic { 6575326Smckusic unsigned char mask; 6585326Smckusic 6595326Smckusic switch (fs->fs_frag) { 6605326Smckusic case 8: 6615326Smckusic return (cp[h] == 0xff); 6625326Smckusic case 4: 6635326Smckusic mask = 0x0f << ((h & 0x1) << 2); 6645326Smckusic return ((cp[h >> 1] & mask) == mask); 6655326Smckusic case 2: 6665326Smckusic mask = 0x03 << ((h & 0x3) << 1); 6675326Smckusic return ((cp[h >> 2] & mask) == mask); 6685326Smckusic case 1: 6695326Smckusic mask = 0x01 << (h & 0x7); 6705326Smckusic return ((cp[h >> 3] & mask) == mask); 6715326Smckusic default: 672*8143Smckusick #ifdef STANDALONE 673*8143Smckusick printf("isblock bad fs_frag %d\n", fs->fs_frag); 674*8143Smckusick #else 6755326Smckusic fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 676*8143Smckusick #endif 6775326Smckusic return; 6785326Smckusic } 6795326Smckusic } 6805326Smckusic 681*8143Smckusick /* 682*8143Smckusick * take a block out of the map 683*8143Smckusick */ 684*8143Smckusick clrblock(fs, cp, h) 685*8143Smckusick struct fs *fs; 686*8143Smckusick unsigned char *cp; 687*8143Smckusick int h; 688*8143Smckusick { 689*8143Smckusick switch ((fs)->fs_frag) { 690*8143Smckusick case 8: 691*8143Smckusick cp[h] = 0; 692*8143Smckusick return; 693*8143Smckusick case 4: 694*8143Smckusick cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 695*8143Smckusick return; 696*8143Smckusick case 2: 697*8143Smckusick cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 698*8143Smckusick return; 699*8143Smckusick case 1: 700*8143Smckusick cp[h >> 3] &= ~(0x01 << (h & 0x7)); 701*8143Smckusick return; 702*8143Smckusick default: 703*8143Smckusick #ifdef STANDALONE 704*8143Smckusick printf("clrblock bad fs_frag %d\n", fs->fs_frag); 705*8143Smckusick #else 706*8143Smckusick fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); 707*8143Smckusick #endif 708*8143Smckusick return; 709*8143Smckusick } 710*8143Smckusick } 711*8143Smckusick 712*8143Smckusick /* 713*8143Smckusick * put a block into the map 714*8143Smckusick */ 7155326Smckusic setblock(fs, cp, h) 7165326Smckusic struct fs *fs; 7175326Smckusic unsigned char *cp; 7185326Smckusic int h; 7195326Smckusic { 7205326Smckusic switch (fs->fs_frag) { 7215326Smckusic case 8: 7225326Smckusic cp[h] = 0xff; 7235326Smckusic return; 7245326Smckusic case 4: 7255326Smckusic cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 7265326Smckusic return; 7275326Smckusic case 2: 7285326Smckusic cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 7295326Smckusic return; 7305326Smckusic case 1: 7315326Smckusic cp[h >> 3] |= (0x01 << (h & 0x7)); 7325326Smckusic return; 7335326Smckusic default: 734*8143Smckusick #ifdef STANDALONE 735*8143Smckusick printf("setblock bad fs_frag %d\n", fs->fs_frag); 736*8143Smckusick #else 7375326Smckusic fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); 738*8143Smckusick #endif 7395326Smckusic return; 7405326Smckusic } 7415326Smckusic } 7426490Smckusick 7436490Smckusick /* tables.c 4.1 82/03/25 */ 7446490Smckusick 7456490Smckusick /* merged into kernel: tables.c 2.1 3/25/82 */ 7466490Smckusick 7476490Smckusick /* last monet version: partab.c 4.2 81/03/08 */ 7486490Smckusick 7496490Smckusick /* 7506490Smckusick * bit patterns for identifying fragments in the block map 7516490Smckusick * used as ((map & around) == inside) 7526490Smckusick */ 7536490Smckusick int around[9] = { 7546490Smckusick 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff 7556490Smckusick }; 7566490Smckusick int inside[9] = { 7576490Smckusick 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe 7586490Smckusick }; 7596490Smckusick 7606490Smckusick /* 7616490Smckusick * given a block map bit pattern, the frag tables tell whether a 7626490Smckusick * particular size fragment is available. 7636490Smckusick * 7646490Smckusick * used as: 7656490Smckusick * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { 7666490Smckusick * at least one fragment of the indicated size is available 7676490Smckusick * } 7686490Smckusick * 7696490Smckusick * These tables are used by the scanc instruction on the VAX to 7706490Smckusick * quickly find an appropriate fragment. 7716490Smckusick */ 7726490Smckusick 7736490Smckusick unsigned char fragtbl124[256] = { 7746490Smckusick 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, 7756490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, 7766490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7776490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7786490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7796490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7806490Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 7816490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 7826490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7836490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7846490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7856490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7866490Smckusick 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, 7876490Smckusick 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, 7886490Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 7896490Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 7906490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7916490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7926490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7936490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7946490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 7956490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 7966490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 7976490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 7986490Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 7996490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 8006490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 8016490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 8026490Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 8036490Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 8046490Smckusick 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, 8056490Smckusick 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, 8066490Smckusick }; 8076490Smckusick 8086490Smckusick unsigned char fragtbl8[256] = { 8096490Smckusick 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 8106490Smckusick 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, 8116490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8126490Smckusick 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, 8136490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8146490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8156490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8166490Smckusick 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, 8176490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8186490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8196490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8206490Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 8216490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8226490Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 8236490Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 8246490Smckusick 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, 8256490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8266490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8276490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8286490Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 8296490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8306490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8316490Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 8326490Smckusick 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, 8336490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8346490Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 8356490Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 8366490Smckusick 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, 8376490Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 8386490Smckusick 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, 8396490Smckusick 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, 8406490Smckusick 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, 8416490Smckusick }; 8426490Smckusick 8436490Smckusick /* 8446490Smckusick * the actual fragtbl array 8456490Smckusick */ 8466490Smckusick unsigned char *fragtbl[MAXFRAG + 1] = { 8476490Smckusick 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, 8486490Smckusick }; 849