13e12c5d1SDavid du Colombier #include "all.h"
23e12c5d1SDavid du Colombier
33e12c5d1SDavid du Colombier #define DSIZE 546000
43e12c5d1SDavid du Colombier #define MAXDEPTH 100
53e12c5d1SDavid du Colombier
63e12c5d1SDavid du Colombier static char* abits;
73e12c5d1SDavid du Colombier static long sizabits;
83e12c5d1SDavid du Colombier static char* qbits;
93e12c5d1SDavid du Colombier static long sizqbits;
103e12c5d1SDavid du Colombier static char* name;
113e12c5d1SDavid du Colombier static long sizname;
123e12c5d1SDavid du Colombier static long fstart;
133e12c5d1SDavid du Colombier static long fsize;
143e12c5d1SDavid du Colombier static long nfiles;
153e12c5d1SDavid du Colombier static long maxq;
167dd7cddfSDavid du Colombier static char* fence;
177dd7cddfSDavid du Colombier static char* fencebase;
183e12c5d1SDavid du Colombier static Device dev;
193e12c5d1SDavid du Colombier static long ndup;
203e12c5d1SDavid du Colombier static long nused;
213e12c5d1SDavid du Colombier static long nfdup;
223e12c5d1SDavid du Colombier static long nqbad;
233e12c5d1SDavid du Colombier static long nfree;
243e12c5d1SDavid du Colombier static long nbad;
253e12c5d1SDavid du Colombier static int mod;
263e12c5d1SDavid du Colombier static int flags;
273e12c5d1SDavid du Colombier static int ronly;
283e12c5d1SDavid du Colombier static int cwflag;
293e12c5d1SDavid du Colombier static long sbaddr;
303e12c5d1SDavid du Colombier static long oldblock;
313e12c5d1SDavid du Colombier static int depth;
323e12c5d1SDavid du Colombier static int maxdepth;
333e12c5d1SDavid du Colombier
343e12c5d1SDavid du Colombier /* local prototypes */
353e12c5d1SDavid du Colombier static int fsck(Dentry*);
363e12c5d1SDavid du Colombier static void ckfreelist(Superb*);
373e12c5d1SDavid du Colombier static void mkfreelist(Superb*);
383e12c5d1SDavid du Colombier static Dentry* maked(long, int, long);
393e12c5d1SDavid du Colombier static void modd(long, int, Dentry*);
403e12c5d1SDavid du Colombier static void xread(long, long);
413e12c5d1SDavid du Colombier static int amark(long);
423e12c5d1SDavid du Colombier static int fmark(long);
433e12c5d1SDavid du Colombier static void missing(void);
443e12c5d1SDavid du Colombier static void qmark(long);
453e12c5d1SDavid du Colombier static void* zalloc(ulong);
463e12c5d1SDavid du Colombier static void* dalloc(ulong);
473e12c5d1SDavid du Colombier static Iobuf* xtag(long, int, long);
483e12c5d1SDavid du Colombier
493e12c5d1SDavid du Colombier static
503e12c5d1SDavid du Colombier void*
zalloc(ulong n)513e12c5d1SDavid du Colombier zalloc(ulong n)
523e12c5d1SDavid du Colombier {
533e12c5d1SDavid du Colombier char *p;
543e12c5d1SDavid du Colombier
553e12c5d1SDavid du Colombier p = malloc(n);
563e12c5d1SDavid du Colombier if(p == 0)
573e12c5d1SDavid du Colombier panic("zalloc: out of memory\n");
583e12c5d1SDavid du Colombier memset(p, '\0', n);
593e12c5d1SDavid du Colombier return p;
603e12c5d1SDavid du Colombier }
613e12c5d1SDavid du Colombier
623e12c5d1SDavid du Colombier static
633e12c5d1SDavid du Colombier void*
dalloc(ulong n)643e12c5d1SDavid du Colombier dalloc(ulong n)
653e12c5d1SDavid du Colombier {
663e12c5d1SDavid du Colombier char *p;
673e12c5d1SDavid du Colombier
687dd7cddfSDavid du Colombier if(fencebase == 0)
697dd7cddfSDavid du Colombier fence = fencebase = zalloc(MAXDEPTH*sizeof(Dentry));
707dd7cddfSDavid du Colombier p = fence;
717dd7cddfSDavid du Colombier fence += n;
727dd7cddfSDavid du Colombier if(fence > fencebase+MAXDEPTH*sizeof(Dentry))
733e12c5d1SDavid du Colombier panic("dalloc too much memory\n");
743e12c5d1SDavid du Colombier return p;
753e12c5d1SDavid du Colombier }
763e12c5d1SDavid du Colombier
773e12c5d1SDavid du Colombier void
check(Filsys * fs,long flag)783e12c5d1SDavid du Colombier check(Filsys *fs, long flag)
793e12c5d1SDavid du Colombier {
803e12c5d1SDavid du Colombier Iobuf *p;
813e12c5d1SDavid du Colombier Superb *sb;
823e12c5d1SDavid du Colombier Dentry *d;
833e12c5d1SDavid du Colombier long raddr;
849a747e4fSDavid du Colombier long nqid;
853e12c5d1SDavid du Colombier
863e12c5d1SDavid du Colombier wlock(&mainlock);
873e12c5d1SDavid du Colombier dev = fs->dev;
883e12c5d1SDavid du Colombier flags = flag;
897dd7cddfSDavid du Colombier fence = fencebase;
903e12c5d1SDavid du Colombier
913e12c5d1SDavid du Colombier sizname = 4000;
923e12c5d1SDavid du Colombier name = zalloc(sizname);
933e12c5d1SDavid du Colombier sizname -= NAMELEN+10; /* for safety */
943e12c5d1SDavid du Colombier
953e12c5d1SDavid du Colombier sbaddr = superaddr(dev);
963e12c5d1SDavid du Colombier raddr = getraddr(dev);
973e12c5d1SDavid du Colombier p = xtag(sbaddr, Tsuper, QPSUPER);
983e12c5d1SDavid du Colombier if(!p){
993e12c5d1SDavid du Colombier cprint("bad superblock\n");
1003e12c5d1SDavid du Colombier goto out;
1013e12c5d1SDavid du Colombier }
1023e12c5d1SDavid du Colombier sb = (Superb*)p->iobuf;
1033e12c5d1SDavid du Colombier fstart = 1;
1043e12c5d1SDavid du Colombier
1053e12c5d1SDavid du Colombier fsize = sb->fsize;
1063e12c5d1SDavid du Colombier sizabits = (fsize-fstart + 7)/8;
1073e12c5d1SDavid du Colombier abits = zalloc(sizabits);
1083e12c5d1SDavid du Colombier
1099a747e4fSDavid du Colombier nqid = sb->qidgen+100; /* not as much of a botch */
1109a747e4fSDavid du Colombier if(nqid > 1024*1024*8)
1119a747e4fSDavid du Colombier nqid = 1024*1024*8;
1129a747e4fSDavid du Colombier if(nqid < 64*1024)
1139a747e4fSDavid du Colombier nqid = 64*1024;
1149a747e4fSDavid du Colombier
1159a747e4fSDavid du Colombier sizqbits = (nqid+7)/8;
1169a747e4fSDavid du Colombier qbits = zalloc(sizqbits);
1179a747e4fSDavid du Colombier
1183e12c5d1SDavid du Colombier mod = 0;
1193e12c5d1SDavid du Colombier nfree = 0;
1203e12c5d1SDavid du Colombier nfdup = 0;
1213e12c5d1SDavid du Colombier nused = 0;
1223e12c5d1SDavid du Colombier nbad = 0;
1233e12c5d1SDavid du Colombier ndup = 0;
1243e12c5d1SDavid du Colombier nqbad = 0;
1253e12c5d1SDavid du Colombier depth = 0;
1263e12c5d1SDavid du Colombier maxdepth = 0;
1273e12c5d1SDavid du Colombier
1283e12c5d1SDavid du Colombier if(flags & Ctouch) {
1293e12c5d1SDavid du Colombier oldblock = fsize/DSIZE;
1303e12c5d1SDavid du Colombier oldblock *= DSIZE;
1313e12c5d1SDavid du Colombier if(oldblock < 0)
1323e12c5d1SDavid du Colombier oldblock = 0;
1333e12c5d1SDavid du Colombier cprint("oldblock = %ld\n", oldblock);
1343e12c5d1SDavid du Colombier }
1353e12c5d1SDavid du Colombier if(amark(sbaddr))
1369a747e4fSDavid du Colombier {}
1373e12c5d1SDavid du Colombier if(cwflag) {
1383e12c5d1SDavid du Colombier if(amark(sb->roraddr))
1399a747e4fSDavid du Colombier {}
1403e12c5d1SDavid du Colombier if(amark(sb->next))
1419a747e4fSDavid du Colombier {}
1423e12c5d1SDavid du Colombier }
1433e12c5d1SDavid du Colombier
1443e12c5d1SDavid du Colombier if(!(flags & Cquiet))
1453e12c5d1SDavid du Colombier cprint("checking file system: %s\n", fs->name);
1463e12c5d1SDavid du Colombier nfiles = 0;
1473e12c5d1SDavid du Colombier maxq = 0;
1483e12c5d1SDavid du Colombier
1493e12c5d1SDavid du Colombier d = maked(raddr, 0, QPROOT);
1503e12c5d1SDavid du Colombier if(d) {
1513e12c5d1SDavid du Colombier if(amark(raddr))
1529a747e4fSDavid du Colombier {}
1533e12c5d1SDavid du Colombier if(fsck(d))
1543e12c5d1SDavid du Colombier modd(raddr, 0, d);
1553e12c5d1SDavid du Colombier depth--;
1567dd7cddfSDavid du Colombier fence -= sizeof(Dentry);
1573e12c5d1SDavid du Colombier if(depth)
1583e12c5d1SDavid du Colombier cprint("depth not zero on return\n");
1593e12c5d1SDavid du Colombier }
1603e12c5d1SDavid du Colombier
1613e12c5d1SDavid du Colombier if(flags & Cfree) {
1623e12c5d1SDavid du Colombier mkfreelist(sb);
1633e12c5d1SDavid du Colombier sb->qidgen = maxq;
1643e12c5d1SDavid du Colombier settag(p, Tsuper, QPNONE);
1653e12c5d1SDavid du Colombier }
1663e12c5d1SDavid du Colombier
1673e12c5d1SDavid du Colombier if(sb->qidgen < maxq)
1683e12c5d1SDavid du Colombier cprint("qid generator low path=%ld maxq=%ld\n",
1693e12c5d1SDavid du Colombier sb->qidgen, maxq);
1703e12c5d1SDavid du Colombier if(!(flags & Cfree))
1713e12c5d1SDavid du Colombier ckfreelist(sb);
1723e12c5d1SDavid du Colombier if(mod) {
1733e12c5d1SDavid du Colombier cprint("file system was modified\n");
1743e12c5d1SDavid du Colombier settag(p, Tsuper, QPNONE);
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier
1773e12c5d1SDavid du Colombier if(!(flags & Cquiet)){
1783e12c5d1SDavid du Colombier cprint("%8ld files\n", nfiles);
1793e12c5d1SDavid du Colombier cprint("%8ld blocks in the file system\n", fsize-fstart);
1803e12c5d1SDavid du Colombier cprint("%8ld used blocks\n", nused);
1813e12c5d1SDavid du Colombier cprint("%8ld free blocks\n", sb->tfree);
1823e12c5d1SDavid du Colombier }
1833e12c5d1SDavid du Colombier if(!(flags & Cfree)){
1843e12c5d1SDavid du Colombier if(nfree != sb->tfree)
1853e12c5d1SDavid du Colombier cprint("%8ld free blocks found\n", nfree);
1863e12c5d1SDavid du Colombier if(nfdup)
1873e12c5d1SDavid du Colombier cprint("%8ld blocks duplicated in the free list\n", nfdup);
1883e12c5d1SDavid du Colombier if(fsize-fstart-nused-nfree)
1893e12c5d1SDavid du Colombier cprint("%8ld missing blocks\n", fsize-fstart-nused-nfree);
1903e12c5d1SDavid du Colombier }
1913e12c5d1SDavid du Colombier if(ndup)
1923e12c5d1SDavid du Colombier cprint("%8ld address duplications\n", ndup);
1933e12c5d1SDavid du Colombier if(nbad)
1943e12c5d1SDavid du Colombier cprint("%8ld bad block addresses\n", nbad);
1953e12c5d1SDavid du Colombier if(nqbad)
1963e12c5d1SDavid du Colombier cprint("%8ld bad qids\n", nqbad);
1973e12c5d1SDavid du Colombier if(!(flags & Cquiet))
1983e12c5d1SDavid du Colombier cprint("%8ld maximum qid path\n", maxq);
1993e12c5d1SDavid du Colombier missing();
2003e12c5d1SDavid du Colombier
2013e12c5d1SDavid du Colombier out:
2023e12c5d1SDavid du Colombier if(p)
2033e12c5d1SDavid du Colombier putbuf(p);
2043e12c5d1SDavid du Colombier free(abits);
2053e12c5d1SDavid du Colombier free(name);
2063e12c5d1SDavid du Colombier free(qbits);
2073e12c5d1SDavid du Colombier wunlock(&mainlock);
2083e12c5d1SDavid du Colombier }
2093e12c5d1SDavid du Colombier
2103e12c5d1SDavid du Colombier static
2113e12c5d1SDavid du Colombier int
touch(long a)2123e12c5d1SDavid du Colombier touch(long a)
2133e12c5d1SDavid du Colombier {
2143e12c5d1SDavid du Colombier Iobuf *p;
2153e12c5d1SDavid du Colombier
2163e12c5d1SDavid du Colombier if((flags&Ctouch) && a && a < oldblock){
2173e12c5d1SDavid du Colombier p = getbuf(dev, a, Bread|Bmod);
2183e12c5d1SDavid du Colombier if(p)
2193e12c5d1SDavid du Colombier putbuf(p);
2203e12c5d1SDavid du Colombier return 1;
2213e12c5d1SDavid du Colombier }
2223e12c5d1SDavid du Colombier return 0;
2233e12c5d1SDavid du Colombier }
2243e12c5d1SDavid du Colombier
2253e12c5d1SDavid du Colombier static
2263e12c5d1SDavid du Colombier int
checkdir(long a,long qpath)2273e12c5d1SDavid du Colombier checkdir(long a, long qpath)
2283e12c5d1SDavid du Colombier {
2293e12c5d1SDavid du Colombier Dentry *nd;
2303e12c5d1SDavid du Colombier int i, ns, dmod;
2313e12c5d1SDavid du Colombier
2323e12c5d1SDavid du Colombier ns = strlen(name);
2333e12c5d1SDavid du Colombier dmod = touch(a);
2343e12c5d1SDavid du Colombier for(i=0; i<DIRPERBUF; i++) {
2353e12c5d1SDavid du Colombier nd = maked(a, i, qpath);
2363e12c5d1SDavid du Colombier if(!nd)
2373e12c5d1SDavid du Colombier break;
2383e12c5d1SDavid du Colombier if(fsck(nd)) {
2393e12c5d1SDavid du Colombier modd(a, i, nd);
2403e12c5d1SDavid du Colombier dmod++;
2413e12c5d1SDavid du Colombier }
2423e12c5d1SDavid du Colombier depth--;
2437dd7cddfSDavid du Colombier fence -= sizeof(Dentry);
2443e12c5d1SDavid du Colombier name[ns] = 0;
2453e12c5d1SDavid du Colombier }
2463e12c5d1SDavid du Colombier name[ns] = 0;
2473e12c5d1SDavid du Colombier return dmod;
2483e12c5d1SDavid du Colombier }
2493e12c5d1SDavid du Colombier
2503e12c5d1SDavid du Colombier static
2513e12c5d1SDavid du Colombier int
checkindir(long a,Dentry * d,long qpath)2523e12c5d1SDavid du Colombier checkindir(long a, Dentry *d, long qpath)
2533e12c5d1SDavid du Colombier {
2543e12c5d1SDavid du Colombier Iobuf *p;
2553e12c5d1SDavid du Colombier int i, dmod;
2563e12c5d1SDavid du Colombier
2573e12c5d1SDavid du Colombier dmod = touch(a);
2583e12c5d1SDavid du Colombier p = xtag(a, Tind1, qpath);
2593e12c5d1SDavid du Colombier if(!p)
2603e12c5d1SDavid du Colombier return dmod;
2613e12c5d1SDavid du Colombier for(i=0; i<INDPERBUF; i++) {
2623e12c5d1SDavid du Colombier a = ((long*)p->iobuf)[i];
2633e12c5d1SDavid du Colombier if(!a)
2643e12c5d1SDavid du Colombier continue;
2653e12c5d1SDavid du Colombier if(amark(a)) {
2663e12c5d1SDavid du Colombier if(flags & Cbad) {
2673e12c5d1SDavid du Colombier ((long*)p->iobuf)[i] = 0;
2683e12c5d1SDavid du Colombier p->flags |= Bmod;
2693e12c5d1SDavid du Colombier }
2703e12c5d1SDavid du Colombier continue;
2713e12c5d1SDavid du Colombier }
2723e12c5d1SDavid du Colombier if(d->mode & DDIR)
2733e12c5d1SDavid du Colombier dmod += checkdir(a, qpath);
2743e12c5d1SDavid du Colombier else if(flags & Crdall)
2753e12c5d1SDavid du Colombier xread(a, qpath);
2763e12c5d1SDavid du Colombier }
2773e12c5d1SDavid du Colombier putbuf(p);
2783e12c5d1SDavid du Colombier return dmod;
2793e12c5d1SDavid du Colombier }
2803e12c5d1SDavid du Colombier
2813e12c5d1SDavid du Colombier static
2823e12c5d1SDavid du Colombier int
fsck(Dentry * d)2833e12c5d1SDavid du Colombier fsck(Dentry *d)
2843e12c5d1SDavid du Colombier {
285*7611b47fSDavid du Colombier char *s;
286*7611b47fSDavid du Colombier Rune r;
2873e12c5d1SDavid du Colombier Iobuf *p;
288*7611b47fSDavid du Colombier int l, i, ns, dmod;
2893e12c5d1SDavid du Colombier long a, qpath;
2903e12c5d1SDavid du Colombier
2913e12c5d1SDavid du Colombier depth++;
2923e12c5d1SDavid du Colombier if(depth >= maxdepth){
2933e12c5d1SDavid du Colombier maxdepth = depth;
2943e12c5d1SDavid du Colombier if(maxdepth >= MAXDEPTH){
2953e12c5d1SDavid du Colombier cprint("max depth exceeded: %s\n", name);
2963e12c5d1SDavid du Colombier return 0;
2973e12c5d1SDavid du Colombier }
2983e12c5d1SDavid du Colombier }
2993e12c5d1SDavid du Colombier dmod = 0;
3003e12c5d1SDavid du Colombier if(!(d->mode & DALLOC))
3013e12c5d1SDavid du Colombier return 0;
3023e12c5d1SDavid du Colombier nfiles++;
3033e12c5d1SDavid du Colombier
3043e12c5d1SDavid du Colombier ns = strlen(name);
3053e12c5d1SDavid du Colombier i = strlen(d->name);
3063e12c5d1SDavid du Colombier if(i >= NAMELEN){
3073e12c5d1SDavid du Colombier d->name[NAMELEN-1] = 0;
3083e12c5d1SDavid du Colombier cprint("%s->name (%s) not terminated\n", name, d->name);
3093e12c5d1SDavid du Colombier return 0;
3103e12c5d1SDavid du Colombier }
3113e12c5d1SDavid du Colombier ns += i;
3123e12c5d1SDavid du Colombier if(ns >= sizname){
3133e12c5d1SDavid du Colombier cprint("%s->name (%s) name too large\n", name, d->name);
3143e12c5d1SDavid du Colombier return 0;
3153e12c5d1SDavid du Colombier }
316*7611b47fSDavid du Colombier for (s = d->name; *s; s += l){
317*7611b47fSDavid du Colombier l = chartorune(&r, s);
318*7611b47fSDavid du Colombier if (r == Runeerror)
319*7611b47fSDavid du Colombier for (i = 0; i < l; i++){
320*7611b47fSDavid du Colombier s[i] = '_';
321*7611b47fSDavid du Colombier cprint("%s->name (%s) bad UTF\n", name, d->name);
322*7611b47fSDavid du Colombier dmod++;
323*7611b47fSDavid du Colombier }
324*7611b47fSDavid du Colombier }
3253e12c5d1SDavid du Colombier strcat(name, d->name);
3263e12c5d1SDavid du Colombier
3273e12c5d1SDavid du Colombier if(d->mode & DDIR){
3283e12c5d1SDavid du Colombier if(ns > 1)
3293e12c5d1SDavid du Colombier strcat(name, "/");
3303e12c5d1SDavid du Colombier if(flags & Cpdir)
3313e12c5d1SDavid du Colombier cprint("%s\n", name);
3323e12c5d1SDavid du Colombier } else
3333e12c5d1SDavid du Colombier if(flags & Cpfile)
3343e12c5d1SDavid du Colombier cprint("%s\n", name);
3353e12c5d1SDavid du Colombier
3363e12c5d1SDavid du Colombier qpath = d->qid.path & ~QPDIR;
3373e12c5d1SDavid du Colombier qmark(qpath);
3383e12c5d1SDavid du Colombier if(qpath > maxq)
3393e12c5d1SDavid du Colombier maxq = qpath;
3403e12c5d1SDavid du Colombier for(i=0; i<NDBLOCK; i++) {
3413e12c5d1SDavid du Colombier a = d->dblock[i];
3423e12c5d1SDavid du Colombier if(!a)
3433e12c5d1SDavid du Colombier continue;
3443e12c5d1SDavid du Colombier if(amark(a)) {
3453e12c5d1SDavid du Colombier d->dblock[i] = 0;
3463e12c5d1SDavid du Colombier dmod++;
3473e12c5d1SDavid du Colombier continue;
3483e12c5d1SDavid du Colombier }
3493e12c5d1SDavid du Colombier if(d->mode & DDIR)
3503e12c5d1SDavid du Colombier dmod += checkdir(a, qpath);
3513e12c5d1SDavid du Colombier else if(flags & Crdall)
3523e12c5d1SDavid du Colombier xread(a, qpath);
3533e12c5d1SDavid du Colombier }
3543e12c5d1SDavid du Colombier a = d->iblock;
3553e12c5d1SDavid du Colombier if(a && amark(a)) {
3563e12c5d1SDavid du Colombier d->iblock = 0;
3573e12c5d1SDavid du Colombier dmod++;
3583e12c5d1SDavid du Colombier }
3593e12c5d1SDavid du Colombier else if(a)
3603e12c5d1SDavid du Colombier dmod += checkindir(a, d, qpath);
3613e12c5d1SDavid du Colombier
3623e12c5d1SDavid du Colombier a = d->diblock;
3633e12c5d1SDavid du Colombier if(a && amark(a)) {
3643e12c5d1SDavid du Colombier d->diblock = 0;
3653e12c5d1SDavid du Colombier return dmod + 1;
3663e12c5d1SDavid du Colombier }
3673e12c5d1SDavid du Colombier dmod += touch(a);
3683e12c5d1SDavid du Colombier if(p = xtag(a, Tind2, qpath)){
3693e12c5d1SDavid du Colombier for(i=0; i<INDPERBUF; i++){
3703e12c5d1SDavid du Colombier a = ((long*)p->iobuf)[i];
3713e12c5d1SDavid du Colombier if(!a)
3723e12c5d1SDavid du Colombier continue;
3733e12c5d1SDavid du Colombier if(amark(a)) {
3743e12c5d1SDavid du Colombier if(flags & Cbad) {
3753e12c5d1SDavid du Colombier ((long*)p->iobuf)[i] = 0;
3763e12c5d1SDavid du Colombier p->flags |= Bmod;
3773e12c5d1SDavid du Colombier }
3783e12c5d1SDavid du Colombier continue;
3793e12c5d1SDavid du Colombier }
3803e12c5d1SDavid du Colombier dmod += checkindir(a, d, qpath);
3813e12c5d1SDavid du Colombier }
3823e12c5d1SDavid du Colombier putbuf(p);
3833e12c5d1SDavid du Colombier }
3843e12c5d1SDavid du Colombier return dmod;
3853e12c5d1SDavid du Colombier }
3863e12c5d1SDavid du Colombier
3873e12c5d1SDavid du Colombier static
3883e12c5d1SDavid du Colombier void
ckfreelist(Superb * sb)3893e12c5d1SDavid du Colombier ckfreelist(Superb *sb)
3903e12c5d1SDavid du Colombier {
3913e12c5d1SDavid du Colombier long a, lo, hi;
3923e12c5d1SDavid du Colombier int n, i;
3933e12c5d1SDavid du Colombier Iobuf *p;
3943e12c5d1SDavid du Colombier Fbuf *fb;
3953e12c5d1SDavid du Colombier
3963e12c5d1SDavid du Colombier
3973e12c5d1SDavid du Colombier strcpy(name, "free list");
3983e12c5d1SDavid du Colombier cprint("check %s\n", name);
3993e12c5d1SDavid du Colombier fb = &sb->fbuf;
4003e12c5d1SDavid du Colombier a = sbaddr;
4013e12c5d1SDavid du Colombier p = 0;
4023e12c5d1SDavid du Colombier lo = 0;
4033e12c5d1SDavid du Colombier hi = 0;
4043e12c5d1SDavid du Colombier for(;;) {
4053e12c5d1SDavid du Colombier n = fb->nfree;
4063e12c5d1SDavid du Colombier if(n < 0 || n > FEPERBUF) {
4073e12c5d1SDavid du Colombier cprint("check: nfree bad %ld\n", a);
4083e12c5d1SDavid du Colombier break;
4093e12c5d1SDavid du Colombier }
4103e12c5d1SDavid du Colombier for(i=1; i<n; i++) {
4113e12c5d1SDavid du Colombier a = fb->free[i];
4123e12c5d1SDavid du Colombier if(a && !fmark(a)) {
4133e12c5d1SDavid du Colombier if(!lo || lo > a)
4143e12c5d1SDavid du Colombier lo = a;
4153e12c5d1SDavid du Colombier if(!hi || hi < a)
4163e12c5d1SDavid du Colombier hi = a;
4173e12c5d1SDavid du Colombier }
4183e12c5d1SDavid du Colombier }
4193e12c5d1SDavid du Colombier a = fb->free[0];
4203e12c5d1SDavid du Colombier if(!a)
4213e12c5d1SDavid du Colombier break;
4223e12c5d1SDavid du Colombier if(fmark(a))
4233e12c5d1SDavid du Colombier break;
4243e12c5d1SDavid du Colombier if(!lo || lo > a)
4253e12c5d1SDavid du Colombier lo = a;
4263e12c5d1SDavid du Colombier if(!hi || hi < a)
4273e12c5d1SDavid du Colombier hi = a;
4283e12c5d1SDavid du Colombier if(p)
4293e12c5d1SDavid du Colombier putbuf(p);
4303e12c5d1SDavid du Colombier p = xtag(a, Tfree, QPNONE);
4313e12c5d1SDavid du Colombier if(!p)
4323e12c5d1SDavid du Colombier break;
4333e12c5d1SDavid du Colombier fb = (Fbuf*)p->iobuf;
4343e12c5d1SDavid du Colombier }
4353e12c5d1SDavid du Colombier if(p)
4363e12c5d1SDavid du Colombier putbuf(p);
4373e12c5d1SDavid du Colombier cprint("lo = %ld; hi = %ld\n", lo, hi);
4383e12c5d1SDavid du Colombier }
4393e12c5d1SDavid du Colombier
4403e12c5d1SDavid du Colombier /*
4413e12c5d1SDavid du Colombier * make freelist from scratch
4423e12c5d1SDavid du Colombier */
4433e12c5d1SDavid du Colombier static
4443e12c5d1SDavid du Colombier void
mkfreelist(Superb * sb)4453e12c5d1SDavid du Colombier mkfreelist(Superb *sb)
4463e12c5d1SDavid du Colombier {
4473e12c5d1SDavid du Colombier long a;
4483e12c5d1SDavid du Colombier int i, b;
4493e12c5d1SDavid du Colombier
4503e12c5d1SDavid du Colombier strcpy(name, "free list");
4513e12c5d1SDavid du Colombier memset(&sb->fbuf, 0, sizeof(sb->fbuf));
4523e12c5d1SDavid du Colombier sb->fbuf.nfree = 1;
4533e12c5d1SDavid du Colombier sb->tfree = 0;
4543e12c5d1SDavid du Colombier for(a=fsize-fstart-1; a >= 0; a--) {
4553e12c5d1SDavid du Colombier i = a/8;
4563e12c5d1SDavid du Colombier if(i < 0 || i >= sizabits)
4573e12c5d1SDavid du Colombier continue;
4583e12c5d1SDavid du Colombier b = 1 << (a&7);
4593e12c5d1SDavid du Colombier if(abits[i] & b)
4603e12c5d1SDavid du Colombier continue;
4613e12c5d1SDavid du Colombier addfree(dev, fstart+a, sb);
4623e12c5d1SDavid du Colombier abits[i] |= b;
4633e12c5d1SDavid du Colombier }
4643e12c5d1SDavid du Colombier }
4653e12c5d1SDavid du Colombier
4663e12c5d1SDavid du Colombier static
4673e12c5d1SDavid du Colombier Dentry*
maked(long a,int s,long qpath)4683e12c5d1SDavid du Colombier maked(long a, int s, long qpath)
4693e12c5d1SDavid du Colombier {
4703e12c5d1SDavid du Colombier Iobuf *p;
4713e12c5d1SDavid du Colombier Dentry *d, *d1;
4723e12c5d1SDavid du Colombier
4733e12c5d1SDavid du Colombier p = xtag(a, Tdir, qpath);
4743e12c5d1SDavid du Colombier if(!p)
4753e12c5d1SDavid du Colombier return 0;
4763e12c5d1SDavid du Colombier d = getdir(p, s);
4773e12c5d1SDavid du Colombier d1 = dalloc(sizeof(Dentry));
478bd389b36SDavid du Colombier memmove(d1, d, sizeof(Dentry));
4793e12c5d1SDavid du Colombier putbuf(p);
4803e12c5d1SDavid du Colombier return d1;
4813e12c5d1SDavid du Colombier }
4823e12c5d1SDavid du Colombier
4833e12c5d1SDavid du Colombier static
4843e12c5d1SDavid du Colombier void
modd(long a,int s,Dentry * d1)4853e12c5d1SDavid du Colombier modd(long a, int s, Dentry *d1)
4863e12c5d1SDavid du Colombier {
4873e12c5d1SDavid du Colombier Iobuf *p;
4883e12c5d1SDavid du Colombier Dentry *d;
4893e12c5d1SDavid du Colombier
4903e12c5d1SDavid du Colombier if(!(flags & Cbad))
4913e12c5d1SDavid du Colombier return;
4923e12c5d1SDavid du Colombier p = getbuf(dev, a, Bread);
4933e12c5d1SDavid du Colombier d = getdir(p, s);
4943e12c5d1SDavid du Colombier if(!d) {
4953e12c5d1SDavid du Colombier if(p)
4963e12c5d1SDavid du Colombier putbuf(p);
4973e12c5d1SDavid du Colombier return;
4983e12c5d1SDavid du Colombier }
499bd389b36SDavid du Colombier memmove(d, d1, sizeof(Dentry));
5003e12c5d1SDavid du Colombier p->flags |= Bmod;
5013e12c5d1SDavid du Colombier putbuf(p);
5023e12c5d1SDavid du Colombier }
5033e12c5d1SDavid du Colombier
5043e12c5d1SDavid du Colombier static
5053e12c5d1SDavid du Colombier void
xread(long a,long qpath)5063e12c5d1SDavid du Colombier xread(long a, long qpath)
5073e12c5d1SDavid du Colombier {
5083e12c5d1SDavid du Colombier Iobuf *p;
5093e12c5d1SDavid du Colombier
5103e12c5d1SDavid du Colombier p = xtag(a, Tfile, qpath);
5113e12c5d1SDavid du Colombier if(p)
5123e12c5d1SDavid du Colombier putbuf(p);
5133e12c5d1SDavid du Colombier }
5143e12c5d1SDavid du Colombier
5153e12c5d1SDavid du Colombier static
5163e12c5d1SDavid du Colombier Iobuf*
xtag(long a,int tag,long qpath)5173e12c5d1SDavid du Colombier xtag(long a, int tag, long qpath)
5183e12c5d1SDavid du Colombier {
5193e12c5d1SDavid du Colombier Iobuf *p;
5203e12c5d1SDavid du Colombier
5213e12c5d1SDavid du Colombier if(a == 0)
5223e12c5d1SDavid du Colombier return 0;
5233e12c5d1SDavid du Colombier p = getbuf(dev, a, Bread);
5243e12c5d1SDavid du Colombier if(!p) {
5253e12c5d1SDavid du Colombier cprint("check: \"%s\": xtag: p null\n", name);
5263e12c5d1SDavid du Colombier if(flags & (Cream|Ctag)) {
5273e12c5d1SDavid du Colombier p = getbuf(dev, a, Bmod);
5283e12c5d1SDavid du Colombier if(p) {
5293e12c5d1SDavid du Colombier memset(p->iobuf, 0, RBUFSIZE);
5303e12c5d1SDavid du Colombier settag(p, tag, qpath);
5313e12c5d1SDavid du Colombier mod++;
5323e12c5d1SDavid du Colombier return p;
5333e12c5d1SDavid du Colombier }
5343e12c5d1SDavid du Colombier }
5353e12c5d1SDavid du Colombier return 0;
5363e12c5d1SDavid du Colombier }
5373e12c5d1SDavid du Colombier if(checktag(p, tag, qpath)) {
5383e12c5d1SDavid du Colombier cprint("check: \"%s\": xtag: checktag\n", name);
5393e12c5d1SDavid du Colombier if(flags & Cream)
5403e12c5d1SDavid du Colombier memset(p->iobuf, 0, RBUFSIZE);
5413e12c5d1SDavid du Colombier if(flags & (Cream|Ctag)) {
5423e12c5d1SDavid du Colombier settag(p, tag, qpath);
5433e12c5d1SDavid du Colombier mod++;
5443e12c5d1SDavid du Colombier }
5453e12c5d1SDavid du Colombier return p;
5463e12c5d1SDavid du Colombier }
5473e12c5d1SDavid du Colombier return p;
5483e12c5d1SDavid du Colombier }
5493e12c5d1SDavid du Colombier
5503e12c5d1SDavid du Colombier static
5513e12c5d1SDavid du Colombier int
amark(long a)5523e12c5d1SDavid du Colombier amark(long a)
5533e12c5d1SDavid du Colombier {
5543e12c5d1SDavid du Colombier long i;
5553e12c5d1SDavid du Colombier int b;
5563e12c5d1SDavid du Colombier
5573e12c5d1SDavid du Colombier if(a < fstart || a >= fsize) {
5583e12c5d1SDavid du Colombier cprint("check: \"%s\": range %ld\n",
5593e12c5d1SDavid du Colombier name, a);
5603e12c5d1SDavid du Colombier nbad++;
5613e12c5d1SDavid du Colombier return 1;
5623e12c5d1SDavid du Colombier }
5633e12c5d1SDavid du Colombier a -= fstart;
5643e12c5d1SDavid du Colombier i = a/8;
5653e12c5d1SDavid du Colombier b = 1 << (a&7);
5663e12c5d1SDavid du Colombier if(abits[i] & b) {
5673e12c5d1SDavid du Colombier if(!ronly) {
5683e12c5d1SDavid du Colombier if(ndup < 10)
5693e12c5d1SDavid du Colombier cprint("check: \"%s\": address dup %ld\n",
5703e12c5d1SDavid du Colombier name, fstart+a);
5713e12c5d1SDavid du Colombier else
5723e12c5d1SDavid du Colombier if(ndup == 10)
5733e12c5d1SDavid du Colombier cprint("...");
5743e12c5d1SDavid du Colombier }
5753e12c5d1SDavid du Colombier ndup++;
5763e12c5d1SDavid du Colombier return 0; /* really?? */
5773e12c5d1SDavid du Colombier }
5783e12c5d1SDavid du Colombier abits[i] |= b;
5793e12c5d1SDavid du Colombier nused++;
5803e12c5d1SDavid du Colombier return 0;
5813e12c5d1SDavid du Colombier }
5823e12c5d1SDavid du Colombier
5833e12c5d1SDavid du Colombier static
5843e12c5d1SDavid du Colombier int
fmark(long a)5853e12c5d1SDavid du Colombier fmark(long a)
5863e12c5d1SDavid du Colombier {
5873e12c5d1SDavid du Colombier long i;
5883e12c5d1SDavid du Colombier int b;
5893e12c5d1SDavid du Colombier
5903e12c5d1SDavid du Colombier if(a < fstart || a >= fsize) {
5913e12c5d1SDavid du Colombier cprint("check: \"%s\": range %ld\n",
5923e12c5d1SDavid du Colombier name, a);
5933e12c5d1SDavid du Colombier nbad++;
5943e12c5d1SDavid du Colombier return 1;
5953e12c5d1SDavid du Colombier }
5963e12c5d1SDavid du Colombier a -= fstart;
5973e12c5d1SDavid du Colombier i = a/8;
5983e12c5d1SDavid du Colombier b = 1 << (a&7);
5993e12c5d1SDavid du Colombier if(abits[i] & b) {
6003e12c5d1SDavid du Colombier cprint("check: \"%s\": address dup %ld\n",
6013e12c5d1SDavid du Colombier name, fstart+a);
6023e12c5d1SDavid du Colombier nfdup++;
6033e12c5d1SDavid du Colombier return 1;
6043e12c5d1SDavid du Colombier }
6053e12c5d1SDavid du Colombier abits[i] |= b;
6063e12c5d1SDavid du Colombier nfree++;
6073e12c5d1SDavid du Colombier return 0;
6083e12c5d1SDavid du Colombier }
6093e12c5d1SDavid du Colombier
6103e12c5d1SDavid du Colombier static
6113e12c5d1SDavid du Colombier void
missing(void)6123e12c5d1SDavid du Colombier missing(void)
6133e12c5d1SDavid du Colombier {
6143e12c5d1SDavid du Colombier long a, i;
6153e12c5d1SDavid du Colombier int b, n;
6163e12c5d1SDavid du Colombier
6173e12c5d1SDavid du Colombier n = 0;
6183e12c5d1SDavid du Colombier for(a=fsize-fstart-1; a>=0; a--) {
6193e12c5d1SDavid du Colombier i = a/8;
6203e12c5d1SDavid du Colombier b = 1 << (a&7);
6213e12c5d1SDavid du Colombier if(!(abits[i] & b)) {
6223e12c5d1SDavid du Colombier cprint("missing: %ld\n", fstart+a);
6233e12c5d1SDavid du Colombier n++;
6243e12c5d1SDavid du Colombier }
6253e12c5d1SDavid du Colombier if(n > 10) {
6263e12c5d1SDavid du Colombier cprint(" ...\n");
6273e12c5d1SDavid du Colombier break;
6283e12c5d1SDavid du Colombier }
6293e12c5d1SDavid du Colombier }
6303e12c5d1SDavid du Colombier }
6313e12c5d1SDavid du Colombier
6323e12c5d1SDavid du Colombier static
6333e12c5d1SDavid du Colombier void
qmark(long qpath)6343e12c5d1SDavid du Colombier qmark(long qpath)
6353e12c5d1SDavid du Colombier {
6363e12c5d1SDavid du Colombier int i, b;
6373e12c5d1SDavid du Colombier
6383e12c5d1SDavid du Colombier i = qpath/8;
6393e12c5d1SDavid du Colombier b = 1 << (qpath&7);
6403e12c5d1SDavid du Colombier if(i < 0 || i >= sizqbits) {
6413e12c5d1SDavid du Colombier nqbad++;
6423e12c5d1SDavid du Colombier if(nqbad < 20)
6433e12c5d1SDavid du Colombier cprint("check: \"%s\": qid out of range %lux\n",
6443e12c5d1SDavid du Colombier name, qpath);
6453e12c5d1SDavid du Colombier return;
6463e12c5d1SDavid du Colombier }
6473e12c5d1SDavid du Colombier if((qbits[i] & b) && !ronly) {
6483e12c5d1SDavid du Colombier nqbad++;
6493e12c5d1SDavid du Colombier if(nqbad < 20)
6503e12c5d1SDavid du Colombier cprint("check: \"%s\": qid dup %lux\n",
6513e12c5d1SDavid du Colombier name, qpath);
6523e12c5d1SDavid du Colombier }
6533e12c5d1SDavid du Colombier qbits[i] |= b;
6543e12c5d1SDavid du Colombier }
655