pass5.c revision 1.8 1 /* $NetBSD: pass5.c,v 1.8 2003/08/07 10:04:18 agc Exp $ */
2
3 /*
4 * Copyright (c) 1980, 1986, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 /*
33 * Copyright (c) 1997 Manuel Bouyer.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. All advertising materials mentioning features or use of this software
44 * must display the following acknowledgement:
45 * This product includes software developed by the University of
46 * California, Berkeley and its contributors.
47 * 4. Neither the name of the University nor the names of its contributors
48 * may be used to endorse or promote products derived from this software
49 * without specific prior written permission.
50 *
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61 * SUCH DAMAGE.
62 */
63
64 #include <sys/cdefs.h>
65 #ifndef lint
66 #if 0
67 static char sccsid[] = "@(#)pass5.c 8.6 (Berkeley) 11/30/94";
68 #else
69 __RCSID("$NetBSD: pass5.c,v 1.8 2003/08/07 10:04:18 agc Exp $");
70 #endif
71 #endif /* not lint */
72
73 #include <sys/param.h>
74 #include <sys/time.h>
75 #include <ufs/ufs/dinode.h>
76 #include <ufs/ext2fs/ext2fs_dinode.h>
77 #include <ufs/ext2fs/ext2fs.h>
78 #include <ufs/ext2fs/ext2fs_extern.h>
79 #include <string.h>
80 #include <malloc.h>
81 #include <stdio.h>
82
83 #include "fsutil.h"
84 #include "fsck.h"
85 #include "extern.h"
86
87
88 void print_bmap __P((u_char *,u_int32_t));
89
90 void
91 pass5()
92 {
93 int c;
94 struct m_ext2fs *fs = &sblock;
95 daddr_t dbase, dmax;
96 daddr_t d;
97 long i, j;
98 struct inodesc idesc[3];
99 struct bufarea *ino_bitmap = NULL, *blk_bitmap = NULL;
100 char *ibmap, *bbmap;
101 u_int32_t cs_ndir, cs_nbfree, cs_nifree;
102 char msg[255];
103
104 cs_ndir = 0;
105 cs_nbfree = 0;
106 cs_nifree = 0;
107
108 ibmap = malloc(fs->e2fs_bsize);
109 bbmap = malloc(fs->e2fs_bsize);
110 if (ibmap == NULL || bbmap == NULL) {
111 errexit("out of memory\n");
112 }
113
114 for (c = 0; c < fs->e2fs_ncg; c++) {
115 u_int32_t nbfree = 0;
116 u_int32_t nifree = 0;
117 u_int32_t ndirs = 0;
118
119 nbfree = 0;
120 nifree = fs->e2fs.e2fs_ipg;
121 ndirs = 0;
122
123 if (blk_bitmap == NULL) {
124 blk_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap),
125 fs->e2fs_bsize);
126 } else {
127 getblk(blk_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap),
128 fs->e2fs_bsize);
129 }
130 if (ino_bitmap == NULL) {
131 ino_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap),
132 fs->e2fs_bsize);
133 } else {
134 getblk(ino_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap),
135 fs->e2fs_bsize);
136 }
137 memset(bbmap, 0, fs->e2fs_bsize);
138 memset(ibmap, 0, fs->e2fs_bsize);
139 memset(&idesc[0], 0, sizeof idesc);
140 for (i = 0; i < 3; i++) {
141 idesc[i].id_type = ADDR;
142 }
143
144 j = fs->e2fs.e2fs_ipg * c + 1;
145
146 for (i = 0; i < fs->e2fs.e2fs_ipg; j++, i++) {
147 if ((j < EXT2_FIRSTINO) && (j != EXT2_ROOTINO)) {
148 setbit(ibmap, i);
149 nifree--;
150 continue;
151 }
152 if (j > fs->e2fs.e2fs_icount) {
153 setbit(ibmap, i);
154 continue;
155 }
156 switch (statemap[j]) {
157
158 case USTATE:
159 break;
160
161 case DSTATE:
162 case DCLEAR:
163 case DFOUND:
164 ndirs++;
165 /* fall through */
166
167 case FSTATE:
168 case FCLEAR:
169 nifree--;
170 setbit(ibmap, i);
171 break;
172
173 default:
174 errexit("BAD STATE %d FOR INODE I=%ld\n",
175 statemap[j], j);
176 }
177 }
178
179 /* fill in unused par of the inode map */
180 for (i = fs->e2fs.e2fs_ipg / NBBY; i < fs->e2fs_bsize; i++)
181 ibmap[i] = 0xff;
182
183 dbase = c * sblock.e2fs.e2fs_bpg +
184 sblock.e2fs.e2fs_first_dblock;
185 dmax = (c+1) * sblock.e2fs.e2fs_bpg +
186 sblock.e2fs.e2fs_first_dblock;
187
188 for (i = 0, d = dbase;
189 d < dmax;
190 d ++, i ++) {
191 if (testbmap(d) || d >= sblock.e2fs.e2fs_bcount) {
192 setbit(bbmap, i);
193 continue;
194 } else {
195 nbfree++;
196 }
197
198 }
199 cs_nbfree += nbfree;
200 cs_nifree += nifree;
201 cs_ndir += ndirs;
202
203 if (debug && (fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree ||
204 fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree ||
205 fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs)) {
206 printf("summary info for cg %d is %d, %d, %d,"
207 "should be %d, %d, %d\n", c,
208 fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree),
209 fs2h16(fs->e2fs_gd[c].ext2bgd_nifree),
210 fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs),
211 nbfree,
212 nifree,
213 ndirs);
214 }
215 (void)snprintf(msg, sizeof(msg),
216 "SUMMARY INFORMATIONS WRONG FOR CG #%d", c);
217 if ((fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree ||
218 fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree ||
219 fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs) &&
220 dofix(&idesc[0], msg)) {
221 fs->e2fs_gd[c].ext2bgd_nbfree = h2fs16(nbfree);
222 fs->e2fs_gd[c].ext2bgd_nifree = h2fs16(nifree);
223 fs->e2fs_gd[c].ext2bgd_ndirs = h2fs16(ndirs);
224 sbdirty();
225 }
226
227 if (debug && memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize)) {
228 printf("blk_bitmap:\n");
229 print_bmap(blk_bitmap->b_un.b_buf, fs->e2fs_bsize);
230 printf("bbmap:\n");
231 print_bmap(bbmap, fs->e2fs_bsize);
232 }
233
234 (void)snprintf(msg, sizeof(msg),
235 "BLK(S) MISSING IN BIT MAPS #%d", c);
236 if (memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize) &&
237 dofix(&idesc[1], msg)) {
238 memcpy(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize);
239 dirty(blk_bitmap);
240 }
241 if (debug && memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize)) {
242 printf("ino_bitmap:\n");
243 print_bmap(ino_bitmap->b_un.b_buf, fs->e2fs_bsize);
244 printf("ibmap:\n");
245 print_bmap(ibmap, fs->e2fs_bsize);
246 }
247 (void)snprintf(msg, sizeof(msg),
248 "INODE(S) MISSING IN BIT MAPS #%d", c);
249 if (memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize) &&
250 dofix(&idesc[1], msg)) {
251 memcpy(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize);
252 dirty(ino_bitmap);
253 }
254
255 }
256 if (debug && (fs->e2fs.e2fs_fbcount != cs_nbfree ||
257 fs->e2fs.e2fs_ficount != cs_nifree)) {
258 printf("summary info bad in superblock: %d, %d should be %d, %d\n",
259 fs->e2fs.e2fs_fbcount, fs->e2fs.e2fs_ficount,
260 cs_nbfree, cs_nifree);
261 }
262 if ((fs->e2fs.e2fs_fbcount != cs_nbfree ||
263 fs->e2fs.e2fs_ficount != cs_nifree)
264 && dofix(&idesc[0], "SUPERBLK SUMMARY INFORMATION BAD")) {
265 fs->e2fs.e2fs_fbcount = cs_nbfree;
266 fs->e2fs.e2fs_ficount = cs_nifree;
267 sbdirty();
268 }
269 }
270
271 void
272 print_bmap(map, size)
273 u_char *map;
274 u_int32_t size;
275 {
276 int i, j;
277
278 i = 0;
279 while (i < size) {
280 printf("%u: ",i);
281 for (j = 0; j < 16; j++, i++)
282 printf("%2x ", (u_int)map[i] & 0xff);
283 printf("\n");
284 }
285 }
286