1*21133Sdist /* 2*21133Sdist * Copyright (c) 1980 Regents of the University of California. 3*21133Sdist * All rights reserved. The Berkeley software License Agreement 4*21133Sdist * specifies the terms and conditions for redistribution. 5*21133Sdist */ 64410Smckusic 7*21133Sdist #ifndef lint 8*21133Sdist static char sccsid[] = "@(#)icheck.c 5.1 (Berkeley) 05/28/85"; 9*21133Sdist #endif not lint 10*21133Sdist 11*21133Sdist 124240Smckusick /* 134240Smckusick * icheck 144240Smckusick */ 154240Smckusick #define NB 500 164240Smckusick #define MAXFN 500 175349Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) 184240Smckusick 194240Smckusick #ifndef STANDALONE 204240Smckusick #include <stdio.h> 214240Smckusick #endif 226490Smckusick #ifndef SIMFS 236490Smckusick #include <sys/param.h> 246490Smckusick #include <sys/inode.h> 256490Smckusick #include <sys/fs.h> 266490Smckusick #else 274240Smckusick #include "../h/param.h" 284240Smckusick #include "../h/inode.h" 294240Smckusick #include "../h/fs.h" 306490Smckusick #endif 314240Smckusick 324240Smckusick union { 334240Smckusick struct fs sb; 345326Smckusic char pad[MAXBSIZE]; 354240Smckusick } sbun; 364240Smckusick #define sblock sbun.sb 374240Smckusick 384240Smckusick union { 394240Smckusick struct cg cg; 405326Smckusic char pad[MAXBSIZE]; 414240Smckusick } cgun; 424240Smckusick #define cgrp cgun.cg 434240Smckusick 444240Smckusick struct dinode itab[MAXIPG]; 454240Smckusick daddr_t blist[NB]; 469298Smckusick daddr_t fsblist[NB]; 474240Smckusick char *bmap; 484240Smckusick 494240Smckusick int mflg; 505098Smckusic int sflg; 514240Smckusick int dflg; 524240Smckusick int fi; 534240Smckusick ino_t ino; 544240Smckusick int cginit; 554240Smckusick 564240Smckusick ino_t nrfile; 574240Smckusick ino_t ndfile; 584240Smckusick ino_t nbfile; 594240Smckusick ino_t ncfile; 606286Smckusick ino_t nlfile; 614240Smckusick 624240Smckusick daddr_t nblock; 634240Smckusick daddr_t nfrag; 644240Smckusick daddr_t nindir; 654240Smckusick daddr_t niindir; 664240Smckusick 674240Smckusick daddr_t nffree; 684240Smckusick daddr_t nbfree; 694240Smckusick 704240Smckusick daddr_t ndup; 714240Smckusick 724240Smckusick int nerror; 734240Smckusick 745098Smckusic extern int inside[], around[]; 755326Smckusic extern unsigned char *fragtbl[]; 765098Smckusic 774240Smckusick long atol(); 784240Smckusick #ifndef STANDALONE 794240Smckusick char *malloc(); 805098Smckusic char *calloc(); 814240Smckusick #endif 824240Smckusick 834240Smckusick main(argc, argv) 845098Smckusic int argc; 855098Smckusic char *argv[]; 864240Smckusick { 874240Smckusick register i; 884240Smckusick long n; 894240Smckusick 904240Smckusick blist[0] = -1; 914240Smckusick #ifndef STANDALONE 924240Smckusick while (--argc) { 934240Smckusick argv++; 944240Smckusick if (**argv=='-') 954240Smckusick switch ((*argv)[1]) { 964240Smckusick case 'd': 974240Smckusick dflg++; 984240Smckusick continue; 994240Smckusick 1004240Smckusick case 'm': 1014240Smckusick mflg++; 1024240Smckusick continue; 1034240Smckusick 1045098Smckusic case 's': 1055098Smckusic sflg++; 1065098Smckusic continue; 1075098Smckusic 1084240Smckusick case 'b': 1094240Smckusick for(i=0; i<NB; i++) { 1104240Smckusick n = atol(argv[1]); 1114240Smckusick if(n == 0) 1124240Smckusick break; 1134240Smckusick blist[i] = n; 1144240Smckusick argv++; 1154240Smckusick argc--; 1164240Smckusick } 1174240Smckusick blist[i] = -1; 1184240Smckusick continue; 1194240Smckusick 1204240Smckusick default: 1214240Smckusick printf("Bad flag\n"); 1224240Smckusick } 1234240Smckusick check(*argv); 1244240Smckusick } 1254240Smckusick #else 1264240Smckusick { 1274240Smckusick static char fname[128]; 1284240Smckusick 1294240Smckusick printf("File: "); 1304240Smckusick gets(fname); 1314240Smckusick check(fname); 1324240Smckusick } 1334240Smckusick #endif 1344240Smckusick return(nerror); 1354240Smckusick } 1364240Smckusick 1374240Smckusick check(file) 1385098Smckusic char *file; 1394240Smckusick { 1404240Smckusick register i, j, c; 1414240Smckusick daddr_t d, cgd, cbase, b; 1424240Smckusick long n; 1439298Smckusick char buf[BUFSIZ]; 1444240Smckusick 1455098Smckusic fi = open(file, sflg ? 2 : 0); 1464240Smckusick if (fi < 0) { 1475098Smckusic perror(file); 1484240Smckusick nerror |= 04; 1494240Smckusick return; 1504240Smckusick } 1514240Smckusick printf("%s:\n", file); 1524240Smckusick nrfile = 0; 1534240Smckusick ndfile = 0; 1544240Smckusick ncfile = 0; 1554240Smckusick nbfile = 0; 1566286Smckusick nlfile = 0; 1574240Smckusick 1584240Smckusick nblock = 0; 1594240Smckusick nfrag = 0; 1604240Smckusick nindir = 0; 1614240Smckusick niindir = 0; 1624240Smckusick 1634240Smckusick ndup = 0; 1644240Smckusick #ifndef STANDALONE 1654240Smckusick sync(); 1664240Smckusick #endif 1675326Smckusic getsb(&sblock, file); 1685326Smckusic if (nerror) 1694240Smckusick return; 1709298Smckusick for (n=0; blist[n] != -1; n++) 1719298Smckusick fsblist[n] = dbtofsb(&sblock, blist[n]); 1724240Smckusick ino = 0; 1735098Smckusic n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short)); 1744240Smckusick #ifdef STANDALONE 1754240Smckusick bmap = NULL; 1764240Smckusick #else 1774240Smckusick bmap = malloc((unsigned)n); 1784240Smckusick #endif 1794240Smckusick if (bmap==NULL) { 1804240Smckusick printf("Not enough core; duplicates unchecked\n"); 1814240Smckusick dflg++; 1825098Smckusic if (sflg) { 1835098Smckusic printf("No Updates\n"); 1845098Smckusic sflg = 0; 1855098Smckusic } 1864240Smckusick } 1874240Smckusick ino = 0; 1884240Smckusick cginit = 1; 1896534Smckusick if (!dflg) { 1906534Smckusick for (i = 0; i < (unsigned)n; i++) 1914240Smckusick bmap[i] = 0; 1926534Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1935382Smckusic cgd = cgtod(&sblock, c); 1946534Smckusick if (c == 0) 1956534Smckusick d = cgbase(&sblock, c); 1966534Smckusick else 1976534Smckusick d = cgsblock(&sblock, c); 1989298Smckusick sprintf(buf, "spare super block %d", c); 1996534Smckusick for (; d < cgd; d += sblock.fs_frag) 2009298Smckusick chk(d, buf, sblock.fs_bsize); 2015382Smckusic d = cgimin(&sblock, c); 2029298Smckusick sprintf(buf, "cylinder group %d", c); 2034240Smckusick while (cgd < d) { 2049298Smckusick chk(cgd, buf, sblock.fs_bsize); 2055326Smckusic cgd += sblock.fs_frag; 2064240Smckusick } 2075382Smckusic d = cgdmin(&sblock, c); 2089298Smckusick i = INOPB(&sblock); 2099298Smckusick for (; cgd < d; cgd += sblock.fs_frag) { 2109298Smckusick sprintf(buf, "inodes %d-%d", ino, ino + i); 2119298Smckusick chk(cgd, buf, sblock.fs_bsize); 2129298Smckusick ino += i; 2139298Smckusick } 2144240Smckusick if (c == 0) { 2156534Smckusick d += howmany(sblock.fs_cssize, sblock.fs_fsize); 2166534Smckusick for (; cgd < d; cgd++) 2176534Smckusick chk(cgd, "csum", sblock.fs_fsize); 2184240Smckusick } 2194240Smckusick } 2204240Smckusick } 2219298Smckusick ino = 0; 2224240Smckusick cginit = 0; 2234240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2245382Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 2254240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 2264240Smckusick for (j=0; j < sblock.fs_ipg; j++) { 2274240Smckusick pass1(&itab[j]); 2284240Smckusick ino++; 2294240Smckusick } 2304240Smckusick } 2314240Smckusick ino = 0; 2324240Smckusick #ifndef STANDALONE 2334240Smckusick sync(); 2344240Smckusick #endif 2355098Smckusic if (sflg) { 2365098Smckusic makecg(); 2375098Smckusic close(fi); 2385098Smckusic #ifndef STANDALONE 2395098Smckusic if (bmap) 2405098Smckusic free(bmap); 2415098Smckusic #endif 2425098Smckusic return; 2435098Smckusic } 2444240Smckusick nffree = 0; 2454240Smckusick nbfree = 0; 2464240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2475382Smckusic cbase = cgbase(&sblock, c); 2485382Smckusic bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp, 2495326Smckusic sblock.fs_cgsize); 2506534Smckusick if (cgrp.cg_magic != CG_MAGIC) 2516534Smckusick printf("cg %d: bad magic number\n", c); 2525326Smckusic for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { 2535326Smckusic if (isblock(&sblock, cgrp.cg_free, 2545326Smckusic b / sblock.fs_frag)) { 2554240Smckusick nbfree++; 2569298Smckusick chk(cbase+b, "free block", sblock.fs_bsize); 2574240Smckusick } else { 2585326Smckusic for (d = 0; d < sblock.fs_frag; d++) 2594240Smckusick if (isset(cgrp.cg_free, b+d)) { 2609298Smckusick chk(cbase+b+d, "free frag", sblock.fs_fsize); 2614240Smckusick nffree++; 2624240Smckusick } 2634240Smckusick } 2644240Smckusick } 2654240Smckusick } 2664240Smckusick close(fi); 2674240Smckusick #ifndef STANDALONE 2684240Smckusick if (bmap) 2694240Smckusick free(bmap); 2704240Smckusick #endif 2714240Smckusick 2726286Smckusick i = nrfile + ndfile + ncfile + nbfile + nlfile; 2734240Smckusick #ifndef STANDALONE 2746286Smckusick printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", 2756286Smckusick i, nrfile, ndfile, nbfile, ncfile, nlfile); 2764240Smckusick #else 2776286Smckusick printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", 2786286Smckusick i, nrfile, ndfile, nbfile, ncfile, nlfile); 2794240Smckusick #endif 2805326Smckusic n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag; 2814240Smckusick #ifdef STANDALONE 2824240Smckusick printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2834240Smckusick n, nindir, niindir, nblock, nfrag); 2845326Smckusic printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, 2854240Smckusick nbfree, nffree); 2864240Smckusick #else 2874240Smckusick printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2884240Smckusick n, nindir, niindir, nblock, nfrag); 2895326Smckusic printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, 2904240Smckusick nbfree, nffree); 2914240Smckusick #endif 2924240Smckusick if(!dflg) { 2934240Smckusick n = 0; 2944410Smckusic for (d = 0; d < sblock.fs_size; d++) 2955326Smckusic if(!duped(d, sblock.fs_fsize)) { 2964240Smckusick if(mflg) 2974240Smckusick printf("%ld missing\n", d); 2984240Smckusick n++; 2994240Smckusick } 3004240Smckusick printf("missing%5ld\n", n); 3014240Smckusick } 3024240Smckusick } 3034240Smckusick 3044240Smckusick pass1(ip) 3054410Smckusic register struct dinode *ip; 3064240Smckusick { 3075326Smckusic daddr_t ind1[MAXNINDIR]; 3085326Smckusic daddr_t ind2[MAXNINDIR]; 3094429Smckusic daddr_t db, ib; 3104429Smckusic register int i, j, k, siz; 3119298Smckusick int lbn; 3129298Smckusick char buf[BUFSIZ]; 3134240Smckusick 3144240Smckusick i = ip->di_mode & IFMT; 3154790Smckusic if(i == 0) 3164240Smckusick return; 3174240Smckusick switch (i) { 3184240Smckusick case IFCHR: 3194240Smckusick ncfile++; 3204240Smckusick return; 3214240Smckusick case IFBLK: 3224240Smckusick nbfile++; 3234240Smckusick return; 3244240Smckusick case IFDIR: 3254240Smckusick ndfile++; 3264240Smckusick break; 3274240Smckusick case IFREG: 3284240Smckusick nrfile++; 3294240Smckusick break; 3306286Smckusick case IFLNK: 3316286Smckusick nlfile++; 3326286Smckusick break; 3334240Smckusick default: 3344240Smckusick printf("bad mode %u\n", ino); 3354240Smckusick return; 3364240Smckusick } 3374410Smckusic for (i = 0; i < NDADDR; i++) { 3384410Smckusic db = ip->di_db[i]; 3394410Smckusic if (db == 0) 3404240Smckusick continue; 3415326Smckusic siz = dblksize(&sblock, ip, i); 3429298Smckusick sprintf(buf, "logical data block %d", i); 3439298Smckusick chk(db, buf, siz); 3445326Smckusic if (siz == sblock.fs_bsize) 3454429Smckusic nblock++; 3464429Smckusic else 3475326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3484240Smckusick } 3494410Smckusic for(i = 0; i < NIADDR; i++) { 3504410Smckusic ib = ip->di_ib[i]; 3519298Smckusick if (ib == 0) 3524240Smckusick continue; 3535326Smckusic if (chk(ib, "1st indirect", sblock.fs_bsize)) 3544410Smckusic continue; 3555326Smckusic bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize); 3564240Smckusick nindir++; 3575326Smckusic for (j = 0; j < NINDIR(&sblock); j++) { 3584410Smckusic ib = ind1[j]; 3594410Smckusic if (ib == 0) 3604240Smckusick continue; 3614410Smckusic if (i == 0) { 3629298Smckusick lbn = NDADDR + j; 3639298Smckusick siz = dblksize(&sblock, ip, lbn); 3649298Smckusick sprintf(buf, "logical data block %d", lbn); 3659298Smckusick chk(ib, buf, siz); 3665326Smckusic if (siz == sblock.fs_bsize) 3674429Smckusic nblock++; 3684429Smckusic else 3695326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3704240Smckusick continue; 3714240Smckusick } 3725326Smckusic if (chk(ib, "2nd indirect", sblock.fs_bsize)) 3734410Smckusic continue; 3745326Smckusic bread(fsbtodb(&sblock, ib), (char *)ind2, 3755326Smckusic sblock.fs_bsize); 3764240Smckusick niindir++; 3775326Smckusic for (k = 0; k < NINDIR(&sblock); k++) { 3784410Smckusic ib = ind2[k]; 3794410Smckusic if (ib == 0) 3804240Smckusick continue; 3819298Smckusick lbn = NDADDR + NINDIR(&sblock) * (i + j) + k; 3829298Smckusick siz = dblksize(&sblock, ip, lbn); 3839298Smckusick sprintf(buf, "logical data block %d", lbn); 3849298Smckusick chk(ib, buf, siz); 3855326Smckusic if (siz == sblock.fs_bsize) 3864429Smckusic nblock++; 3874429Smckusic else 3885326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3894240Smckusick } 3904240Smckusick } 3914240Smckusick } 3924240Smckusick } 3934240Smckusick 3944429Smckusic chk(bno, s, size) 3954410Smckusic daddr_t bno; 3964410Smckusic char *s; 3974429Smckusic int size; 3984240Smckusick { 3994240Smckusick register n, cg; 4005957Smckusic int frags; 4014240Smckusick 4025382Smckusic cg = dtog(&sblock, bno); 4036534Smckusick if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) { 4044240Smckusick printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 4054240Smckusick return(1); 4064240Smckusick } 4079298Smckusick frags = numfrags(&sblock, size); 4089298Smckusick if (frags == sblock.fs_frag) { 4094429Smckusic if (duped(bno, size)) { 4104429Smckusic printf("%ld dup block; inode=%u, class=%s\n", 4114429Smckusic bno, ino, s); 4125326Smckusic ndup += sblock.fs_frag; 4134429Smckusic } 4144429Smckusic } else { 4155957Smckusic for (n = 0; n < frags; n++) { 4165326Smckusic if (duped(bno + n, sblock.fs_fsize)) { 4174429Smckusic printf("%ld dup frag; inode=%u, class=%s\n", 4184429Smckusic bno, ino, s); 4194429Smckusic ndup++; 4204429Smckusic } 4214429Smckusic } 4224240Smckusick } 4234240Smckusick for (n=0; blist[n] != -1; n++) 4249298Smckusick if (fsblist[n] >= bno && fsblist[n] < bno + frags) 4259298Smckusick printf("%ld arg; frag %d of %d, inode=%u, class=%s\n", 4269298Smckusick blist[n], fsblist[n] - bno, frags, ino, s); 4274240Smckusick return(0); 4284240Smckusick } 4294240Smckusick 4304429Smckusic duped(bno, size) 4314410Smckusic daddr_t bno; 4324429Smckusic int size; 4334240Smckusick { 4344240Smckusick if(dflg) 4354240Smckusick return(0); 4365326Smckusic if (size != sblock.fs_fsize && size != sblock.fs_bsize) 4374429Smckusic printf("bad size %d to duped\n", size); 4385326Smckusic if (size == sblock.fs_fsize) { 4394410Smckusic if (isset(bmap, bno)) 4404410Smckusic return(1); 4414410Smckusic setbit(bmap, bno); 4424410Smckusic return (0); 4434410Smckusic } 4445326Smckusic if (bno % sblock.fs_frag != 0) 4454410Smckusic printf("bad bno %d to duped\n", bno); 4465326Smckusic if (isblock(&sblock, bmap, bno/sblock.fs_frag)) 4474410Smckusic return (1); 4485326Smckusic setblock(&sblock, bmap, bno/sblock.fs_frag); 4494240Smckusick return(0); 4504240Smckusick } 4514240Smckusick 4525098Smckusic makecg() 4535098Smckusic { 4545098Smckusic int c, blk; 4556534Smckusick daddr_t dbase, d, dlower, dupper, dmax; 4565098Smckusic long i, j, s; 4575098Smckusic register struct csum *cs; 4585098Smckusic register struct dinode *dp; 4595098Smckusic 4605098Smckusic sblock.fs_cstotal.cs_nbfree = 0; 4615098Smckusic sblock.fs_cstotal.cs_nffree = 0; 4625098Smckusic sblock.fs_cstotal.cs_nifree = 0; 4635098Smckusic sblock.fs_cstotal.cs_ndir = 0; 4645098Smckusic for (c = 0; c < sblock.fs_ncg; c++) { 4655382Smckusic dbase = cgbase(&sblock, c); 4665098Smckusic dmax = dbase + sblock.fs_fpg; 4675410Smckusic if (dmax > sblock.fs_size) { 4685410Smckusic for ( ; dmax >= sblock.fs_size; dmax--) 4695400Smckusic clrbit(cgrp.cg_free, dmax - dbase); 4705410Smckusic dmax++; 4715410Smckusic } 4726534Smckusick dlower = cgsblock(&sblock, c) - dbase; 4736534Smckusick dupper = cgdmin(&sblock, c) - dbase; 4745326Smckusic cs = &sblock.fs_cs(&sblock, c); 4755098Smckusic cgrp.cg_time = time(0); 4765098Smckusic cgrp.cg_magic = CG_MAGIC; 4775098Smckusic cgrp.cg_cgx = c; 4788143Smckusick if (c == sblock.fs_ncg - 1) 4798143Smckusick cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 4808143Smckusick else 4818143Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 4825098Smckusic cgrp.cg_niblk = sblock.fs_ipg; 4835098Smckusic cgrp.cg_ndblk = dmax - dbase; 4845098Smckusic cgrp.cg_cs.cs_ndir = 0; 4855098Smckusic cgrp.cg_cs.cs_nffree = 0; 4865098Smckusic cgrp.cg_cs.cs_nbfree = 0; 4875098Smckusic cgrp.cg_cs.cs_nifree = 0; 4886534Smckusick cgrp.cg_rotor = 0; 4896534Smckusick cgrp.cg_frotor = 0; 4905098Smckusic cgrp.cg_irotor = 0; 4915326Smckusic for (i = 0; i < sblock.fs_frag; i++) 4925098Smckusic cgrp.cg_frsum[i] = 0; 4935382Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 4945098Smckusic sblock.fs_ipg * sizeof(struct dinode)); 4955098Smckusic for (i = 0; i < sblock.fs_ipg; i++) { 4965945Smckusic cgrp.cg_cs.cs_nifree++; 4975945Smckusic clrbit(cgrp.cg_iused, i); 4985098Smckusic dp = &itab[i]; 4995098Smckusic if ((dp->di_mode & IFMT) != 0) { 5005098Smckusic if ((dp->di_mode & IFMT) == IFDIR) 5015098Smckusic cgrp.cg_cs.cs_ndir++; 5025945Smckusic cgrp.cg_cs.cs_nifree--; 5035098Smckusic setbit(cgrp.cg_iused, i); 5045098Smckusic continue; 5055098Smckusic } 5065098Smckusic } 5075098Smckusic while (i < MAXIPG) { 5085098Smckusic clrbit(cgrp.cg_iused, i); 5095098Smckusic i++; 5105098Smckusic } 5115338Smckusic if (c == 0) 5125338Smckusic for (i = 0; i < ROOTINO; i++) { 5135338Smckusic setbit(cgrp.cg_iused, i); 5145338Smckusic cgrp.cg_cs.cs_nifree--; 5155338Smckusic } 5165372Smckusic for (s = 0; s < MAXCPG; s++) { 5175372Smckusic cgrp.cg_btot[s] = 0; 5185098Smckusic for (i = 0; i < NRPOS; i++) 5195098Smckusic cgrp.cg_b[s][i] = 0; 5205372Smckusic } 5215098Smckusic if (c == 0) { 5226534Smckusick dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 5235098Smckusic } 5246534Smckusick for (d = dlower; d < dupper; d++) 5255098Smckusic clrbit(cgrp.cg_free, d); 5266534Smckusick for (d = 0; (d + sblock.fs_frag) <= dmax - dbase; 5276534Smckusick d += sblock.fs_frag) { 5285098Smckusic j = 0; 5295326Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5306534Smckusick if (!isset(bmap, dbase + d + i)) { 5316534Smckusick setbit(cgrp.cg_free, d + i); 5325098Smckusic j++; 5335098Smckusic } else 5345098Smckusic clrbit(cgrp.cg_free, d+i); 5355098Smckusic } 5365326Smckusic if (j == sblock.fs_frag) { 5375098Smckusic cgrp.cg_cs.cs_nbfree++; 5385372Smckusic cgrp.cg_btot[cbtocylno(&sblock, d)]++; 5395364Smckusic cgrp.cg_b[cbtocylno(&sblock, d)] 5405364Smckusic [cbtorpos(&sblock, d)]++; 5415098Smckusic } else if (j > 0) { 5425098Smckusic cgrp.cg_cs.cs_nffree += j; 5436534Smckusick blk = blkmap(&sblock, cgrp.cg_free, d); 5445326Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 5455098Smckusic } 5465098Smckusic } 5475098Smckusic for (j = d; d < dmax - dbase; d++) { 5486534Smckusick if (!isset(bmap, dbase + d)) { 5495098Smckusic setbit(cgrp.cg_free, d); 5505098Smckusic cgrp.cg_cs.cs_nffree++; 5515098Smckusic } else 5525098Smckusic clrbit(cgrp.cg_free, d); 5535098Smckusic } 5548143Smckusick for (; d % sblock.fs_frag != 0; d++) 5558143Smckusick clrbit(cgrp.cg_free, d); 5565098Smckusic if (j != d) { 5576534Smckusick blk = blkmap(&sblock, cgrp.cg_free, j); 5585326Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 5595098Smckusic } 5608143Smckusick for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++) 5618143Smckusick clrblock(&sblock, cgrp.cg_free, d); 5625098Smckusic sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree; 5635098Smckusic sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree; 5645098Smckusic sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree; 5655098Smckusic sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir; 5665098Smckusic *cs = cgrp.cg_cs; 5675382Smckusic bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp, 5685326Smckusic sblock.fs_cgsize); 5695098Smckusic } 5706534Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 5716534Smckusick bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 5726534Smckusick (char *)sblock.fs_csp[j], 5736534Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 5746534Smckusick sblock.fs_cssize - i : sblock.fs_bsize); 5755098Smckusic } 5765098Smckusic sblock.fs_ronly = 0; 5775098Smckusic sblock.fs_fmod = 0; 5785349Smckusic bwrite(SBLOCK, (char *)&sblock, SBSIZE); 5795098Smckusic } 5805098Smckusic 5815098Smckusic /* 5825098Smckusic * update the frsum fields to reflect addition or deletion 5835098Smckusic * of some frags 5845098Smckusic */ 5855326Smckusic fragacct(fs, fragmap, fraglist, cnt) 5865326Smckusic struct fs *fs; 5875098Smckusic int fragmap; 5885098Smckusic long fraglist[]; 5895098Smckusic int cnt; 5905098Smckusic { 5915098Smckusic int inblk; 5925098Smckusic register int field, subfield; 5935098Smckusic register int siz, pos; 5945098Smckusic 5955326Smckusic inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1); 5965098Smckusic fragmap <<= 1; 5975326Smckusic for (siz = 1; siz < fs->fs_frag; siz++) { 5986291Smckusick if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 5995098Smckusic continue; 6005098Smckusic field = around[siz]; 6015098Smckusic subfield = inside[siz]; 6025326Smckusic for (pos = siz; pos <= fs->fs_frag; pos++) { 6035098Smckusic if ((fragmap & field) == subfield) { 6045098Smckusic fraglist[siz] += cnt; 6055098Smckusic pos += siz; 6065098Smckusic field <<= siz; 6075098Smckusic subfield <<= siz; 6085098Smckusic } 6095098Smckusic field <<= 1; 6105098Smckusic subfield <<= 1; 6115098Smckusic } 6125098Smckusic } 6135098Smckusic } 6145098Smckusic 6155326Smckusic getsb(fs, file) 6165326Smckusic register struct fs *fs; 6175326Smckusic char *file; 6185326Smckusic { 6196534Smckusick int i, j, size; 6205326Smckusic 6215349Smckusic if (bread(SBLOCK, fs, SBSIZE)) { 6225326Smckusic printf("bad super block"); 6235326Smckusic perror(file); 6245326Smckusic nerror |= 04; 6255326Smckusic return; 6265326Smckusic } 6275326Smckusic if (fs->fs_magic != FS_MAGIC) { 6285326Smckusic printf("%s: bad magic number\n", file); 6295326Smckusic nerror |= 04; 6305326Smckusic return; 6315326Smckusic } 6326534Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 6336534Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 6346534Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 6356534Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, size); 6366534Smckusick bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)), 6376534Smckusick (char *)fs->fs_csp[j], size); 6385326Smckusic } 6395326Smckusic } 6405326Smckusic 6415098Smckusic bwrite(blk, buf, size) 6425098Smckusic char *buf; 6435098Smckusic daddr_t blk; 6445098Smckusic register size; 6455098Smckusic { 6465326Smckusic if (lseek(fi, blk * DEV_BSIZE, 0) < 0) { 6475098Smckusic perror("FS SEEK"); 6485098Smckusic return(1); 6495098Smckusic } 6505098Smckusic if (write(fi, buf, size) != size) { 6515098Smckusic perror("FS WRITE"); 6525098Smckusic return(1); 6535098Smckusic } 6545326Smckusic return (0); 6555098Smckusic } 6565098Smckusic 6574240Smckusick bread(bno, buf, cnt) 6584410Smckusic daddr_t bno; 6594410Smckusic char *buf; 6604240Smckusick { 6614240Smckusick register i; 6624240Smckusick 6635326Smckusic lseek(fi, bno * DEV_BSIZE, 0); 6644240Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 6655098Smckusic if (sflg) { 6665098Smckusic printf("No Update\n"); 6675098Smckusic sflg = 0; 6685098Smckusic } 6695326Smckusic for(i=0; i<sblock.fs_bsize; i++) 6704240Smckusick buf[i] = 0; 6715326Smckusic return (1); 6724240Smckusick } 6735326Smckusic return (0); 6744240Smckusick } 6755326Smckusic 6765326Smckusic /* 6778143Smckusick * check if a block is available 6785326Smckusic */ 6795326Smckusic isblock(fs, cp, h) 6805326Smckusic struct fs *fs; 6815326Smckusic unsigned char *cp; 6825326Smckusic int h; 6835326Smckusic { 6845326Smckusic unsigned char mask; 6855326Smckusic 6865326Smckusic switch (fs->fs_frag) { 6875326Smckusic case 8: 6885326Smckusic return (cp[h] == 0xff); 6895326Smckusic case 4: 6905326Smckusic mask = 0x0f << ((h & 0x1) << 2); 6915326Smckusic return ((cp[h >> 1] & mask) == mask); 6925326Smckusic case 2: 6935326Smckusic mask = 0x03 << ((h & 0x3) << 1); 6945326Smckusic return ((cp[h >> 2] & mask) == mask); 6955326Smckusic case 1: 6965326Smckusic mask = 0x01 << (h & 0x7); 6975326Smckusic return ((cp[h >> 3] & mask) == mask); 6985326Smckusic default: 6998143Smckusick #ifdef STANDALONE 7008143Smckusick printf("isblock bad fs_frag %d\n", fs->fs_frag); 7018143Smckusick #else 7025326Smckusic fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 7038143Smckusick #endif 7045326Smckusic return; 7055326Smckusic } 7065326Smckusic } 7075326Smckusic 7088143Smckusick /* 7098143Smckusick * take a block out of the map 7108143Smckusick */ 7118143Smckusick clrblock(fs, cp, h) 7128143Smckusick struct fs *fs; 7138143Smckusick unsigned char *cp; 7148143Smckusick int h; 7158143Smckusick { 7168143Smckusick switch ((fs)->fs_frag) { 7178143Smckusick case 8: 7188143Smckusick cp[h] = 0; 7198143Smckusick return; 7208143Smckusick case 4: 7218143Smckusick cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 7228143Smckusick return; 7238143Smckusick case 2: 7248143Smckusick cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 7258143Smckusick return; 7268143Smckusick case 1: 7278143Smckusick cp[h >> 3] &= ~(0x01 << (h & 0x7)); 7288143Smckusick return; 7298143Smckusick default: 7308143Smckusick #ifdef STANDALONE 7318143Smckusick printf("clrblock bad fs_frag %d\n", fs->fs_frag); 7328143Smckusick #else 7338143Smckusick fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); 7348143Smckusick #endif 7358143Smckusick return; 7368143Smckusick } 7378143Smckusick } 7388143Smckusick 7398143Smckusick /* 7408143Smckusick * put a block into the map 7418143Smckusick */ 7425326Smckusic setblock(fs, cp, h) 7435326Smckusic struct fs *fs; 7445326Smckusic unsigned char *cp; 7455326Smckusic int h; 7465326Smckusic { 7475326Smckusic switch (fs->fs_frag) { 7485326Smckusic case 8: 7495326Smckusic cp[h] = 0xff; 7505326Smckusic return; 7515326Smckusic case 4: 7525326Smckusic cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 7535326Smckusic return; 7545326Smckusic case 2: 7555326Smckusic cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 7565326Smckusic return; 7575326Smckusic case 1: 7585326Smckusic cp[h >> 3] |= (0x01 << (h & 0x7)); 7595326Smckusic return; 7605326Smckusic default: 7618143Smckusick #ifdef STANDALONE 7628143Smckusick printf("setblock bad fs_frag %d\n", fs->fs_frag); 7638143Smckusick #else 7645326Smckusic fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); 7658143Smckusick #endif 7665326Smckusic return; 7675326Smckusic } 7685326Smckusic } 7696490Smckusick 7706490Smckusick /* tables.c 4.1 82/03/25 */ 7716490Smckusick 7726490Smckusick /* merged into kernel: tables.c 2.1 3/25/82 */ 7736490Smckusick 7746490Smckusick /* last monet version: partab.c 4.2 81/03/08 */ 7756490Smckusick 7766490Smckusick /* 7776490Smckusick * bit patterns for identifying fragments in the block map 7786490Smckusick * used as ((map & around) == inside) 7796490Smckusick */ 7806490Smckusick int around[9] = { 7816490Smckusick 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff 7826490Smckusick }; 7836490Smckusick int inside[9] = { 7846490Smckusick 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe 7856490Smckusick }; 7866490Smckusick 7876490Smckusick /* 7886490Smckusick * given a block map bit pattern, the frag tables tell whether a 7896490Smckusick * particular size fragment is available. 7906490Smckusick * 7916490Smckusick * used as: 7926490Smckusick * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { 7936490Smckusick * at least one fragment of the indicated size is available 7946490Smckusick * } 7956490Smckusick * 7966490Smckusick * These tables are used by the scanc instruction on the VAX to 7976490Smckusick * quickly find an appropriate fragment. 7986490Smckusick */ 7996490Smckusick 8006490Smckusick unsigned char fragtbl124[256] = { 8016490Smckusick 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, 8026490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, 8036490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8046490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8056490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8066490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8076490Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 8086490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 8096490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8106490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8116490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8126490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8136490Smckusick 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, 8146490Smckusick 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, 8156490Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 8166490Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 8176490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8186490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8196490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8206490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8216490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8226490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8236490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 8246490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 8256490Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 8266490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 8276490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 8286490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 8296490Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 8306490Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 8316490Smckusick 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, 8326490Smckusick 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, 8336490Smckusick }; 8346490Smckusick 8356490Smckusick unsigned char fragtbl8[256] = { 8366490Smckusick 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 8376490Smckusick 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, 8386490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8396490Smckusick 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, 8406490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8416490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8426490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8436490Smckusick 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, 8446490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8456490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8466490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8476490Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 8486490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8496490Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 8506490Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 8516490Smckusick 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, 8526490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8536490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8546490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8556490Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 8566490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8576490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8586490Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 8596490Smckusick 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, 8606490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8616490Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 8626490Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 8636490Smckusick 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, 8646490Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 8656490Smckusick 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, 8666490Smckusick 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, 8676490Smckusick 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, 8686490Smckusick }; 8696490Smckusick 8706490Smckusick /* 8716490Smckusick * the actual fragtbl array 8726490Smckusick */ 8736490Smckusick unsigned char *fragtbl[MAXFRAG + 1] = { 8746490Smckusick 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, 8756490Smckusick }; 876