1 static char *sccsid = "@(#)icheck.c 1.8 (Berkeley) 11/07/81"; 2 3 /* 4 * icheck 5 */ 6 #define NB 500 7 #define BITS 8 8 #define MAXFN 500 9 10 #ifndef STANDALONE 11 #include <stdio.h> 12 #endif 13 #include "../h/param.h" 14 #include "../h/inode.h" 15 #include "../h/fs.h" 16 17 union { 18 struct fs sb; 19 char pad[BSIZE]; 20 } sbun; 21 #define sblock sbun.sb 22 23 union { 24 struct cg cg; 25 char pad[BSIZE]; 26 } cgun; 27 #define cgrp cgun.cg 28 29 struct dinode itab[MAXIPG]; 30 daddr_t blist[NB]; 31 char *bmap; 32 33 int mflg; 34 int dflg; 35 int fi; 36 ino_t ino; 37 int cginit; 38 39 ino_t nrfile; 40 ino_t ndfile; 41 ino_t nbfile; 42 ino_t ncfile; 43 ino_t nmcfile; 44 45 daddr_t nblock; 46 daddr_t nfrag; 47 daddr_t nindir; 48 daddr_t niindir; 49 50 daddr_t nffree; 51 daddr_t nbfree; 52 53 daddr_t ndup; 54 55 int nerror; 56 57 long atol(); 58 daddr_t alloc(); 59 #ifndef STANDALONE 60 char *malloc(); 61 #endif 62 63 main(argc, argv) 64 char *argv[]; 65 { 66 register i; 67 long n; 68 69 blist[0] = -1; 70 #ifndef STANDALONE 71 while (--argc) { 72 argv++; 73 if (**argv=='-') 74 switch ((*argv)[1]) { 75 case 'd': 76 dflg++; 77 continue; 78 79 case 'm': 80 mflg++; 81 continue; 82 83 case 'b': 84 for(i=0; i<NB; i++) { 85 n = atol(argv[1]); 86 if(n == 0) 87 break; 88 blist[i] = n; 89 argv++; 90 argc--; 91 } 92 blist[i] = -1; 93 continue; 94 95 default: 96 printf("Bad flag\n"); 97 } 98 check(*argv); 99 } 100 #else 101 { 102 static char fname[128]; 103 104 printf("File: "); 105 gets(fname); 106 check(fname); 107 } 108 #endif 109 return(nerror); 110 } 111 112 check(file) 113 char *file; 114 { 115 register i, j, c; 116 daddr_t d, cgd, cbase, b; 117 long n; 118 119 fi = open(file, 0); 120 if (fi < 0) { 121 printf("cannot open %s\n", file); 122 nerror |= 04; 123 return; 124 } 125 printf("%s:\n", file); 126 nrfile = 0; 127 ndfile = 0; 128 ncfile = 0; 129 nbfile = 0; 130 nmcfile = 0; 131 132 nblock = 0; 133 nfrag = 0; 134 nindir = 0; 135 niindir = 0; 136 137 ndup = 0; 138 #ifndef STANDALONE 139 sync(); 140 #endif 141 bread(SBLOCK, (char *)&sblock, BSIZE); 142 if (sblock.fs_magic != FS_MAGIC) { 143 printf("%s: bad magic number\n", file); 144 nerror |= 04; 145 return; 146 } 147 for (n = 0; n < howmany(cssize(&sblock), BSIZE); n++) { 148 sblock.fs_csp[n] = (struct csum *)calloc(1, BSIZE); 149 bread(csaddr(&sblock) + (n * FRAG), 150 (char *)sblock.fs_csp[n], BSIZE); 151 } 152 ino = 0; 153 n = (sblock.fs_size*FRAG + BITS-1) / BITS; 154 #ifdef STANDALONE 155 bmap = NULL; 156 #else 157 bmap = malloc((unsigned)n); 158 #endif 159 if (bmap==NULL) { 160 printf("Not enough core; duplicates unchecked\n"); 161 dflg++; 162 } 163 ino = 0; 164 cginit = 1; 165 if(!dflg) { 166 for (i=0; i<(unsigned)n; i++) 167 bmap[i] = 0; 168 for (c=0; c < sblock.fs_ncg; c++) { 169 cgd = cgtod(c, &sblock); 170 for (d = cgbase(c, &sblock); d < cgd; d += FRAG) 171 chk(d, "badcg", BSIZE); 172 d = cgimin(c, &sblock); 173 while (cgd < d) { 174 chk(cgd, "cg", BSIZE); 175 cgd += FRAG; 176 } 177 d = cgdmin(c, &sblock); 178 for (; cgd < d; cgd += FRAG) 179 chk(cgd, "inode", BSIZE); 180 if (c == 0) { 181 d += howmany(cssize(&sblock), FSIZE); 182 for (; cgd < d; cgd += FRAG) 183 chk(cgd, "csum", BSIZE); 184 } 185 } 186 } 187 cginit = 0; 188 for (c = 0; c < sblock.fs_ncg; c++) { 189 bread(cgimin(c,&sblock), (char *)itab, 190 sblock.fs_ipg * sizeof (struct dinode)); 191 for (j=0; j < sblock.fs_ipg; j++) { 192 pass1(&itab[j]); 193 ino++; 194 } 195 } 196 ino = 0; 197 #ifndef STANDALONE 198 sync(); 199 #endif 200 bread(SBLOCK, (char *)&sblock, sizeof(sblock)); 201 nffree = 0; 202 nbfree = 0; 203 for (c = 0; c < sblock.fs_ncg; c++) { 204 cbase = cgbase(c,&sblock); 205 bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize); 206 for (b = 0; b < sblock.fs_fpg; b += FRAG) { 207 if (isblock(cgrp.cg_free, b / FRAG)) { 208 nbfree++; 209 chk(cbase+b, "block", BSIZE); 210 } else { 211 for (d = 0; d < FRAG; d++) 212 if (isset(cgrp.cg_free, b+d)) { 213 chk(cbase+b+d, "frag", FSIZE); 214 nffree++; 215 } 216 } 217 } 218 } 219 close(fi); 220 #ifndef STANDALONE 221 if (bmap) 222 free(bmap); 223 #endif 224 225 i = nrfile + ndfile + ncfile + nbfile + nmcfile; 226 #ifndef STANDALONE 227 printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 228 i, nrfile, ndfile, nbfile, ncfile, nmcfile); 229 #else 230 printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 231 i, nrfile, ndfile, nbfile, ncfile, nmcfile); 232 #endif 233 n = (nblock + nindir + niindir) * FRAG + nfrag; 234 #ifdef STANDALONE 235 printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 236 n, nindir, niindir, nblock, nfrag); 237 printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 238 nbfree, nffree); 239 #else 240 printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 241 n, nindir, niindir, nblock, nfrag); 242 printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 243 nbfree, nffree); 244 #endif 245 if(!dflg) { 246 n = 0; 247 for (d = 0; d < sblock.fs_size; d++) 248 if(!duped(d, FSIZE)) { 249 if(mflg) 250 printf("%ld missing\n", d); 251 n++; 252 } 253 printf("missing%5ld\n", n); 254 } 255 } 256 257 pass1(ip) 258 register struct dinode *ip; 259 { 260 daddr_t ind1[NINDIR]; 261 daddr_t ind2[NINDIR]; 262 daddr_t db, ib; 263 register int i, j, k, siz; 264 265 i = ip->di_mode & IFMT; 266 if(i == 0) 267 return; 268 switch (i) { 269 case IFCHR: 270 ncfile++; 271 return; 272 case IFBLK: 273 nbfile++; 274 return; 275 case IFDIR: 276 ndfile++; 277 break; 278 case IFREG: 279 nrfile++; 280 break; 281 default: 282 printf("bad mode %u\n", ino); 283 return; 284 } 285 for (i = 0; i < NDADDR; i++) { 286 db = ip->di_db[i]; 287 if (db == 0) 288 continue; 289 siz = dblksize(ip, i); 290 chk(db, "data (block)", siz); 291 if (siz == BSIZE) 292 nblock++; 293 else 294 nfrag += howmany(siz, FSIZE); 295 } 296 for(i = 0; i < NIADDR; i++) { 297 ib = ip->di_ib[i]; 298 if(ib == 0) 299 continue; 300 if (chk(ib, "1st indirect", BSIZE)) 301 continue; 302 bread(ib, (char *)ind1, BSIZE); 303 nindir++; 304 for (j = 0; j < NINDIR; j++) { 305 ib = ind1[j]; 306 if (ib == 0) 307 continue; 308 if (i == 0) { 309 siz = dblksize(ip, NDADDR + j); 310 chk(ib, "data (large)", siz); 311 if (siz == BSIZE) 312 nblock++; 313 else 314 nfrag += howmany(siz, FSIZE); 315 continue; 316 } 317 if (chk(ib, "2nd indirect", BSIZE)) 318 continue; 319 bread(ib, (char *)ind2, BSIZE); 320 niindir++; 321 for (k = 0; k < NINDIR; k++) { 322 ib = ind2[k]; 323 if (ib == 0) 324 continue; 325 siz = dblksize(ip, 326 NDADDR + NINDIR * (i + j) + k); 327 chk(ib, "data (huge)", siz); 328 if (siz == BSIZE) 329 nblock++; 330 else 331 nfrag += howmany(siz, FSIZE); 332 } 333 } 334 } 335 } 336 337 chk(bno, s, size) 338 daddr_t bno; 339 char *s; 340 int size; 341 { 342 register n, cg; 343 344 cg = dtog(bno, &sblock); 345 if (cginit==0 && 346 bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) { 347 printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 348 return(1); 349 } 350 if (size == BSIZE) { 351 if (duped(bno, size)) { 352 printf("%ld dup block; inode=%u, class=%s\n", 353 bno, ino, s); 354 ndup += FRAG; 355 } 356 } else { 357 for (n = 0; n < size / FSIZE; n++) { 358 if (duped(bno + n, FSIZE)) { 359 printf("%ld dup frag; inode=%u, class=%s\n", 360 bno, ino, s); 361 ndup++; 362 } 363 } 364 } 365 for (n=0; blist[n] != -1; n++) 366 if (bno == blist[n]) 367 printf("%ld arg; inode=%u, class=%s\n", bno, ino, s); 368 return(0); 369 } 370 371 duped(bno, size) 372 daddr_t bno; 373 int size; 374 { 375 if(dflg) 376 return(0); 377 if (size != FSIZE && size != BSIZE) 378 printf("bad size %d to duped\n", size); 379 if (size == FSIZE) { 380 if (isset(bmap, bno)) 381 return(1); 382 setbit(bmap, bno); 383 return (0); 384 } 385 if (bno % FRAG != 0) 386 printf("bad bno %d to duped\n", bno); 387 if (isblock(bmap, bno/FRAG)) 388 return (1); 389 setblock(bmap, bno/FRAG); 390 return(0); 391 } 392 393 bread(bno, buf, cnt) 394 daddr_t bno; 395 char *buf; 396 { 397 register i; 398 399 lseek(fi, bno*FSIZE, 0); 400 if ((i = read(fi, buf, cnt)) != cnt) { 401 for(i=0; i<BSIZE; i++) 402 buf[i] = 0; 403 } 404 } 405