1*5946Smckusic static char *sccsid = "@(#)dcheck.c 1.7 (Berkeley) 02/23/82"; 24238Smckusick /* 34238Smckusick * dcheck - check directory consistency 44238Smckusick */ 54238Smckusick #define NB 10 65348Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) 74238Smckusick 84238Smckusick #include "../h/param.h" 94238Smckusick #include "../h/inode.h" 104238Smckusick #include "../h/fs.h" 11*5946Smckusic #include <ndir.h> 12*5946Smckusic #include <stdio.h> 134238Smckusick 144238Smckusick union { 154238Smckusick struct fs fs; 165326Smckusic char pad[MAXBSIZE]; 174238Smckusick } fsun; 184238Smckusick #define sblock fsun.fs 194238Smckusick 20*5946Smckusic struct dirstuff { 21*5946Smckusic int loc; 22*5946Smckusic struct dinode *ip; 23*5946Smckusic char dbuf[MAXBSIZE]; 24*5946Smckusic }; 25*5946Smckusic 264238Smckusick struct dinode itab[MAXIPG]; 274253Smckusic struct dinode *gip; 284238Smckusick ino_t ilist[NB]; 294238Smckusick 304238Smckusick int fi; 314238Smckusick ino_t ino; 324238Smckusick ino_t *ecount; 334238Smckusick int headpr; 344238Smckusick int nfiles; 354238Smckusick 364238Smckusick int nerror; 374238Smckusick daddr_t bmap(); 384238Smckusick long atol(); 394238Smckusick char *malloc(); 404238Smckusick 414238Smckusick main(argc, argv) 424238Smckusick char *argv[]; 434238Smckusick { 444238Smckusick register i; 454238Smckusick long n; 464238Smckusick 474238Smckusick while (--argc) { 484238Smckusick argv++; 494238Smckusick if (**argv=='-') 504238Smckusick switch ((*argv)[1]) { 514238Smckusick 524238Smckusick case 'i': 534238Smckusick for(i=0; i<NB; i++) { 544238Smckusick n = atol(argv[1]); 554238Smckusick if(n == 0) 564238Smckusick break; 574238Smckusick ilist[i] = n; 584238Smckusick argv++; 594238Smckusick argc--; 604238Smckusick } 614238Smckusick ilist[i] = 0; 624238Smckusick continue; 634238Smckusick 644238Smckusick default: 654238Smckusick printf("Bad flag %c\n", (*argv)[1]); 664238Smckusick nerror++; 674238Smckusick } 684238Smckusick check(*argv); 694238Smckusick } 704238Smckusick return(nerror); 714238Smckusick } 724238Smckusick 734238Smckusick check(file) 744238Smckusick char *file; 754238Smckusick { 764238Smckusick register i, j, c; 774238Smckusick 784238Smckusick fi = open(file, 0); 794238Smckusick if(fi < 0) { 804238Smckusick printf("cannot open %s\n", file); 814238Smckusick nerror++; 824238Smckusick return; 834238Smckusick } 844238Smckusick headpr = 0; 854238Smckusick printf("%s:\n", file); 864238Smckusick sync(); 875348Smckusic bread(SBLOCK, (char *)&sblock, SBSIZE); 884238Smckusick if (sblock.fs_magic != FS_MAGIC) { 894238Smckusick printf("%s: not a file system\n", file); 904238Smckusick nerror++; 914238Smckusick return; 924238Smckusick } 934238Smckusick nfiles = sblock.fs_ipg * sblock.fs_ncg; 944238Smckusick if (nfiles > 65535) { 954238Smckusick printf("%s: preposterous number of files\n", file); 964238Smckusick nerror++; 974238Smckusick return; 984238Smckusick } 994238Smckusick ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount)); 1004238Smckusick if (ecount == 0) { 1014238Smckusick printf("%s: not enough core for %d files\n", file, nfiles); 1024238Smckusick exit(04); 1034238Smckusick } 1044238Smckusick for (i = 0; i<=nfiles; i++) 1054238Smckusick ecount[i] = 0; 1064238Smckusick ino = 0; 1074238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1085379Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 1094238Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1104238Smckusick for (j = 0; j < sblock.fs_ipg; j++) { 1114238Smckusick pass1(&itab[j]); 1124238Smckusick ino++; 1134238Smckusick } 1144238Smckusick } 1154238Smckusick ino = 0; 1164238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1175379Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 1184238Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1194238Smckusick for (j = 0; j < sblock.fs_ipg; j++) { 1204238Smckusick pass2(&itab[j]); 1214238Smckusick ino++; 1224238Smckusick } 1234238Smckusick } 1244238Smckusick free(ecount); 1254238Smckusick } 1264238Smckusick 1274238Smckusick pass1(ip) 128*5946Smckusic register struct dinode *ip; 1294238Smckusick { 130*5946Smckusic register struct direct *dp; 131*5946Smckusic struct dirstuff dirp; 1324238Smckusick int k; 1334238Smckusick 1344238Smckusick if((ip->di_mode&IFMT) != IFDIR) 1354238Smckusick return; 136*5946Smckusic dirp.loc = 0; 137*5946Smckusic dirp.ip = ip; 1384253Smckusic gip = ip; 139*5946Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 140*5946Smckusic if(dp->d_ino == 0) 141*5946Smckusic continue; 142*5946Smckusic if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) { 143*5946Smckusic printf("%d bad; %d/%s\n", 144*5946Smckusic dp->d_ino, ino, dp->d_name); 145*5946Smckusic nerror++; 146*5946Smckusic continue; 147*5946Smckusic } 148*5946Smckusic for (k = 0; ilist[k] != 0; k++) 149*5946Smckusic if (ilist[k] == dp->d_ino) { 150*5946Smckusic printf("%d arg; %d/%s\n", 151*5946Smckusic dp->d_ino, ino, dp->d_name); 1524238Smckusick nerror++; 1534238Smckusick } 154*5946Smckusic ecount[dp->d_ino]++; 1554238Smckusick } 1564238Smckusick } 1574238Smckusick 1584238Smckusick pass2(ip) 1594238Smckusick register struct dinode *ip; 1604238Smckusick { 1614238Smckusick register i; 1624238Smckusick 1634238Smckusick i = ino; 1644238Smckusick if ((ip->di_mode&IFMT)==0 && ecount[i]==0) 1654238Smckusick return; 1664238Smckusick if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) 1674238Smckusick return; 1684238Smckusick if (headpr==0) { 1694238Smckusick printf(" entries link cnt\n"); 1704238Smckusick headpr++; 1714238Smckusick } 1724238Smckusick printf("%u\t%d\t%d\n", ino, 1734238Smckusick ecount[i], ip->di_nlink); 1744238Smckusick } 1754238Smckusick 176*5946Smckusic /* 177*5946Smckusic * get next entry in a directory. 178*5946Smckusic */ 179*5946Smckusic struct direct * 180*5946Smckusic readdir(dirp) 181*5946Smckusic register struct dirstuff *dirp; 182*5946Smckusic { 183*5946Smckusic register struct direct *dp; 184*5946Smckusic daddr_t lbn, d; 185*5946Smckusic 186*5946Smckusic for(;;) { 187*5946Smckusic if (dirp->loc >= dirp->ip->di_size) 188*5946Smckusic return NULL; 189*5946Smckusic if ((lbn = dirp->loc / sblock.fs_bsize) == 0) { 190*5946Smckusic d = bmap(lbn); 191*5946Smckusic if(d == 0) 192*5946Smckusic return NULL; 193*5946Smckusic bread(fsbtodb(&sblock, d), dirp->dbuf, 194*5946Smckusic dblksize(&sblock, dirp->ip, lbn)); 195*5946Smckusic } 196*5946Smckusic dp = (struct direct *) 197*5946Smckusic (dirp->dbuf + dirp->loc % sblock.fs_bsize); 198*5946Smckusic dirp->loc += dp->d_reclen; 199*5946Smckusic if (dp->d_ino == 0) 200*5946Smckusic continue; 201*5946Smckusic return (dp); 202*5946Smckusic } 203*5946Smckusic } 204*5946Smckusic 2054238Smckusick bread(bno, buf, cnt) 2064238Smckusick daddr_t bno; 2074238Smckusick char *buf; 2084238Smckusick { 2094238Smckusick register i; 2104238Smckusick 2115326Smckusic lseek(fi, bno * DEV_BSIZE, 0); 2124238Smckusick if (read(fi, buf, cnt) != cnt) { 2134238Smckusick printf("read error %d\n", bno); 2145326Smckusic for(i=0; i < cnt; i++) 2154238Smckusick buf[i] = 0; 2164238Smckusick } 2174238Smckusick } 2184238Smckusick 2194238Smckusick daddr_t 2204238Smckusick bmap(i) 2214238Smckusick { 2225326Smckusic daddr_t ibuf[MAXNINDIR]; 2234238Smckusick 2244238Smckusick if(i < NDADDR) 2254253Smckusic return(gip->di_db[i]); 2264238Smckusick i -= NDADDR; 2275326Smckusic if(i > NINDIR(&sblock)) { 2284238Smckusick printf("%u - huge directory\n", ino); 2294238Smckusick return((daddr_t)0); 2304238Smckusick } 2315326Smckusic bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf)); 2324238Smckusick return(ibuf[i]); 2334238Smckusick } 234