Correct BSD License clause numbering from 1-2-4 to 1-2-3.
[dragonfly.git] / sbin / fsck / pass5.c
1 /*
2  * Copyright (c) 1980, 1986, 1993
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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. Neither the name of the University nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * @(#)pass5.c  8.9 (Berkeley) 4/28/95
30  * $FreeBSD: src/sbin/fsck/pass5.c,v 1.17.2.2 2002/11/26 04:46:59 julian Exp $
31  */
32
33 #include <sys/param.h>
34
35 #include <vfs/ufs/dinode.h>
36 #include <vfs/ufs/fs.h>
37
38 #include <err.h>
39 #include <string.h>
40
41 #include "fsck.h"
42
43 void
44 pass5(void)
45 {
46         int c, blk, frags, basesize, sumsize, mapsize, savednrpos = 0;
47         int inomapsize, blkmapsize;
48         struct fs *fs = &sblock;
49         struct cg *cg = &cgrp;
50         ufs_daddr_t dbase, dmax;
51         ufs_daddr_t d;
52         long i, j, k;
53         struct csum *cs;
54         struct csum cstotal;
55         struct inodesc idesc[3];
56         char buf[MAXBSIZE];
57         struct cg *newcg = (struct cg *)buf;
58         struct ocg *ocg = (struct ocg *)buf;
59
60         inoinfo(WINO)->ino_state = USTATE;
61         memset(newcg, 0, (size_t)fs->fs_cgsize);
62         newcg->cg_niblk = fs->fs_ipg;
63         if (cvtlevel >= 3) {
64                 if (fs->fs_maxcontig < 2 && fs->fs_contigsumsize > 0) {
65                         if (preen)
66                                 pwarn("DELETING CLUSTERING MAPS\n");
67                         if (preen || reply("DELETE CLUSTERING MAPS")) {
68                                 fs->fs_contigsumsize = 0;
69                                 doinglevel1 = 1;
70                                 sbdirty();
71                         }
72                 }
73                 if (fs->fs_maxcontig > 1) {
74                         char *doit = NULL;
75
76                         if (fs->fs_contigsumsize < 1) {
77                                 doit = "CREAT";
78                         } else if (fs->fs_contigsumsize < fs->fs_maxcontig &&
79                                    fs->fs_contigsumsize < FS_MAXCONTIG) {
80                                 doit = "EXPAND";
81                         }
82                         if (doit) {
83                                 i = fs->fs_contigsumsize;
84                                 fs->fs_contigsumsize =
85                                     MIN(fs->fs_maxcontig, FS_MAXCONTIG);
86                                 if (CGSIZE(fs) > fs->fs_bsize) {
87                                         pwarn("CANNOT %s CLUSTER MAPS\n", doit);
88                                         fs->fs_contigsumsize = i;
89                                 } else if (preen ||
90                                     reply("CREATE CLUSTER MAPS")) {
91                                         if (preen)
92                                                 pwarn("%sING CLUSTER MAPS\n",
93                                                     doit);
94                                         fs->fs_cgsize =
95                                             fragroundup(fs, CGSIZE(fs));
96                                         doinglevel1 = 1;
97                                         sbdirty();
98                                 }
99                         }
100                 }
101         }
102         switch ((int)fs->fs_postblformat) {
103
104         case FS_42POSTBLFMT:
105                 basesize = (char *)(&ocg->cg_btot[0]) -
106                     (char *)(&ocg->cg_firstfield);
107                 sumsize = &ocg->cg_iused[0] - (u_int8_t *)(&ocg->cg_btot[0]);
108                 mapsize = &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
109                         (u_char *)&ocg->cg_iused[0];
110                 blkmapsize = howmany(fs->fs_fpg, NBBY);
111                 inomapsize = &ocg->cg_free[0] - (u_char *)&ocg->cg_iused[0];
112                 ocg->cg_magic = CG_MAGIC;
113                 savednrpos = fs->fs_nrpos;
114                 fs->fs_nrpos = 8;
115                 break;
116
117         case FS_DYNAMICPOSTBLFMT:
118                 newcg->cg_btotoff =
119                      &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield);
120                 newcg->cg_boff =
121                     newcg->cg_btotoff + fs->fs_cpg * sizeof(int32_t);
122                 newcg->cg_iusedoff = newcg->cg_boff +
123                     fs->fs_cpg * fs->fs_nrpos * sizeof(u_int16_t);
124                 newcg->cg_freeoff =
125                     newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
126                 inomapsize = newcg->cg_freeoff - newcg->cg_iusedoff;
127                 newcg->cg_nextfreeoff = newcg->cg_freeoff +
128                     howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs), NBBY);
129                 blkmapsize = newcg->cg_nextfreeoff - newcg->cg_freeoff;
130                 if (fs->fs_contigsumsize > 0) {
131                         newcg->cg_clustersumoff = newcg->cg_nextfreeoff -
132                             sizeof(u_int32_t);
133                         newcg->cg_clustersumoff =
134                             roundup(newcg->cg_clustersumoff, sizeof(u_int32_t));
135                         newcg->cg_clusteroff = newcg->cg_clustersumoff +
136                             (fs->fs_contigsumsize + 1) * sizeof(u_int32_t);
137                         newcg->cg_nextfreeoff = newcg->cg_clusteroff +
138                             howmany(fs->fs_cpg * fs->fs_spc / NSPB(fs), NBBY);
139                 }
140                 newcg->cg_magic = CG_MAGIC;
141                 basesize = &newcg->cg_space[0] -
142                     (u_char *)(&newcg->cg_firstfield);
143                 sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
144                 mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
145                 break;
146
147         default:
148                 inomapsize = blkmapsize = sumsize = 0;  /* keep lint happy */
149                 errx(EEXIT, "UNKNOWN ROTATIONAL TABLE FORMAT %d",
150                         fs->fs_postblformat);
151         }
152         memset(&idesc[0], 0, sizeof idesc);
153         for (i = 0; i < 3; i++) {
154                 idesc[i].id_type = ADDR;
155                 if (doinglevel2)
156                         idesc[i].id_fix = FIX;
157         }
158         memset(&cstotal, 0, sizeof(struct csum));
159         j = blknum(fs, fs->fs_size + fs->fs_frag - 1);
160         for (i = fs->fs_size; i < j; i++)
161                 setbmap(i);
162         for (c = 0; c < fs->fs_ncg; c++) {
163                 if (got_siginfo) {
164                         printf("%s: phase 5: cyl group %d of %d (%d%%)\n",
165                             cdevname, c, sblock.fs_ncg,
166                             c * 100 / sblock.fs_ncg);
167                         got_siginfo = 0;
168                 }
169                 getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
170                 if (!cg_chkmagic(cg))
171                         pfatal("CG %d: BAD MAGIC NUMBER\n", c);
172                 dbase = cgbase(fs, c);
173                 dmax = dbase + fs->fs_fpg;
174                 if (dmax > fs->fs_size)
175                         dmax = fs->fs_size;
176                 newcg->cg_time = cg->cg_time;
177                 newcg->cg_cgx = c;
178                 if (c == fs->fs_ncg - 1)
179                         newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
180                 else
181                         newcg->cg_ncyl = fs->fs_cpg;
182                 newcg->cg_ndblk = dmax - dbase;
183                 if (fs->fs_contigsumsize > 0)
184                         newcg->cg_nclusterblks = newcg->cg_ndblk / fs->fs_frag;
185                 newcg->cg_cs.cs_ndir = 0;
186                 newcg->cg_cs.cs_nffree = 0;
187                 newcg->cg_cs.cs_nbfree = 0;
188                 newcg->cg_cs.cs_nifree = fs->fs_ipg;
189                 if ((cg->cg_rotor >= 0) && (cg->cg_rotor < newcg->cg_ndblk))
190                         newcg->cg_rotor = cg->cg_rotor;
191                 else
192                         newcg->cg_rotor = 0;
193                 if ((cg->cg_frotor >= 0) && (cg->cg_frotor < newcg->cg_ndblk))
194                         newcg->cg_frotor = cg->cg_frotor;
195                 else
196                         newcg->cg_frotor = 0;
197                 if ((cg->cg_irotor >= 0) && (cg->cg_irotor < newcg->cg_niblk))
198                         newcg->cg_irotor = cg->cg_irotor;
199                 else
200                         newcg->cg_irotor = 0;
201                 memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
202                 memset(&cg_blktot(newcg)[0], 0,
203                       (size_t)(sumsize + mapsize));
204                 if (fs->fs_postblformat == FS_42POSTBLFMT)
205                         ocg->cg_magic = CG_MAGIC;
206                 j = fs->fs_ipg * c;
207                 for (i = 0; i < inostathead[c].il_numalloced; j++, i++) {
208                         switch (inoinfo(j)->ino_state) {
209
210                         case USTATE:
211                                 break;
212
213                         case DSTATE:
214                         case DCLEAR:
215                         case DFOUND:
216                                 newcg->cg_cs.cs_ndir++;
217                                 /* fall through */
218
219                         case FSTATE:
220                         case FCLEAR:
221                                 newcg->cg_cs.cs_nifree--;
222                                 setbit(cg_inosused(newcg), i);
223                                 break;
224
225                         default:
226                                 if (j < ROOTINO)
227                                         break;
228                                 errx(EEXIT, "BAD STATE %d FOR INODE I=%ld",
229                                     inoinfo(j)->ino_state, j);
230                         }
231                 }
232                 if (c == 0)
233                         for (i = 0; i < ROOTINO; i++) {
234                                 setbit(cg_inosused(newcg), i);
235                                 newcg->cg_cs.cs_nifree--;
236                         }
237                 for (i = 0, d = dbase;
238                      d < dmax;
239                      d += fs->fs_frag, i += fs->fs_frag) {
240                         frags = 0;
241                         for (j = 0; j < fs->fs_frag; j++) {
242                                 if (testbmap(d + j))
243                                         continue;
244                                 setbit(cg_blksfree(newcg), i + j);
245                                 frags++;
246                         }
247                         if (frags == fs->fs_frag) {
248                                 newcg->cg_cs.cs_nbfree++;
249                                 j = cbtocylno(fs, i);
250                                 cg_blktot(newcg)[j]++;
251                                 cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
252                                 if (fs->fs_contigsumsize > 0)
253                                         setbit(cg_clustersfree(newcg),
254                                             i / fs->fs_frag);
255                         } else if (frags > 0) {
256                                 newcg->cg_cs.cs_nffree += frags;
257                                 blk = blkmap(fs, cg_blksfree(newcg), i);
258                                 ffs_fragacct(fs, blk, newcg->cg_frsum, 1);
259                         }
260                 }
261                 if (fs->fs_contigsumsize > 0) {
262                         int32_t *sump = cg_clustersum(newcg);
263                         u_char *mapp = cg_clustersfree(newcg);
264                         int map = *mapp++;
265                         int bit = 1;
266                         int run = 0;
267
268                         for (i = 0; i < newcg->cg_nclusterblks; i++) {
269                                 if ((map & bit) != 0) {
270                                         run++;
271                                 } else if (run != 0) {
272                                         if (run > fs->fs_contigsumsize)
273                                                 run = fs->fs_contigsumsize;
274                                         sump[run]++;
275                                         run = 0;
276                                 }
277                                 if ((i & (NBBY - 1)) != (NBBY - 1)) {
278                                         bit <<= 1;
279                                 } else {
280                                         map = *mapp++;
281                                         bit = 1;
282                                 }
283                         }
284                         if (run != 0) {
285                                 if (run > fs->fs_contigsumsize)
286                                         run = fs->fs_contigsumsize;
287                                 sump[run]++;
288                         }
289                 }
290                 cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
291                 cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
292                 cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
293                 cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
294                 cs = &fs->fs_cs(fs, c);
295                 if (memcmp(&newcg->cg_cs, cs, sizeof *cs) != 0 &&
296                     dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
297                         memmove(cs, &newcg->cg_cs, sizeof *cs);
298                         sbdirty();
299                 }
300                 if (doinglevel1) {
301                         memmove(cg, newcg, (size_t)fs->fs_cgsize);
302                         cgdirty();
303                         continue;
304                 }
305                 if ((memcmp(newcg, cg, basesize) != 0 ||
306                      memcmp(&cg_blktot(newcg)[0],
307                           &cg_blktot(cg)[0], sumsize) != 0) &&
308                     dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
309                         memmove(cg, newcg, (size_t)basesize);
310                         memmove(&cg_blktot(cg)[0],
311                                &cg_blktot(newcg)[0], (size_t)sumsize);
312                         cgdirty();
313                 }
314                 if (usedsoftdep) {
315                         for (i = 0; i < inomapsize; i++) {
316                                 j = cg_inosused(newcg)[i];
317                                 if ((cg_inosused(cg)[i] & j) == j)
318                                         continue;
319                                 for (k = 0; k < NBBY; k++) {
320                                         if ((j & (1 << k)) == 0)
321                                                 continue;
322                                         if (cg_inosused(cg)[i] & (1 << k))
323                                                 continue;
324                                         pwarn("ALLOCATED INODE %d MARKED FREE\n",
325                                             c * fs->fs_ipg + i * NBBY + k);
326                                 }
327                         }
328                         for (i = 0; i < blkmapsize; i++) {
329                                 j = cg_blksfree(cg)[i];
330                                 if ((cg_blksfree(newcg)[i] & j) == j)
331                                         continue;
332                                 for (k = 0; k < NBBY; k++) {
333                                         if ((j & (1 << k)) == 0)
334                                                 continue;
335                                         if (cg_blksfree(newcg)[i] & (1 << k))
336                                                 continue;
337                                         pwarn("ALLOCATED FRAG %d MARKED FREE\n",
338                                             c * fs->fs_fpg + i * NBBY + k);
339                                 }
340                         }
341                 }
342                 if (memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0 &&
343                     dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
344                         memmove(cg_inosused(cg), cg_inosused(newcg),
345                               (size_t)mapsize);
346                         cgdirty();
347                 }
348         }
349         if (fs->fs_postblformat == FS_42POSTBLFMT)
350                 fs->fs_nrpos = savednrpos;
351         if (memcmp(&cstotal, &fs->fs_cstotal, sizeof *cs) != 0
352             && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
353                 memmove(&fs->fs_cstotal, &cstotal, sizeof *cs);
354                 fs->fs_ronly = 0;
355                 fs->fs_fmod = 0;
356                 sbdirty();
357         }
358 }