1*5957Smckusic static char *sccsid = "@(#)dcheck.c 1.8 (Berkeley) 02/25/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" 115946Smckusic #include <ndir.h> 125946Smckusic #include <stdio.h> 134238Smckusick 144238Smckusick union { 154238Smckusick struct fs fs; 165326Smckusic char pad[MAXBSIZE]; 174238Smckusick } fsun; 184238Smckusick #define sblock fsun.fs 194238Smckusick 205946Smckusic struct dirstuff { 215946Smckusic int loc; 225946Smckusic struct dinode *ip; 235946Smckusic char dbuf[MAXBSIZE]; 245946Smckusic }; 255946Smckusic 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) 1285946Smckusic register struct dinode *ip; 1294238Smckusick { 1305946Smckusic register struct direct *dp; 1315946Smckusic struct dirstuff dirp; 1324238Smckusick int k; 1334238Smckusick 1344238Smckusick if((ip->di_mode&IFMT) != IFDIR) 1354238Smckusick return; 1365946Smckusic dirp.loc = 0; 1375946Smckusic dirp.ip = ip; 1384253Smckusic gip = ip; 1395946Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 1405946Smckusic if(dp->d_ino == 0) 1415946Smckusic continue; 1425946Smckusic if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) { 1435946Smckusic printf("%d bad; %d/%s\n", 1445946Smckusic dp->d_ino, ino, dp->d_name); 1455946Smckusic nerror++; 1465946Smckusic continue; 1475946Smckusic } 1485946Smckusic for (k = 0; ilist[k] != 0; k++) 1495946Smckusic if (ilist[k] == dp->d_ino) { 1505946Smckusic printf("%d arg; %d/%s\n", 1515946Smckusic dp->d_ino, ino, dp->d_name); 1524238Smckusick nerror++; 1534238Smckusick } 1545946Smckusic 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 1765946Smckusic /* 1775946Smckusic * get next entry in a directory. 1785946Smckusic */ 1795946Smckusic struct direct * 1805946Smckusic readdir(dirp) 1815946Smckusic register struct dirstuff *dirp; 1825946Smckusic { 1835946Smckusic register struct direct *dp; 1845946Smckusic daddr_t lbn, d; 1855946Smckusic 1865946Smckusic for(;;) { 1875946Smckusic if (dirp->loc >= dirp->ip->di_size) 1885946Smckusic return NULL; 189*5957Smckusic if ((lbn = lblkno(&sblock, dirp->loc)) == 0) { 1905946Smckusic d = bmap(lbn); 1915946Smckusic if(d == 0) 1925946Smckusic return NULL; 1935946Smckusic bread(fsbtodb(&sblock, d), dirp->dbuf, 1945946Smckusic dblksize(&sblock, dirp->ip, lbn)); 1955946Smckusic } 1965946Smckusic dp = (struct direct *) 197*5957Smckusic (dirp->dbuf + blkoff(&sblock, dirp->loc)); 1985946Smckusic dirp->loc += dp->d_reclen; 1995946Smckusic if (dp->d_ino == 0) 2005946Smckusic continue; 2015946Smckusic return (dp); 2025946Smckusic } 2035946Smckusic } 2045946Smckusic 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