update for new file system
[unix-history] / usr / src / sbin / icheck / icheck.c
index 13a00ed..8d8574a 100644 (file)
@@ -1,4 +1,4 @@
-static char *sccsid = "@(#)icheck.c    2.2 (Berkeley) %G%";
+static char *sccsid = "@(#)icheck.c    2.4 (Berkeley) %G%";
 
 /*
  * icheck
 
 /*
  * icheck
@@ -34,6 +34,7 @@ union {
 
 struct dinode  itab[MAXIPG];
 daddr_t        blist[NB];
 
 struct dinode  itab[MAXIPG];
 daddr_t        blist[NB];
+daddr_t        fsblist[NB];
 char   *bmap;
 
 int    mflg;
 char   *bmap;
 
 int    mflg;
@@ -130,6 +131,7 @@ check(file)
        register i, j, c;
        daddr_t d, cgd, cbase, b;
        long n;
        register i, j, c;
        daddr_t d, cgd, cbase, b;
        long n;
+       char buf[BUFSIZ];
 
        fi = open(file, sflg ? 2 : 0);
        if (fi < 0) {
 
        fi = open(file, sflg ? 2 : 0);
        if (fi < 0) {
@@ -156,6 +158,8 @@ check(file)
        getsb(&sblock, file);
        if (nerror)
                return;
        getsb(&sblock, file);
        if (nerror)
                return;
+       for (n=0; blist[n] != -1; n++)
+               fsblist[n] = dbtofsb(&sblock, blist[n]);
        ino = 0;
        n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
 #ifdef STANDALONE
        ino = 0;
        n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short));
 #ifdef STANDALONE
@@ -182,16 +186,22 @@ check(file)
                                d = cgbase(&sblock, c);
                        else
                                d = cgsblock(&sblock, c);
                                d = cgbase(&sblock, c);
                        else
                                d = cgsblock(&sblock, c);
+                       sprintf(buf, "spare super block %d", c);
                        for (; d < cgd; d += sblock.fs_frag)
                        for (; d < cgd; d += sblock.fs_frag)
-                               chk(d, "badcg", sblock.fs_bsize);
+                               chk(d, buf, sblock.fs_bsize);
                        d = cgimin(&sblock, c);
                        d = cgimin(&sblock, c);
+                       sprintf(buf, "cylinder group %d", c);
                        while (cgd < d) {
                        while (cgd < d) {
-                               chk(cgd, "cg", sblock.fs_bsize);
+                               chk(cgd, buf, sblock.fs_bsize);
                                cgd += sblock.fs_frag;
                        }
                        d = cgdmin(&sblock, c);
                                cgd += sblock.fs_frag;
                        }
                        d = cgdmin(&sblock, c);
-                       for (; cgd < d; cgd += sblock.fs_frag)
-                               chk(cgd, "inode", sblock.fs_bsize);
+                       i = INOPB(&sblock);
+                       for (; cgd < d; cgd += sblock.fs_frag) {
+                               sprintf(buf, "inodes %d-%d", ino, ino + i);
+                               chk(cgd, buf, sblock.fs_bsize);
+                               ino += i;
+                       }
                        if (c == 0) {
                                d += howmany(sblock.fs_cssize, sblock.fs_fsize);
                                for (; cgd < d; cgd++)
                        if (c == 0) {
                                d += howmany(sblock.fs_cssize, sblock.fs_fsize);
                                for (; cgd < d; cgd++)
@@ -199,6 +209,7 @@ check(file)
                        }
                }
        }
                        }
                }
        }
+       ino = 0;
        cginit = 0;
        for (c = 0; c < sblock.fs_ncg; c++) {
                bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
        cginit = 0;
        for (c = 0; c < sblock.fs_ncg; c++) {
                bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab,
@@ -233,11 +244,11 @@ check(file)
                        if (isblock(&sblock, cgrp.cg_free,
                            b / sblock.fs_frag)) {
                                nbfree++;
                        if (isblock(&sblock, cgrp.cg_free,
                            b / sblock.fs_frag)) {
                                nbfree++;
-                               chk(cbase+b, "block", sblock.fs_bsize);
+                               chk(cbase+b, "free block", sblock.fs_bsize);
                        } else {
                                for (d = 0; d < sblock.fs_frag; d++)
                                        if (isset(cgrp.cg_free, b+d)) {
                        } else {
                                for (d = 0; d < sblock.fs_frag; d++)
                                        if (isset(cgrp.cg_free, b+d)) {
-                                               chk(cbase+b+d, "frag", sblock.fs_fsize);
+                                               chk(cbase+b+d, "free frag", sblock.fs_fsize);
                                                nffree++;
                                        }
                        }
                                                nffree++;
                                        }
                        }
@@ -288,6 +299,8 @@ pass1(ip)
        daddr_t ind2[MAXNINDIR];
        daddr_t db, ib;
        register int i, j, k, siz;
        daddr_t ind2[MAXNINDIR];
        daddr_t db, ib;
        register int i, j, k, siz;
+       int lbn;
+       char buf[BUFSIZ];
 
        i = ip->di_mode & IFMT;
        if(i == 0)
 
        i = ip->di_mode & IFMT;
        if(i == 0)
@@ -317,7 +330,8 @@ pass1(ip)
                if (db == 0)
                        continue;
                siz = dblksize(&sblock, ip, i);
                if (db == 0)
                        continue;
                siz = dblksize(&sblock, ip, i);
-               chk(db, "data (block)", siz);
+               sprintf(buf, "logical data block %d", i);
+               chk(db, buf, siz);
                if (siz == sblock.fs_bsize)
                        nblock++;
                else
                if (siz == sblock.fs_bsize)
                        nblock++;
                else
@@ -325,7 +339,7 @@ pass1(ip)
        }
        for(i = 0; i < NIADDR; i++) {
                ib = ip->di_ib[i];
        }
        for(i = 0; i < NIADDR; i++) {
                ib = ip->di_ib[i];
-               if(ib == 0)
+               if (ib == 0)
                        continue;
                if (chk(ib, "1st indirect", sblock.fs_bsize))
                        continue;
                        continue;
                if (chk(ib, "1st indirect", sblock.fs_bsize))
                        continue;
@@ -336,8 +350,10 @@ pass1(ip)
                        if (ib == 0)
                                continue;
                        if (i == 0) {
                        if (ib == 0)
                                continue;
                        if (i == 0) {
-                               siz = dblksize(&sblock, ip, NDADDR + j);
-                               chk(ib, "data (large)", siz);
+                               lbn = NDADDR + j;
+                               siz = dblksize(&sblock, ip, lbn);
+                               sprintf(buf, "logical data block %d", lbn);
+                               chk(ib, buf, siz);
                                if (siz == sblock.fs_bsize)
                                        nblock++;
                                else
                                if (siz == sblock.fs_bsize)
                                        nblock++;
                                else
@@ -353,9 +369,10 @@ pass1(ip)
                                ib = ind2[k];
                                if (ib == 0)
                                        continue;
                                ib = ind2[k];
                                if (ib == 0)
                                        continue;
-                               siz = dblksize(&sblock, ip,
-                                   NDADDR + NINDIR(&sblock) * (i + j) + k);
-                               chk(ib, "data (huge)", siz);
+                               lbn = NDADDR + NINDIR(&sblock) * (i + j) + k;
+                               siz = dblksize(&sblock, ip, lbn);
+                               sprintf(buf, "logical data block %d", lbn);
+                               chk(ib, buf, siz);
                                if (siz == sblock.fs_bsize)
                                        nblock++;
                                else
                                if (siz == sblock.fs_bsize)
                                        nblock++;
                                else
@@ -378,14 +395,14 @@ chk(bno, s, size)
                printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
                return(1);
        }
                printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
                return(1);
        }
-       if (size == sblock.fs_bsize) {
+       frags = numfrags(&sblock, size);
+       if (frags == sblock.fs_frag) {
                if (duped(bno, size)) {
                        printf("%ld dup block; inode=%u, class=%s\n",
                            bno, ino, s);
                        ndup += sblock.fs_frag;
                }
        } else {
                if (duped(bno, size)) {
                        printf("%ld dup block; inode=%u, class=%s\n",
                            bno, ino, s);
                        ndup += sblock.fs_frag;
                }
        } else {
-               frags = numfrags(&sblock, size);
                for (n = 0; n < frags; n++) {
                        if (duped(bno + n, sblock.fs_fsize)) {
                                printf("%ld dup frag; inode=%u, class=%s\n",
                for (n = 0; n < frags; n++) {
                        if (duped(bno + n, sblock.fs_fsize)) {
                                printf("%ld dup frag; inode=%u, class=%s\n",
@@ -395,8 +412,9 @@ chk(bno, s, size)
                }
        }
        for (n=0; blist[n] != -1; n++)
                }
        }
        for (n=0; blist[n] != -1; n++)
-               if (bno == blist[n])
-                       printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
+               if (fsblist[n] >= bno && fsblist[n] < bno + frags)
+                       printf("%ld arg; frag %d of %d, inode=%u, class=%s\n",
+                               blist[n], fsblist[n] - bno, frags, ino, s);
        return(0);
 }
 
        return(0);
 }
 
@@ -448,7 +466,10 @@ makecg()
                cgrp.cg_time = time(0);
                cgrp.cg_magic = CG_MAGIC;
                cgrp.cg_cgx = c;
                cgrp.cg_time = time(0);
                cgrp.cg_magic = CG_MAGIC;
                cgrp.cg_cgx = c;
-               cgrp.cg_ncyl = sblock.fs_cpg;
+               if (c == sblock.fs_ncg - 1)
+                       cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg;
+               else
+                       cgrp.cg_ncyl = sblock.fs_cpg;
                cgrp.cg_niblk = sblock.fs_ipg;
                cgrp.cg_ndblk = dmax - dbase;
                cgrp.cg_cs.cs_ndir = 0;
                cgrp.cg_niblk = sblock.fs_ipg;
                cgrp.cg_ndblk = dmax - dbase;
                cgrp.cg_cs.cs_ndir = 0;
@@ -521,12 +542,14 @@ makecg()
                        } else
                                clrbit(cgrp.cg_free, d);
                }
                        } else
                                clrbit(cgrp.cg_free, d);
                }
+               for (; d % sblock.fs_frag != 0; d++)
+                       clrbit(cgrp.cg_free, d);
                if (j != d) {
                        blk = blkmap(&sblock, cgrp.cg_free, j);
                        fragacct(&sblock, blk, cgrp.cg_frsum, 1);
                }
                if (j != d) {
                        blk = blkmap(&sblock, cgrp.cg_free, j);
                        fragacct(&sblock, blk, cgrp.cg_frsum, 1);
                }
-               for (; d < MAXBPG(&sblock); d++)
-                       clrbit(cgrp.cg_free, d);
+               for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++)
+                       clrblock(&sblock, cgrp.cg_free, d);
                sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
                sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
                sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
                sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree;
                sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree;
                sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree;
@@ -642,9 +665,8 @@ bread(bno, buf, cnt)
 }
 
 /*
 }
 
 /*
- * block operations
+ * check if a block is available
  */
  */
-
 isblock(fs, cp, h)
        struct fs *fs;
        unsigned char *cp;
 isblock(fs, cp, h)
        struct fs *fs;
        unsigned char *cp;
@@ -665,11 +687,49 @@ isblock(fs, cp, h)
                mask = 0x01 << (h & 0x7);
                return ((cp[h >> 3] & mask) == mask);
        default:
                mask = 0x01 << (h & 0x7);
                return ((cp[h >> 3] & mask) == mask);
        default:
+#ifdef STANDALONE
+               printf("isblock bad fs_frag %d\n", fs->fs_frag);
+#else
                fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
                fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag);
+#endif
                return;
        }
 }
 
                return;
        }
 }
 
+/*
+ * take a block out of the map
+ */
+clrblock(fs, cp, h)
+       struct fs *fs;
+       unsigned char *cp;
+       int h;
+{
+       switch ((fs)->fs_frag) {
+       case 8:
+               cp[h] = 0;
+               return;
+       case 4:
+               cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2));
+               return;
+       case 2:
+               cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1));
+               return;
+       case 1:
+               cp[h >> 3] &= ~(0x01 << (h & 0x7));
+               return;
+       default:
+#ifdef STANDALONE
+               printf("clrblock bad fs_frag %d\n", fs->fs_frag);
+#else
+               fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag);
+#endif
+               return;
+       }
+}
+
+/*
+ * put a block into the map
+ */
 setblock(fs, cp, h)
        struct fs *fs;
        unsigned char *cp;
 setblock(fs, cp, h)
        struct fs *fs;
        unsigned char *cp;
@@ -689,7 +749,11 @@ setblock(fs, cp, h)
                cp[h >> 3] |= (0x01 << (h & 0x7));
                return;
        default:
                cp[h >> 3] |= (0x01 << (h & 0x7));
                return;
        default:
+#ifdef STANDALONE
+               printf("setblock bad fs_frag %d\n", fs->fs_frag);
+#else
                fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
                fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag);
+#endif
                return;
        }
 }
                return;
        }
 }