1 static char *sccsid = "@(#)dcheck.c 1.1 (Berkeley) 08/26/81"; 2 /* 3 * dcheck - check directory consistency 4 */ 5 #define NB 10 6 #define NDIR (BSIZE/sizeof(struct direct)) 7 8 #include <stdio.h> 9 #include "../h/param.h" 10 #include "../h/inode.h" 11 #include "../h/ino.h" 12 #include "../h/dir.h" 13 #include "../h/fs.h" 14 15 union { 16 struct fs fs; 17 char pad[BSIZE]; 18 } fsun; 19 #define sblock fsun.fs 20 21 struct dinode itab[MAXIPG]; 22 daddr_t iaddr[NDADDR+NIADDR]; 23 ino_t ilist[NB]; 24 25 int fi; 26 ino_t ino; 27 ino_t *ecount; 28 int headpr; 29 int nfiles; 30 31 int nerror; 32 daddr_t bmap(); 33 long atol(); 34 char *malloc(); 35 36 main(argc, argv) 37 char *argv[]; 38 { 39 register i; 40 long n; 41 42 while (--argc) { 43 argv++; 44 if (**argv=='-') 45 switch ((*argv)[1]) { 46 47 case 'i': 48 for(i=0; i<NB; i++) { 49 n = atol(argv[1]); 50 if(n == 0) 51 break; 52 ilist[i] = n; 53 argv++; 54 argc--; 55 } 56 ilist[i] = 0; 57 continue; 58 59 default: 60 printf("Bad flag %c\n", (*argv)[1]); 61 nerror++; 62 } 63 check(*argv); 64 } 65 return(nerror); 66 } 67 68 check(file) 69 char *file; 70 { 71 register i, j, c; 72 73 fi = open(file, 0); 74 if(fi < 0) { 75 printf("cannot open %s\n", file); 76 nerror++; 77 return; 78 } 79 headpr = 0; 80 printf("%s:\n", file); 81 sync(); 82 bread(SBLOCK, (char *)&sblock, BSIZE); 83 if (sblock.fs_magic != FS_MAGIC) { 84 printf("%s: not a file system\n", file); 85 nerror++; 86 return; 87 } 88 nfiles = sblock.fs_ipg * sblock.fs_ncg; 89 if (nfiles > 65535) { 90 printf("%s: preposterous number of files\n", file); 91 nerror++; 92 return; 93 } 94 ecount = (ino_t *)malloc((nfiles+1) * sizeof (*ecount)); 95 if (ecount == 0) { 96 printf("%s: not enough core for %d files\n", file, nfiles); 97 exit(04); 98 } 99 for (i = 0; i<=nfiles; i++) 100 ecount[i] = 0; 101 ino = 0; 102 for (c = 0; c < sblock.fs_ncg; c++) { 103 bread(cgimin(c, &sblock), (char *)itab, 104 sblock.fs_ipg * sizeof (struct dinode)); 105 for (j = 0; j < sblock.fs_ipg; j++) { 106 pass1(&itab[j]); 107 ino++; 108 } 109 } 110 ino = 0; 111 for (c = 0; c < sblock.fs_ncg; c++) { 112 bread(cgimin(c, &sblock), (char *)itab, 113 sblock.fs_ipg * sizeof (struct dinode)); 114 for (j = 0; j < sblock.fs_ipg; j++) { 115 pass2(&itab[j]); 116 ino++; 117 } 118 } 119 free(ecount); 120 } 121 122 pass1(ip) 123 register struct dinode *ip; 124 { 125 struct direct dbuf[NDIR]; 126 long doff; 127 struct direct *dp; 128 register i, j; 129 int k; 130 daddr_t d; 131 ino_t kno; 132 133 if((ip->di_mode&IFMT) != IFDIR) 134 return; 135 l3tol(iaddr, ip->di_addr, NDADDR+NIADDR); 136 doff = 0; 137 for(i=0;; i++) { 138 if(doff >= ip->di_size) 139 break; 140 d = bmap(i); 141 if(d == 0) 142 break; 143 bread(d, (char *)dbuf, BSIZE); 144 for(j=0; j<NDIR; j++) { 145 if(doff >= ip->di_size) 146 break; 147 doff += sizeof(struct direct); 148 dp = &dbuf[j]; 149 kno = dp->d_ino; 150 if(kno == 0) 151 continue; 152 if(kno > nfiles || kno < ROOTINO) { 153 printf("%d bad; %d/%.*s\n", 154 kno, ino, DIRSIZ, dp->d_name); 155 nerror++; 156 continue; 157 } 158 for (k=0; ilist[k] != 0; k++) 159 if (ilist[k]==kno) { 160 printf("%d arg; %d/%.*s\n", 161 kno, ino, DIRSIZ, dp->d_name); 162 nerror++; 163 } 164 ecount[kno]++; 165 } 166 } 167 } 168 169 pass2(ip) 170 register struct dinode *ip; 171 { 172 register i; 173 174 i = ino; 175 if ((ip->di_mode&IFMT)==0 && ecount[i]==0) 176 return; 177 if (ip->di_nlink==ecount[i] && ip->di_nlink!=0) 178 return; 179 if (headpr==0) { 180 printf(" entries link cnt\n"); 181 headpr++; 182 } 183 printf("%u\t%d\t%d\n", ino, 184 ecount[i], ip->di_nlink); 185 } 186 187 bread(bno, buf, cnt) 188 daddr_t bno; 189 char *buf; 190 { 191 register i; 192 193 lseek(fi, bno*FSIZE, 0); 194 if (read(fi, buf, cnt) != cnt) { 195 printf("read error %d\n", bno); 196 for(i=0; i<BSIZE; i++) 197 buf[i] = 0; 198 } 199 } 200 201 daddr_t 202 bmap(i) 203 { 204 daddr_t ibuf[NINDIR]; 205 206 if(i < NDADDR) 207 return(iaddr[i]); 208 i -= NDADDR; 209 if(i > NINDIR) { 210 printf("%u - huge directory\n", ino); 211 return((daddr_t)0); 212 } 213 bread(iaddr[NDADDR], (char *)ibuf, sizeof(ibuf)); 214 return(ibuf[i]); 215 } 216