Import Upstream version 1.8.5
[hcoop/debian/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 }