1*4238Smckusick static char *sccsid = "@(#)dcheck.c 1.1 (Berkeley) 08/26/81"; 2*4238Smckusick /* 3*4238Smckusick * dcheck - check directory consistency 4*4238Smckusick */ 5*4238Smckusick #define NB 10 6*4238Smckusick #define NDIR (BSIZE/sizeof(struct direct)) 7*4238Smckusick 8*4238Smckusick #include <stdio.h> 9*4238Smckusick #include "../h/param.h" 10*4238Smckusick #include "../h/inode.h" 11*4238Smckusick #include "../h/ino.h" 12*4238Smckusick #include "../h/dir.h" 13*4238Smckusick #include "../h/fs.h" 14*4238Smckusick 15*4238Smckusick union { 16*4238Smckusick struct fs fs; 17*4238Smckusick char pad[BSIZE]; 18*4238Smckusick } fsun; 19*4238Smckusick #define sblock fsun.fs 20*4238Smckusick 21*4238Smckusick struct dinode itab[MAXIPG]; 22*4238Smckusick daddr_t iaddr[NDADDR+NIADDR]; 23*4238Smckusick ino_t ilist[NB]; 24*4238Smckusick 25*4238Smckusick int fi; 26*4238Smckusick ino_t ino; 27*4238Smckusick ino_t *ecount; 28*4238Smckusick int headpr; 29*4238Smckusick int nfiles; 30*4238Smckusick 31*4238Smckusick int nerror; 32*4238Smckusick daddr_t bmap(); 33*4238Smckusick long atol(); 34*4238Smckusick char *malloc(); 35*4238Smckusick 36*4238Smckusick main(argc, argv) 37*4238Smckusick char *argv[]; 38*4238Smckusick { 39*4238Smckusick register i; 40*4238Smckusick long n; 41*4238Smckusick 42*4238Smckusick while (--argc) { 43*4238Smckusick argv++; 44*4238Smckusick if (**argv=='-') 45*4238Smckusick switch ((*argv)[1]) { 46*4238Smckusick 47*4238Smckusick case 'i': 48*4238Smckusick for(i=0; i<NB; i++) { 49*4238Smckusick n = atol(argv[1]); 50*4238Smckusick if(n == 0) 51*4238Smckusick break; 52*4238Smckusick ilist[i] = n; 53*4238Smckusick argv++; 54*4238Smckusick argc--; 55*4238Smckusick } 56*4238Smckusick ilist[i] = 0; 57*4238Smckusick continue; 58*4238Smckusick 59*4238Smckusick default: 60*4238Smckusick printf("Bad flag %c\n", (*argv)[1]); 61*4238Smckusick nerror++; 62*4238Smckusick } 63*4238Smckusick check(*argv); 64*4238Smckusick } 65*4238Smckusick return(nerror); 66*4238Smckusick } 67*4238Smckusick 68*4238Smckusick check(file) 69*4238Smckusick char *file; 70*4238Smckusick { 71*4238Smckusick register i, j, c; 72*4238Smckusick 73*4238Smckusick fi = open(file, 0); 74*4238Smckusick if(fi < 0) { 75*4238Smckusick printf("cannot open %s\n", file); 76*4238Smckusick nerror++; 77*4238Smckusick return; 78*4238Smckusick } 79*4238Smckusick headpr = 0; 80*4238Smckusick printf("%s:\n", file); 81*4238Smckusick sync(); 82*4238Smckusick bread(SBLOCK, (char *)&sblock, BSIZE); 83*4238Smckusick if (sblock.fs_magic != FS_MAGIC) { 84*4238Smckusick printf("%s: not a file system\n", file); 85*4238Smckusick nerror++; 86*4238Smckusick return; 87*4238Smckusick } 88*4238Smckusick nfiles = sblock.fs_ipg * sblock.fs_ncg; 89*4238Smckusick if (nfiles > 65535) { 90*4238Smckusick printf("%s: preposterous number of files\n", file); 91*4238Smckusick nerror++; 92*4238Smckusick return; 93*4238Smckusick } 94*4238Smckusick ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount)); 95*4238Smckusick if (ecount == 0) { 96*4238Smckusick printf("%s: not enough core for %d files\n", file, nfiles); 97*4238Smckusick exit(04); 98*4238Smckusick } 99*4238Smckusick for (i = 0; i<=nfiles; i++) 100*4238Smckusick ecount[i] = 0; 101*4238Smckusick ino = 0; 102*4238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 103*4238Smckusick bread(cgimin(c, &sblock), (char *)itab, 104*4238Smckusick sblock.fs_ipg * sizeof (struct dinode)); 105*4238Smckusick for (j = 0; j < sblock.fs_ipg; j++) { 106*4238Smckusick pass1(&itab[j]); 107*4238Smckusick ino++; 108*4238Smckusick } 109*4238Smckusick } 110*4238Smckusick ino = 0; 111*4238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 112*4238Smckusick bread(cgimin(c, &sblock), (char *)itab, 113*4238Smckusick sblock.fs_ipg * sizeof (struct dinode)); 114*4238Smckusick for (j = 0; j < sblock.fs_ipg; j++) { 115*4238Smckusick pass2(&itab[j]); 116*4238Smckusick ino++; 117*4238Smckusick } 118*4238Smckusick } 119*4238Smckusick free(ecount); 120*4238Smckusick } 121*4238Smckusick 122*4238Smckusick pass1(ip) 123*4238Smckusick register struct dinode *ip; 124*4238Smckusick { 125*4238Smckusick struct direct dbuf[NDIR]; 126*4238Smckusick long doff; 127*4238Smckusick struct direct *dp; 128*4238Smckusick register i, j; 129*4238Smckusick int k; 130*4238Smckusick daddr_t d; 131*4238Smckusick ino_t kno; 132*4238Smckusick 133*4238Smckusick if((ip->di_mode&IFMT) != IFDIR) 134*4238Smckusick return; 135*4238Smckusick l3tol(iaddr, ip->di_addr, NDADDR+NIADDR); 136*4238Smckusick doff = 0; 137*4238Smckusick for(i=0;; i++) { 138*4238Smckusick if(doff >= ip->di_size) 139*4238Smckusick break; 140*4238Smckusick d = bmap(i); 141*4238Smckusick if(d == 0) 142*4238Smckusick break; 143*4238Smckusick bread(d, (char *)dbuf, BSIZE); 144*4238Smckusick for(j=0; j<NDIR; j++) { 145*4238Smckusick if(doff >= ip->di_size) 146*4238Smckusick break; 147*4238Smckusick doff += sizeof(struct direct); 148*4238Smckusick dp = &dbuf[j]; 149*4238Smckusick kno = dp->d_ino; 150*4238Smckusick if(kno == 0) 151*4238Smckusick continue; 152*4238Smckusick if(kno > nfiles || kno < ROOTINO) { 153*4238Smckusick printf("%d bad; %d/%.*s\n", 154*4238Smckusick kno, ino, DIRSIZ, dp->d_name); 155*4238Smckusick nerror++; 156*4238Smckusick continue; 157*4238Smckusick } 158*4238Smckusick for (k=0; ilist[k] != 0; k++) 159*4238Smckusick if (ilist[k]==kno) { 160*4238Smckusick printf("%d arg; %d/%.*s\n", 161*4238Smckusick kno, ino, DIRSIZ, dp->d_name); 162*4238Smckusick nerror++; 163*4238Smckusick } 164*4238Smckusick ecount[kno]++; 165*4238Smckusick } 166*4238Smckusick } 167*4238Smckusick } 168*4238Smckusick 169*4238Smckusick pass2(ip) 170*4238Smckusick register struct dinode *ip; 171*4238Smckusick { 172*4238Smckusick register i; 173*4238Smckusick 174*4238Smckusick i = ino; 175*4238Smckusick if ((ip->di_mode&IFMT)==0 && ecount[i]==0) 176*4238Smckusick return; 177*4238Smckusick if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) 178*4238Smckusick return; 179*4238Smckusick if (headpr==0) { 180*4238Smckusick printf(" entries link cnt\n"); 181*4238Smckusick headpr++; 182*4238Smckusick } 183*4238Smckusick printf("%u\t%d\t%d\n", ino, 184*4238Smckusick ecount[i], ip->di_nlink); 185*4238Smckusick } 186*4238Smckusick 187*4238Smckusick bread(bno, buf, cnt) 188*4238Smckusick daddr_t bno; 189*4238Smckusick char *buf; 190*4238Smckusick { 191*4238Smckusick register i; 192*4238Smckusick 193*4238Smckusick lseek(fi, bno*FSIZE, 0); 194*4238Smckusick if (read(fi, buf, cnt) != cnt) { 195*4238Smckusick printf("read error %d\n", bno); 196*4238Smckusick for(i=0; i<BSIZE; i++) 197*4238Smckusick buf[i] = 0; 198*4238Smckusick } 199*4238Smckusick } 200*4238Smckusick 201*4238Smckusick daddr_t 202*4238Smckusick bmap(i) 203*4238Smckusick { 204*4238Smckusick daddr_t ibuf[NINDIR]; 205*4238Smckusick 206*4238Smckusick if(i < NDADDR) 207*4238Smckusick return(iaddr[i]); 208*4238Smckusick i -= NDADDR; 209*4238Smckusick if(i > NINDIR) { 210*4238Smckusick printf("%u - huge directory\n", ino); 211*4238Smckusick return((daddr_t)0); 212*4238Smckusick } 213*4238Smckusick bread(iaddr[NDADDR], (char *)ibuf, sizeof(ibuf)); 214*4238Smckusick return(ibuf[i]); 215*4238Smckusick } 216