121133Sdist /* 221133Sdist * Copyright (c) 1980 Regents of the University of California. 321133Sdist * All rights reserved. The Berkeley software License Agreement 421133Sdist * specifies the terms and conditions for redistribution. 521133Sdist */ 64410Smckusic 721133Sdist #ifndef lint 8*32441Sbostic static char sccsid[] = "@(#)icheck.c 5.3 (Berkeley) 10/22/87"; 921133Sdist #endif not lint 1021133Sdist 1121133Sdist 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; 7330558Smckusick long dev_bsize = 1; 744240Smckusick 755098Smckusic extern int inside[], around[]; 765326Smckusic extern unsigned char *fragtbl[]; 775098Smckusic 784240Smckusick long atol(); 794240Smckusick #ifndef STANDALONE 804240Smckusick char *malloc(); 815098Smckusic char *calloc(); 824240Smckusick #endif 834240Smckusick 844240Smckusick main(argc, argv) 855098Smckusic int argc; 865098Smckusic char *argv[]; 874240Smckusick { 884240Smckusick register i; 894240Smckusick long n; 904240Smckusick 914240Smckusick blist[0] = -1; 924240Smckusick #ifndef STANDALONE 934240Smckusick while (--argc) { 944240Smckusick argv++; 954240Smckusick if (**argv=='-') 964240Smckusick switch ((*argv)[1]) { 974240Smckusick case 'd': 984240Smckusick dflg++; 994240Smckusick continue; 1004240Smckusick 1014240Smckusick case 'm': 1024240Smckusick mflg++; 1034240Smckusick continue; 1044240Smckusick 1055098Smckusic case 's': 1065098Smckusic sflg++; 1075098Smckusic continue; 1085098Smckusic 1094240Smckusick case 'b': 1104240Smckusick for(i=0; i<NB; i++) { 1114240Smckusick n = atol(argv[1]); 1124240Smckusick if(n == 0) 1134240Smckusick break; 1144240Smckusick blist[i] = n; 1154240Smckusick argv++; 1164240Smckusick argc--; 1174240Smckusick } 1184240Smckusick blist[i] = -1; 1194240Smckusick continue; 1204240Smckusick 1214240Smckusick default: 1224240Smckusick printf("Bad flag\n"); 1234240Smckusick } 1244240Smckusick check(*argv); 1254240Smckusick } 1264240Smckusick #else 1274240Smckusick { 1284240Smckusick static char fname[128]; 1294240Smckusick 1304240Smckusick printf("File: "); 1314240Smckusick gets(fname); 1324240Smckusick check(fname); 1334240Smckusick } 1344240Smckusick #endif 1354240Smckusick return(nerror); 1364240Smckusick } 1374240Smckusick 1384240Smckusick check(file) 1395098Smckusic char *file; 1404240Smckusick { 1414240Smckusick register i, j, c; 1424240Smckusick daddr_t d, cgd, cbase, b; 1434240Smckusick long n; 1449298Smckusick char buf[BUFSIZ]; 1454240Smckusick 1465098Smckusic fi = open(file, sflg ? 2 : 0); 1474240Smckusick if (fi < 0) { 1485098Smckusic perror(file); 1494240Smckusick nerror |= 04; 1504240Smckusick return; 1514240Smckusick } 1524240Smckusick printf("%s:\n", file); 1534240Smckusick nrfile = 0; 1544240Smckusick ndfile = 0; 1554240Smckusick ncfile = 0; 1564240Smckusick nbfile = 0; 1576286Smckusick nlfile = 0; 1584240Smckusick 1594240Smckusick nblock = 0; 1604240Smckusick nfrag = 0; 1614240Smckusick nindir = 0; 1624240Smckusick niindir = 0; 1634240Smckusick 1644240Smckusick ndup = 0; 1654240Smckusick #ifndef STANDALONE 1664240Smckusick sync(); 1674240Smckusick #endif 1685326Smckusic getsb(&sblock, file); 1695326Smckusic if (nerror) 1704240Smckusick return; 1719298Smckusick for (n=0; blist[n] != -1; n++) 1729298Smckusick fsblist[n] = dbtofsb(&sblock, blist[n]); 1734240Smckusick ino = 0; 1745098Smckusic n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short)); 1754240Smckusick #ifdef STANDALONE 1764240Smckusick bmap = NULL; 1774240Smckusick #else 1784240Smckusick bmap = malloc((unsigned)n); 1794240Smckusick #endif 1804240Smckusick if (bmap==NULL) { 1814240Smckusick printf("Not enough core; duplicates unchecked\n"); 1824240Smckusick dflg++; 1835098Smckusic if (sflg) { 1845098Smckusic printf("No Updates\n"); 1855098Smckusic sflg = 0; 1865098Smckusic } 1874240Smckusick } 1884240Smckusick ino = 0; 1894240Smckusick cginit = 1; 1906534Smckusick if (!dflg) { 1916534Smckusick for (i = 0; i < (unsigned)n; i++) 1924240Smckusick bmap[i] = 0; 1936534Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1945382Smckusic cgd = cgtod(&sblock, c); 1956534Smckusick if (c == 0) 1966534Smckusick d = cgbase(&sblock, c); 1976534Smckusick else 1986534Smckusick d = cgsblock(&sblock, c); 199*32441Sbostic (void)sprintf(buf, "spare super block %d", c); 2006534Smckusick for (; d < cgd; d += sblock.fs_frag) 2019298Smckusick chk(d, buf, sblock.fs_bsize); 2025382Smckusic d = cgimin(&sblock, c); 203*32441Sbostic (void)sprintf(buf, "cylinder group %d", c); 2044240Smckusick while (cgd < d) { 2059298Smckusick chk(cgd, buf, sblock.fs_bsize); 2065326Smckusic cgd += sblock.fs_frag; 2074240Smckusick } 2085382Smckusic d = cgdmin(&sblock, c); 2099298Smckusick i = INOPB(&sblock); 2109298Smckusick for (; cgd < d; cgd += sblock.fs_frag) { 211*32441Sbostic (void)sprintf(buf, "inodes %d-%d", ino, ino + i); 2129298Smckusick chk(cgd, buf, sblock.fs_bsize); 2139298Smckusick ino += i; 2149298Smckusick } 2154240Smckusick if (c == 0) { 2166534Smckusick d += howmany(sblock.fs_cssize, sblock.fs_fsize); 2176534Smckusick for (; cgd < d; cgd++) 2186534Smckusick chk(cgd, "csum", sblock.fs_fsize); 2194240Smckusick } 2204240Smckusick } 2214240Smckusick } 2229298Smckusick ino = 0; 2234240Smckusick cginit = 0; 2244240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2255382Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 2264240Smckusick sblock.fs_ipg * sizeof (struct dinode)); 2274240Smckusick for (j=0; j < sblock.fs_ipg; j++) { 2284240Smckusick pass1(&itab[j]); 2294240Smckusick ino++; 2304240Smckusick } 2314240Smckusick } 2324240Smckusick ino = 0; 2334240Smckusick #ifndef STANDALONE 2344240Smckusick sync(); 2354240Smckusick #endif 2365098Smckusic if (sflg) { 2375098Smckusic makecg(); 2385098Smckusic close(fi); 2395098Smckusic #ifndef STANDALONE 2405098Smckusic if (bmap) 2415098Smckusic free(bmap); 2425098Smckusic #endif 2435098Smckusic return; 2445098Smckusic } 2454240Smckusick nffree = 0; 2464240Smckusick nbfree = 0; 2474240Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 2485382Smckusic cbase = cgbase(&sblock, c); 2495382Smckusic bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp, 2505326Smckusic sblock.fs_cgsize); 2516534Smckusick if (cgrp.cg_magic != CG_MAGIC) 2526534Smckusick printf("cg %d: bad magic number\n", c); 2535326Smckusic for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { 2545326Smckusic if (isblock(&sblock, cgrp.cg_free, 2555326Smckusic b / sblock.fs_frag)) { 2564240Smckusick nbfree++; 2579298Smckusick chk(cbase+b, "free block", sblock.fs_bsize); 2584240Smckusick } else { 2595326Smckusic for (d = 0; d < sblock.fs_frag; d++) 2604240Smckusick if (isset(cgrp.cg_free, b+d)) { 2619298Smckusick chk(cbase+b+d, "free frag", sblock.fs_fsize); 2624240Smckusick nffree++; 2634240Smckusick } 2644240Smckusick } 2654240Smckusick } 2664240Smckusick } 2674240Smckusick close(fi); 2684240Smckusick #ifndef STANDALONE 2694240Smckusick if (bmap) 2704240Smckusick free(bmap); 2714240Smckusick #endif 2724240Smckusick 2736286Smckusick i = nrfile + ndfile + ncfile + nbfile + nlfile; 2744240Smckusick #ifndef STANDALONE 2756286Smckusick printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", 2766286Smckusick i, nrfile, ndfile, nbfile, ncfile, nlfile); 2774240Smckusick #else 2786286Smckusick printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", 2796286Smckusick i, nrfile, ndfile, nbfile, ncfile, nlfile); 2804240Smckusick #endif 2815326Smckusic n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag; 2824240Smckusick #ifdef STANDALONE 2834240Smckusick printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2844240Smckusick n, nindir, niindir, nblock, nfrag); 2855326Smckusic printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, 2864240Smckusick nbfree, nffree); 2874240Smckusick #else 2884240Smckusick printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 2894240Smckusick n, nindir, niindir, nblock, nfrag); 2905326Smckusic printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, 2914240Smckusick nbfree, nffree); 2924240Smckusick #endif 2934240Smckusick if(!dflg) { 2944240Smckusick n = 0; 2954410Smckusic for (d = 0; d < sblock.fs_size; d++) 2965326Smckusic if(!duped(d, sblock.fs_fsize)) { 2974240Smckusick if(mflg) 2984240Smckusick printf("%ld missing\n", d); 2994240Smckusick n++; 3004240Smckusick } 3014240Smckusick printf("missing%5ld\n", n); 3024240Smckusick } 3034240Smckusick } 3044240Smckusick 3054240Smckusick pass1(ip) 3064410Smckusic register struct dinode *ip; 3074240Smckusick { 3085326Smckusic daddr_t ind1[MAXNINDIR]; 3095326Smckusic daddr_t ind2[MAXNINDIR]; 3104429Smckusic daddr_t db, ib; 3114429Smckusic register int i, j, k, siz; 3129298Smckusick int lbn; 3139298Smckusick char buf[BUFSIZ]; 3144240Smckusick 3154240Smckusick i = ip->di_mode & IFMT; 3164790Smckusic if(i == 0) 3174240Smckusick return; 3184240Smckusick switch (i) { 3194240Smckusick case IFCHR: 3204240Smckusick ncfile++; 3214240Smckusick return; 3224240Smckusick case IFBLK: 3234240Smckusick nbfile++; 3244240Smckusick return; 3254240Smckusick case IFDIR: 3264240Smckusick ndfile++; 3274240Smckusick break; 3284240Smckusick case IFREG: 3294240Smckusick nrfile++; 3304240Smckusick break; 3316286Smckusick case IFLNK: 3326286Smckusick nlfile++; 3336286Smckusick break; 3344240Smckusick default: 3354240Smckusick printf("bad mode %u\n", ino); 3364240Smckusick return; 3374240Smckusick } 3384410Smckusic for (i = 0; i < NDADDR; i++) { 3394410Smckusic db = ip->di_db[i]; 3404410Smckusic if (db == 0) 3414240Smckusick continue; 3425326Smckusic siz = dblksize(&sblock, ip, i); 343*32441Sbostic (void)sprintf(buf, "logical data block %d", i); 3449298Smckusick chk(db, buf, siz); 3455326Smckusic if (siz == sblock.fs_bsize) 3464429Smckusic nblock++; 3474429Smckusic else 3485326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3494240Smckusick } 3504410Smckusic for(i = 0; i < NIADDR; i++) { 3514410Smckusic ib = ip->di_ib[i]; 3529298Smckusick if (ib == 0) 3534240Smckusick continue; 3545326Smckusic if (chk(ib, "1st indirect", sblock.fs_bsize)) 3554410Smckusic continue; 3565326Smckusic bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize); 3574240Smckusick nindir++; 3585326Smckusic for (j = 0; j < NINDIR(&sblock); j++) { 3594410Smckusic ib = ind1[j]; 3604410Smckusic if (ib == 0) 3614240Smckusick continue; 3624410Smckusic if (i == 0) { 3639298Smckusick lbn = NDADDR + j; 3649298Smckusick siz = dblksize(&sblock, ip, lbn); 365*32441Sbostic (void)sprintf(buf, "logical data block %d", lbn); 3669298Smckusick chk(ib, buf, siz); 3675326Smckusic if (siz == sblock.fs_bsize) 3684429Smckusic nblock++; 3694429Smckusic else 3705326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3714240Smckusick continue; 3724240Smckusick } 3735326Smckusic if (chk(ib, "2nd indirect", sblock.fs_bsize)) 3744410Smckusic continue; 3755326Smckusic bread(fsbtodb(&sblock, ib), (char *)ind2, 3765326Smckusic sblock.fs_bsize); 3774240Smckusick niindir++; 3785326Smckusic for (k = 0; k < NINDIR(&sblock); k++) { 3794410Smckusic ib = ind2[k]; 3804410Smckusic if (ib == 0) 3814240Smckusick continue; 3829298Smckusick lbn = NDADDR + NINDIR(&sblock) * (i + j) + k; 3839298Smckusick siz = dblksize(&sblock, ip, lbn); 384*32441Sbostic (void)sprintf(buf, "logical data block %d", lbn); 3859298Smckusick chk(ib, buf, siz); 3865326Smckusic if (siz == sblock.fs_bsize) 3874429Smckusic nblock++; 3884429Smckusic else 3895326Smckusic nfrag += howmany(siz, sblock.fs_fsize); 3904240Smckusick } 3914240Smckusick } 3924240Smckusick } 3934240Smckusick } 3944240Smckusick 3954429Smckusic chk(bno, s, size) 3964410Smckusic daddr_t bno; 3974410Smckusic char *s; 3984429Smckusic int size; 3994240Smckusick { 4004240Smckusick register n, cg; 4015957Smckusic int frags; 4024240Smckusick 4035382Smckusic cg = dtog(&sblock, bno); 4046534Smckusick if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) { 4054240Smckusick printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 4064240Smckusick return(1); 4074240Smckusick } 4089298Smckusick frags = numfrags(&sblock, size); 4099298Smckusick if (frags == sblock.fs_frag) { 4104429Smckusic if (duped(bno, size)) { 4114429Smckusic printf("%ld dup block; inode=%u, class=%s\n", 4124429Smckusic bno, ino, s); 4135326Smckusic ndup += sblock.fs_frag; 4144429Smckusic } 4154429Smckusic } else { 4165957Smckusic for (n = 0; n < frags; n++) { 4175326Smckusic if (duped(bno + n, sblock.fs_fsize)) { 4184429Smckusic printf("%ld dup frag; inode=%u, class=%s\n", 4194429Smckusic bno, ino, s); 4204429Smckusic ndup++; 4214429Smckusic } 4224429Smckusic } 4234240Smckusick } 4244240Smckusick for (n=0; blist[n] != -1; n++) 4259298Smckusick if (fsblist[n] >= bno && fsblist[n] < bno + frags) 4269298Smckusick printf("%ld arg; frag %d of %d, inode=%u, class=%s\n", 4279298Smckusick blist[n], fsblist[n] - bno, frags, ino, s); 4284240Smckusick return(0); 4294240Smckusick } 4304240Smckusick 4314429Smckusic duped(bno, size) 4324410Smckusic daddr_t bno; 4334429Smckusic int size; 4344240Smckusick { 4354240Smckusick if(dflg) 4364240Smckusick return(0); 4375326Smckusic if (size != sblock.fs_fsize && size != sblock.fs_bsize) 4384429Smckusic printf("bad size %d to duped\n", size); 4395326Smckusic if (size == sblock.fs_fsize) { 4404410Smckusic if (isset(bmap, bno)) 4414410Smckusic return(1); 4424410Smckusic setbit(bmap, bno); 4434410Smckusic return (0); 4444410Smckusic } 4455326Smckusic if (bno % sblock.fs_frag != 0) 4464410Smckusic printf("bad bno %d to duped\n", bno); 4475326Smckusic if (isblock(&sblock, bmap, bno/sblock.fs_frag)) 4484410Smckusic return (1); 4495326Smckusic setblock(&sblock, bmap, bno/sblock.fs_frag); 4504240Smckusick return(0); 4514240Smckusick } 4524240Smckusick 4535098Smckusic makecg() 4545098Smckusic { 4555098Smckusic int c, blk; 4566534Smckusick daddr_t dbase, d, dlower, dupper, dmax; 4575098Smckusic long i, j, s; 4585098Smckusic register struct csum *cs; 4595098Smckusic register struct dinode *dp; 4605098Smckusic 4615098Smckusic sblock.fs_cstotal.cs_nbfree = 0; 4625098Smckusic sblock.fs_cstotal.cs_nffree = 0; 4635098Smckusic sblock.fs_cstotal.cs_nifree = 0; 4645098Smckusic sblock.fs_cstotal.cs_ndir = 0; 4655098Smckusic for (c = 0; c < sblock.fs_ncg; c++) { 4665382Smckusic dbase = cgbase(&sblock, c); 4675098Smckusic dmax = dbase + sblock.fs_fpg; 4685410Smckusic if (dmax > sblock.fs_size) { 4695410Smckusic for ( ; dmax >= sblock.fs_size; dmax--) 4705400Smckusic clrbit(cgrp.cg_free, dmax - dbase); 4715410Smckusic dmax++; 4725410Smckusic } 4736534Smckusick dlower = cgsblock(&sblock, c) - dbase; 4746534Smckusick dupper = cgdmin(&sblock, c) - dbase; 4755326Smckusic cs = &sblock.fs_cs(&sblock, c); 4765098Smckusic cgrp.cg_time = time(0); 4775098Smckusic cgrp.cg_magic = CG_MAGIC; 4785098Smckusic cgrp.cg_cgx = c; 4798143Smckusick if (c == sblock.fs_ncg - 1) 4808143Smckusick cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; 4818143Smckusick else 4828143Smckusick cgrp.cg_ncyl = sblock.fs_cpg; 4835098Smckusic cgrp.cg_niblk = sblock.fs_ipg; 4845098Smckusic cgrp.cg_ndblk = dmax - dbase; 4855098Smckusic cgrp.cg_cs.cs_ndir = 0; 4865098Smckusic cgrp.cg_cs.cs_nffree = 0; 4875098Smckusic cgrp.cg_cs.cs_nbfree = 0; 4885098Smckusic cgrp.cg_cs.cs_nifree = 0; 4896534Smckusick cgrp.cg_rotor = 0; 4906534Smckusick cgrp.cg_frotor = 0; 4915098Smckusic cgrp.cg_irotor = 0; 4925326Smckusic for (i = 0; i < sblock.fs_frag; i++) 4935098Smckusic cgrp.cg_frsum[i] = 0; 4945382Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 4955098Smckusic sblock.fs_ipg * sizeof(struct dinode)); 4965098Smckusic for (i = 0; i < sblock.fs_ipg; i++) { 4975945Smckusic cgrp.cg_cs.cs_nifree++; 4985945Smckusic clrbit(cgrp.cg_iused, i); 4995098Smckusic dp = &itab[i]; 5005098Smckusic if ((dp->di_mode & IFMT) != 0) { 5015098Smckusic if ((dp->di_mode & IFMT) == IFDIR) 5025098Smckusic cgrp.cg_cs.cs_ndir++; 5035945Smckusic cgrp.cg_cs.cs_nifree--; 5045098Smckusic setbit(cgrp.cg_iused, i); 5055098Smckusic continue; 5065098Smckusic } 5075098Smckusic } 5085098Smckusic while (i < MAXIPG) { 5095098Smckusic clrbit(cgrp.cg_iused, i); 5105098Smckusic i++; 5115098Smckusic } 5125338Smckusic if (c == 0) 5135338Smckusic for (i = 0; i < ROOTINO; i++) { 5145338Smckusic setbit(cgrp.cg_iused, i); 5155338Smckusic cgrp.cg_cs.cs_nifree--; 5165338Smckusic } 5175372Smckusic for (s = 0; s < MAXCPG; s++) { 5185372Smckusic cgrp.cg_btot[s] = 0; 5195098Smckusic for (i = 0; i < NRPOS; i++) 5205098Smckusic cgrp.cg_b[s][i] = 0; 5215372Smckusic } 5225098Smckusic if (c == 0) { 5236534Smckusick dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); 5245098Smckusic } 5256534Smckusick for (d = dlower; d < dupper; d++) 5265098Smckusic clrbit(cgrp.cg_free, d); 5276534Smckusick for (d = 0; (d + sblock.fs_frag) <= dmax - dbase; 5286534Smckusick d += sblock.fs_frag) { 5295098Smckusic j = 0; 5305326Smckusic for (i = 0; i < sblock.fs_frag; i++) { 5316534Smckusick if (!isset(bmap, dbase + d + i)) { 5326534Smckusick setbit(cgrp.cg_free, d + i); 5335098Smckusic j++; 5345098Smckusic } else 5355098Smckusic clrbit(cgrp.cg_free, d+i); 5365098Smckusic } 5375326Smckusic if (j == sblock.fs_frag) { 5385098Smckusic cgrp.cg_cs.cs_nbfree++; 5395372Smckusic cgrp.cg_btot[cbtocylno(&sblock, d)]++; 5405364Smckusic cgrp.cg_b[cbtocylno(&sblock, d)] 5415364Smckusic [cbtorpos(&sblock, d)]++; 5425098Smckusic } else if (j > 0) { 5435098Smckusic cgrp.cg_cs.cs_nffree += j; 5446534Smckusick blk = blkmap(&sblock, cgrp.cg_free, d); 5455326Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 5465098Smckusic } 5475098Smckusic } 5485098Smckusic for (j = d; d < dmax - dbase; d++) { 5496534Smckusick if (!isset(bmap, dbase + d)) { 5505098Smckusic setbit(cgrp.cg_free, d); 5515098Smckusic cgrp.cg_cs.cs_nffree++; 5525098Smckusic } else 5535098Smckusic clrbit(cgrp.cg_free, d); 5545098Smckusic } 5558143Smckusick for (; d % sblock.fs_frag != 0; d++) 5568143Smckusick clrbit(cgrp.cg_free, d); 5575098Smckusic if (j != d) { 5586534Smckusick blk = blkmap(&sblock, cgrp.cg_free, j); 5595326Smckusic fragacct(&sblock, blk, cgrp.cg_frsum, 1); 5605098Smckusic } 5618143Smckusick for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++) 5628143Smckusick clrblock(&sblock, cgrp.cg_free, d); 5635098Smckusic sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree; 5645098Smckusic sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree; 5655098Smckusic sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree; 5665098Smckusic sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir; 5675098Smckusic *cs = cgrp.cg_cs; 5685382Smckusic bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp, 5695326Smckusic sblock.fs_cgsize); 5705098Smckusic } 5716534Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 5726534Smckusick bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), 5736534Smckusick (char *)sblock.fs_csp[j], 5746534Smckusick sblock.fs_cssize - i < sblock.fs_bsize ? 5756534Smckusick sblock.fs_cssize - i : sblock.fs_bsize); 5765098Smckusic } 5775098Smckusic sblock.fs_ronly = 0; 5785098Smckusic sblock.fs_fmod = 0; 57930558Smckusick bwrite(SBOFF / dev_bsize, (char *)&sblock, SBSIZE); 5805098Smckusic } 5815098Smckusic 5825098Smckusic /* 5835098Smckusic * update the frsum fields to reflect addition or deletion 5845098Smckusic * of some frags 5855098Smckusic */ 5865326Smckusic fragacct(fs, fragmap, fraglist, cnt) 5875326Smckusic struct fs *fs; 5885098Smckusic int fragmap; 5895098Smckusic long fraglist[]; 5905098Smckusic int cnt; 5915098Smckusic { 5925098Smckusic int inblk; 5935098Smckusic register int field, subfield; 5945098Smckusic register int siz, pos; 5955098Smckusic 5965326Smckusic inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1); 5975098Smckusic fragmap <<= 1; 5985326Smckusic for (siz = 1; siz < fs->fs_frag; siz++) { 5996291Smckusick if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) 6005098Smckusic continue; 6015098Smckusic field = around[siz]; 6025098Smckusic subfield = inside[siz]; 6035326Smckusic for (pos = siz; pos <= fs->fs_frag; pos++) { 6045098Smckusic if ((fragmap & field) == subfield) { 6055098Smckusic fraglist[siz] += cnt; 6065098Smckusic pos += siz; 6075098Smckusic field <<= siz; 6085098Smckusic subfield <<= siz; 6095098Smckusic } 6105098Smckusic field <<= 1; 6115098Smckusic subfield <<= 1; 6125098Smckusic } 6135098Smckusic } 6145098Smckusic } 6155098Smckusic 6165326Smckusic getsb(fs, file) 6175326Smckusic register struct fs *fs; 6185326Smckusic char *file; 6195326Smckusic { 6206534Smckusick int i, j, size; 6215326Smckusic 62230558Smckusick if (bread(SBOFF, fs, SBSIZE)) { 6235326Smckusic printf("bad super block"); 6245326Smckusic perror(file); 6255326Smckusic nerror |= 04; 6265326Smckusic return; 6275326Smckusic } 6285326Smckusic if (fs->fs_magic != FS_MAGIC) { 6295326Smckusic printf("%s: bad magic number\n", file); 6305326Smckusic nerror |= 04; 6315326Smckusic return; 6325326Smckusic } 63330558Smckusick dev_bsize = fs->fs_fsize / fsbtodb(fs, 1); 6346534Smckusick for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { 6356534Smckusick size = sblock.fs_cssize - i < sblock.fs_bsize ? 6366534Smckusick sblock.fs_cssize - i : sblock.fs_bsize; 6376534Smckusick sblock.fs_csp[j] = (struct csum *)calloc(1, size); 6386534Smckusick bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)), 6396534Smckusick (char *)fs->fs_csp[j], size); 6405326Smckusic } 6415326Smckusic } 6425326Smckusic 6435098Smckusic bwrite(blk, buf, size) 6445098Smckusic char *buf; 6455098Smckusic daddr_t blk; 6465098Smckusic register size; 6475098Smckusic { 64830558Smckusick if (lseek(fi, blk * dev_bsize, 0) < 0) { 6495098Smckusic perror("FS SEEK"); 6505098Smckusic return(1); 6515098Smckusic } 6525098Smckusic if (write(fi, buf, size) != size) { 6535098Smckusic perror("FS WRITE"); 6545098Smckusic return(1); 6555098Smckusic } 6565326Smckusic return (0); 6575098Smckusic } 6585098Smckusic 6594240Smckusick bread(bno, buf, cnt) 6604410Smckusic daddr_t bno; 6614410Smckusic char *buf; 6624240Smckusick { 6634240Smckusick register i; 6644240Smckusick 66530558Smckusick lseek(fi, bno * dev_bsize, 0); 6664240Smckusick if ((i = read(fi, buf, cnt)) != cnt) { 6675098Smckusic if (sflg) { 6685098Smckusic printf("No Update\n"); 6695098Smckusic sflg = 0; 6705098Smckusic } 6715326Smckusic for(i=0; i<sblock.fs_bsize; i++) 6724240Smckusick buf[i] = 0; 6735326Smckusic return (1); 6744240Smckusick } 6755326Smckusic return (0); 6764240Smckusick } 6775326Smckusic 6785326Smckusic /* 6798143Smckusick * check if a block is available 6805326Smckusic */ 6815326Smckusic isblock(fs, cp, h) 6825326Smckusic struct fs *fs; 6835326Smckusic unsigned char *cp; 6845326Smckusic int h; 6855326Smckusic { 6865326Smckusic unsigned char mask; 6875326Smckusic 6885326Smckusic switch (fs->fs_frag) { 6895326Smckusic case 8: 6905326Smckusic return (cp[h] == 0xff); 6915326Smckusic case 4: 6925326Smckusic mask = 0x0f << ((h & 0x1) << 2); 6935326Smckusic return ((cp[h >> 1] & mask) == mask); 6945326Smckusic case 2: 6955326Smckusic mask = 0x03 << ((h & 0x3) << 1); 6965326Smckusic return ((cp[h >> 2] & mask) == mask); 6975326Smckusic case 1: 6985326Smckusic mask = 0x01 << (h & 0x7); 6995326Smckusic return ((cp[h >> 3] & mask) == mask); 7005326Smckusic default: 7018143Smckusick #ifdef STANDALONE 7028143Smckusick printf("isblock bad fs_frag %d\n", fs->fs_frag); 7038143Smckusick #else 7045326Smckusic fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); 7058143Smckusick #endif 7065326Smckusic return; 7075326Smckusic } 7085326Smckusic } 7095326Smckusic 7108143Smckusick /* 7118143Smckusick * take a block out of the map 7128143Smckusick */ 7138143Smckusick clrblock(fs, cp, h) 7148143Smckusick struct fs *fs; 7158143Smckusick unsigned char *cp; 7168143Smckusick int h; 7178143Smckusick { 7188143Smckusick switch ((fs)->fs_frag) { 7198143Smckusick case 8: 7208143Smckusick cp[h] = 0; 7218143Smckusick return; 7228143Smckusick case 4: 7238143Smckusick cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); 7248143Smckusick return; 7258143Smckusick case 2: 7268143Smckusick cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); 7278143Smckusick return; 7288143Smckusick case 1: 7298143Smckusick cp[h >> 3] &= ~(0x01 << (h & 0x7)); 7308143Smckusick return; 7318143Smckusick default: 7328143Smckusick #ifdef STANDALONE 7338143Smckusick printf("clrblock bad fs_frag %d\n", fs->fs_frag); 7348143Smckusick #else 7358143Smckusick fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); 7368143Smckusick #endif 7378143Smckusick return; 7388143Smckusick } 7398143Smckusick } 7408143Smckusick 7418143Smckusick /* 7428143Smckusick * put a block into the map 7438143Smckusick */ 7445326Smckusic setblock(fs, cp, h) 7455326Smckusic struct fs *fs; 7465326Smckusic unsigned char *cp; 7475326Smckusic int h; 7485326Smckusic { 7495326Smckusic switch (fs->fs_frag) { 7505326Smckusic case 8: 7515326Smckusic cp[h] = 0xff; 7525326Smckusic return; 7535326Smckusic case 4: 7545326Smckusic cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); 7555326Smckusic return; 7565326Smckusic case 2: 7575326Smckusic cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); 7585326Smckusic return; 7595326Smckusic case 1: 7605326Smckusic cp[h >> 3] |= (0x01 << (h & 0x7)); 7615326Smckusic return; 7625326Smckusic default: 7638143Smckusick #ifdef STANDALONE 7648143Smckusick printf("setblock bad fs_frag %d\n", fs->fs_frag); 7658143Smckusick #else 7665326Smckusic fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); 7678143Smckusick #endif 7685326Smckusic return; 7695326Smckusic } 7705326Smckusic } 7716490Smckusick 7726490Smckusick /* tables.c 4.1 82/03/25 */ 7736490Smckusick 7746490Smckusick /* merged into kernel: tables.c 2.1 3/25/82 */ 7756490Smckusick 7766490Smckusick /* last monet version: partab.c 4.2 81/03/08 */ 7776490Smckusick 7786490Smckusick /* 7796490Smckusick * bit patterns for identifying fragments in the block map 7806490Smckusick * used as ((map & around) == inside) 7816490Smckusick */ 7826490Smckusick int around[9] = { 7836490Smckusick 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff 7846490Smckusick }; 7856490Smckusick int inside[9] = { 7866490Smckusick 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe 7876490Smckusick }; 7886490Smckusick 7896490Smckusick /* 7906490Smckusick * given a block map bit pattern, the frag tables tell whether a 7916490Smckusick * particular size fragment is available. 7926490Smckusick * 7936490Smckusick * used as: 7946490Smckusick * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { 7956490Smckusick * at least one fragment of the indicated size is available 7966490Smckusick * } 7976490Smckusick * 7986490Smckusick * These tables are used by the scanc instruction on the VAX to 7996490Smckusick * quickly find an appropriate fragment. 8006490Smckusick */ 8016490Smckusick 8026490Smckusick unsigned char fragtbl124[256] = { 8036490Smckusick 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, 8046490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, 8056490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8066490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8076490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8086490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8096490Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 8106490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 8116490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8126490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8136490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8146490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8156490Smckusick 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, 8166490Smckusick 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, 8176490Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 8186490Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 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 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, 8246490Smckusick 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, 8256490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 8266490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 8276490Smckusick 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, 8286490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, 8296490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 8306490Smckusick 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, 8316490Smckusick 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, 8326490Smckusick 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, 8336490Smckusick 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, 8346490Smckusick 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, 8356490Smckusick }; 8366490Smckusick 8376490Smckusick unsigned char fragtbl8[256] = { 8386490Smckusick 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, 8396490Smckusick 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, 8406490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8416490Smckusick 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, 8426490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8436490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8446490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8456490Smckusick 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, 8466490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8476490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8486490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8496490Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 8506490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8516490Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 8526490Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 8536490Smckusick 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, 8546490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8556490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8566490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8576490Smckusick 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, 8586490Smckusick 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, 8596490Smckusick 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, 8606490Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 8616490Smckusick 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, 8626490Smckusick 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, 8636490Smckusick 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, 8646490Smckusick 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, 8656490Smckusick 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, 8666490Smckusick 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, 8676490Smckusick 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, 8686490Smckusick 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, 8696490Smckusick 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, 8706490Smckusick }; 8716490Smckusick 8726490Smckusick /* 8736490Smckusick * the actual fragtbl array 8746490Smckusick */ 8756490Smckusick unsigned char *fragtbl[MAXFRAG + 1] = { 8766490Smckusick 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, 8776490Smckusick }; 878