Commit | Line | Data |
---|---|---|
76797561 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 | ||
62ae4dc6 | 7 | #ifndef lint |
04723d6b | 8 | static char sccsid[] = "@(#)pass5.c 5.3 (Berkeley) %G%"; |
76797561 | 9 | #endif not lint |
62ae4dc6 KM |
10 | |
11 | #include <sys/param.h> | |
12 | #include <sys/inode.h> | |
13 | #include <sys/fs.h> | |
14 | #include "fsck.h" | |
15 | ||
16 | pass5() | |
17 | { | |
993a756c KM |
18 | int c, blk, frags, sumsize, mapsize; |
19 | daddr_t dbase, dmax, d; | |
20 | register long i, j; | |
21 | struct csum *cs; | |
22 | time_t now; | |
23 | struct csum cstotal; | |
24 | struct inodesc idesc; | |
25 | char buf[MAXBSIZE]; | |
26 | register struct cg *newcg = (struct cg *)buf; | |
62ae4dc6 | 27 | |
993a756c KM |
28 | bzero((char *)newcg, sblock.fs_cgsize); |
29 | newcg->cg_magic = CG_MAGIC; | |
30 | bzero((char *)&idesc, sizeof(struct inodesc)); | |
31 | idesc.id_type = ADDR; | |
32 | bzero((char *)&cstotal, sizeof(struct csum)); | |
33 | sumsize = cgrp.cg_iused - (char *)(&cgrp); | |
af484010 KM |
34 | mapsize = &cgrp.cg_free[howmany(sblock.fs_fpg, NBBY)] - |
35 | (u_char *)cgrp.cg_iused; | |
993a756c | 36 | (void)time(&now); |
62ae4dc6 | 37 | for (c = 0; c < sblock.fs_ncg; c++) { |
49505034 | 38 | getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize); |
993a756c | 39 | if (cgrp.cg_magic != CG_MAGIC) |
62ae4dc6 | 40 | pfatal("CG %d: BAD MAGIC NUMBER\n", c); |
993a756c KM |
41 | dbase = cgbase(&sblock, c); |
42 | dmax = dbase + sblock.fs_fpg; | |
43 | if (dmax > sblock.fs_size) | |
44 | dmax = sblock.fs_size; | |
45 | if (now > cgrp.cg_time) | |
46 | newcg->cg_time = cgrp.cg_time; | |
47 | else | |
48 | newcg->cg_time = now; | |
49 | newcg->cg_cgx = c; | |
50 | if (c == sblock.fs_ncg - 1) | |
51 | newcg->cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg; | |
52 | else | |
53 | newcg->cg_ncyl = sblock.fs_cpg; | |
54 | newcg->cg_niblk = sblock.fs_ipg; | |
55 | newcg->cg_ndblk = dmax - dbase; | |
56 | newcg->cg_cs.cs_ndir = 0; | |
57 | newcg->cg_cs.cs_nffree = 0; | |
58 | newcg->cg_cs.cs_nbfree = 0; | |
59 | newcg->cg_cs.cs_nifree = sblock.fs_ipg; | |
60 | if (cgrp.cg_rotor < newcg->cg_ndblk) | |
61 | newcg->cg_rotor = cgrp.cg_rotor; | |
62 | else | |
63 | newcg->cg_rotor = 0; | |
64 | if (cgrp.cg_frotor < newcg->cg_ndblk) | |
65 | newcg->cg_frotor = cgrp.cg_frotor; | |
66 | else | |
67 | newcg->cg_frotor = 0; | |
68 | if (cgrp.cg_irotor < newcg->cg_niblk) | |
69 | newcg->cg_irotor = cgrp.cg_irotor; | |
70 | else | |
71 | newcg->cg_irotor = 0; | |
72 | bzero((char *)newcg->cg_frsum, sizeof newcg->cg_frsum); | |
73 | bzero((char *)newcg->cg_btot, sizeof newcg->cg_btot); | |
74 | bzero((char *)newcg->cg_b, sizeof newcg->cg_b); | |
75 | bzero((char *)newcg->cg_free, howmany(sblock.fs_fpg, NBBY)); | |
76 | bzero((char *)newcg->cg_iused, howmany(sblock.fs_ipg, NBBY)); | |
77 | j = sblock.fs_ipg * c; | |
78 | for (i = 0; i < sblock.fs_ipg; j++, i++) { | |
79 | switch (statemap[j]) { | |
80 | ||
81 | case USTATE: | |
82 | break; | |
83 | ||
84 | case DSTATE: | |
85 | case DCLEAR: | |
86 | case DFOUND: | |
87 | newcg->cg_cs.cs_ndir++; | |
88 | /* fall through */ | |
89 | ||
90 | case FSTATE: | |
91 | case FCLEAR: | |
92 | newcg->cg_cs.cs_nifree--; | |
93 | setbit(newcg->cg_iused, i); | |
94 | break; | |
ea4448dc KM |
95 | |
96 | default: | |
97 | if (j < ROOTINO) | |
98 | break; | |
99 | errexit("BAD STATE %d FOR INODE I=%d", | |
100 | statemap[j], j); | |
993a756c | 101 | } |
62ae4dc6 | 102 | } |
993a756c KM |
103 | if (c == 0) |
104 | for (i = 0; i < ROOTINO; i++) { | |
105 | setbit(newcg->cg_iused, i); | |
106 | newcg->cg_cs.cs_nifree--; | |
107 | } | |
108 | for (i = 0, d = dbase; | |
109 | d <= dmax - sblock.fs_frag; | |
110 | d += sblock.fs_frag, i += sblock.fs_frag) { | |
111 | frags = 0; | |
112 | for (j = 0; j < sblock.fs_frag; j++) { | |
113 | if (getbmap(d + j)) | |
114 | continue; | |
115 | setbit(newcg->cg_free, i + j); | |
116 | frags++; | |
117 | } | |
118 | if (frags == sblock.fs_frag) { | |
119 | newcg->cg_cs.cs_nbfree++; | |
120 | j = cbtocylno(&sblock, i); | |
121 | newcg->cg_btot[j]++; | |
122 | newcg->cg_b[j][cbtorpos(&sblock, i)]++; | |
123 | } else if (frags > 0) { | |
124 | newcg->cg_cs.cs_nffree += frags; | |
125 | blk = blkmap(&sblock, newcg->cg_free, i); | |
126 | fragacct(&sblock, blk, newcg->cg_frsum, 1); | |
62ae4dc6 | 127 | } |
62ae4dc6 | 128 | } |
993a756c KM |
129 | for (frags = d; d < dmax; d++) { |
130 | if (getbmap(d)) | |
131 | continue; | |
132 | setbit(newcg->cg_free, d - dbase); | |
133 | newcg->cg_cs.cs_nffree++; | |
62ae4dc6 | 134 | } |
993a756c | 135 | if (frags != d) { |
04723d6b SL |
136 | #ifdef tahoe |
137 | /* tahoe compiler workaround */ | |
138 | int x = frags - dbase; | |
139 | blk = blkmap(&sblock, newcg->cg_free, x); | |
140 | #else | |
993a756c | 141 | blk = blkmap(&sblock, newcg->cg_free, (frags - dbase)); |
04723d6b | 142 | #endif |
993a756c | 143 | fragacct(&sblock, blk, newcg->cg_frsum, 1); |
62ae4dc6 | 144 | } |
993a756c KM |
145 | cstotal.cs_nffree += newcg->cg_cs.cs_nffree; |
146 | cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree; | |
147 | cstotal.cs_nifree += newcg->cg_cs.cs_nifree; | |
148 | cstotal.cs_ndir += newcg->cg_cs.cs_ndir; | |
149 | if (bcmp(newcg->cg_iused, cgrp.cg_iused, mapsize) != 0 && | |
150 | dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) { | |
151 | bcopy(newcg->cg_iused, cgrp.cg_iused, mapsize); | |
152 | cgdirty(); | |
62ae4dc6 | 153 | } |
993a756c KM |
154 | if (bcmp((char *)newcg, (char *)&cgrp, sumsize) != 0 && |
155 | dofix(&idesc, "SUMMARY INFORMATION BAD")) { | |
156 | bcopy((char *)newcg, (char *)&cgrp, sumsize); | |
157 | cgdirty(); | |
62ae4dc6 | 158 | } |
993a756c KM |
159 | cs = &sblock.fs_cs(&sblock, c); |
160 | if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 && | |
161 | dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { | |
162 | bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs); | |
163 | sbdirty(); | |
62ae4dc6 KM |
164 | } |
165 | } | |
993a756c KM |
166 | if (bcmp((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs) != 0 |
167 | && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) { | |
168 | bcopy((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs); | |
169 | sblock.fs_ronly = 0; | |
170 | sblock.fs_fmod = 0; | |
171 | sbdirty(); | |
172 | } | |
62ae4dc6 | 173 | } |