1*6493Smckusick static char *sccsid = "@(#)dcheck.c 2.1 (Berkeley) 04/08/82"; 24238Smckusick /* 34238Smckusick * dcheck - check directory consistency 44238Smckusick */ 54238Smckusick #define NB 10 65348Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) 74238Smckusick 8*6493Smckusick #ifndef SIMFS 9*6493Smckusick #include <sys/param.h> 10*6493Smckusick #include <sys/inode.h> 11*6493Smckusick #include <sys/fs.h> 12*6493Smckusick #else 134238Smckusick #include "../h/param.h" 144238Smckusick #include "../h/inode.h" 154238Smckusick #include "../h/fs.h" 16*6493Smckusick #endif 175946Smckusic #include <ndir.h> 185946Smckusic #include <stdio.h> 194238Smckusick 204238Smckusick union { 214238Smckusick struct fs fs; 225326Smckusic char pad[MAXBSIZE]; 234238Smckusick } fsun; 244238Smckusick #define sblock fsun.fs 254238Smckusick 265946Smckusic struct dirstuff { 275946Smckusic int loc; 285946Smckusic struct dinode *ip; 295946Smckusic char dbuf[MAXBSIZE]; 305946Smckusic }; 315946Smckusic 324238Smckusick struct dinode itab[MAXIPG]; 334253Smckusic struct dinode *gip; 344238Smckusick ino_t ilist[NB]; 354238Smckusick 364238Smckusick int fi; 374238Smckusick ino_t ino; 384238Smckusick ino_t *ecount; 394238Smckusick int headpr; 404238Smckusick int nfiles; 414238Smckusick 424238Smckusick int nerror; 434238Smckusick daddr_t bmap(); 444238Smckusick long atol(); 454238Smckusick char *malloc(); 464238Smckusick 474238Smckusick main(argc, argv) 484238Smckusick char *argv[]; 494238Smckusick { 504238Smckusick register i; 514238Smckusick long n; 524238Smckusick 534238Smckusick while (--argc) { 544238Smckusick argv++; 554238Smckusick if (**argv=='-') 564238Smckusick switch ((*argv)[1]) { 574238Smckusick 584238Smckusick case 'i': 594238Smckusick for(i=0; i<NB; i++) { 604238Smckusick n = atol(argv[1]); 614238Smckusick if(n == 0) 624238Smckusick break; 634238Smckusick ilist[i] = n; 644238Smckusick argv++; 654238Smckusick argc--; 664238Smckusick } 674238Smckusick ilist[i] = 0; 684238Smckusick continue; 694238Smckusick 704238Smckusick default: 714238Smckusick printf("Bad flag %c\n", (*argv)[1]); 724238Smckusick nerror++; 734238Smckusick } 744238Smckusick check(*argv); 754238Smckusick } 764238Smckusick return(nerror); 774238Smckusick } 784238Smckusick 794238Smckusick check(file) 804238Smckusick char *file; 814238Smckusick { 824238Smckusick register i, j, c; 834238Smckusick 844238Smckusick fi = open(file, 0); 854238Smckusick if(fi < 0) { 864238Smckusick printf("cannot open %s\n", file); 874238Smckusick nerror++; 884238Smckusick return; 894238Smckusick } 904238Smckusick headpr = 0; 914238Smckusick printf("%s:\n", file); 924238Smckusick sync(); 935348Smckusic bread(SBLOCK, (char *)&sblock, SBSIZE); 944238Smckusick if (sblock.fs_magic != FS_MAGIC) { 954238Smckusick printf("%s: not a file system\n", file); 964238Smckusick nerror++; 974238Smckusick return; 984238Smckusick } 994238Smckusick nfiles = sblock.fs_ipg * sblock.fs_ncg; 1004238Smckusick if (nfiles > 65535) { 1014238Smckusick printf("%s: preposterous number of files\n", file); 1024238Smckusick nerror++; 1034238Smckusick return; 1044238Smckusick } 1054238Smckusick ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount)); 1064238Smckusick if (ecount == 0) { 1074238Smckusick printf("%s: not enough core for %d files\n", file, nfiles); 1084238Smckusick exit(04); 1094238Smckusick } 1104238Smckusick for (i = 0; i<=nfiles; i++) 1114238Smckusick ecount[i] = 0; 1124238Smckusick ino = 0; 1134238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1145379Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 1154238Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1164238Smckusick for (j = 0; j < sblock.fs_ipg; j++) { 1174238Smckusick pass1(&itab[j]); 1184238Smckusick ino++; 1194238Smckusick } 1204238Smckusick } 1214238Smckusick ino = 0; 1224238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1235379Smckusic bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, 1244238Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1254238Smckusick for (j = 0; j < sblock.fs_ipg; j++) { 1264238Smckusick pass2(&itab[j]); 1274238Smckusick ino++; 1284238Smckusick } 1294238Smckusick } 1304238Smckusick free(ecount); 1314238Smckusick } 1324238Smckusick 1334238Smckusick pass1(ip) 1345946Smckusic register struct dinode *ip; 1354238Smckusick { 1365946Smckusic register struct direct *dp; 1375946Smckusic struct dirstuff dirp; 1384238Smckusick int k; 1394238Smckusick 1404238Smckusick if((ip->di_mode&IFMT) != IFDIR) 1414238Smckusick return; 1425946Smckusic dirp.loc = 0; 1435946Smckusic dirp.ip = ip; 1444253Smckusic gip = ip; 1455946Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 1465946Smckusic if(dp->d_ino == 0) 1475946Smckusic continue; 1485946Smckusic if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) { 1495946Smckusic printf("%d bad; %d/%s\n", 1505946Smckusic dp->d_ino, ino, dp->d_name); 1515946Smckusic nerror++; 1525946Smckusic continue; 1535946Smckusic } 1545946Smckusic for (k = 0; ilist[k] != 0; k++) 1555946Smckusic if (ilist[k] == dp->d_ino) { 1565946Smckusic printf("%d arg; %d/%s\n", 1575946Smckusic dp->d_ino, ino, dp->d_name); 1584238Smckusick nerror++; 1594238Smckusick } 1605946Smckusic ecount[dp->d_ino]++; 1614238Smckusick } 1624238Smckusick } 1634238Smckusick 1644238Smckusick pass2(ip) 1654238Smckusick register struct dinode *ip; 1664238Smckusick { 1674238Smckusick register i; 1684238Smckusick 1694238Smckusick i = ino; 1704238Smckusick if ((ip->di_mode&IFMT)==0 && ecount[i]==0) 1714238Smckusick return; 1724238Smckusick if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) 1734238Smckusick return; 1744238Smckusick if (headpr==0) { 1754238Smckusick printf(" entries link cnt\n"); 1764238Smckusick headpr++; 1774238Smckusick } 1784238Smckusick printf("%u\t%d\t%d\n", ino, 1794238Smckusick ecount[i], ip->di_nlink); 1804238Smckusick } 1814238Smckusick 1825946Smckusic /* 1835946Smckusic * get next entry in a directory. 1845946Smckusic */ 1855946Smckusic struct direct * 1865946Smckusic readdir(dirp) 1875946Smckusic register struct dirstuff *dirp; 1885946Smckusic { 1895946Smckusic register struct direct *dp; 1905946Smckusic daddr_t lbn, d; 1915946Smckusic 1925946Smckusic for(;;) { 1935946Smckusic if (dirp->loc >= dirp->ip->di_size) 1945946Smckusic return NULL; 1955957Smckusic if ((lbn = lblkno(&sblock, dirp->loc)) == 0) { 1965946Smckusic d = bmap(lbn); 1975946Smckusic if(d == 0) 1985946Smckusic return NULL; 1995946Smckusic bread(fsbtodb(&sblock, d), dirp->dbuf, 2005946Smckusic dblksize(&sblock, dirp->ip, lbn)); 2015946Smckusic } 2025946Smckusic dp = (struct direct *) 2035957Smckusic (dirp->dbuf + blkoff(&sblock, dirp->loc)); 2045946Smckusic dirp->loc += dp->d_reclen; 2055946Smckusic if (dp->d_ino == 0) 2065946Smckusic continue; 2075946Smckusic return (dp); 2085946Smckusic } 2095946Smckusic } 2105946Smckusic 2114238Smckusick bread(bno, buf, cnt) 2124238Smckusick daddr_t bno; 2134238Smckusick char *buf; 2144238Smckusick { 2154238Smckusick register i; 2164238Smckusick 2175326Smckusic lseek(fi, bno * DEV_BSIZE, 0); 2184238Smckusick if (read(fi, buf, cnt) != cnt) { 2194238Smckusick printf("read error %d\n", bno); 2205326Smckusic for(i=0; i < cnt; i++) 2214238Smckusick buf[i] = 0; 2224238Smckusick } 2234238Smckusick } 2244238Smckusick 2254238Smckusick daddr_t 2264238Smckusick bmap(i) 2274238Smckusick { 2285326Smckusic daddr_t ibuf[MAXNINDIR]; 2294238Smckusick 2304238Smckusick if(i < NDADDR) 2314253Smckusic return(gip->di_db[i]); 2324238Smckusick i -= NDADDR; 2335326Smckusic if(i > NINDIR(&sblock)) { 2344238Smckusick printf("%u - huge directory\n", ino); 2354238Smckusick return((daddr_t)0); 2364238Smckusick } 2375326Smckusic bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf)); 2384238Smckusick return(ibuf[i]); 2394238Smckusick } 240