allow users to specify optimization preference
[unix-history] / usr / src / sbin / icheck / icheck.c
CommitLineData
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
8static 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
32union {
33 struct fs sb;
b6407c9d 34 char pad[MAXBSIZE];
b42940ce
KM
35} sbun;
36#define sblock sbun.sb
37
38union {
39 struct cg cg;
b6407c9d 40 char pad[MAXBSIZE];
b42940ce
KM
41} cgun;
42#define cgrp cgun.cg
43
44struct dinode itab[MAXIPG];
b42940ce 45daddr_t blist[NB];
211b1482 46daddr_t fsblist[NB];
b42940ce
KM
47char *bmap;
48
b42940ce 49int mflg;
19f19804 50int sflg;
b42940ce
KM
51int dflg;
52int fi;
53ino_t ino;
54int cginit;
55
56ino_t nrfile;
57ino_t ndfile;
58ino_t nbfile;
59ino_t ncfile;
ea47352d 60ino_t nlfile;
b42940ce
KM
61
62daddr_t nblock;
63daddr_t nfrag;
b42940ce 64daddr_t nindir;
b42940ce
KM
65daddr_t niindir;
66
67daddr_t nffree;
b42940ce
KM
68daddr_t nbfree;
69
70daddr_t ndup;
71
72int nerror;
73
19f19804 74extern int inside[], around[];
b6407c9d 75extern unsigned char *fragtbl[];
19f19804 76
b42940ce 77long atol();
b42940ce
KM
78#ifndef STANDALONE
79char *malloc();
19f19804 80char *calloc();
b42940ce
KM
81#endif
82
83main(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
137check(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
304pass1(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 394chk(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 430duped(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
452makecg()
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
585fragacct(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
615getsb(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
641bwrite(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 657bread(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
679isblock(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 */
711clrblock(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
742setblock(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 */
780int around[9] = {
781 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
782};
783int 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
800unsigned 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
835unsigned 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 */
873unsigned char *fragtbl[MAXFRAG + 1] = {
874 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
875};