Commit | Line | Data |
---|---|---|
211b1482 | 1 | static char *sccsid = "@(#)icheck.c 2.4 (Berkeley) %G%"; |
955f6ff8 | 2 | |
b42940ce KM |
3 | /* |
4 | * icheck | |
5 | */ | |
6 | #define NB 500 | |
b42940ce | 7 | #define MAXFN 500 |
c312eebd | 8 | #define MAXNINDIR (MAXBSIZE / sizeof (daddr_t)) |
b42940ce KM |
9 | |
10 | #ifndef STANDALONE | |
11 | #include <stdio.h> | |
12 | #endif | |
77bfdd01 KM |
13 | #ifndef SIMFS |
14 | #include <sys/param.h> | |
15 | #include <sys/inode.h> | |
16 | #include <sys/fs.h> | |
17 | #else | |
b42940ce KM |
18 | #include "../h/param.h" |
19 | #include "../h/inode.h" | |
b42940ce | 20 | #include "../h/fs.h" |
77bfdd01 | 21 | #endif |
b42940ce | 22 | |
b42940ce KM |
23 | union { |
24 | struct fs sb; | |
b6407c9d | 25 | char pad[MAXBSIZE]; |
b42940ce KM |
26 | } sbun; |
27 | #define sblock sbun.sb | |
28 | ||
29 | union { | |
30 | struct cg cg; | |
b6407c9d | 31 | char pad[MAXBSIZE]; |
b42940ce KM |
32 | } cgun; |
33 | #define cgrp cgun.cg | |
34 | ||
35 | struct dinode itab[MAXIPG]; | |
b42940ce | 36 | daddr_t blist[NB]; |
211b1482 | 37 | daddr_t fsblist[NB]; |
b42940ce KM |
38 | char *bmap; |
39 | ||
b42940ce | 40 | int mflg; |
19f19804 | 41 | int sflg; |
b42940ce KM |
42 | int dflg; |
43 | int fi; | |
44 | ino_t ino; | |
45 | int cginit; | |
46 | ||
47 | ino_t nrfile; | |
48 | ino_t ndfile; | |
49 | ino_t nbfile; | |
50 | ino_t ncfile; | |
ea47352d | 51 | ino_t nlfile; |
b42940ce KM |
52 | |
53 | daddr_t nblock; | |
54 | daddr_t nfrag; | |
b42940ce | 55 | daddr_t nindir; |
b42940ce KM |
56 | daddr_t niindir; |
57 | ||
58 | daddr_t nffree; | |
b42940ce KM |
59 | daddr_t nbfree; |
60 | ||
61 | daddr_t ndup; | |
62 | ||
63 | int nerror; | |
64 | ||
19f19804 | 65 | extern int inside[], around[]; |
b6407c9d | 66 | extern unsigned char *fragtbl[]; |
19f19804 | 67 | |
b42940ce | 68 | long atol(); |
b42940ce KM |
69 | #ifndef STANDALONE |
70 | char *malloc(); | |
19f19804 | 71 | char *calloc(); |
b42940ce KM |
72 | #endif |
73 | ||
74 | main(argc, argv) | |
19f19804 KM |
75 | int argc; |
76 | char *argv[]; | |
b42940ce KM |
77 | { |
78 | register i; | |
79 | long n; | |
80 | ||
81 | blist[0] = -1; | |
82 | #ifndef STANDALONE | |
83 | while (--argc) { | |
84 | argv++; | |
85 | if (**argv=='-') | |
86 | switch ((*argv)[1]) { | |
87 | case 'd': | |
88 | dflg++; | |
89 | continue; | |
90 | ||
91 | case 'm': | |
92 | mflg++; | |
93 | continue; | |
94 | ||
19f19804 KM |
95 | case 's': |
96 | sflg++; | |
97 | continue; | |
98 | ||
b42940ce KM |
99 | case 'b': |
100 | for(i=0; i<NB; i++) { | |
101 | n = atol(argv[1]); | |
102 | if(n == 0) | |
103 | break; | |
104 | blist[i] = n; | |
105 | argv++; | |
106 | argc--; | |
107 | } | |
108 | blist[i] = -1; | |
109 | continue; | |
110 | ||
111 | default: | |
112 | printf("Bad flag\n"); | |
113 | } | |
114 | check(*argv); | |
115 | } | |
116 | #else | |
117 | { | |
118 | static char fname[128]; | |
119 | ||
120 | printf("File: "); | |
121 | gets(fname); | |
122 | check(fname); | |
123 | } | |
124 | #endif | |
125 | return(nerror); | |
126 | } | |
127 | ||
128 | check(file) | |
19f19804 | 129 | char *file; |
b42940ce KM |
130 | { |
131 | register i, j, c; | |
132 | daddr_t d, cgd, cbase, b; | |
133 | long n; | |
211b1482 | 134 | char buf[BUFSIZ]; |
b42940ce | 135 | |
19f19804 | 136 | fi = open(file, sflg ? 2 : 0); |
b42940ce | 137 | if (fi < 0) { |
19f19804 | 138 | perror(file); |
b42940ce KM |
139 | nerror |= 04; |
140 | return; | |
141 | } | |
142 | printf("%s:\n", file); | |
143 | nrfile = 0; | |
144 | ndfile = 0; | |
145 | ncfile = 0; | |
146 | nbfile = 0; | |
ea47352d | 147 | nlfile = 0; |
b42940ce KM |
148 | |
149 | nblock = 0; | |
150 | nfrag = 0; | |
b42940ce | 151 | nindir = 0; |
b42940ce KM |
152 | niindir = 0; |
153 | ||
154 | ndup = 0; | |
155 | #ifndef STANDALONE | |
156 | sync(); | |
157 | #endif | |
b6407c9d KM |
158 | getsb(&sblock, file); |
159 | if (nerror) | |
b42940ce | 160 | return; |
211b1482 KM |
161 | for (n=0; blist[n] != -1; n++) |
162 | fsblist[n] = dbtofsb(&sblock, blist[n]); | |
b42940ce | 163 | ino = 0; |
19f19804 | 164 | n = roundup(howmany(sblock.fs_size, NBBY), sizeof(short)); |
b42940ce KM |
165 | #ifdef STANDALONE |
166 | bmap = NULL; | |
167 | #else | |
168 | bmap = malloc((unsigned)n); | |
169 | #endif | |
170 | if (bmap==NULL) { | |
171 | printf("Not enough core; duplicates unchecked\n"); | |
172 | dflg++; | |
19f19804 KM |
173 | if (sflg) { |
174 | printf("No Updates\n"); | |
175 | sflg = 0; | |
176 | } | |
b42940ce KM |
177 | } |
178 | ino = 0; | |
179 | cginit = 1; | |
bf541624 KM |
180 | if (!dflg) { |
181 | for (i = 0; i < (unsigned)n; i++) | |
b42940ce | 182 | bmap[i] = 0; |
bf541624 | 183 | for (c = 0; c < sblock.fs_ncg; c++) { |
6994bf5d | 184 | cgd = cgtod(&sblock, c); |
bf541624 KM |
185 | if (c == 0) |
186 | d = cgbase(&sblock, c); | |
187 | else | |
188 | d = cgsblock(&sblock, c); | |
211b1482 | 189 | sprintf(buf, "spare super block %d", c); |
bf541624 | 190 | for (; d < cgd; d += sblock.fs_frag) |
211b1482 | 191 | chk(d, buf, sblock.fs_bsize); |
6994bf5d | 192 | d = cgimin(&sblock, c); |
211b1482 | 193 | sprintf(buf, "cylinder group %d", c); |
b42940ce | 194 | while (cgd < d) { |
211b1482 | 195 | chk(cgd, buf, sblock.fs_bsize); |
b6407c9d | 196 | cgd += sblock.fs_frag; |
b42940ce | 197 | } |
6994bf5d | 198 | d = cgdmin(&sblock, c); |
211b1482 KM |
199 | i = INOPB(&sblock); |
200 | for (; cgd < d; cgd += sblock.fs_frag) { | |
201 | sprintf(buf, "inodes %d-%d", ino, ino + i); | |
202 | chk(cgd, buf, sblock.fs_bsize); | |
203 | ino += i; | |
204 | } | |
b42940ce | 205 | if (c == 0) { |
bf541624 KM |
206 | d += howmany(sblock.fs_cssize, sblock.fs_fsize); |
207 | for (; cgd < d; cgd++) | |
208 | chk(cgd, "csum", sblock.fs_fsize); | |
b42940ce KM |
209 | } |
210 | } | |
211 | } | |
211b1482 | 212 | ino = 0; |
b42940ce KM |
213 | cginit = 0; |
214 | for (c = 0; c < sblock.fs_ncg; c++) { | |
6994bf5d | 215 | bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, |
b42940ce KM |
216 | sblock.fs_ipg * sizeof (struct dinode)); |
217 | for (j=0; j < sblock.fs_ipg; j++) { | |
218 | pass1(&itab[j]); | |
219 | ino++; | |
220 | } | |
221 | } | |
222 | ino = 0; | |
223 | #ifndef STANDALONE | |
224 | sync(); | |
225 | #endif | |
19f19804 KM |
226 | if (sflg) { |
227 | makecg(); | |
228 | close(fi); | |
229 | #ifndef STANDALONE | |
230 | if (bmap) | |
231 | free(bmap); | |
232 | #endif | |
233 | return; | |
234 | } | |
b42940ce | 235 | nffree = 0; |
b42940ce KM |
236 | nbfree = 0; |
237 | for (c = 0; c < sblock.fs_ncg; c++) { | |
6994bf5d KM |
238 | cbase = cgbase(&sblock, c); |
239 | bread(fsbtodb(&sblock, cgtod(&sblock, c)), (char *)&cgrp, | |
b6407c9d | 240 | sblock.fs_cgsize); |
bf541624 KM |
241 | if (cgrp.cg_magic != CG_MAGIC) |
242 | printf("cg %d: bad magic number\n", c); | |
b6407c9d KM |
243 | for (b = 0; b < sblock.fs_fpg; b += sblock.fs_frag) { |
244 | if (isblock(&sblock, cgrp.cg_free, | |
245 | b / sblock.fs_frag)) { | |
b42940ce | 246 | nbfree++; |
211b1482 | 247 | chk(cbase+b, "free block", sblock.fs_bsize); |
b42940ce | 248 | } else { |
b6407c9d | 249 | for (d = 0; d < sblock.fs_frag; d++) |
b42940ce | 250 | if (isset(cgrp.cg_free, b+d)) { |
211b1482 | 251 | chk(cbase+b+d, "free frag", sblock.fs_fsize); |
b42940ce | 252 | nffree++; |
b42940ce KM |
253 | } |
254 | } | |
255 | } | |
256 | } | |
257 | close(fi); | |
258 | #ifndef STANDALONE | |
259 | if (bmap) | |
260 | free(bmap); | |
261 | #endif | |
262 | ||
ea47352d | 263 | i = nrfile + ndfile + ncfile + nbfile + nlfile; |
b42940ce | 264 | #ifndef STANDALONE |
ea47352d KM |
265 | printf("files %6u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", |
266 | i, nrfile, ndfile, nbfile, ncfile, nlfile); | |
b42940ce | 267 | #else |
ea47352d KM |
268 | printf("files %u (r=%u,d=%u,b=%u,c=%u,sl=%u)\n", |
269 | i, nrfile, ndfile, nbfile, ncfile, nlfile); | |
b42940ce | 270 | #endif |
b6407c9d | 271 | n = (nblock + nindir + niindir) * sblock.fs_frag + nfrag; |
b42940ce KM |
272 | #ifdef STANDALONE |
273 | printf("used %ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", | |
274 | n, nindir, niindir, nblock, nfrag); | |
b6407c9d | 275 | printf("free %ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, |
b42940ce KM |
276 | nbfree, nffree); |
277 | #else | |
278 | printf("used %7ld (i=%ld,ii=%ld,b=%ld,f=%ld)\n", | |
279 | n, nindir, niindir, nblock, nfrag); | |
b6407c9d | 280 | printf("free %7ld (b=%ld,f=%ld)\n", nffree + sblock.fs_frag * nbfree, |
b42940ce KM |
281 | nbfree, nffree); |
282 | #endif | |
283 | if(!dflg) { | |
284 | n = 0; | |
955f6ff8 | 285 | for (d = 0; d < sblock.fs_size; d++) |
b6407c9d | 286 | if(!duped(d, sblock.fs_fsize)) { |
b42940ce KM |
287 | if(mflg) |
288 | printf("%ld missing\n", d); | |
289 | n++; | |
290 | } | |
291 | printf("missing%5ld\n", n); | |
292 | } | |
293 | } | |
294 | ||
295 | pass1(ip) | |
955f6ff8 | 296 | register struct dinode *ip; |
b42940ce | 297 | { |
b6407c9d KM |
298 | daddr_t ind1[MAXNINDIR]; |
299 | daddr_t ind2[MAXNINDIR]; | |
07670f7d KM |
300 | daddr_t db, ib; |
301 | register int i, j, k, siz; | |
211b1482 KM |
302 | int lbn; |
303 | char buf[BUFSIZ]; | |
b42940ce KM |
304 | |
305 | i = ip->di_mode & IFMT; | |
0947395d | 306 | if(i == 0) |
b42940ce | 307 | return; |
b42940ce KM |
308 | switch (i) { |
309 | case IFCHR: | |
310 | ncfile++; | |
311 | return; | |
312 | case IFBLK: | |
313 | nbfile++; | |
314 | return; | |
315 | case IFDIR: | |
316 | ndfile++; | |
317 | break; | |
318 | case IFREG: | |
319 | nrfile++; | |
320 | break; | |
ea47352d KM |
321 | case IFLNK: |
322 | nlfile++; | |
323 | break; | |
b42940ce KM |
324 | default: |
325 | printf("bad mode %u\n", ino); | |
326 | return; | |
327 | } | |
955f6ff8 KM |
328 | for (i = 0; i < NDADDR; i++) { |
329 | db = ip->di_db[i]; | |
330 | if (db == 0) | |
b42940ce | 331 | continue; |
b6407c9d | 332 | siz = dblksize(&sblock, ip, i); |
211b1482 KM |
333 | sprintf(buf, "logical data block %d", i); |
334 | chk(db, buf, siz); | |
b6407c9d | 335 | if (siz == sblock.fs_bsize) |
07670f7d KM |
336 | nblock++; |
337 | else | |
b6407c9d | 338 | nfrag += howmany(siz, sblock.fs_fsize); |
b42940ce | 339 | } |
955f6ff8 KM |
340 | for(i = 0; i < NIADDR; i++) { |
341 | ib = ip->di_ib[i]; | |
211b1482 | 342 | if (ib == 0) |
955f6ff8 | 343 | continue; |
b6407c9d | 344 | if (chk(ib, "1st indirect", sblock.fs_bsize)) |
b42940ce | 345 | continue; |
b6407c9d | 346 | bread(fsbtodb(&sblock, ib), (char *)ind1, sblock.fs_bsize); |
b42940ce | 347 | nindir++; |
b6407c9d | 348 | for (j = 0; j < NINDIR(&sblock); j++) { |
955f6ff8 KM |
349 | ib = ind1[j]; |
350 | if (ib == 0) | |
b42940ce | 351 | continue; |
955f6ff8 | 352 | if (i == 0) { |
211b1482 KM |
353 | lbn = NDADDR + j; |
354 | siz = dblksize(&sblock, ip, lbn); | |
355 | sprintf(buf, "logical data block %d", lbn); | |
356 | chk(ib, buf, siz); | |
b6407c9d | 357 | if (siz == sblock.fs_bsize) |
07670f7d KM |
358 | nblock++; |
359 | else | |
b6407c9d | 360 | nfrag += howmany(siz, sblock.fs_fsize); |
b42940ce KM |
361 | continue; |
362 | } | |
b6407c9d | 363 | if (chk(ib, "2nd indirect", sblock.fs_bsize)) |
955f6ff8 | 364 | continue; |
b6407c9d KM |
365 | bread(fsbtodb(&sblock, ib), (char *)ind2, |
366 | sblock.fs_bsize); | |
b42940ce | 367 | niindir++; |
b6407c9d | 368 | for (k = 0; k < NINDIR(&sblock); k++) { |
955f6ff8 KM |
369 | ib = ind2[k]; |
370 | if (ib == 0) | |
b42940ce | 371 | continue; |
211b1482 KM |
372 | lbn = NDADDR + NINDIR(&sblock) * (i + j) + k; |
373 | siz = dblksize(&sblock, ip, lbn); | |
374 | sprintf(buf, "logical data block %d", lbn); | |
375 | chk(ib, buf, siz); | |
b6407c9d | 376 | if (siz == sblock.fs_bsize) |
07670f7d KM |
377 | nblock++; |
378 | else | |
b6407c9d | 379 | nfrag += howmany(siz, sblock.fs_fsize); |
b42940ce | 380 | } |
b42940ce KM |
381 | } |
382 | } | |
383 | } | |
384 | ||
07670f7d | 385 | chk(bno, s, size) |
955f6ff8 KM |
386 | daddr_t bno; |
387 | char *s; | |
07670f7d | 388 | int size; |
b42940ce KM |
389 | { |
390 | register n, cg; | |
3352e84a | 391 | int frags; |
b42940ce | 392 | |
6994bf5d | 393 | cg = dtog(&sblock, bno); |
bf541624 | 394 | if (cginit == 0 && bno >= sblock.fs_frag * sblock.fs_size) { |
b42940ce KM |
395 | printf("%ld bad; inode=%u, class=%s\n", bno, ino, s); |
396 | return(1); | |
397 | } | |
211b1482 KM |
398 | frags = numfrags(&sblock, size); |
399 | if (frags == sblock.fs_frag) { | |
07670f7d KM |
400 | if (duped(bno, size)) { |
401 | printf("%ld dup block; inode=%u, class=%s\n", | |
402 | bno, ino, s); | |
b6407c9d | 403 | ndup += sblock.fs_frag; |
07670f7d KM |
404 | } |
405 | } else { | |
3352e84a | 406 | for (n = 0; n < frags; n++) { |
b6407c9d | 407 | if (duped(bno + n, sblock.fs_fsize)) { |
07670f7d KM |
408 | printf("%ld dup frag; inode=%u, class=%s\n", |
409 | bno, ino, s); | |
410 | ndup++; | |
411 | } | |
412 | } | |
b42940ce KM |
413 | } |
414 | for (n=0; blist[n] != -1; n++) | |
211b1482 KM |
415 | if (fsblist[n] >= bno && fsblist[n] < bno + frags) |
416 | printf("%ld arg; frag %d of %d, inode=%u, class=%s\n", | |
417 | blist[n], fsblist[n] - bno, frags, ino, s); | |
b42940ce KM |
418 | return(0); |
419 | } | |
420 | ||
07670f7d | 421 | duped(bno, size) |
955f6ff8 | 422 | daddr_t bno; |
07670f7d | 423 | int size; |
b42940ce | 424 | { |
b42940ce KM |
425 | if(dflg) |
426 | return(0); | |
b6407c9d | 427 | if (size != sblock.fs_fsize && size != sblock.fs_bsize) |
07670f7d | 428 | printf("bad size %d to duped\n", size); |
b6407c9d | 429 | if (size == sblock.fs_fsize) { |
955f6ff8 KM |
430 | if (isset(bmap, bno)) |
431 | return(1); | |
432 | setbit(bmap, bno); | |
433 | return (0); | |
434 | } | |
b6407c9d | 435 | if (bno % sblock.fs_frag != 0) |
955f6ff8 | 436 | printf("bad bno %d to duped\n", bno); |
b6407c9d | 437 | if (isblock(&sblock, bmap, bno/sblock.fs_frag)) |
955f6ff8 | 438 | return (1); |
b6407c9d | 439 | setblock(&sblock, bmap, bno/sblock.fs_frag); |
b42940ce KM |
440 | return(0); |
441 | } | |
442 | ||
19f19804 KM |
443 | makecg() |
444 | { | |
445 | int c, blk; | |
bf541624 | 446 | daddr_t dbase, d, dlower, dupper, dmax; |
19f19804 KM |
447 | long i, j, s; |
448 | register struct csum *cs; | |
449 | register struct dinode *dp; | |
450 | ||
451 | sblock.fs_cstotal.cs_nbfree = 0; | |
452 | sblock.fs_cstotal.cs_nffree = 0; | |
453 | sblock.fs_cstotal.cs_nifree = 0; | |
454 | sblock.fs_cstotal.cs_ndir = 0; | |
19f19804 | 455 | for (c = 0; c < sblock.fs_ncg; c++) { |
6994bf5d | 456 | dbase = cgbase(&sblock, c); |
19f19804 | 457 | dmax = dbase + sblock.fs_fpg; |
8f99f49c KM |
458 | if (dmax > sblock.fs_size) { |
459 | for ( ; dmax >= sblock.fs_size; dmax--) | |
2e9860b5 | 460 | clrbit(cgrp.cg_free, dmax - dbase); |
8f99f49c KM |
461 | dmax++; |
462 | } | |
bf541624 KM |
463 | dlower = cgsblock(&sblock, c) - dbase; |
464 | dupper = cgdmin(&sblock, c) - dbase; | |
b6407c9d | 465 | cs = &sblock.fs_cs(&sblock, c); |
19f19804 KM |
466 | cgrp.cg_time = time(0); |
467 | cgrp.cg_magic = CG_MAGIC; | |
468 | cgrp.cg_cgx = c; | |
3969097b KM |
469 | if (c == sblock.fs_ncg - 1) |
470 | cgrp.cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; | |
471 | else | |
472 | cgrp.cg_ncyl = sblock.fs_cpg; | |
19f19804 KM |
473 | cgrp.cg_niblk = sblock.fs_ipg; |
474 | cgrp.cg_ndblk = dmax - dbase; | |
475 | cgrp.cg_cs.cs_ndir = 0; | |
476 | cgrp.cg_cs.cs_nffree = 0; | |
477 | cgrp.cg_cs.cs_nbfree = 0; | |
478 | cgrp.cg_cs.cs_nifree = 0; | |
bf541624 KM |
479 | cgrp.cg_rotor = 0; |
480 | cgrp.cg_frotor = 0; | |
19f19804 | 481 | cgrp.cg_irotor = 0; |
b6407c9d | 482 | for (i = 0; i < sblock.fs_frag; i++) |
19f19804 | 483 | cgrp.cg_frsum[i] = 0; |
6994bf5d | 484 | bread(fsbtodb(&sblock, cgimin(&sblock, c)), (char *)itab, |
19f19804 KM |
485 | sblock.fs_ipg * sizeof(struct dinode)); |
486 | for (i = 0; i < sblock.fs_ipg; i++) { | |
bf4c734c KM |
487 | cgrp.cg_cs.cs_nifree++; |
488 | clrbit(cgrp.cg_iused, i); | |
19f19804 | 489 | dp = &itab[i]; |
19f19804 KM |
490 | if ((dp->di_mode & IFMT) != 0) { |
491 | if ((dp->di_mode & IFMT) == IFDIR) | |
492 | cgrp.cg_cs.cs_ndir++; | |
bf4c734c | 493 | cgrp.cg_cs.cs_nifree--; |
19f19804 KM |
494 | setbit(cgrp.cg_iused, i); |
495 | continue; | |
496 | } | |
19f19804 KM |
497 | } |
498 | while (i < MAXIPG) { | |
499 | clrbit(cgrp.cg_iused, i); | |
500 | i++; | |
501 | } | |
8e5c1c7c KM |
502 | if (c == 0) |
503 | for (i = 0; i < ROOTINO; i++) { | |
504 | setbit(cgrp.cg_iused, i); | |
505 | cgrp.cg_cs.cs_nifree--; | |
506 | } | |
43f6367c KM |
507 | for (s = 0; s < MAXCPG; s++) { |
508 | cgrp.cg_btot[s] = 0; | |
19f19804 KM |
509 | for (i = 0; i < NRPOS; i++) |
510 | cgrp.cg_b[s][i] = 0; | |
43f6367c | 511 | } |
19f19804 | 512 | if (c == 0) { |
bf541624 | 513 | dupper += howmany(sblock.fs_cssize, sblock.fs_fsize); |
19f19804 | 514 | } |
bf541624 | 515 | for (d = dlower; d < dupper; d++) |
19f19804 | 516 | clrbit(cgrp.cg_free, d); |
bf541624 KM |
517 | for (d = 0; (d + sblock.fs_frag) <= dmax - dbase; |
518 | d += sblock.fs_frag) { | |
19f19804 | 519 | j = 0; |
b6407c9d | 520 | for (i = 0; i < sblock.fs_frag; i++) { |
bf541624 KM |
521 | if (!isset(bmap, dbase + d + i)) { |
522 | setbit(cgrp.cg_free, d + i); | |
19f19804 KM |
523 | j++; |
524 | } else | |
525 | clrbit(cgrp.cg_free, d+i); | |
526 | } | |
b6407c9d | 527 | if (j == sblock.fs_frag) { |
19f19804 | 528 | cgrp.cg_cs.cs_nbfree++; |
43f6367c | 529 | cgrp.cg_btot[cbtocylno(&sblock, d)]++; |
aca50d72 KM |
530 | cgrp.cg_b[cbtocylno(&sblock, d)] |
531 | [cbtorpos(&sblock, d)]++; | |
19f19804 KM |
532 | } else if (j > 0) { |
533 | cgrp.cg_cs.cs_nffree += j; | |
bf541624 | 534 | blk = blkmap(&sblock, cgrp.cg_free, d); |
b6407c9d | 535 | fragacct(&sblock, blk, cgrp.cg_frsum, 1); |
19f19804 KM |
536 | } |
537 | } | |
538 | for (j = d; d < dmax - dbase; d++) { | |
bf541624 | 539 | if (!isset(bmap, dbase + d)) { |
19f19804 KM |
540 | setbit(cgrp.cg_free, d); |
541 | cgrp.cg_cs.cs_nffree++; | |
542 | } else | |
543 | clrbit(cgrp.cg_free, d); | |
544 | } | |
3969097b KM |
545 | for (; d % sblock.fs_frag != 0; d++) |
546 | clrbit(cgrp.cg_free, d); | |
19f19804 | 547 | if (j != d) { |
bf541624 | 548 | blk = blkmap(&sblock, cgrp.cg_free, j); |
b6407c9d | 549 | fragacct(&sblock, blk, cgrp.cg_frsum, 1); |
19f19804 | 550 | } |
3969097b KM |
551 | for (d /= sblock.fs_frag; d < MAXBPG(&sblock); d ++) |
552 | clrblock(&sblock, cgrp.cg_free, d); | |
19f19804 KM |
553 | sblock.fs_cstotal.cs_nffree += cgrp.cg_cs.cs_nffree; |
554 | sblock.fs_cstotal.cs_nbfree += cgrp.cg_cs.cs_nbfree; | |
555 | sblock.fs_cstotal.cs_nifree += cgrp.cg_cs.cs_nifree; | |
556 | sblock.fs_cstotal.cs_ndir += cgrp.cg_cs.cs_ndir; | |
557 | *cs = cgrp.cg_cs; | |
6994bf5d | 558 | bwrite(fsbtodb(&sblock, cgtod(&sblock, c)), &cgrp, |
b6407c9d | 559 | sblock.fs_cgsize); |
19f19804 | 560 | } |
bf541624 KM |
561 | for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { |
562 | bwrite(fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag), | |
563 | (char *)sblock.fs_csp[j], | |
564 | sblock.fs_cssize - i < sblock.fs_bsize ? | |
565 | sblock.fs_cssize - i : sblock.fs_bsize); | |
19f19804 KM |
566 | } |
567 | sblock.fs_ronly = 0; | |
568 | sblock.fs_fmod = 0; | |
c312eebd | 569 | bwrite(SBLOCK, (char *)&sblock, SBSIZE); |
19f19804 KM |
570 | } |
571 | ||
572 | /* | |
573 | * update the frsum fields to reflect addition or deletion | |
574 | * of some frags | |
575 | */ | |
b6407c9d KM |
576 | fragacct(fs, fragmap, fraglist, cnt) |
577 | struct fs *fs; | |
19f19804 KM |
578 | int fragmap; |
579 | long fraglist[]; | |
580 | int cnt; | |
581 | { | |
582 | int inblk; | |
583 | register int field, subfield; | |
584 | register int siz, pos; | |
585 | ||
b6407c9d | 586 | inblk = (int)(fragtbl[fs->fs_frag][fragmap] << 1); |
19f19804 | 587 | fragmap <<= 1; |
b6407c9d | 588 | for (siz = 1; siz < fs->fs_frag; siz++) { |
156b8f82 | 589 | if ((inblk & (1 << (siz + (fs->fs_frag % NBBY)))) == 0) |
19f19804 KM |
590 | continue; |
591 | field = around[siz]; | |
592 | subfield = inside[siz]; | |
b6407c9d | 593 | for (pos = siz; pos <= fs->fs_frag; pos++) { |
19f19804 KM |
594 | if ((fragmap & field) == subfield) { |
595 | fraglist[siz] += cnt; | |
596 | pos += siz; | |
597 | field <<= siz; | |
598 | subfield <<= siz; | |
599 | } | |
600 | field <<= 1; | |
601 | subfield <<= 1; | |
602 | } | |
603 | } | |
604 | } | |
605 | ||
b6407c9d KM |
606 | getsb(fs, file) |
607 | register struct fs *fs; | |
608 | char *file; | |
609 | { | |
bf541624 | 610 | int i, j, size; |
b6407c9d | 611 | |
c312eebd | 612 | if (bread(SBLOCK, fs, SBSIZE)) { |
b6407c9d KM |
613 | printf("bad super block"); |
614 | perror(file); | |
615 | nerror |= 04; | |
616 | return; | |
617 | } | |
618 | if (fs->fs_magic != FS_MAGIC) { | |
619 | printf("%s: bad magic number\n", file); | |
620 | nerror |= 04; | |
621 | return; | |
622 | } | |
bf541624 KM |
623 | for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) { |
624 | size = sblock.fs_cssize - i < sblock.fs_bsize ? | |
625 | sblock.fs_cssize - i : sblock.fs_bsize; | |
626 | sblock.fs_csp[j] = (struct csum *)calloc(1, size); | |
627 | bread(fsbtodb(fs, fs->fs_csaddr + (j * fs->fs_frag)), | |
628 | (char *)fs->fs_csp[j], size); | |
b6407c9d KM |
629 | } |
630 | } | |
631 | ||
19f19804 KM |
632 | bwrite(blk, buf, size) |
633 | char *buf; | |
634 | daddr_t blk; | |
635 | register size; | |
636 | { | |
b6407c9d | 637 | if (lseek(fi, blk * DEV_BSIZE, 0) < 0) { |
19f19804 KM |
638 | perror("FS SEEK"); |
639 | return(1); | |
640 | } | |
641 | if (write(fi, buf, size) != size) { | |
642 | perror("FS WRITE"); | |
643 | return(1); | |
644 | } | |
b6407c9d | 645 | return (0); |
19f19804 KM |
646 | } |
647 | ||
b42940ce | 648 | bread(bno, buf, cnt) |
955f6ff8 KM |
649 | daddr_t bno; |
650 | char *buf; | |
b42940ce KM |
651 | { |
652 | register i; | |
653 | ||
b6407c9d | 654 | lseek(fi, bno * DEV_BSIZE, 0); |
b42940ce | 655 | if ((i = read(fi, buf, cnt)) != cnt) { |
19f19804 KM |
656 | if (sflg) { |
657 | printf("No Update\n"); | |
658 | sflg = 0; | |
659 | } | |
b6407c9d | 660 | for(i=0; i<sblock.fs_bsize; i++) |
b42940ce | 661 | buf[i] = 0; |
b6407c9d KM |
662 | return (1); |
663 | } | |
664 | return (0); | |
665 | } | |
666 | ||
667 | /* | |
3969097b | 668 | * check if a block is available |
b6407c9d | 669 | */ |
b6407c9d KM |
670 | isblock(fs, cp, h) |
671 | struct fs *fs; | |
672 | unsigned char *cp; | |
673 | int h; | |
674 | { | |
675 | unsigned char mask; | |
676 | ||
677 | switch (fs->fs_frag) { | |
678 | case 8: | |
679 | return (cp[h] == 0xff); | |
680 | case 4: | |
681 | mask = 0x0f << ((h & 0x1) << 2); | |
682 | return ((cp[h >> 1] & mask) == mask); | |
683 | case 2: | |
684 | mask = 0x03 << ((h & 0x3) << 1); | |
685 | return ((cp[h >> 2] & mask) == mask); | |
686 | case 1: | |
687 | mask = 0x01 << (h & 0x7); | |
688 | return ((cp[h >> 3] & mask) == mask); | |
689 | default: | |
3969097b KM |
690 | #ifdef STANDALONE |
691 | printf("isblock bad fs_frag %d\n", fs->fs_frag); | |
692 | #else | |
b6407c9d | 693 | fprintf(stderr, "isblock bad fs_frag %d\n", fs->fs_frag); |
3969097b KM |
694 | #endif |
695 | return; | |
696 | } | |
697 | } | |
698 | ||
699 | /* | |
700 | * take a block out of the map | |
701 | */ | |
702 | clrblock(fs, cp, h) | |
703 | struct fs *fs; | |
704 | unsigned char *cp; | |
705 | int h; | |
706 | { | |
707 | switch ((fs)->fs_frag) { | |
708 | case 8: | |
709 | cp[h] = 0; | |
710 | return; | |
711 | case 4: | |
712 | cp[h >> 1] &= ~(0x0f << ((h & 0x1) << 2)); | |
713 | return; | |
714 | case 2: | |
715 | cp[h >> 2] &= ~(0x03 << ((h & 0x3) << 1)); | |
716 | return; | |
717 | case 1: | |
718 | cp[h >> 3] &= ~(0x01 << (h & 0x7)); | |
719 | return; | |
720 | default: | |
721 | #ifdef STANDALONE | |
722 | printf("clrblock bad fs_frag %d\n", fs->fs_frag); | |
723 | #else | |
724 | fprintf(stderr, "clrblock bad fs_frag %d\n", fs->fs_frag); | |
725 | #endif | |
b6407c9d KM |
726 | return; |
727 | } | |
728 | } | |
729 | ||
3969097b KM |
730 | /* |
731 | * put a block into the map | |
732 | */ | |
b6407c9d KM |
733 | setblock(fs, cp, h) |
734 | struct fs *fs; | |
735 | unsigned char *cp; | |
736 | int h; | |
737 | { | |
738 | switch (fs->fs_frag) { | |
739 | case 8: | |
740 | cp[h] = 0xff; | |
741 | return; | |
742 | case 4: | |
743 | cp[h >> 1] |= (0x0f << ((h & 0x1) << 2)); | |
744 | return; | |
745 | case 2: | |
746 | cp[h >> 2] |= (0x03 << ((h & 0x3) << 1)); | |
747 | return; | |
748 | case 1: | |
749 | cp[h >> 3] |= (0x01 << (h & 0x7)); | |
750 | return; | |
751 | default: | |
3969097b KM |
752 | #ifdef STANDALONE |
753 | printf("setblock bad fs_frag %d\n", fs->fs_frag); | |
754 | #else | |
b6407c9d | 755 | fprintf(stderr, "setblock bad fs_frag %d\n", fs->fs_frag); |
3969097b | 756 | #endif |
b6407c9d | 757 | return; |
b42940ce KM |
758 | } |
759 | } | |
77bfdd01 KM |
760 | |
761 | /* tables.c 4.1 82/03/25 */ | |
762 | ||
763 | /* merged into kernel: tables.c 2.1 3/25/82 */ | |
764 | ||
765 | /* last monet version: partab.c 4.2 81/03/08 */ | |
766 | ||
767 | /* | |
768 | * bit patterns for identifying fragments in the block map | |
769 | * used as ((map & around) == inside) | |
770 | */ | |
771 | int around[9] = { | |
772 | 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff | |
773 | }; | |
774 | int inside[9] = { | |
775 | 0x0, 0x2, 0x6, 0xe, 0x1e, 0x3e, 0x7e, 0xfe, 0x1fe | |
776 | }; | |
777 | ||
778 | /* | |
779 | * given a block map bit pattern, the frag tables tell whether a | |
780 | * particular size fragment is available. | |
781 | * | |
782 | * used as: | |
783 | * if ((1 << (size - 1)) & fragtbl[fs->fs_frag][map] { | |
784 | * at least one fragment of the indicated size is available | |
785 | * } | |
786 | * | |
787 | * These tables are used by the scanc instruction on the VAX to | |
788 | * quickly find an appropriate fragment. | |
789 | */ | |
790 | ||
791 | unsigned char fragtbl124[256] = { | |
792 | 0x00, 0x16, 0x16, 0x2a, 0x16, 0x16, 0x26, 0x4e, | |
793 | 0x16, 0x16, 0x16, 0x3e, 0x2a, 0x3e, 0x4e, 0x8a, | |
794 | 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, | |
795 | 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, | |
796 | 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, | |
797 | 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, | |
798 | 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, | |
799 | 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, | |
800 | 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, | |
801 | 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, | |
802 | 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, | |
803 | 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, | |
804 | 0x26, 0x36, 0x36, 0x2e, 0x36, 0x36, 0x26, 0x6e, | |
805 | 0x36, 0x36, 0x36, 0x3e, 0x2e, 0x3e, 0x6e, 0xae, | |
806 | 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, | |
807 | 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, | |
808 | 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, | |
809 | 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, | |
810 | 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, | |
811 | 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, | |
812 | 0x16, 0x16, 0x16, 0x3e, 0x16, 0x16, 0x36, 0x5e, | |
813 | 0x16, 0x16, 0x16, 0x3e, 0x3e, 0x3e, 0x5e, 0x9e, | |
814 | 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, | |
815 | 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, | |
816 | 0x2a, 0x3e, 0x3e, 0x2a, 0x3e, 0x3e, 0x2e, 0x6e, | |
817 | 0x3e, 0x3e, 0x3e, 0x3e, 0x2a, 0x3e, 0x6e, 0xaa, | |
818 | 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, | |
819 | 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x7e, 0xbe, | |
820 | 0x4e, 0x5e, 0x5e, 0x6e, 0x5e, 0x5e, 0x6e, 0x4e, | |
821 | 0x5e, 0x5e, 0x5e, 0x7e, 0x6e, 0x7e, 0x4e, 0xce, | |
822 | 0x8a, 0x9e, 0x9e, 0xaa, 0x9e, 0x9e, 0xae, 0xce, | |
823 | 0x9e, 0x9e, 0x9e, 0xbe, 0xaa, 0xbe, 0xce, 0x8a, | |
824 | }; | |
825 | ||
826 | unsigned char fragtbl8[256] = { | |
827 | 0x00, 0x01, 0x01, 0x02, 0x01, 0x01, 0x02, 0x04, | |
828 | 0x01, 0x01, 0x01, 0x03, 0x02, 0x03, 0x04, 0x08, | |
829 | 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, | |
830 | 0x02, 0x03, 0x03, 0x02, 0x04, 0x05, 0x08, 0x10, | |
831 | 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, | |
832 | 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, | |
833 | 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, | |
834 | 0x04, 0x05, 0x05, 0x06, 0x08, 0x09, 0x10, 0x20, | |
835 | 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, | |
836 | 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, | |
837 | 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, | |
838 | 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, | |
839 | 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, | |
840 | 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, | |
841 | 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, | |
842 | 0x08, 0x09, 0x09, 0x0a, 0x10, 0x11, 0x20, 0x40, | |
843 | 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, | |
844 | 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, | |
845 | 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, | |
846 | 0x03, 0x03, 0x03, 0x03, 0x05, 0x05, 0x09, 0x11, | |
847 | 0x01, 0x01, 0x01, 0x03, 0x01, 0x01, 0x03, 0x05, | |
848 | 0x01, 0x01, 0x01, 0x03, 0x03, 0x03, 0x05, 0x09, | |
849 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, | |
850 | 0x05, 0x05, 0x05, 0x07, 0x09, 0x09, 0x11, 0x21, | |
851 | 0x02, 0x03, 0x03, 0x02, 0x03, 0x03, 0x02, 0x06, | |
852 | 0x03, 0x03, 0x03, 0x03, 0x02, 0x03, 0x06, 0x0a, | |
853 | 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x07, | |
854 | 0x02, 0x03, 0x03, 0x02, 0x06, 0x07, 0x0a, 0x12, | |
855 | 0x04, 0x05, 0x05, 0x06, 0x05, 0x05, 0x06, 0x04, | |
856 | 0x05, 0x05, 0x05, 0x07, 0x06, 0x07, 0x04, 0x0c, | |
857 | 0x08, 0x09, 0x09, 0x0a, 0x09, 0x09, 0x0a, 0x0c, | |
858 | 0x10, 0x11, 0x11, 0x12, 0x20, 0x21, 0x40, 0x80, | |
859 | }; | |
860 | ||
861 | /* | |
862 | * the actual fragtbl array | |
863 | */ | |
864 | unsigned char *fragtbl[MAXFRAG + 1] = { | |
865 | 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8, | |
866 | }; |