2632e247e1370771afe7bdbe477e8679dc3a9df7
[openafs.git] / src / vfsck / pass5.c
1 /*
2  * Copyright (c) 1980, 1986 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that the above copyright notice and this paragraph are
7  * duplicated in all such forms and that any documentation,
8  * advertising materials, and other materials related to such
9  * distribution and use acknowledge that the software was developed
10  * by the University of California, Berkeley.  The name of the
11  * University may not be used to endorse or promote products derived
12  * from this software without specific prior written permission.
13  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
14  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16  */
17
18 #include <afsconfig.h>
19 #include <afs/param.h>
20
21 #include <roken.h>
22
23 #include <ctype.h>
24
25 #define VICE
26 #ifdef  AFS_OSF_ENV
27 #include <sys/vnode.h>
28 #include <sys/mount.h>
29 #include <ufs/inode.h>
30 #include <ufs/fs.h>
31 #define _BSD
32 #define _KERNEL
33 #include <ufs/dir.h>
34 #undef  _KERNEL
35 #undef  _BSD
36 #else /* AFS_OSF_ENV */
37 #ifdef AFS_VFSINCL_ENV
38 #include <sys/vnode.h>
39 #ifdef    AFS_SUN5_ENV
40 #include <sys/fs/ufs_inode.h>
41 #include <sys/fs/ufs_fs.h>
42 #define _KERNEL
43 #include <sys/fs/ufs_fsdir.h>
44 #undef _KERNEL
45 #include <sys/fs/ufs_mount.h>
46 #else
47 #include <ufs/inode.h>
48 #include <ufs/fs.h>
49 #endif
50 #else /* AFS_VFSINCL_ENV */
51 #include <sys/inode.h>
52 #ifdef  AFS_HPUX_ENV
53 #define LONGFILENAMES   1
54 #include <sys/sysmacros.h>
55 #include <sys/ino.h>
56 #endif
57 #include <sys/fs.h>
58 #endif /* AFS_VFSINCL_ENV */
59 #endif /* AFS_OSF_ENV */
60 #include <afs/osi_inode.h>
61
62 #include "fsck.h"
63
64 #if     defined(AFS_SUN_ENV) || defined(AFS_OSF_ENV)
65 #define AFS_NEWCG_ENV
66 #else
67 #undef AFS_NEWCG_ENV
68 #endif
69
70 #ifndef AFS_NEWCG_ENV
71 /* define enough so this thing compiles! */
72 #define FS_42POSTBLFMT          1
73 #define FS_DYNAMICPOSTBLFMT     2
74 #endif /* AFS_NEWCG_ENV */
75
76 pass5()
77 {
78     int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
79     struct fs *fs = &sblock;
80     struct cg *cg = &cgrp;
81     daddr_t dbase, dmax;
82     daddr_t d;
83     long i, j;
84     struct csum *cs;
85     time_t now;
86     struct csum cstotal;
87     struct inodesc idesc[3];
88     char buf[MAXBSIZE];
89     int postype;
90
91 #ifdef AFS_NEWCG_ENV
92     struct cg *newcg = (struct cg *)buf;
93     struct ocg *ocg = (struct ocg *)buf;
94 #else /* AFS_NEWCG_ENV */
95     /* don't bother with newcg format yet, most systems don't support it */
96     struct cg *newcg = (struct cg *)buf;
97     struct cg *ocg = (struct cg *)buf;
98 #endif /* AFS_NEWCG_ENV */
99
100     memset(newcg, 0, (int)fs->fs_cgsize);
101     newcg->cg_niblk = fs->fs_ipg;
102 #ifdef AFS_NEWCG_ENV
103     postype = (int)fs->fs_postblformat;
104 #else /* AFS_NEWCG_ENV */
105     postype = FS_42POSTBLFMT;
106 #endif /* AFS_NEWCG_ENV */
107     switch (postype) {
108
109     case FS_42POSTBLFMT:
110         basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link);
111         sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]);
112         mapsize =
113             &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
114             (u_char *) & ocg->cg_iused[0];
115         ocg->cg_magic = CG_MAGIC;
116 #ifdef AFS_NEWCG_ENV
117         savednrpos = fs->fs_nrpos;
118         fs->fs_nrpos = 8;
119 #endif /* AFS_NEWCG_ENV */
120         break;
121
122 #ifdef AFS_NEWCG_ENV
123     case FS_DYNAMICPOSTBLFMT:
124         newcg->cg_btotoff =
125 #ifdef  __alpha
126             /* Matches decl in ufs/fs.h */
127             &newcg->cg_space[0] - (u_char *) (&newcg->cg_link[0]);
128 #else /* __alpha */
129             &newcg->cg_space[0] - (u_char *) (&newcg->cg_link);
130 #endif
131         newcg->cg_boff = newcg->cg_btotoff + fs->fs_cpg * sizeof(afs_int32);
132         newcg->cg_iusedoff =
133             newcg->cg_boff + fs->fs_cpg * fs->fs_nrpos * sizeof(short);
134         newcg->cg_freeoff = newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
135         newcg->cg_nextfreeoff =
136             newcg->cg_freeoff + howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs),
137                                         NBBY);
138         newcg->cg_magic = CG_MAGIC;
139 #ifdef  __alpha
140         /* Matches decl in ufs/fs.h */
141         basesize = &newcg->cg_space[0] - (u_char *) (&newcg->cg_link[0]);
142 #else /* __alpha */
143         basesize = &newcg->cg_space[0] - (u_char *) (&newcg->cg_link);
144 #endif
145         sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
146         mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
147         break;
148
149     default:
150         errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", fs->fs_postblformat);
151 #endif /* AFS_NEWCG_ENV */
152
153     }
154     memset(&idesc[0], 0, sizeof idesc);
155     for (i = 0; i < 3; i++)
156         idesc[i].id_type = ADDR;
157     memset(&cstotal, 0, sizeof(struct csum));
158     (void)time(&now);
159 #ifdef notdef
160     /* this is the original from UCB/McKusick, but it is clearly wrong.  It is
161      * rounding the # of fragments to the next 1024 (in our case, with a 1K/8K file system),
162      * while instead it should be rounding to the next block.
163      *
164      * In addition, we should be sure that we allocate enough space, but that seems to be
165      * ensured by the fact that the bitmap is rounded up to the nearest short, and that there
166      * are never more than 16 frags per block.
167      */
168     for (i = fs->fs_size; i < fragroundup(fs, fs->fs_size); i++)
169 #else
170     c = 1 << fs->fs_fragshift;  /* unit to which we want to round */
171     for (i = fs->fs_size; i < roundup(fs->fs_size, c); i++)
172 #endif
173         setbmap(i);
174     for (c = 0; c < fs->fs_ncg; c++) {
175         getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
176 #ifdef AFS_NEWCG_ENV
177         if (!cg_chkmagic(cg))
178             pfatal("CG %d: BAD MAGIC NUMBER\n", c);
179 #else /* AFS_NEWCG_ENV */
180         if (cg->cg_magic != CG_MAGIC)
181             pfatal("CG %d: BAD MAGIC NUMBER\n", c);
182 #endif /* AFS_NEWCG_ENV */
183         dbase = cgbase(fs, c);
184         dmax = dbase + fs->fs_fpg;
185         if (dmax > fs->fs_size)
186             dmax = fs->fs_size;
187         if (now > cg->cg_time)
188             newcg->cg_time = cg->cg_time;
189         else
190             newcg->cg_time = now;
191         newcg->cg_cgx = c;
192         if (c == fs->fs_ncg - 1)
193             newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
194         else
195             newcg->cg_ncyl = fs->fs_cpg;
196         newcg->cg_ndblk = dmax - dbase;
197         newcg->cg_cs.cs_ndir = 0;
198         newcg->cg_cs.cs_nffree = 0;
199         newcg->cg_cs.cs_nbfree = 0;
200         newcg->cg_cs.cs_nifree = fs->fs_ipg;
201         if (cg->cg_rotor < newcg->cg_ndblk)
202             newcg->cg_rotor = cg->cg_rotor;
203         else
204             newcg->cg_rotor = 0;
205         if (cg->cg_frotor < newcg->cg_ndblk)
206             newcg->cg_frotor = cg->cg_frotor;
207         else
208             newcg->cg_frotor = 0;
209         if (cg->cg_irotor < newcg->cg_niblk)
210             newcg->cg_irotor = cg->cg_irotor;
211         else
212             newcg->cg_irotor = 0;
213         memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
214 #ifdef AFS_NEWCG_ENV
215         memset(&cg_blktot(newcg)[0], 0, sumsize + mapsize);
216 #else /* AFS_NEWCG_ENV */
217         memset(newcg->cg_btot, 0, sizeof(newcg->cg_btot));
218         memset(newcg->cg_b, 0, sizeof(newcg->cg_b));
219         memset(newcg->cg_iused, 0, sizeof(newcg->cg_iused));
220         memset(newcg->cg_free, 0, howmany(fs->fs_fpg, NBBY));
221 #endif /* AFS_NEWCG_ENV */
222 #ifdef AFS_NEWCG_ENV
223         if (fs->fs_postblformat == FS_42POSTBLFMT)
224             ocg->cg_magic = CG_MAGIC;
225 #endif /* AFS_NEWCG_ENV */
226         j = fs->fs_ipg * c;
227         for (i = 0; i < fs->fs_ipg; j++, i++) {
228 #if defined(ACLS) && defined(AFS_HPUX_ENV)
229             switch (statemap[j] & STATE) {
230 #else
231             switch (statemap[j]) {
232 #endif
233             case USTATE:
234                 break;
235
236             case DSTATE:
237             case DCLEAR:
238             case DFOUND:
239                 newcg->cg_cs.cs_ndir++;
240                 /* fall through */
241
242 #ifdef VICE
243             case VSTATE:
244 #endif /* VICE */
245             case FSTATE:
246             case FCLEAR:
247                 newcg->cg_cs.cs_nifree--;
248 #ifdef AFS_NEWCG_ENV
249                 setbit(cg_inosused(newcg), i);
250 #else
251                 setbit(newcg->cg_iused, i);
252 #endif /* AFS_NEWCG_ENV */
253                 break;
254
255 #if defined(ACLS) && defined(AFS_HPUX_ENV)
256                 /* hpux has more dynamic states (CSTATE, CRSTATE) */
257             case CSTATE:
258             case CRSTATE:
259                 break;
260 #endif
261             default:
262                 if (j < ROOTINO)
263                     break;
264                 errexit("BAD STATE %d FOR INODE I=%d", statemap[j], j);
265             }
266         }
267         if (c == 0)
268             for (i = 0; i < ROOTINO; i++) {
269 #ifdef AFS_NEWCG_ENV
270                 setbit(cg_inosused(newcg), i);
271 #else
272                 setbit(newcg->cg_iused, i);
273 #endif /* AFS_NEWCG_ENV */
274                 newcg->cg_cs.cs_nifree--;
275             }
276         for (i = 0, d = dbase; d < dmax; d += fs->fs_frag, i += fs->fs_frag) {
277             frags = 0;
278             for (j = 0; j < fs->fs_frag; j++) {
279                 if (testbmap(d + j))
280                     continue;
281 #ifdef AFS_NEWCG_ENV
282                 setbit(cg_blksfree(newcg), i + j);
283 #else /* AFS_NEWCG_ENV */
284                 setbit(newcg->cg_free, i + j);
285 #endif /* AFS_NEWCG_ENV */
286                 frags++;
287             }
288             if (frags == fs->fs_frag) {
289                 newcg->cg_cs.cs_nbfree++;
290                 j = cbtocylno(fs, i);
291 #ifdef AFS_NEWCG_ENV
292                 cg_blktot(newcg)[j]++;
293                 cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
294 #else /* AFS_NEWCG_ENV */
295                 newcg->cg_btot[j]++;
296                 newcg->cg_b[j][cbtorpos(fs, i)]++;
297 #endif /* AFS_NEWCG_ENV */
298             } else if (frags > 0) {
299                 newcg->cg_cs.cs_nffree += frags;
300 #ifdef AFS_NEWCG_ENV
301                 blk = blkmap(fs, cg_blksfree(newcg), i);
302 #else /* AFS_NEWCG_ENV */
303                 blk = blkmap(fs, newcg->cg_free, i);
304 #endif /* AFS_NEWCG_ENV */
305                 fragacct(fs, blk, newcg->cg_frsum, 1);
306             }
307         }
308         cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
309         cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
310         cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
311         cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
312         cs = &fs->fs_cs(fs, c);
313         if (memcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0
314             && dofix(&idesc[0],
315                      "FREE BLK COUNT(S) WRONG IN CYL GROUP (SUPERBLK)")) {
316             memcpy((char *)cs, (char *)&newcg->cg_cs, sizeof *cs);
317             sbdirty();
318         }
319 #ifdef AFS_NEWCG_ENV
320         if (cvtflag) {
321             memcpy((char *)cg, (char *)newcg, (int)fs->fs_cgsize);
322             cgdirty();
323             continue;
324         }
325 #endif /* AFS_NEWCG_ENV */
326 #ifdef AFS_NEWCG_ENV
327         if (memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0
328             && dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
329             memcpy(cg_inosused(cg), cg_inosused(newcg), mapsize);
330             cgdirty();
331         }
332 #else /* AFS_NEWCG_ENV */
333         if (memcmp(newcg->cg_iused, cg->cg_iused, mapsize) != 0
334             && dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
335             memcpy(cg->cg_iused, newcg->cg_iused, mapsize);
336             cgdirty();
337         }
338 #endif /* AFS_NEWCG_ENV */
339         if ((memcmp((char *)newcg, (char *)cg, basesize) != 0 ||
340 #ifdef AFS_NEWCG_ENV
341              memcmp((char *)&cg_blktot(newcg)[0], (char *)&cg_blktot(cg)[0],
342                     sumsize) != 0) &&
343 #else /* AFS_NEWCG_ENV */
344              memcmp((char *)newcg->cg_btot, (char *)cg->cg_btot,
345                     sumsize) != 0) &&
346 #endif /* AFS_NEWCG_ENV */
347             dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
348 #ifdef AFS_NEWCG_ENV
349             memcpy((char *)cg, (char *)newcg, basesize);
350             memcpy((char *)&cg_blktot(cg)[0], (char *)&cg_blktot(newcg)[0],
351                    sumsize);
352 #else /* AFS_NEWCG_ENV */
353             memcpy((char *)cg, (char *)newcg, basesize);
354             memcpy((char *)cg->cg_btot, (char *)newcg->cg_btot, sumsize);
355 #endif /* AFS_NEWCG_ENV */
356             cgdirty();
357         }
358     }
359 #ifdef AFS_NEWCG_ENV
360     if (fs->fs_postblformat == FS_42POSTBLFMT)
361         fs->fs_nrpos = savednrpos;
362 #endif /* AFS_NEWCG_ENV */
363     if (memcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0
364         && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
365         memcpy((char *)&fs->fs_cstotal, (char *)&cstotal, sizeof *cs);
366         fs->fs_ronly = 0;
367         sbfine(fs);
368         sbdirty();
369     }
370 }
371
372 /* returns true if sbdirty should be called */
373 sbfine(fs)
374      struct fs *fs;
375 {
376     int rcode;
377     rcode = 0;
378     if (fs->fs_fmod != 0) {
379         fs->fs_fmod = 0;
380         rcode = 1;
381     }
382     return rcode;
383 }