2 * Copyright (c) 1980, 1986, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * @(#)pass5.c 8.9 (Berkeley) 4/28/95
34 * $FreeBSD: src/sbin/fsck/pass5.c,v 1.17.2.2 2002/11/26 04:46:59 julian Exp $
35 * $DragonFly: src/sbin/fsck/pass5.c,v 1.5 2005/11/06 12:13:53 swildner Exp $
38 #include <sys/param.h>
40 #include <vfs/ufs/dinode.h>
41 #include <vfs/ufs/fs.h>
51 int c
, blk
, frags
, basesize
, sumsize
, mapsize
, savednrpos
= 0;
52 int inomapsize
, blkmapsize
;
53 struct fs
*fs
= &sblock
;
54 struct cg
*cg
= &cgrp
;
55 ufs_daddr_t dbase
, dmax
;
60 struct inodesc idesc
[3];
62 struct cg
*newcg
= (struct cg
*)buf
;
63 struct ocg
*ocg
= (struct ocg
*)buf
;
65 inoinfo(WINO
)->ino_state
= USTATE
;
66 memset(newcg
, 0, (size_t)fs
->fs_cgsize
);
67 newcg
->cg_niblk
= fs
->fs_ipg
;
69 if (fs
->fs_maxcontig
< 2 && fs
->fs_contigsumsize
> 0) {
71 pwarn("DELETING CLUSTERING MAPS\n");
72 if (preen
|| reply("DELETE CLUSTERING MAPS")) {
73 fs
->fs_contigsumsize
= 0;
78 if (fs
->fs_maxcontig
> 1) {
81 if (fs
->fs_contigsumsize
< 1) {
83 } else if (fs
->fs_contigsumsize
< fs
->fs_maxcontig
&&
84 fs
->fs_contigsumsize
< FS_MAXCONTIG
) {
88 i
= fs
->fs_contigsumsize
;
89 fs
->fs_contigsumsize
=
90 MIN(fs
->fs_maxcontig
, FS_MAXCONTIG
);
91 if (CGSIZE(fs
) > fs
->fs_bsize
) {
92 pwarn("CANNOT %s CLUSTER MAPS\n", doit
);
93 fs
->fs_contigsumsize
= i
;
95 reply("CREATE CLUSTER MAPS")) {
97 pwarn("%sING CLUSTER MAPS\n",
100 fragroundup(fs
, CGSIZE(fs
));
107 switch ((int)fs
->fs_postblformat
) {
110 basesize
= (char *)(&ocg
->cg_btot
[0]) -
111 (char *)(&ocg
->cg_firstfield
);
112 sumsize
= &ocg
->cg_iused
[0] - (u_int8_t
*)(&ocg
->cg_btot
[0]);
113 mapsize
= &ocg
->cg_free
[howmany(fs
->fs_fpg
, NBBY
)] -
114 (u_char
*)&ocg
->cg_iused
[0];
115 blkmapsize
= howmany(fs
->fs_fpg
, NBBY
);
116 inomapsize
= &ocg
->cg_free
[0] - (u_char
*)&ocg
->cg_iused
[0];
117 ocg
->cg_magic
= CG_MAGIC
;
118 savednrpos
= fs
->fs_nrpos
;
122 case FS_DYNAMICPOSTBLFMT
:
124 &newcg
->cg_space
[0] - (u_char
*)(&newcg
->cg_firstfield
);
126 newcg
->cg_btotoff
+ fs
->fs_cpg
* sizeof(int32_t);
127 newcg
->cg_iusedoff
= newcg
->cg_boff
+
128 fs
->fs_cpg
* fs
->fs_nrpos
* sizeof(u_int16_t
);
130 newcg
->cg_iusedoff
+ howmany(fs
->fs_ipg
, NBBY
);
131 inomapsize
= newcg
->cg_freeoff
- newcg
->cg_iusedoff
;
132 newcg
->cg_nextfreeoff
= newcg
->cg_freeoff
+
133 howmany(fs
->fs_cpg
* fs
->fs_spc
/ NSPF(fs
), NBBY
);
134 blkmapsize
= newcg
->cg_nextfreeoff
- newcg
->cg_freeoff
;
135 if (fs
->fs_contigsumsize
> 0) {
136 newcg
->cg_clustersumoff
= newcg
->cg_nextfreeoff
-
138 newcg
->cg_clustersumoff
=
139 roundup(newcg
->cg_clustersumoff
, sizeof(u_int32_t
));
140 newcg
->cg_clusteroff
= newcg
->cg_clustersumoff
+
141 (fs
->fs_contigsumsize
+ 1) * sizeof(u_int32_t
);
142 newcg
->cg_nextfreeoff
= newcg
->cg_clusteroff
+
143 howmany(fs
->fs_cpg
* fs
->fs_spc
/ NSPB(fs
), NBBY
);
145 newcg
->cg_magic
= CG_MAGIC
;
146 basesize
= &newcg
->cg_space
[0] -
147 (u_char
*)(&newcg
->cg_firstfield
);
148 sumsize
= newcg
->cg_iusedoff
- newcg
->cg_btotoff
;
149 mapsize
= newcg
->cg_nextfreeoff
- newcg
->cg_iusedoff
;
153 inomapsize
= blkmapsize
= sumsize
= 0; /* keep lint happy */
154 errx(EEXIT
, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
155 fs
->fs_postblformat
);
157 memset(&idesc
[0], 0, sizeof idesc
);
158 for (i
= 0; i
< 3; i
++) {
159 idesc
[i
].id_type
= ADDR
;
161 idesc
[i
].id_fix
= FIX
;
163 memset(&cstotal
, 0, sizeof(struct csum
));
164 j
= blknum(fs
, fs
->fs_size
+ fs
->fs_frag
- 1);
165 for (i
= fs
->fs_size
; i
< j
; i
++)
167 for (c
= 0; c
< fs
->fs_ncg
; c
++) {
169 printf("%s: phase 5: cyl group %d of %d (%d%%)\n",
170 cdevname
, c
, sblock
.fs_ncg
,
171 c
* 100 / sblock
.fs_ncg
);
174 getblk(&cgblk
, cgtod(fs
, c
), fs
->fs_cgsize
);
175 if (!cg_chkmagic(cg
))
176 pfatal("CG %d: BAD MAGIC NUMBER\n", c
);
177 dbase
= cgbase(fs
, c
);
178 dmax
= dbase
+ fs
->fs_fpg
;
179 if (dmax
> fs
->fs_size
)
181 newcg
->cg_time
= cg
->cg_time
;
183 if (c
== fs
->fs_ncg
- 1)
184 newcg
->cg_ncyl
= fs
->fs_ncyl
% fs
->fs_cpg
;
186 newcg
->cg_ncyl
= fs
->fs_cpg
;
187 newcg
->cg_ndblk
= dmax
- dbase
;
188 if (fs
->fs_contigsumsize
> 0)
189 newcg
->cg_nclusterblks
= newcg
->cg_ndblk
/ fs
->fs_frag
;
190 newcg
->cg_cs
.cs_ndir
= 0;
191 newcg
->cg_cs
.cs_nffree
= 0;
192 newcg
->cg_cs
.cs_nbfree
= 0;
193 newcg
->cg_cs
.cs_nifree
= fs
->fs_ipg
;
194 if ((cg
->cg_rotor
>= 0) && (cg
->cg_rotor
< newcg
->cg_ndblk
))
195 newcg
->cg_rotor
= cg
->cg_rotor
;
198 if ((cg
->cg_frotor
>= 0) && (cg
->cg_frotor
< newcg
->cg_ndblk
))
199 newcg
->cg_frotor
= cg
->cg_frotor
;
201 newcg
->cg_frotor
= 0;
202 if ((cg
->cg_irotor
>= 0) && (cg
->cg_irotor
< newcg
->cg_niblk
))
203 newcg
->cg_irotor
= cg
->cg_irotor
;
205 newcg
->cg_irotor
= 0;
206 memset(&newcg
->cg_frsum
[0], 0, sizeof newcg
->cg_frsum
);
207 memset(&cg_blktot(newcg
)[0], 0,
208 (size_t)(sumsize
+ mapsize
));
209 if (fs
->fs_postblformat
== FS_42POSTBLFMT
)
210 ocg
->cg_magic
= CG_MAGIC
;
212 for (i
= 0; i
< inostathead
[c
].il_numalloced
; j
++, i
++) {
213 switch (inoinfo(j
)->ino_state
) {
221 newcg
->cg_cs
.cs_ndir
++;
226 newcg
->cg_cs
.cs_nifree
--;
227 setbit(cg_inosused(newcg
), i
);
233 errx(EEXIT
, "BAD STATE %d FOR INODE I=%ld",
234 inoinfo(j
)->ino_state
, j
);
238 for (i
= 0; i
< ROOTINO
; i
++) {
239 setbit(cg_inosused(newcg
), i
);
240 newcg
->cg_cs
.cs_nifree
--;
242 for (i
= 0, d
= dbase
;
244 d
+= fs
->fs_frag
, i
+= fs
->fs_frag
) {
246 for (j
= 0; j
< fs
->fs_frag
; j
++) {
249 setbit(cg_blksfree(newcg
), i
+ j
);
252 if (frags
== fs
->fs_frag
) {
253 newcg
->cg_cs
.cs_nbfree
++;
254 j
= cbtocylno(fs
, i
);
255 cg_blktot(newcg
)[j
]++;
256 cg_blks(fs
, newcg
, j
)[cbtorpos(fs
, i
)]++;
257 if (fs
->fs_contigsumsize
> 0)
258 setbit(cg_clustersfree(newcg
),
260 } else if (frags
> 0) {
261 newcg
->cg_cs
.cs_nffree
+= frags
;
262 blk
= blkmap(fs
, cg_blksfree(newcg
), i
);
263 ffs_fragacct(fs
, blk
, newcg
->cg_frsum
, 1);
266 if (fs
->fs_contigsumsize
> 0) {
267 int32_t *sump
= cg_clustersum(newcg
);
268 u_char
*mapp
= cg_clustersfree(newcg
);
273 for (i
= 0; i
< newcg
->cg_nclusterblks
; i
++) {
274 if ((map
& bit
) != 0) {
276 } else if (run
!= 0) {
277 if (run
> fs
->fs_contigsumsize
)
278 run
= fs
->fs_contigsumsize
;
282 if ((i
& (NBBY
- 1)) != (NBBY
- 1)) {
290 if (run
> fs
->fs_contigsumsize
)
291 run
= fs
->fs_contigsumsize
;
295 cstotal
.cs_nffree
+= newcg
->cg_cs
.cs_nffree
;
296 cstotal
.cs_nbfree
+= newcg
->cg_cs
.cs_nbfree
;
297 cstotal
.cs_nifree
+= newcg
->cg_cs
.cs_nifree
;
298 cstotal
.cs_ndir
+= newcg
->cg_cs
.cs_ndir
;
299 cs
= &fs
->fs_cs(fs
, c
);
300 if (memcmp(&newcg
->cg_cs
, cs
, sizeof *cs
) != 0 &&
301 dofix(&idesc
[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
302 memmove(cs
, &newcg
->cg_cs
, sizeof *cs
);
306 memmove(cg
, newcg
, (size_t)fs
->fs_cgsize
);
310 if ((memcmp(newcg
, cg
, basesize
) != 0 ||
311 memcmp(&cg_blktot(newcg
)[0],
312 &cg_blktot(cg
)[0], sumsize
) != 0) &&
313 dofix(&idesc
[2], "SUMMARY INFORMATION BAD")) {
314 memmove(cg
, newcg
, (size_t)basesize
);
315 memmove(&cg_blktot(cg
)[0],
316 &cg_blktot(newcg
)[0], (size_t)sumsize
);
320 for (i
= 0; i
< inomapsize
; i
++) {
321 j
= cg_inosused(newcg
)[i
];
322 if ((cg_inosused(cg
)[i
] & j
) == j
)
324 for (k
= 0; k
< NBBY
; k
++) {
325 if ((j
& (1 << k
)) == 0)
327 if (cg_inosused(cg
)[i
] & (1 << k
))
329 pwarn("ALLOCATED INODE %d MARKED FREE\n",
330 c
* fs
->fs_ipg
+ i
* NBBY
+ k
);
333 for (i
= 0; i
< blkmapsize
; i
++) {
334 j
= cg_blksfree(cg
)[i
];
335 if ((cg_blksfree(newcg
)[i
] & j
) == j
)
337 for (k
= 0; k
< NBBY
; k
++) {
338 if ((j
& (1 << k
)) == 0)
340 if (cg_blksfree(newcg
)[i
] & (1 << k
))
342 pwarn("ALLOCATED FRAG %d MARKED FREE\n",
343 c
* fs
->fs_fpg
+ i
* NBBY
+ k
);
347 if (memcmp(cg_inosused(newcg
), cg_inosused(cg
), mapsize
) != 0 &&
348 dofix(&idesc
[1], "BLK(S) MISSING IN BIT MAPS")) {
349 memmove(cg_inosused(cg
), cg_inosused(newcg
),
354 if (fs
->fs_postblformat
== FS_42POSTBLFMT
)
355 fs
->fs_nrpos
= savednrpos
;
356 if (memcmp(&cstotal
, &fs
->fs_cstotal
, sizeof *cs
) != 0
357 && dofix(&idesc
[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
358 memmove(&fs
->fs_cstotal
, &cstotal
, sizeof *cs
);