1 static char *sccsid = "@(#)icheck.c 1.5 (Berkeley) 09/22/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 sflg; 34 int mflg; 35 int dflg; 36 int fi; 37 ino_t ino; 38 int cginit; 39 40 ino_t nrfile; 41 ino_t ndfile; 42 ino_t nbfile; 43 ino_t ncfile; 44 ino_t nmcfile; 45 46 daddr_t nblock; 47 daddr_t nfrag; 48 daddr_t nindir; 49 daddr_t niindir; 50 51 daddr_t nffree; 52 daddr_t nbfree; 53 54 daddr_t ndup; 55 56 int nerror; 57 58 long atol(); 59 daddr_t alloc(); 60 #ifndef STANDALONE 61 char *malloc(); 62 #endif 63 64 main(argc, argv) 65 char *argv[]; 66 { 67 register i; 68 long n; 69 70 blist[0] = -1; 71 #ifndef STANDALONE 72 while (--argc) { 73 argv++; 74 if (**argv=='-') 75 switch ((*argv)[1]) { 76 case 'd': 77 dflg++; 78 continue; 79 80 case 'm': 81 mflg++; 82 continue; 83 84 case 's': 85 sflg++; 86 continue; 87 88 case 'b': 89 for(i=0; i<NB; i++) { 90 n = atol(argv[1]); 91 if(n == 0) 92 break; 93 blist[i] = n; 94 argv++; 95 argc--; 96 } 97 blist[i] = -1; 98 continue; 99 100 default: 101 printf("Bad flag\n"); 102 } 103 check(*argv); 104 } 105 #else 106 { 107 static char fname[128]; 108 109 printf("File: "); 110 gets(fname); 111 check(fname); 112 } 113 #endif 114 return(nerror); 115 } 116 117 check(file) 118 char *file; 119 { 120 register i, j, c; 121 daddr_t d, cgd, cbase, b; 122 long n; 123 124 fi = open(file, sflg?2:0); 125 if (fi < 0) { 126 printf("cannot open %s\n", file); 127 nerror |= 04; 128 return; 129 } 130 printf("%s:\n", file); 131 nrfile = 0; 132 ndfile = 0; 133 ncfile = 0; 134 nbfile = 0; 135 nmcfile = 0; 136 137 nblock = 0; 138 nfrag = 0; 139 nindir = 0; 140 niindir = 0; 141 142 ndup = 0; 143 #ifndef STANDALONE 144 sync(); 145 #endif 146 bread(SBLOCK, (char *)&sblock, BSIZE); 147 if (sblock.fs_magic != FS_MAGIC) { 148 printf("%s: bad magic number\n", file); 149 nerror |= 04; 150 return; 151 } 152 sblock.fs_cs = 153 (struct csum *)calloc(howmany(cssize(&sblock), BSIZE), BSIZE); 154 lseek(fi, csaddr(&sblock)*FSIZE, 0); 155 read(fi, (char *)sblock.fs_cs, cssize(&sblock)); 156 ino = 0; 157 n = (sblock.fs_size*FRAG + BITS-1) / BITS; 158 #ifdef STANDALONE 159 bmap = NULL; 160 #else 161 bmap = malloc((unsigned)n); 162 #endif 163 if (bmap==NULL) { 164 printf("Not enough core; duplicates unchecked\n"); 165 dflg++; 166 sflg = 0; 167 } 168 ino = 0; 169 cginit = 1; 170 if(!dflg) { 171 for (i=0; i<(unsigned)n; i++) 172 bmap[i] = 0; 173 for (c=0; c < sblock.fs_ncg; c++) { 174 cgd = cgtod(c, &sblock); 175 for (d = cgbase(c, &sblock); d < cgd; d += FRAG) 176 chk(d, "badcg", BSIZE); 177 d = cgimin(c, &sblock); 178 while (cgd < d) { 179 chk(cgd, "cg", BSIZE); 180 cgd += FRAG; 181 } 182 d = cgdmin(c, &sblock); 183 for (; cgd < d; cgd += FRAG) 184 chk(cgd, "inode", BSIZE); 185 if (c == 0) { 186 d += howmany(cssize(&sblock), FSIZE); 187 for (; cgd < d; cgd += FRAG) 188 chk(cgd, "csum", BSIZE); 189 } 190 } 191 } 192 cginit = 0; 193 for (c = 0; c < sblock.fs_ncg; c++) { 194 bread(cgimin(c,&sblock), (char *)itab, 195 sblock.fs_ipg * sizeof (struct dinode)); 196 for (j=0; j < sblock.fs_ipg; j++) { 197 pass1(&itab[j]); 198 ino++; 199 } 200 } 201 ino = 0; 202 #ifndef STANDALONE 203 sync(); 204 #endif 205 bread(SBLOCK, (char *)&sblock, sizeof(sblock)); 206 if (sflg) { 207 makecg(); 208 close(fi); 209 #ifndef STANDALONE 210 if (bmap) 211 free(bmap); 212 #endif 213 return; 214 } 215 nffree = 0; 216 nbfree = 0; 217 for (c = 0; c < sblock.fs_ncg; c++) { 218 cbase = cgbase(c,&sblock); 219 bread(cgtod(c,&sblock), (char *)&cgrp, sblock.fs_cgsize); 220 for (b = 0; b < sblock.fs_fpg; b += FRAG) { 221 if (isblock(cgrp.cg_free, b / FRAG)) { 222 nbfree++; 223 chk(cbase+b, "block", BSIZE); 224 } else { 225 for (d = 0; d < FRAG; d++) 226 if (isset(cgrp.cg_free, b+d)) { 227 chk(cbase+b+d, "frag", FSIZE); 228 nffree++; 229 } 230 } 231 } 232 } 233 close(fi); 234 #ifndef STANDALONE 235 if (bmap) 236 free(bmap); 237 #endif 238 239 i = nrfile + ndfile + ncfile + nbfile + nmcfile; 240 #ifndef STANDALONE 241 printf("files %6u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 242 i, nrfile, ndfile, nbfile, ncfile, nmcfile); 243 #else 244 printf("files %u (r=%u,d=%u,b=%u,c=%u,mc=%u)\n", 245 i, nrfile, ndfile, nbfile, ncfile, nmcfile); 246 #endif 247 n = (nblock + nindir + niindir) * FRAG + nfrag; 248 #ifdef STANDALONE 249 printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 250 n, nindir, niindir, nblock, nfrag); 251 printf("free %ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 252 nbfree, nffree); 253 #else 254 printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", 255 n, nindir, niindir, nblock, nfrag); 256 printf("free %7ld (b=%ld,f=%ld)\n", nffree + FRAG * nbfree, 257 nbfree, nffree); 258 #endif 259 if(!dflg) { 260 n = 0; 261 for (d = 0; d < sblock.fs_size; d++) 262 if(!duped(d, FSIZE)) { 263 if(mflg) 264 printf("%ld missing\n", d); 265 n++; 266 } 267 printf("missing%5ld\n", n); 268 } 269 } 270 271 pass1(ip) 272 register struct dinode *ip; 273 { 274 daddr_t ind1[NINDIR]; 275 daddr_t ind2[NINDIR]; 276 daddr_t db, ib; 277 register int i, j, k, siz; 278 279 i = ip->di_mode & IFMT; 280 if(i == 0) { 281 sblock.fs_nifree++; 282 return; 283 } 284 switch (i) { 285 case IFCHR: 286 ncfile++; 287 return; 288 case IFBLK: 289 nbfile++; 290 return; 291 case IFDIR: 292 ndfile++; 293 break; 294 case IFREG: 295 nrfile++; 296 break; 297 default: 298 printf("bad mode %u\n", ino); 299 return; 300 } 301 for (i = 0; i < NDADDR; i++) { 302 db = ip->di_db[i]; 303 if (db == 0) 304 continue; 305 siz = dblksize(ip, i); 306 chk(db, "data (block)", siz); 307 if (siz == BSIZE) 308 nblock++; 309 else 310 nfrag += howmany(siz, FSIZE); 311 } 312 for(i = 0; i < NIADDR; i++) { 313 ib = ip->di_ib[i]; 314 if(ib == 0) 315 continue; 316 if (chk(ib, "1st indirect", BSIZE)) 317 continue; 318 bread(ib, (char *)ind1, BSIZE); 319 nindir++; 320 for (j = 0; j < NINDIR; j++) { 321 ib = ind1[j]; 322 if (ib == 0) 323 continue; 324 if (i == 0) { 325 siz = dblksize(ip, NDADDR + j); 326 chk(ib, "data (large)", siz); 327 if (siz == BSIZE) 328 nblock++; 329 else 330 nfrag += howmany(siz, FSIZE); 331 continue; 332 } 333 if (chk(ib, "2nd indirect", BSIZE)) 334 continue; 335 bread(ib, (char *)ind2, BSIZE); 336 niindir++; 337 for (k = 0; k < NINDIR; k++) { 338 ib = ind2[k]; 339 if (ib == 0) 340 continue; 341 siz = dblksize(ip, 342 NDADDR + NINDIR * (i + j) + k); 343 chk(ib, "data (huge)", siz); 344 if (siz == BSIZE) 345 nblock++; 346 else 347 nfrag += howmany(siz, FSIZE); 348 } 349 } 350 } 351 } 352 353 chk(bno, s, size) 354 daddr_t bno; 355 char *s; 356 int size; 357 { 358 register n, cg; 359 360 cg = dtog(bno, &sblock); 361 if (cginit==0 && 362 bno<cgdmin(cg,&sblock) || bno >= FRAG * sblock.fs_size) { 363 printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); 364 return(1); 365 } 366 if (size == BSIZE) { 367 if (duped(bno, size)) { 368 printf("%ld dup block; inode=%u, class=%s\n", 369 bno, ino, s); 370 ndup += FRAG; 371 } 372 } else { 373 for (n = 0; n < size / FSIZE; n++) { 374 if (duped(bno + n, FSIZE)) { 375 printf("%ld dup frag; inode=%u, class=%s\n", 376 bno, ino, s); 377 ndup++; 378 } 379 } 380 } 381 for (n=0; blist[n] != -1; n++) 382 if (bno == blist[n]) 383 printf("%ld arg; inode=%u, class=%s\n", bno, ino, s); 384 return(0); 385 } 386 387 duped(bno, size) 388 daddr_t bno; 389 int size; 390 { 391 if(dflg) 392 return(0); 393 if (size != FSIZE && size != BSIZE) 394 printf("bad size %d to duped\n", size); 395 if (size == FSIZE) { 396 if (isset(bmap, bno)) 397 return(1); 398 setbit(bmap, bno); 399 return (0); 400 } 401 if (bno % FRAG != 0) 402 printf("bad bno %d to duped\n", bno); 403 if (isblock(bmap, bno/FRAG)) 404 return (1); 405 setblock(bmap, bno/FRAG); 406 return(0); 407 } 408 409 bread(bno, buf, cnt) 410 daddr_t bno; 411 char *buf; 412 { 413 register i; 414 415 lseek(fi, bno*FSIZE, 0); 416 if ((i = read(fi, buf, cnt)) != cnt) { 417 if (sflg) { 418 printf("No update\n"); 419 sflg = 0; 420 } 421 for(i=0; i<BSIZE; i++) 422 buf[i] = 0; 423 } 424 } 425 426 bwrite(bno, buf, cnt) 427 daddr_t bno; 428 char *buf; 429 { 430 lseek(fi, bno*FSIZE, 0); 431 if (write(fi, buf, cnt) != cnt) 432 printf("write error %d\n", tell(fi)/BSIZE); 433 } 434 435 makecg() 436 { 437 int c; 438 daddr_t dbase, d, dmin, dmax; 439 long i, j, s; 440 register struct csum *cs; 441 442 sblock.fs_nbfree = 0; 443 sblock.fs_nffree = 0; 444 for (c = 0; c < sblock.fs_ncg; c++) { 445 bread(cgimin(c,&sblock), (char *)itab, 446 sblock.fs_ipg * sizeof (struct dinode)); 447 dbase = cgbase(c, &sblock); 448 dmax = dbase + sblock.fs_fpg; 449 if (dmax > sblock.fs_size) 450 dmax = sblock.fs_size; 451 cs = &sblock.fs_cs[c]; 452 cgrp.cg_time = time((long)0); 453 cgrp.cg_magic = CG_MAGIC; 454 cgrp.cg_cgx = c; 455 cgrp.cg_ncyl = sblock.fs_cpg; 456 cgrp.cg_niblk = sblock.fs_ipg; 457 cgrp.cg_ndblk = dmax - dbase; 458 cgrp.cg_ndir = 0; 459 cgrp.cg_nffree = 0; 460 cgrp.cg_nbfree = 0; 461 cgrp.cg_nifree = 0; 462 for (i = 0; i < sblock.fs_ipg; i++) 463 switch (itab[i].di_mode&IFMT) { 464 465 case 0: 466 cgrp.cg_nifree++; 467 clrbit(cgrp.cg_iused, i); 468 continue; 469 470 case IFDIR: 471 cgrp.cg_ndir++; 472 /* fall into ... */ 473 474 default: 475 setbit(cgrp.cg_iused, i); 476 continue; 477 } 478 while (i < MAXIPG) { 479 clrbit(cgrp.cg_iused, i); 480 i++; 481 } 482 for (s = 0; s < MAXCPG; s++) 483 for (i = 0; i < NRPOS; i++) 484 cgrp.cg_b[s][i] = 0; 485 dmin = cgdmin(c, &sblock) - dbase; 486 if (c == 0) 487 dmin += howmany(cssize(&sblock), BSIZE) * FRAG; 488 for (d = 0; d < dmin; d++) 489 clrbit(cgrp.cg_free, d); 490 #define getbmap(i) isset(bmap, i) 491 for (; (d + FRAG) <= dmax - dbase; d += FRAG) { 492 j = 0; 493 for (i = 0; i < FRAG; i++) { 494 if (!getbmap(dbase+d+i)) { 495 setbit(cgrp.cg_free, d+i); 496 j++; 497 } else 498 clrbit(cgrp.cg_free, d+i); 499 } 500 if (j == FRAG) { 501 cgrp.cg_nbfree++; 502 s = d * NSPF; 503 cgrp.cg_b[s/sblock.fs_spc] 504 [s%sblock.fs_nsect*NRPOS/sblock.fs_nsect]++; 505 } else 506 cgrp.cg_nffree += j; 507 } 508 for (; d < dmax - dbase; d++) { 509 if (!getbmap(dbase+d)) { 510 setbit(cgrp.cg_free, d); 511 cgrp.cg_nffree++; 512 } else 513 clrbit(cgrp.cg_free, d); 514 } 515 for (; d < MAXBPG; d++) 516 clrbit(cgrp.cg_free, d); 517 sblock.fs_nffree += cgrp.cg_nffree; 518 sblock.fs_nbfree += cgrp.cg_nbfree; 519 cs->cs_ndir = cgrp.cg_ndir; 520 cs->cs_nifree = cgrp.cg_nifree; 521 cs->cs_nbfree = cgrp.cg_nbfree; 522 bwrite(cgtod(c, &sblock), (char *)&cgrp, sblock.fs_cgsize); 523 } 524 sblock.fs_ronly = 0; 525 sblock.fs_fmod = 0; 526 bwrite(SBLOCK, (char *)&sblock, sizeof (sblock)); 527 lseek(fi, csaddr(&sblock) * FSIZE, 0); 528 if (write(fi,(char *)sblock.fs_cs,cssize(&sblock)) != cssize(&sblock)) 529 printf("write error %d\n", tell(fi)/BSIZE); 530 } 531