122489Sdist /* 222489Sdist * Copyright (c) 1980 Regents of the University of California. 322489Sdist * All rights reserved. The Berkeley software License Agreement 422489Sdist * specifies the terms and conditions for redistribution. 522489Sdist */ 622489Sdist 713550Ssam #ifndef lint 822489Sdist char copyright[] = 922489Sdist "@(#) Copyright (c) 1980 Regents of the University of California.\n\ 1022489Sdist All rights reserved.\n"; 1122489Sdist #endif not lint 1222489Sdist 1322489Sdist #ifndef lint 14*34151Smckusick static char sccsid[] = "@(#)dcheck.c 5.3 (Berkeley) 05/02/88"; 1522489Sdist #endif not lint 1622489Sdist 174238Smckusick /* 184238Smckusick * dcheck - check directory consistency 194238Smckusick */ 204238Smckusick #define NB 10 215348Smckusic #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) 224238Smckusick 236493Smckusick #include <sys/param.h> 246493Smckusick #include <sys/inode.h> 256493Smckusick #include <sys/fs.h> 2613550Ssam #include <sys/dir.h> 275946Smckusic #include <stdio.h> 284238Smckusick 294238Smckusick union { 304238Smckusick struct fs fs; 31*34151Smckusick char pad[SBSIZE]; 324238Smckusick } fsun; 334238Smckusick #define sblock fsun.fs 344238Smckusick 355946Smckusic struct dirstuff { 365946Smckusic int loc; 375946Smckusic struct dinode *ip; 385946Smckusic char dbuf[MAXBSIZE]; 395946Smckusic }; 405946Smckusic 41*34151Smckusick struct dinode itab[MAXBSIZE / sizeof(struct dinode)]; 424253Smckusic struct dinode *gip; 434238Smckusick ino_t ilist[NB]; 444238Smckusick 454238Smckusick int fi; 464238Smckusick ino_t ino; 474238Smckusick ino_t *ecount; 484238Smckusick int headpr; 494238Smckusick int nfiles; 5030558Smckusick long dev_bsize = 1; 514238Smckusick 524238Smckusick int nerror; 534238Smckusick daddr_t bmap(); 544238Smckusick long atol(); 554238Smckusick char *malloc(); 564238Smckusick 574238Smckusick main(argc, argv) 584238Smckusick char *argv[]; 594238Smckusick { 604238Smckusick register i; 614238Smckusick long n; 624238Smckusick 634238Smckusick while (--argc) { 644238Smckusick argv++; 654238Smckusick if (**argv=='-') 664238Smckusick switch ((*argv)[1]) { 674238Smckusick 684238Smckusick case 'i': 694238Smckusick for(i=0; i<NB; i++) { 704238Smckusick n = atol(argv[1]); 714238Smckusick if(n == 0) 724238Smckusick break; 734238Smckusick ilist[i] = n; 744238Smckusick argv++; 754238Smckusick argc--; 764238Smckusick } 774238Smckusick ilist[i] = 0; 784238Smckusick continue; 794238Smckusick 804238Smckusick default: 814238Smckusick printf("Bad flag %c\n", (*argv)[1]); 824238Smckusick nerror++; 834238Smckusick } 844238Smckusick check(*argv); 854238Smckusick } 864238Smckusick return(nerror); 874238Smckusick } 884238Smckusick 894238Smckusick check(file) 904238Smckusick char *file; 914238Smckusick { 924238Smckusick register i, j, c; 934238Smckusick 944238Smckusick fi = open(file, 0); 954238Smckusick if(fi < 0) { 964238Smckusick printf("cannot open %s\n", file); 974238Smckusick nerror++; 984238Smckusick return; 994238Smckusick } 1004238Smckusick headpr = 0; 1014238Smckusick printf("%s:\n", file); 1024238Smckusick sync(); 10330558Smckusick bread(SBOFF, (char *)&sblock, SBSIZE); 1044238Smckusick if (sblock.fs_magic != FS_MAGIC) { 1054238Smckusick printf("%s: not a file system\n", file); 1064238Smckusick nerror++; 1074238Smckusick return; 1084238Smckusick } 10930558Smckusick dev_bsize = sblock.fs_fsize / fsbtodb(&sblock, 1); 1104238Smckusick nfiles = sblock.fs_ipg * sblock.fs_ncg; 1114238Smckusick ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount)); 1124238Smckusick if (ecount == 0) { 1134238Smckusick printf("%s: not enough core for %d files\n", file, nfiles); 1144238Smckusick exit(04); 1154238Smckusick } 1164238Smckusick for (i = 0; i<=nfiles; i++) 1174238Smckusick ecount[i] = 0; 1184238Smckusick ino = 0; 1194238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 120*34151Smckusick for (i = 0; 121*34151Smckusick i < sblock.fs_ipg / INOPF(&sblock); 122*34151Smckusick i += sblock.fs_frag) { 123*34151Smckusick bread(fsbtodb(&sblock, cgimin(&sblock, c) + i), 124*34151Smckusick (char *)itab, sblock.fs_bsize); 125*34151Smckusick for (j = 0; j < INOPB(&sblock); j++) { 126*34151Smckusick pass1(&itab[j]); 127*34151Smckusick ino++; 128*34151Smckusick } 1294238Smckusick } 1304238Smckusick } 1314238Smckusick ino = 0; 1324238Smckusick for (c = 0; c < sblock.fs_ncg; c++) { 133*34151Smckusick for (i = 0; 134*34151Smckusick i < sblock.fs_ipg / INOPF(&sblock); 135*34151Smckusick i += sblock.fs_frag) { 136*34151Smckusick bread(fsbtodb(&sblock, cgimin(&sblock, c) + i), 137*34151Smckusick (char *)itab, sblock.fs_bsize); 138*34151Smckusick for (j = 0; j < INOPB(&sblock); j++) { 139*34151Smckusick pass2(&itab[j]); 140*34151Smckusick ino++; 141*34151Smckusick } 1424238Smckusick } 1434238Smckusick } 1444238Smckusick free(ecount); 1454238Smckusick } 1464238Smckusick 1474238Smckusick pass1(ip) 1485946Smckusic register struct dinode *ip; 1494238Smckusick { 1505946Smckusic register struct direct *dp; 1515946Smckusic struct dirstuff dirp; 1524238Smckusick int k; 1534238Smckusick 1544238Smckusick if((ip->di_mode&IFMT) != IFDIR) 1554238Smckusick return; 1565946Smckusic dirp.loc = 0; 1575946Smckusic dirp.ip = ip; 1584253Smckusic gip = ip; 1595946Smckusic for (dp = readdir(&dirp); dp != NULL; dp = readdir(&dirp)) { 1605946Smckusic if(dp->d_ino == 0) 1615946Smckusic continue; 1625946Smckusic if(dp->d_ino > nfiles || dp->d_ino < ROOTINO) { 1635946Smckusic printf("%d bad; %d/%s\n", 1645946Smckusic dp->d_ino, ino, dp->d_name); 1655946Smckusic nerror++; 1665946Smckusic continue; 1675946Smckusic } 1685946Smckusic for (k = 0; ilist[k] != 0; k++) 1695946Smckusic if (ilist[k] == dp->d_ino) { 1705946Smckusic printf("%d arg; %d/%s\n", 1715946Smckusic dp->d_ino, ino, dp->d_name); 1724238Smckusick nerror++; 1734238Smckusick } 1745946Smckusic ecount[dp->d_ino]++; 1754238Smckusick } 1764238Smckusick } 1774238Smckusick 1784238Smckusick pass2(ip) 1794238Smckusick register struct dinode *ip; 1804238Smckusick { 1814238Smckusick register i; 1824238Smckusick 1834238Smckusick i = ino; 1844238Smckusick if ((ip->di_mode&IFMT)==0 && ecount[i]==0) 1854238Smckusick return; 1864238Smckusick if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) 1874238Smckusick return; 1884238Smckusick if (headpr==0) { 1894238Smckusick printf(" entries link cnt\n"); 1904238Smckusick headpr++; 1914238Smckusick } 1924238Smckusick printf("%u\t%d\t%d\n", ino, 1934238Smckusick ecount[i], ip->di_nlink); 1944238Smckusick } 1954238Smckusick 1965946Smckusic /* 1975946Smckusic * get next entry in a directory. 1985946Smckusic */ 1995946Smckusic struct direct * 2005946Smckusic readdir(dirp) 2015946Smckusic register struct dirstuff *dirp; 2025946Smckusic { 2035946Smckusic register struct direct *dp; 2045946Smckusic daddr_t lbn, d; 2055946Smckusic 2065946Smckusic for(;;) { 2075946Smckusic if (dirp->loc >= dirp->ip->di_size) 2085946Smckusic return NULL; 2095957Smckusic if ((lbn = lblkno(&sblock, dirp->loc)) == 0) { 2105946Smckusic d = bmap(lbn); 2115946Smckusic if(d == 0) 2125946Smckusic return NULL; 2135946Smckusic bread(fsbtodb(&sblock, d), dirp->dbuf, 2145946Smckusic dblksize(&sblock, dirp->ip, lbn)); 2155946Smckusic } 2165946Smckusic dp = (struct direct *) 2175957Smckusic (dirp->dbuf + blkoff(&sblock, dirp->loc)); 2185946Smckusic dirp->loc += dp->d_reclen; 2195946Smckusic if (dp->d_ino == 0) 2205946Smckusic continue; 2215946Smckusic return (dp); 2225946Smckusic } 2235946Smckusic } 2245946Smckusic 2254238Smckusick bread(bno, buf, cnt) 2264238Smckusick daddr_t bno; 2274238Smckusick char *buf; 2284238Smckusick { 2294238Smckusick register i; 2304238Smckusick 23130558Smckusick lseek(fi, bno * dev_bsize, 0); 2324238Smckusick if (read(fi, buf, cnt) != cnt) { 2334238Smckusick printf("read error %d\n", bno); 2345326Smckusic for(i=0; i < cnt; i++) 2354238Smckusick buf[i] = 0; 2364238Smckusick } 2374238Smckusick } 2384238Smckusick 2394238Smckusick daddr_t 2404238Smckusick bmap(i) 2414238Smckusick { 2425326Smckusic daddr_t ibuf[MAXNINDIR]; 2434238Smckusick 2444238Smckusick if(i < NDADDR) 2454253Smckusic return(gip->di_db[i]); 2464238Smckusick i -= NDADDR; 2475326Smckusic if(i > NINDIR(&sblock)) { 2484238Smckusick printf("%u - huge directory\n", ino); 2494238Smckusick return((daddr_t)0); 2504238Smckusick } 2515326Smckusic bread(fsbtodb(&sblock, gip->di_ib[0]), (char *)ibuf, sizeof(ibuf)); 2524238Smckusick return(ibuf[i]); 2534238Smckusick } 254