1 |
/* Pass 5 of GNU fsck -- check allocation maps and summaries |
/* Pass 5 of GNU fsck -- check allocation maps and summaries |
2 |
Copyright (C) 1994, 1996 Free Software Foundation, Inc. |
Copyright (C) 1994,96,2001 Free Software Foundation, Inc. |
3 |
Written by Michael I. Bushnell. |
Written by Michael I. Bushnell. |
4 |
|
|
5 |
This file is part of the GNU Hurd. |
This file is part of the GNU Hurd. |
23 |
/* From ../ufs/subr.c: */ |
/* From ../ufs/subr.c: */ |
24 |
|
|
25 |
/* |
/* |
26 |
* Update the frsum fields to reflect addition or deletion |
* Update the frsum fields to reflect addition or deletion |
27 |
* of some frags. |
* of some frags. |
28 |
*/ |
*/ |
29 |
static void |
static void |
87 |
|
|
88 |
sbcsums = alloca (fragroundup (sblock, sblock->fs_cssize)); |
sbcsums = alloca (fragroundup (sblock, sblock->fs_cssize)); |
89 |
|
|
90 |
readblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, |
readblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, |
91 |
fragroundup (sblock, sblock->fs_cssize)); |
fragroundup (sblock, sblock->fs_cssize)); |
92 |
|
|
93 |
/* Construct a CG structure; initialize everything that's the same |
/* Construct a CG structure; initialize everything that's the same |
105 |
savednrpos = sblock->fs_nrpos; |
savednrpos = sblock->fs_nrpos; |
106 |
sblock->fs_nrpos = 8; |
sblock->fs_nrpos = 8; |
107 |
break; |
break; |
108 |
|
|
109 |
case FS_DYNAMICPOSTBLFMT: |
case FS_DYNAMICPOSTBLFMT: |
110 |
/* Set fields unique to new cg structure */ |
/* Set fields unique to new cg structure */ |
111 |
newcg->cg_btotoff = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); |
newcg->cg_btotoff = &newcg->cg_space[0] - (u_char *)(&newcg->cg_link); |
112 |
newcg->cg_boff = newcg->cg_btotoff + sblock->fs_cpg * sizeof (long); |
newcg->cg_boff = newcg->cg_btotoff + sblock->fs_cpg * sizeof (long); |
113 |
newcg->cg_iusedoff = newcg->cg_boff + (sblock->fs_cpg |
newcg->cg_iusedoff = newcg->cg_boff + (sblock->fs_cpg |
114 |
* sblock->fs_nrpos |
* sblock->fs_nrpos |
115 |
* sizeof (short)); |
* sizeof (short)); |
116 |
newcg->cg_freeoff = newcg->cg_iusedoff + howmany (sblock->fs_ipg, NBBY); |
newcg->cg_freeoff = newcg->cg_iusedoff + howmany (sblock->fs_ipg, NBBY); |
117 |
|
|
118 |
if (sblock->fs_contigsumsize <= 0) |
if (sblock->fs_contigsumsize <= 0) |
119 |
{ |
{ |
120 |
newcg->cg_nextfreeoff = |
newcg->cg_nextfreeoff = |
121 |
(newcg->cg_freeoff |
(newcg->cg_freeoff |
122 |
+ howmany (sblock->fs_cpg * sblock->fs_spc / NSPF (sblock), |
+ howmany (sblock->fs_cpg * sblock->fs_spc / NSPF (sblock), |
123 |
NBBY)); |
NBBY)); |
124 |
} |
} |
125 |
else |
else |
126 |
{ |
{ |
127 |
newcg->cg_clustersumoff = |
newcg->cg_clustersumoff = |
128 |
(newcg->cg_freeoff |
(newcg->cg_freeoff |
129 |
+ howmany (sblock->fs_cpg * sblock->fs_spc / NSPF (sblock), NBBY) |
+ howmany (sblock->fs_cpg * sblock->fs_spc / NSPF (sblock), NBBY) |
130 |
- sizeof (long)); |
- sizeof (long)); |
131 |
newcg->cg_clustersumoff = |
newcg->cg_clustersumoff = |
132 |
roundup (newcg->cg_clustersumoff, sizeof (long)); |
roundup (newcg->cg_clustersumoff, sizeof (long)); |
133 |
newcg->cg_clusteroff = |
newcg->cg_clusteroff = |
134 |
(newcg->cg_clustersumoff |
(newcg->cg_clustersumoff |
135 |
+ (sblock->fs_contigsumsize + 1) * sizeof (long)); |
+ (sblock->fs_contigsumsize + 1) * sizeof (long)); |
136 |
newcg->cg_nextfreeoff = |
newcg->cg_nextfreeoff = |
137 |
(newcg->cg_clusteroff |
(newcg->cg_clusteroff |
138 |
+ howmany (sblock->fs_cpg * sblock->fs_spc / NSPB (sblock), |
+ howmany (sblock->fs_cpg * sblock->fs_spc / NSPB (sblock), |
139 |
NBBY)); |
NBBY)); |
140 |
} |
} |
141 |
|
|
150 |
default: |
default: |
151 |
errexit ("UNKNOWN POSTBL FORMAT"); |
errexit ("UNKNOWN POSTBL FORMAT"); |
152 |
} |
} |
153 |
|
|
154 |
bzero (&cstotal, sizeof (struct csum)); |
bzero (&cstotal, sizeof (struct csum)); |
155 |
|
|
156 |
/* Mark fragments past the end of the filesystem as used. */ |
/* Mark fragments past the end of the filesystem as used. */ |
157 |
j = blknum (sblock, sblock->fs_size + sblock->fs_frag - 1); |
j = blknum (sblock, sblock->fs_size + sblock->fs_frag - 1); |
158 |
for (i = sblock->fs_size; i < j; i++) |
for (i = sblock->fs_size; i < j; i++) |
159 |
setbmap (i); |
setbmap (i); |
160 |
|
|
161 |
/* Now walk through the cylinder groups, checking each one. */ |
/* Now walk through the cylinder groups, checking each one. */ |
162 |
for (c = 0; c < sblock->fs_ncg; c++) |
for (c = 0; c < sblock->fs_ncg; c++) |
163 |
{ |
{ |
164 |
int dbase, dmax; |
int dbase, dmax; |
165 |
|
|
166 |
/* Read the cylinder group structure */ |
/* Read the cylinder group structure */ |
167 |
readblock (fsbtodb (sblock, cgtod (sblock, c)), cg, sblock->fs_cgsize); |
readblock (fsbtodb (sblock, cgtod (sblock, c)), cg, sblock->fs_cgsize); |
168 |
writecg = 0; |
writecg = 0; |
169 |
|
|
170 |
if (!cg_chkmagic (cg)) |
if (!cg_chkmagic (cg)) |
171 |
warning (1, "CG %d: BAD MAGIC NUMBER", c); |
warning (1, "CG %d: BAD MAGIC NUMBER", c); |
172 |
|
|
173 |
/* Compute first and last data block addresses in this group */ |
/* Compute first and last data block addresses in this group */ |
174 |
dbase = cgbase (sblock, c); |
dbase = cgbase (sblock, c); |
175 |
dmax = dbase + sblock->fs_fpg; |
dmax = dbase + sblock->fs_fpg; |
176 |
if (dmax > sblock->fs_size) |
if (dmax > sblock->fs_size) |
177 |
dmax = sblock->fs_size; |
dmax = sblock->fs_size; |
178 |
|
|
179 |
/* Initialize newcg fully; values from cg for those |
/* Initialize newcg fully; values from cg for those |
180 |
we can't check. */ |
we can't check. */ |
181 |
newcg->cg_time = cg->cg_time; |
newcg->cg_time = cg->cg_time; |
230 |
pfix ("FIXED"); |
pfix ("FIXED"); |
231 |
} |
} |
232 |
} |
} |
233 |
|
|
234 |
/* Zero the block maps and summary areas */ |
/* Zero the block maps and summary areas */ |
235 |
bzero (&newcg->cg_frsum[0], sizeof newcg->cg_frsum); |
bzero (&newcg->cg_frsum[0], sizeof newcg->cg_frsum); |
236 |
bzero (&cg_blktot (newcg)[0], sumsize + mapsize); |
bzero (&cg_blktot (newcg)[0], sumsize + mapsize); |
267 |
setbit (cg_inosused (newcg), i); |
setbit (cg_inosused (newcg), i); |
268 |
newcg->cg_cs.cs_nifree--; |
newcg->cg_cs.cs_nifree--; |
269 |
} |
} |
270 |
|
|
271 |
/* Walk through each data block, accounting for it in |
/* Walk through each data block, accounting for it in |
272 |
the block map and in newcg->cg_cs. */ |
the block map and in newcg->cg_cs. */ |
273 |
/* In this look, D is the block number and I is the |
/* In this look, D is the block number and I is the |
274 |
block number relative to this CG. */ |
block number relative to this CG. */ |
277 |
d += sblock->fs_frag, i += sblock->fs_frag) |
d += sblock->fs_frag, i += sblock->fs_frag) |
278 |
{ |
{ |
279 |
int frags = 0; |
int frags = 0; |
280 |
|
|
281 |
/* Set each free frag of this block in the block map; |
/* Set each free frag of this block in the block map; |
282 |
count how many frags were free. */ |
count how many frags were free. */ |
283 |
for (j = 0; j < sblock->fs_frag; j++) |
for (j = 0; j < sblock->fs_frag; j++) |
287 |
setbit (cg_blksfree (newcg), i + j); |
setbit (cg_blksfree (newcg), i + j); |
288 |
frags++; |
frags++; |
289 |
} |
} |
290 |
|
|
291 |
/* If all the frags were free, then count this as |
/* If all the frags were free, then count this as |
292 |
a free block too. */ |
a free block too. */ |
293 |
if (frags == sblock->fs_frag) |
if (frags == sblock->fs_frag) |
294 |
{ |
{ |
308 |
ffs_fragacct (sblock, blk, newcg->cg_frsum, 1); |
ffs_fragacct (sblock, blk, newcg->cg_frsum, 1); |
309 |
} |
} |
310 |
} |
} |
311 |
|
|
312 |
if (sblock->fs_contigsumsize > 0) |
if (sblock->fs_contigsumsize > 0) |
313 |
{ |
{ |
314 |
long *sump = cg_clustersum (newcg); |
long *sump = cg_clustersum (newcg); |
316 |
int map = *mapp++; |
int map = *mapp++; |
317 |
int bit = 1; |
int bit = 1; |
318 |
int run = 0; |
int run = 0; |
319 |
|
|
320 |
for (i = 0; i < newcg->cg_nclusterblks; i++) |
for (i = 0; i < newcg->cg_nclusterblks; i++) |
321 |
{ |
{ |
322 |
if ((map & bit) != 0) |
if ((map & bit) != 0) |
363 |
pfix ("FIXED"); |
pfix ("FIXED"); |
364 |
} |
} |
365 |
} |
} |
366 |
|
|
367 |
/* Check inode and block maps */ |
/* Check inode and block maps */ |
368 |
if (bcmp (cg_inosused (newcg), cg_inosused (cg), mapsize)) |
if (bcmp (cg_inosused (newcg), cg_inosused (cg), mapsize)) |
369 |
{ |
{ |
375 |
pfix ("FIXED"); |
pfix ("FIXED"); |
376 |
} |
} |
377 |
} |
} |
378 |
|
|
379 |
if (bcmp (&cg_blktot(newcg)[0], &cg_blktot(cg)[0], sumsize)) |
if (bcmp (&cg_blktot(newcg)[0], &cg_blktot(cg)[0], sumsize)) |
380 |
{ |
{ |
381 |
problem (0, "SUMMARY INFORMATION FOR CG %d BAD", c); |
problem (0, "SUMMARY INFORMATION FOR CG %d BAD", c); |
386 |
pfix ("FIXED"); |
pfix ("FIXED"); |
387 |
} |
} |
388 |
} |
} |
389 |
|
|
390 |
if (bcmp (newcg, cg, basesize)) |
if (bcmp (newcg, cg, basesize)) |
391 |
{ |
{ |
392 |
problem (0, "CYLINDER GROUP %d BAD", c); |
problem (0, "CYLINDER GROUP %d BAD", c); |
399 |
} |
} |
400 |
|
|
401 |
if (writecg) |
if (writecg) |
402 |
writeblock (fsbtodb (sblock, cgtod (sblock, c)), |
writeblock (fsbtodb (sblock, cgtod (sblock, c)), |
403 |
cg, sblock->fs_cgsize); |
cg, sblock->fs_cgsize); |
404 |
} |
} |
405 |
|
|
406 |
/* Restore nrpos */ |
/* Restore nrpos */ |
407 |
if (sblock->fs_postblformat == FS_42POSTBLFMT) |
if (sblock->fs_postblformat == FS_42POSTBLFMT) |
408 |
sblock->fs_nrpos = savednrpos; |
sblock->fs_nrpos = savednrpos; |
409 |
|
|
410 |
if (bcmp (&cstotal, &sblock->fs_cstotal, sizeof (struct csum))) |
if (bcmp (&cstotal, &sblock->fs_cstotal, sizeof (struct csum))) |
411 |
{ |
{ |
412 |
problem (0, "TOTAL FREE BLK COUNTS WRONG IN SUPERBLOCK"); |
problem (0, "TOTAL FREE BLK COUNTS WRONG IN SUPERBLOCK"); |
430 |
pfix ("MARKED CLEAN"); |
pfix ("MARKED CLEAN"); |
431 |
} |
} |
432 |
} |
} |
433 |
|
|
434 |
if (writesb) |
if (writesb) |
435 |
writeblock (SBLOCK, sblock, SBSIZE); |
writeblock (SBLOCK, sblock, SBSIZE); |
436 |
|
|
437 |
if (writecsum) |
if (writecsum) |
438 |
{ |
{ |
439 |
|
const int cssize = fragroundup (sblock, sblock->fs_cssize); |
440 |
struct csum *test; |
struct csum *test; |
441 |
|
|
442 |
writeblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, |
writeblock (fsbtodb (sblock, sblock->fs_csaddr), sbcsums, |
443 |
fragroundup (sblock, sblock->fs_cssize)); |
fragroundup (sblock, sblock->fs_cssize)); |
444 |
|
|
445 |
test = alloca (fragroundup (sblock, sblock->fs_cssize)); |
test = alloca (cssize); |
446 |
readblock (fsbtodb (sblock, sblock->fs_csaddr), test, |
readblock (fsbtodb (sblock, sblock->fs_csaddr), test, cssize); |
447 |
fragroundup (sblock, sblock->fs_cssize)); |
if (bcmp (test, sbcsums, cssize)) |
|
if (bcmp (test, sbcsums, fragroundup (sblock, sblock->fs_cssize))) |
|
448 |
warning (0, "CSUM WRITE INCONSISTENT"); |
warning (0, "CSUM WRITE INCONSISTENT"); |
449 |
} |
} |
450 |
} |
} |