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