BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 17 Oct 1979 19:07:39 +0000 (11:07 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Wed, 17 Oct 1979 19:07:39 +0000 (11:07 -0800)
Work on file usr/src/cmd/icheck.c

Synthesized-from: 3bsd

usr/src/cmd/icheck.c [new file with mode: 0644]

diff --git a/usr/src/cmd/icheck.c b/usr/src/cmd/icheck.c
new file mode 100644 (file)
index 0000000..6c1b632
--- /dev/null
@@ -0,0 +1,475 @@
+#define        NI      16
+#define        NB      10
+#define        BITS    8
+#define        MAXFN   500
+
+#ifndef STANDALONE
+#include <stdio.h>
+#endif
+#include <sys/param.h>
+#include <sys/inode.h>
+#include <sys/ino.h>
+#include <sys/fblk.h>
+#include <sys/filsys.h>
+
+struct filsys  sblock;
+struct dinode  itab[INOPB*NI];
+daddr_t        iaddr[NADDR];
+daddr_t        blist[NB];
+char   *bmap;
+
+int    sflg;
+int    mflg;
+int    dflg;
+int    fi;
+ino_t  ino;
+
+ino_t  nrfile;
+ino_t  ndfile;
+ino_t  nbfile;
+ino_t  ncfile;
+
+daddr_t        ndirect;
+daddr_t        nindir;
+daddr_t        niindir;
+daddr_t        niiindir;
+daddr_t        nfree;
+daddr_t        ndup;
+
+int    nerror;
+
+long   atol();
+daddr_t        alloc();
+#ifndef STANDALONE
+char   *malloc();
+#endif
+
+main(argc, argv)
+char *argv[];
+{
+       register i;
+       long n;
+
+       blist[0] = -1;
+#ifndef STANDALONE
+       while (--argc) {
+               argv++;
+               if (**argv=='-')
+               switch ((*argv)[1]) {
+               case 'd':
+                       dflg++;
+                       continue;
+
+
+               case 'm':
+                       mflg++;
+                       continue;
+
+               case 's':
+                       sflg++;
+                       continue;
+
+               case 'b':
+                       for(i=0; i<NB; i++) {
+                               n = atol(argv[1]);
+                               if(n == 0)
+                                       break;
+                               blist[i] = n;
+                               argv++;
+                               argc--;
+                       }
+                       blist[i] = -1;
+                       continue;
+
+               default:
+                       printf("Bad flag\n");
+               }
+               check(*argv);
+       }
+#else
+       {
+               static char fname[0];
+
+               printf("File: ");
+               gets(fname);
+               check(fname);
+       }
+#endif
+       return(nerror);
+}
+
+check(file)
+char *file;
+{
+       register i, j;
+       ino_t mino;
+       daddr_t d;
+       long n;
+
+       fi = open(file, sflg?2:0);
+       if (fi < 0) {
+               printf("cannot open %s\n", file);
+               nerror |= 04;
+               return;
+       }
+       printf("%s:\n", file);
+       nrfile = 0;
+       ndfile = 0;
+       ncfile = 0;
+       nbfile = 0;
+
+       ndirect = 0;
+       nindir = 0;
+       niindir = 0;
+       niiindir = 0;
+
+       ndup = 0;
+#ifndef STANDALONE
+       sync();
+#endif
+       bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
+       mino = ((int)sblock.s_isize-2) * INOPB;
+       ino = 0;
+       n = (sblock.s_fsize - (int)sblock.s_isize + BITS-1) / BITS;
+       if (n != (unsigned)n) {
+               printf("Check fsize and isize: %ld, %u\n",
+                  sblock.s_fsize, (int)sblock.s_isize);
+       }
+#ifdef STANDALONE
+       bmap = NULL;
+#else
+       bmap = malloc((unsigned)n);
+#endif
+       if (bmap==NULL) {
+               printf("Not enough core; duplicates unchecked\n");
+               dflg++;
+               sflg = 0;
+       }
+       if(!dflg)
+       for(i=0; i<(unsigned)n; i++)
+               bmap[i] = 0;
+       for(i=2;; i+=NI) {
+               if(ino >= mino)
+                       break;
+               bread((daddr_t)i, (char *)itab, sizeof(itab));
+               for(j=0; j<INOPB*NI; j++) {
+                       if(ino >= mino)
+                               break;
+                       ino++;
+                       pass1(&itab[j]);
+               }
+       }
+       ino = 0;
+#ifndef STANDALONE
+       sync();
+#endif
+       bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
+       if (sflg) {
+               makefree();
+               close(fi);
+#ifndef STANDALONE
+               if (bmap)
+                       free(bmap);
+#endif
+               return;
+       }
+       nfree = 0;
+       while(n = alloc()) {
+               if (chk(n, "free"))
+                       break;
+               nfree++;
+       }
+       close(fi);
+#ifndef STANDALONE
+       if (bmap)
+               free(bmap);
+#endif
+
+       i = nrfile + ndfile + ncfile + nbfile;
+#ifndef STANDALONE
+       printf("files %6u (r=%u,d=%u,b=%u,c=%u)\n",
+               i, nrfile, ndfile, nbfile, ncfile);
+#else
+       printf("files %u (r=%u,d=%u,b=%u,c=%u)\n",
+               i, nrfile, ndfile, nbfile, ncfile);
+#endif
+       n = ndirect + nindir + niindir + niindir;
+#ifdef STANDALONE
+       printf("used %ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
+               n, nindir, niindir, niiindir, ndirect);
+       printf("free %ld\n", nfree);
+#else
+       printf("used %7ld (i=%ld,ii=%ld,iii=%ld,d=%ld)\n",
+               n, nindir, niindir, niiindir, ndirect);
+       printf("free %7ld\n", nfree);
+#endif
+       if(!dflg) {
+               n = 0;
+               for(d=(int)sblock.s_isize; d<sblock.s_fsize; d++)
+                       if(!duped(d)) {
+                               if(mflg)
+                                       printf("%ld missing\n", d);
+                               n++;
+                       }
+               printf("missing%5ld\n", n);
+       }
+}
+
+pass1(ip)
+register struct dinode *ip;
+{
+       daddr_t ind1[NINDIR];
+       daddr_t ind2[NINDIR];
+       daddr_t ind3[NINDIR];
+       register i, j;
+       int k, l;
+
+       i = ip->di_mode & IFMT;
+       if(i == 0) {
+               sblock.s_tinode++;
+               return;
+       }
+       if(i == IFCHR) {
+               ncfile++;
+               return;
+       }
+       if(i == IFBLK) {
+               nbfile++;
+               return;
+       }
+       if(i == IFDIR)
+               ndfile++; else
+       if(i == IFREG)
+               nrfile++;
+       else {
+               printf("bad mode %u\n", ino);
+               return;
+       }
+       l3tol(iaddr, ip->di_addr, NADDR);
+       for(i=0; i<NADDR; i++) {
+               if(iaddr[i] == 0)
+                       continue;
+               if(i < NADDR-3) {
+                       ndirect++;
+                       chk(iaddr[i], "data (small)");
+                       continue;
+               }
+               nindir++;
+               if (chk(iaddr[i], "1st indirect"))
+                               continue;
+               bread(iaddr[i], (char *)ind1, BSIZE);
+               for(j=0; j<NINDIR; j++) {
+                       if(ind1[j] == 0)
+                               continue;
+                       if(i == NADDR-3) {
+                               ndirect++;
+                               chk(ind1[j], "data (large)");
+                               continue;
+                       }
+                       niindir++;
+                       if(chk(ind1[j], "2nd indirect"))
+                               continue;
+                       bread(ind1[j], (char *)ind2, BSIZE);
+                       for(k=0; k<NINDIR; k++) {
+                               if(ind2[k] == 0)
+                                       continue;
+                               if(i == NADDR-2) {
+                                       ndirect++;
+                                       chk(ind2[k], "data (huge)");
+                                       continue;
+                               }
+                               niiindir++;
+                               if(chk(ind2[k], "3rd indirect"))
+                                       continue;
+                               bread(ind2[k], (char *)ind3, BSIZE);
+                               for(l=0; l<NINDIR; l++)
+                                       if(ind3[l]) {
+                                               ndirect++;
+                                               chk(ind3[l], "data (garg)");
+                                       }
+                       }
+               }
+       }
+}
+
+chk(bno, s)
+daddr_t bno;
+char *s;
+{
+       register n;
+
+       if (bno<(int)sblock.s_isize || bno>=sblock.s_fsize) {
+               printf("%ld bad; inode=%u, class=%s\n", bno, ino, s);
+               return(1);
+       }
+       if(duped(bno)) {
+               printf("%ld dup; inode=%u, class=%s\n", bno, ino, s);
+               ndup++;
+       }
+       for (n=0; blist[n] != -1; n++)
+               if (bno == blist[n])
+                       printf("%ld arg; inode=%u, class=%s\n", bno, ino, s);
+       return(0);
+}
+
+duped(bno)
+daddr_t bno;
+{
+       daddr_t d;
+       register m, n;
+
+       if(dflg)
+               return(0);
+       d = bno - (int)sblock.s_isize;
+       m = 1 << (d%BITS);
+       n = (d/BITS);
+       if(bmap[n] & m)
+               return(1);
+       bmap[n] |= m;
+       return(0);
+}
+
+daddr_t
+alloc()
+{
+       int i;
+       daddr_t bno;
+       union {
+               char    data[BSIZE];
+               struct  fblk fb;
+       } buf;
+
+       sblock.s_tfree--;
+       if (sblock.s_nfree<=0)
+               return(0);
+       if (sblock.s_nfree>NICFREE) {
+               printf("Bad free list, s.b. count = %d\n", sblock.s_nfree);
+               return(0);
+       }
+       bno = sblock.s_free[--sblock.s_nfree];
+       sblock.s_free[sblock.s_nfree] = (daddr_t)0;
+       if(bno == 0)
+               return(bno);
+       if(sblock.s_nfree <= 0) {
+               bread(bno, buf.data, BSIZE);
+               sblock.s_nfree = buf.df_nfree;
+               if (sblock.s_nfree<0 || sblock.s_nfree>NICFREE) {
+                       printf("Bad free list, entry count of block %ld = %d\n",
+                               bno, sblock.s_nfree);
+                       sblock.s_nfree = 0;
+                       return(0);
+               }
+               for(i=0; i<NICFREE; i++)
+                       sblock.s_free[i] = buf.df_free[i];
+       }
+       return(bno);
+}
+
+bfree(bno)
+daddr_t bno;
+{
+       union {
+               char    data[BSIZE];
+               struct  fblk fb;
+       } buf;
+       int i;
+
+       sblock.s_tfree++;
+       if(sblock.s_nfree >= NICFREE) {
+               for(i=0; i<BSIZE; i++)
+                       buf.data[i] = 0;
+               buf.df_nfree = sblock.s_nfree;
+               for(i=0; i<NICFREE; i++)
+                       buf.df_free[i] = sblock.s_free[i];
+               bwrite(bno, buf.data);
+               sblock.s_nfree = 0;
+       }
+       sblock.s_free[sblock.s_nfree] = bno;
+       sblock.s_nfree++;
+}
+
+bread(bno, buf, cnt)
+daddr_t bno;
+char *buf;
+{
+       register i;
+
+       lseek(fi, bno*BSIZE, 0);
+       if (read(fi, buf, cnt) != cnt) {
+               printf("read error %ld\n", bno);
+               if (sflg) {
+                       printf("No update\n");
+                       sflg = 0;
+               }
+               for(i=0; i<BSIZE; i++)
+                       buf[i] = 0;
+       }
+}
+
+bwrite(bno, buf)
+daddr_t bno;
+char   *buf;
+{
+
+       lseek(fi, bno*BSIZE, 0);
+       if (write(fi, buf, BSIZE) != BSIZE)
+               printf("write error %ld\n", bno);
+}
+
+makefree()
+{
+       char flg[MAXFN];
+       int adr[MAXFN];
+       register i, j;
+       daddr_t f, d;
+       int m, n;
+
+       n = sblock.s_n;
+       if(n <= 0 || n > MAXFN)
+               n = MAXFN;
+       sblock.s_n = n;
+       m = sblock.s_m;
+       if(m <= 0 || m > sblock.s_n)
+               m = 3;
+       sblock.s_m = m;
+
+       for(i=0; i<n; i++)
+               flg[i] = 0;
+       i = 0;
+       for(j=0; j<n; j++) {
+               while(flg[i])
+                       i = (i+1)%n;
+               adr[j] = i+1;
+               flg[i]++;
+               i = (i+m)%n;
+       }
+
+       sblock.s_nfree = 0;
+       sblock.s_ninode = 0;
+       sblock.s_flock = 0;
+       sblock.s_ilock = 0;
+       sblock.s_fmod = 0;
+       sblock.s_ronly = 0;
+#ifndef STANDALONE
+       time(&sblock.s_time);
+#endif
+       sblock.s_tfree = 0;
+       sblock.s_tinode = 0;
+
+       bfree((daddr_t)0);
+       d = sblock.s_fsize-1;
+       while(d%sblock.s_n)
+               d++;
+       for(; d > 0; d -= sblock.s_n)
+       for(i=0; i<sblock.s_n; i++) {
+               f = d - adr[i];
+               if(f < sblock.s_fsize && f >= (int)sblock.s_isize)
+                       if(!duped(f))
+                               bfree(f);
+       }
+       bwrite((daddr_t)1, (char *)&sblock);
+#ifndef STANDALONE
+       sync();
+#endif
+       return;
+}