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 $
37 #include <sys/param.h>
39 #include <vfs/ufs/dinode.h>
40 #include <vfs/ufs/fs.h>
50 int c
, blk
, frags
, basesize
, sumsize
, mapsize
, savednrpos
= 0;
51 int inomapsize
, blkmapsize
;
52 struct fs
*fs
= &sblock
;
53 struct cg
*cg
= &cgrp
;
54 ufs_daddr_t dbase
, dmax
;
59 struct inodesc idesc
[3];
61 struct cg
*newcg
= (struct cg
*)buf
;
62 struct ocg
*ocg
= (struct ocg
*)buf
;
64 inoinfo(WINO
)->ino_state
= USTATE
;
65 memset(newcg
, 0, (size_t)fs
->fs_cgsize
);
66 newcg
->cg_niblk
= fs
->fs_ipg
;
68 if (fs
->fs_maxcontig
< 2 && fs
->fs_contigsumsize
> 0) {
70 pwarn("DELETING CLUSTERING MAPS\n");
71 if (preen
|| reply("DELETE CLUSTERING MAPS")) {
72 fs
->fs_contigsumsize
= 0;
77 if (fs
->fs_maxcontig
> 1) {
80 if (fs
->fs_contigsumsize
< 1) {
82 } else if (fs
->fs_contigsumsize
< fs
->fs_maxcontig
&&
83 fs
->fs_contigsumsize
< FS_MAXCONTIG
) {
87 i
= fs
->fs_contigsumsize
;
88 fs
->fs_contigsumsize
=
89 MIN(fs
->fs_maxcontig
, FS_MAXCONTIG
);
90 if (CGSIZE(fs
) > fs
->fs_bsize
) {
91 pwarn("CANNOT %s CLUSTER MAPS\n", doit
);
92 fs
->fs_contigsumsize
= i
;
94 reply("CREATE CLUSTER MAPS")) {
96 pwarn("%sING CLUSTER MAPS\n",
99 fragroundup(fs
, CGSIZE(fs
));
106 switch ((int)fs
->fs_postblformat
) {
109 basesize
= (char *)(&ocg
->cg_btot
[0]) -
110 (char *)(&ocg
->cg_firstfield
);
111 sumsize
= &ocg
->cg_iused
[0] - (u_int8_t
*)(&ocg
->cg_btot
[0]);
112 mapsize
= &ocg
->cg_free
[howmany(fs
->fs_fpg
, NBBY
)] -
113 (u_char
*)&ocg
->cg_iused
[0];
114 blkmapsize
= howmany(fs
->fs_fpg
, NBBY
);
115 inomapsize
= &ocg
->cg_free
[0] - (u_char
*)&ocg
->cg_iused
[0];
116 ocg
->cg_magic
= CG_MAGIC
;
117 savednrpos
= fs
->fs_nrpos
;
121 case FS_DYNAMICPOSTBLFMT
:
123 &newcg
->cg_space
[0] - (u_char
*)(&newcg
->cg_firstfield
);
125 newcg
->cg_btotoff
+ fs
->fs_cpg
* sizeof(int32_t);
126 newcg
->cg_iusedoff
= newcg
->cg_boff
+
127 fs
->fs_cpg
* fs
->fs_nrpos
* sizeof(u_int16_t
);
129 newcg
->cg_iusedoff
+ howmany(fs
->fs_ipg
, NBBY
);
130 inomapsize
= newcg
->cg_freeoff
- newcg
->cg_iusedoff
;
131 newcg
->cg_nextfreeoff
= newcg
->cg_freeoff
+
132 howmany(fs
->fs_cpg
* fs
->fs_spc
/ NSPF(fs
), NBBY
);
133 blkmapsize
= newcg
->cg_nextfreeoff
- newcg
->cg_freeoff
;
134 if (fs
->fs_contigsumsize
> 0) {
135 newcg
->cg_clustersumoff
= newcg
->cg_nextfreeoff
-
137 newcg
->cg_clustersumoff
=
138 roundup(newcg
->cg_clustersumoff
, sizeof(u_int32_t
));
139 newcg
->cg_clusteroff
= newcg
->cg_clustersumoff
+
140 (fs
->fs_contigsumsize
+ 1) * sizeof(u_int32_t
);
141 newcg
->cg_nextfreeoff
= newcg
->cg_clusteroff
+
142 howmany(fs
->fs_cpg
* fs
->fs_spc
/ NSPB(fs
), NBBY
);
144 newcg
->cg_magic
= CG_MAGIC
;
145 basesize
= &newcg
->cg_space
[0] -
146 (u_char
*)(&newcg
->cg_firstfield
);
147 sumsize
= newcg
->cg_iusedoff
- newcg
->cg_btotoff
;
148 mapsize
= newcg
->cg_nextfreeoff
- newcg
->cg_iusedoff
;
152 inomapsize
= blkmapsize
= sumsize
= 0; /* keep lint happy */
153 errx(EEXIT
, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
154 fs
->fs_postblformat
);
156 memset(&idesc
[0], 0, sizeof idesc
);
157 for (i
= 0; i
< 3; i
++) {
158 idesc
[i
].id_type
= ADDR
;
160 idesc
[i
].id_fix
= FIX
;
162 memset(&cstotal
, 0, sizeof(struct csum
));
163 j
= blknum(fs
, fs
->fs_size
+ fs
->fs_frag
- 1);
164 for (i
= fs
->fs_size
; i
< j
; i
++)
166 for (c
= 0; c
< fs
->fs_ncg
; c
++) {
168 printf("%s: phase 5: cyl group %d of %d (%d%%)\n",
169 cdevname
, c
, sblock
.fs_ncg
,
170 c
* 100 / sblock
.fs_ncg
);
173 getblk(&cgblk
, cgtod(fs
, c
), fs
->fs_cgsize
);
174 if (!cg_chkmagic(cg
))
175 pfatal("CG %d: BAD MAGIC NUMBER\n", c
);
176 dbase
= cgbase(fs
, c
);
177 dmax
= dbase
+ fs
->fs_fpg
;
178 if (dmax
> fs
->fs_size
)
180 newcg
->cg_time
= cg
->cg_time
;
182 if (c
== fs
->fs_ncg
- 1)
183 newcg
->cg_ncyl
= fs
->fs_ncyl
% fs
->fs_cpg
;
185 newcg
->cg_ncyl
= fs
->fs_cpg
;
186 newcg
->cg_ndblk
= dmax
- dbase
;
187 if (fs
->fs_contigsumsize
> 0)
188 newcg
->cg_nclusterblks
= newcg
->cg_ndblk
/ fs
->fs_frag
;
189 newcg
->cg_cs
.cs_ndir
= 0;
190 newcg
->cg_cs
.cs_nffree
= 0;
191 newcg
->cg_cs
.cs_nbfree
= 0;
192 newcg
->cg_cs
.cs_nifree
= fs
->fs_ipg
;
193 if ((cg
->cg_rotor
>= 0) && (cg
->cg_rotor
< newcg
->cg_ndblk
))
194 newcg
->cg_rotor
= cg
->cg_rotor
;
197 if ((cg
->cg_frotor
>= 0) && (cg
->cg_frotor
< newcg
->cg_ndblk
))
198 newcg
->cg_frotor
= cg
->cg_frotor
;
200 newcg
->cg_frotor
= 0;
201 if ((cg
->cg_irotor
>= 0) && (cg
->cg_irotor
< newcg
->cg_niblk
))
202 newcg
->cg_irotor
= cg
->cg_irotor
;
204 newcg
->cg_irotor
= 0;
205 memset(&newcg
->cg_frsum
[0], 0, sizeof newcg
->cg_frsum
);
206 memset(&cg_blktot(newcg
)[0], 0,
207 (size_t)(sumsize
+ mapsize
));
208 if (fs
->fs_postblformat
== FS_42POSTBLFMT
)
209 ocg
->cg_magic
= CG_MAGIC
;
211 for (i
= 0; i
< inostathead
[c
].il_numalloced
; j
++, i
++) {
212 switch (inoinfo(j
)->ino_state
) {
220 newcg
->cg_cs
.cs_ndir
++;
225 newcg
->cg_cs
.cs_nifree
--;
226 setbit(cg_inosused(newcg
), i
);
232 errx(EEXIT
, "BAD STATE %d FOR INODE I=%ld",
233 inoinfo(j
)->ino_state
, j
);
237 for (i
= 0; i
< ROOTINO
; i
++) {
238 setbit(cg_inosused(newcg
), i
);
239 newcg
->cg_cs
.cs_nifree
--;
241 for (i
= 0, d
= dbase
;
243 d
+= fs
->fs_frag
, i
+= fs
->fs_frag
) {
245 for (j
= 0; j
< fs
->fs_frag
; j
++) {
248 setbit(cg_blksfree(newcg
), i
+ j
);
251 if (frags
== fs
->fs_frag
) {
252 newcg
->cg_cs
.cs_nbfree
++;
253 j
= cbtocylno(fs
, i
);
254 cg_blktot(newcg
)[j
]++;
255 cg_blks(fs
, newcg
, j
)[cbtorpos(fs
, i
)]++;
256 if (fs
->fs_contigsumsize
> 0)
257 setbit(cg_clustersfree(newcg
),
259 } else if (frags
> 0) {
260 newcg
->cg_cs
.cs_nffree
+= frags
;
261 blk
= blkmap(fs
, cg_blksfree(newcg
), i
);
262 ffs_fragacct(fs
, blk
, newcg
->cg_frsum
, 1);
265 if (fs
->fs_contigsumsize
> 0) {
266 int32_t *sump
= cg_clustersum(newcg
);
267 u_char
*mapp
= cg_clustersfree(newcg
);
272 for (i
= 0; i
< newcg
->cg_nclusterblks
; i
++) {
273 if ((map
& bit
) != 0) {
275 } else if (run
!= 0) {
276 if (run
> fs
->fs_contigsumsize
)
277 run
= fs
->fs_contigsumsize
;
281 if ((i
& (NBBY
- 1)) != (NBBY
- 1)) {
289 if (run
> fs
->fs_contigsumsize
)
290 run
= fs
->fs_contigsumsize
;
294 cstotal
.cs_nffree
+= newcg
->cg_cs
.cs_nffree
;
295 cstotal
.cs_nbfree
+= newcg
->cg_cs
.cs_nbfree
;
296 cstotal
.cs_nifree
+= newcg
->cg_cs
.cs_nifree
;
297 cstotal
.cs_ndir
+= newcg
->cg_cs
.cs_ndir
;
298 cs
= &fs
->fs_cs(fs
, c
);
299 if (memcmp(&newcg
->cg_cs
, cs
, sizeof *cs
) != 0 &&
300 dofix(&idesc
[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
301 memmove(cs
, &newcg
->cg_cs
, sizeof *cs
);
305 memmove(cg
, newcg
, (size_t)fs
->fs_cgsize
);
309 if ((memcmp(newcg
, cg
, basesize
) != 0 ||
310 memcmp(&cg_blktot(newcg
)[0],
311 &cg_blktot(cg
)[0], sumsize
) != 0) &&
312 dofix(&idesc
[2], "SUMMARY INFORMATION BAD")) {
313 memmove(cg
, newcg
, (size_t)basesize
);
314 memmove(&cg_blktot(cg
)[0],
315 &cg_blktot(newcg
)[0], (size_t)sumsize
);
319 for (i
= 0; i
< inomapsize
; i
++) {
320 j
= cg_inosused(newcg
)[i
];
321 if ((cg_inosused(cg
)[i
] & j
) == j
)
323 for (k
= 0; k
< NBBY
; k
++) {
324 if ((j
& (1 << k
)) == 0)
326 if (cg_inosused(cg
)[i
] & (1 << k
))
328 pwarn("ALLOCATED INODE %d MARKED FREE\n",
329 c
* fs
->fs_ipg
+ i
* NBBY
+ k
);
332 for (i
= 0; i
< blkmapsize
; i
++) {
333 j
= cg_blksfree(cg
)[i
];
334 if ((cg_blksfree(newcg
)[i
] & j
) == j
)
336 for (k
= 0; k
< NBBY
; k
++) {
337 if ((j
& (1 << k
)) == 0)
339 if (cg_blksfree(newcg
)[i
] & (1 << k
))
341 pwarn("ALLOCATED FRAG %d MARKED FREE\n",
342 c
* fs
->fs_fpg
+ i
* NBBY
+ k
);
346 if (memcmp(cg_inosused(newcg
), cg_inosused(cg
), mapsize
) != 0 &&
347 dofix(&idesc
[1], "BLK(S) MISSING IN BIT MAPS")) {
348 memmove(cg_inosused(cg
), cg_inosused(newcg
),
353 if (fs
->fs_postblformat
== FS_42POSTBLFMT
)
354 fs
->fs_nrpos
= savednrpos
;
355 if (memcmp(&cstotal
, &fs
->fs_cstotal
, sizeof *cs
) != 0
356 && dofix(&idesc
[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
357 memmove(&fs
->fs_cstotal
, &cstotal
, sizeof *cs
);