add rps and minfree arguments
[unix-history] / usr / src / sbin / icheck / icheck.c
CommitLineData
211b1482 1static 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
23union {
24 struct fs sb;
b6407c9d 25 char pad[MAXBSIZE];
b42940ce
KM
26} sbun;
27#define sblock sbun.sb
28
29union {
30 struct cg cg;
b6407c9d 31 char pad[MAXBSIZE];
b42940ce
KM
32} cgun;
33#define cgrp cgun.cg
34
35struct dinode itab[MAXIPG];
b42940ce 36daddr_t blist[NB];
211b1482 37daddr_t fsblist[NB];
b42940ce
KM
38char *bmap;
39
b42940ce 40int mflg;
19f19804 41int sflg;
b42940ce
KM
42int dflg;
43int fi;
44ino_t ino;
45int cginit;
46
47ino_t nrfile;
48ino_t ndfile;
49ino_t nbfile;
50ino_t ncfile;
ea47352d 51ino_t nlfile;
b42940ce
KM
52
53daddr_t nblock;
54daddr_t nfrag;
b42940ce 55daddr_t nindir;
b42940ce
KM
56daddr_t niindir;
57
58daddr_t nffree;
b42940ce
KM
59daddr_t nbfree;
60
61daddr_t ndup;
62
63int nerror;
64
19f19804 65extern int inside[], around[];
b6407c9d 66extern unsigned char *fragtbl[];
19f19804 67
b42940ce 68long atol();
b42940ce
KM
69#ifndef STANDALONE
70char *malloc();
19f19804 71char *calloc();
b42940ce
KM
72#endif
73
74main(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
128check(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
295pass1(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 385chk(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 421duped(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
443makecg()
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
576fragacct(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
606getsb(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
632bwrite(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 648bread(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
670isblock(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 */
702clrblock(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
733setblock(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 */
771int around[9] = {
772 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff
773};
774int 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
791unsigned 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
826unsigned 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 */
864unsigned char *fragtbl[MAXFRAG + 1] = {
865 0, fragtbl124, fragtbl124, 0, fragtbl124, 0, 0, 0, fragtbl8,
866};