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