1*5348Smckusic static char *sccsid = "@(#)dcheck.c 1.5 (Berkeley) 01/06/82"; 24238Smckusick /* 34238Smckusick * dcheck - check directory consistency 44238Smckusick */ 54238Smckusick #define NB 10 65326Smckusic #define NDIR(fs) ((fs)->fs_bsize/sizeof(struct direct)) 75326Smckusic #define MAXNDIR (MAXBSIZE/sizeof(struct direct)) 8*5348Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) 94238Smckusick 104238Smckusick #include <stdio.h> 114238Smckusick #include "../h/param.h" 124238Smckusick #include "../h/inode.h" 134238Smckusick #include "../h/dir.h" 144238Smckusick #include "../h/fs.h" 154238Smckusick 164238Smckusick union { 174238Smckusick struct fs fs; 185326Smckusic char pad[MAXBSIZE]; 194238Smckusick } fsun; 204238Smckusick #define sblock fsun.fs 214238Smckusick 224238Smckusick struct dinode itab[MAXIPG]; 234253Smckusic struct dinode *gip; 244238Smckusick ino_t ilist[NB]; 254238Smckusick 264238Smckusick int fi; 274238Smckusick ino_t ino; 284238Smckusick ino_t *ecount; 294238Smckusick int headpr; 304238Smckusick int nfiles; 314238Smckusick 324238Smckusick int nerror; 334238Smckusick daddr_t bmap(); 344238Smckusick long atol(); 354238Smckusick char *malloc(); 364238Smckusick 374238Smckusick main(argc, argv) 384238Smckusick char *argv[]; 394238Smckusick { 404238Smckusick register i; 414238Smckusick long n; 424238Smckusick 434238Smckusick while (--argc) { 444238Smckusick argv++; 454238Smckusick if (**argv=='-') 464238Smckusick switch ((*argv)[1]) { 474238Smckusick 484238Smckusick case 'i': 494238Smckusick for(i=0; i<NB; i++) { 504238Smckusick n = atol(argv[1]); 514238Smckusick if(n == 0) 524238Smckusick break; 534238Smckusick ilist[i] = n; 544238Smckusick argv++; 554238Smckusick argc--; 564238Smckusick } 574238Smckusick ilist[i] = 0; 584238Smckusick continue; 594238Smckusick 604238Smckusick default: 614238Smckusick printf("Bad flag %c\n", (*argv)[1]); 624238Smckusick nerror++; 634238Smckusick } 644238Smckusick check(*argv); 654238Smckusick } 664238Smckusick return(nerror); 674238Smckusick } 684238Smckusick 694238Smckusick check(file) 704238Smckusick char *file; 714238Smckusick { 724238Smckusick register i, j, c; 734238Smckusick 744238Smckusick fi = open(file, 0); 754238Smckusick if(fi < 0) { 764238Smckusick printf("cannot open %s\n", file); 774238Smckusick nerror++; 784238Smckusick return; 794238Smckusick } 804238Smckusick headpr = 0; 814238Smckusick printf("%s:\n", file); 824238Smckusick sync(); 83*5348Smckusic bread(SBLOCK, (char *)&sblock, SBSIZE); 844238Smckusick if (sblock.fs_magic != FS_MAGIC) { 854238Smckusick printf("%s: not a file system\n", file); 864238Smckusick nerror++; 874238Smckusick return; 884238Smckusick } 894238Smckusick nfiles = sblock.fs_ipg * sblock.fs_ncg; 904238Smckusick if (nfiles > 65535) { 914238Smckusick printf("%s: preposterous number of files\n", file); 924238Smckusick nerror++; 934238Smckusick return; 944238Smckusick } 954238Smckusick ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount)); 964238Smckusick if (ecount == 0) { 974238Smckusick printf("%s: not enough core for %d files\n", file, nfiles); 984238Smckusick exit(04); 994238Smckusick } 1004238Smckusick for (i = 0; i<=nfiles; i++) 1014238Smckusick ecount[i] = 0; 1024238Smckusick ino = 0; 1034238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1045326Smckusic bread(fsbtodb(&sblock, cgimin(c, &sblock)), (char *)itab, 1054238Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1064238Smckusick for (j = 0; j < sblock.fs_ipg; j++) { 1074238Smckusick pass1(&itab[j]); 1084238Smckusick ino++; 1094238Smckusick } 1104238Smckusick } 1114238Smckusick ino = 0; 1124238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 1135326Smckusic bread(fsbtodb(&sblock, cgimin(c, &sblock)), (char *)itab, 1144238Smckusick sblock.fs_ipg * sizeof (struct dinode)); 1154238Smckusick for (j = 0; j < sblock.fs_ipg; j++) { 1164238Smckusick pass2(&itab[j]); 1174238Smckusick ino++; 1184238Smckusick } 1194238Smckusick } 1204238Smckusick free(ecount); 1214238Smckusick } 1224238Smckusick 1234238Smckusick pass1(ip) 1244238Smckusick register struct dinode *ip; 1254238Smckusick { 1265326Smckusic struct direct dbuf[MAXNDIR]; 1274238Smckusick long doff; 1284238Smckusick struct direct *dp; 1294238Smckusick register i, j; 1304238Smckusick int k; 1314238Smckusick daddr_t d; 1324238Smckusick ino_t kno; 1334238Smckusick 1344238Smckusick if((ip->di_mode&IFMT) != IFDIR) 1354238Smckusick return; 1364253Smckusic gip = ip; 1374238Smckusick doff = 0; 1384238Smckusick for(i=0;; i++) { 1394238Smckusick if(doff >= ip->di_size) 1404238Smckusick break; 1414238Smckusick d = bmap(i); 1424238Smckusick if(d == 0) 1434238Smckusick break; 1445326Smckusic bread(fsbtodb(&sblock, d), (char *)dbuf, sblock.fs_bsize); 1455326Smckusic for(j=0; j < NDIR(&sblock); j++) { 1464238Smckusick if(doff >= ip->di_size) 1474238Smckusick break; 1484238Smckusick doff += sizeof(struct direct); 1494238Smckusick dp = &dbuf[j]; 1504238Smckusick kno = dp->d_ino; 1514238Smckusick if(kno == 0) 1524238Smckusick continue; 1534238Smckusick if(kno > nfiles || kno < ROOTINO) { 1544238Smckusick printf("%d bad; %d/%.*s\n", 1554238Smckusick kno, ino, DIRSIZ, dp->d_name); 1564238Smckusick nerror++; 1574238Smckusick continue; 1584238Smckusick } 1594238Smckusick for (k=0; ilist[k] != 0; k++) 1604238Smckusick if (ilist[k]==kno) { 1614238Smckusick printf("%d arg; %d/%.*s\n", 1624238Smckusick kno, ino, DIRSIZ, dp->d_name); 1634238Smckusick nerror++; 1644238Smckusick } 1654238Smckusick ecount[kno]++; 1664238Smckusick } 1674238Smckusick } 1684238Smckusick } 1694238Smckusick 1704238Smckusick pass2(ip) 1714238Smckusick register struct dinode *ip; 1724238Smckusick { 1734238Smckusick register i; 1744238Smckusick 1754238Smckusick i = ino; 1764238Smckusick if ((ip->di_mode&IFMT)==0 && ecount[i]==0) 1774238Smckusick return; 1784238Smckusick if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) 1794238Smckusick return; 1804238Smckusick if (headpr==0) { 1814238Smckusick printf(" entries link cnt\n"); 1824238Smckusick headpr++; 1834238Smckusick } 1844238Smckusick printf("%u\t%d\t%d\n", ino, 1854238Smckusick ecount[i], ip->di_nlink); 1864238Smckusick } 1874238Smckusick 1884238Smckusick bread(bno, buf, cnt) 1894238Smckusick daddr_t bno; 1904238Smckusick char *buf; 1914238Smckusick { 1924238Smckusick register i; 1934238Smckusick 1945326Smckusic lseek(fi, bno * DEV_BSIZE, 0); 1954238Smckusick if (read(fi, buf, cnt) != cnt) { 1964238Smckusick printf("read error %d\n", bno); 1975326Smckusic for(i=0; i < cnt; i++) 1984238Smckusick buf[i] = 0; 1994238Smckusick } 2004238Smckusick } 2014238Smckusick 2024238Smckusick daddr_t 2034238Smckusick bmap(i) 2044238Smckusick { 2055326Smckusic daddr_t ibuf[MAXNINDIR]; 2064238Smckusick 2074238Smckusick if(i < NDADDR) 2084253Smckusic return(gip->di_db[i]); 2094238Smckusick i -= NDADDR; 2105326Smckusic if(i > NINDIR(&sblock)) { 2114238Smckusick printf("%u - huge directory\n", ino); 2124238Smckusick return((daddr_t)0); 2134238Smckusick } 2145326Smckusic bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf)); 2154238Smckusick return(ibuf[i]); 2164238Smckusick } 217