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