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