BSD 3 development
authorBill Joy <wnj@ucbvax.Berkeley.EDU>
Thu, 27 Dec 1979 03:17:08 +0000 (19:17 -0800)
committerBill Joy <wnj@ucbvax.Berkeley.EDU>
Thu, 27 Dec 1979 03:17:08 +0000 (19:17 -0800)
Work on file usr/src/cmd/dcheck.c

Synthesized-from: 3bsd

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

diff --git a/usr/src/cmd/dcheck.c b/usr/src/cmd/dcheck.c
new file mode 100644 (file)
index 0000000..b479a83
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * dcheck - check directory consistency
+ */
+#define        NI      16
+#define        NB      10
+#define        NDIR    (BSIZE/sizeof(struct direct))
+
+#include <stdio.h>
+#include <sys/param.h>
+#include <sys/inode.h>
+#include <sys/ino.h>
+#include <sys/dir.h>
+#include <sys/filsys.h>
+#include <sys/fblk.h>
+
+
+struct filsys  sblock;
+struct dinode  itab[INOPB*NI];
+daddr_t        iaddr[NADDR];
+ino_t  ilist[NB];
+
+int    fi;
+ino_t  ino;
+char   *ecount;
+int    headpr;
+unsigned       nfiles;
+
+int    nerror;
+daddr_t        bmap();
+long   atol();
+char   *malloc();
+
+main(argc, argv)
+char *argv[];
+{
+       register i;
+       long n;
+
+       while (--argc) {
+               argv++;
+               if (**argv=='-')
+               switch ((*argv)[1]) {
+
+               case 'i':
+                       for(i=0; i<NB; i++) {
+                               n = atol(argv[1]);
+                               if(n == 0)
+                                       break;
+                               ilist[i] = n;
+                               argv++;
+                               argc--;
+                       }
+                       ilist[i] = 0;
+                       continue;
+
+               default:
+                       printf("Bad flag %c\n", (*argv)[1]);
+                       nerror++;
+               }
+               check(*argv);
+       }
+       return(nerror);
+}
+
+check(file)
+char *file;
+{
+       register i;
+       register j;
+
+       fi = open(file, 0);
+       if(fi < 0) {
+               printf("cannot open %s\n", file);
+               nerror++;
+               return;
+       }
+       headpr = 0;
+       printf("%s:\n", file);
+       sync();
+       bread((daddr_t)1, (char *)&sblock, sizeof(sblock));
+       nfiles = (sblock.s_isize-2)*INOPB;
+       if (nfiles > 250000) {
+               printf("Only doing 250000 files\n");
+               nfiles = 250000;
+       }
+       ecount = malloc(nfiles+1);
+       if (ecount==NULL) {
+               printf("Not enough core\n");
+               exit(04);
+       }
+       for (i=0; i<=nfiles; i++)
+               ecount[i] = 0;
+       ino = 0;
+       for(i=2;; i+=NI) {
+               if(ino >= nfiles)
+                       break;
+               bread((daddr_t)i, (char *)itab, sizeof(itab));
+               for(j=0; j<INOPB*NI; j++) {
+                       if(ino >= nfiles)
+                               break;
+                       ino++;
+                       pass1(&itab[j]);
+               }
+       }
+       ino = 0;
+       for(i=2;; i+=NI) {
+               if(ino >= nfiles)
+                       break;
+               bread((daddr_t)i, (char *)itab, sizeof(itab));
+               for(j=0; j<INOPB*NI; j++) {
+                       if(ino >= nfiles)
+                               break;
+                       ino++;
+                       pass2(&itab[j]);
+               }
+       }
+       free(ecount);
+}
+
+pass1(ip)
+register struct dinode *ip;
+{
+       struct direct dbuf[NDIR];
+       long doff;
+       struct direct *dp;
+       register i, j;
+       int k;
+       daddr_t d;
+       ino_t kno;
+
+       if((ip->di_mode&IFMT) != IFDIR)
+               return;
+       l3tol(iaddr, ip->di_addr, NADDR);
+       doff = 0;
+       for(i=0;; i++) {
+               if(doff >= ip->di_size)
+                       break;
+               d = bmap(i);
+               if(d == 0)
+                       break;
+               bread(d, (char *)dbuf, BSIZE);
+               for(j=0; j<NDIR; j++) {
+                       if(doff >= ip->di_size)
+                               break;
+                       doff += sizeof(struct direct);
+                       dp = &dbuf[j];
+                       kno = dp->d_ino;
+                       if(kno == 0)
+                               continue;
+                       if(kno > nfiles || kno <= 1) {
+                               printf("%5u bad; %u/%.14s\n", kno, ino, dp->d_name);
+                               nerror++;
+                               continue;
+                       }
+                       for (k=0; ilist[k] != 0; k++)
+                               if (ilist[k]==kno) {
+                                       printf("%5u arg; %u/%.14s\n", kno, ino, dp->d_name);
+                                       nerror++;
+                               }
+                       ecount[kno]++;
+                       if (ecount[kno] == 0)
+                               ecount[kno] = 0377;
+               }
+       }
+}
+
+pass2(ip)
+register struct dinode *ip;
+{
+       register i;
+
+       i = ino;
+       if ((ip->di_mode&IFMT)==0 && ecount[i]==0)
+               return;
+       if (ip->di_nlink==((ecount[i])&0377) && ip->di_nlink!=0)
+               return;
+       if (headpr==0) {
+               printf("     entries  link cnt\n");
+               headpr++;
+       }
+       printf("%u      %d      %d\n", ino,
+           ecount[i]&0377, ip->di_nlink);
+}
+
+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 %d\n", bno);
+               for(i=0; i<BSIZE; i++)
+                       buf[i] = 0;
+       }
+}
+
+
+daddr_t
+bmap(i)
+{
+       daddr_t ibuf[NINDIR];
+
+       if(i < NADDR-3)
+               return(iaddr[i]);
+       i -= NADDR-3;
+       if(i > NINDIR) {
+               printf("%u - huge directory\n", ino);
+               return((daddr_t)0);
+       }
+       bread(iaddr[NADDR-3], (char *)ibuf, sizeof(ibuf));
+       return(ibuf[i]);
+}