2 * Copyright (c) 1980, 1986 The Regents of the University of California.
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.
18 #include <afsconfig.h>
19 #include <afs/param.h>
23 #include <sys/param.h>
26 #include <sys/vnode.h>
27 #include <sys/mount.h>
28 #include <ufs/inode.h>
36 #else /* AFS_OSF_ENV */
37 #ifdef AFS_VFSINCL_ENV
38 #include <sys/vnode.h>
42 #include <sys/fs/ufs_inode.h>
43 #include <sys/fs/ufs_fs.h>
45 #include <sys/fs/ufs_fsdir.h>
47 #include <sys/fs/ufs_mount.h>
49 #include <ufs/inode.h>
52 #else /* AFS_VFSINCL_ENV */
53 #include <sys/inode.h>
56 #define LONGFILENAMES 1
57 #include <sys/sysmacros.h>
61 #endif /* AFS_VFSINCL_ENV */
62 #endif /* AFS_OSF_ENV */
63 #include <afs/osi_inode.h>
67 #if defined(AFS_SUN_ENV) || defined(AFS_OSF_ENV)
74 /* define enough so this thing compiles! */
75 #define FS_42POSTBLFMT 1
76 #define FS_DYNAMICPOSTBLFMT 2
77 #endif /* AFS_NEWCG_ENV */
81 int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
82 register struct fs *fs = &sblock;
83 register struct cg *cg = &cgrp;
90 struct inodesc idesc[3];
95 register struct cg *newcg = (struct cg *)buf;
96 struct ocg *ocg = (struct ocg *)buf;
97 #else /* AFS_NEWCG_ENV */
98 /* don't bother with newcg format yet, most systems don't support it */
99 register struct cg *newcg = (struct cg *)buf;
100 struct cg *ocg = (struct cg *)buf;
101 #endif /* AFS_NEWCG_ENV */
103 memset((char *)newcg, 0, (int)fs->fs_cgsize);
104 newcg->cg_niblk = fs->fs_ipg;
106 postype = (int)fs->fs_postblformat;
107 #else /* AFS_NEWCG_ENV */
108 postype = FS_42POSTBLFMT;
109 #endif /* AFS_NEWCG_ENV */
113 basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link);
114 sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]);
116 &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
117 (u_char *) & ocg->cg_iused[0];
118 ocg->cg_magic = CG_MAGIC;
120 savednrpos = fs->fs_nrpos;
122 #endif /* AFS_NEWCG_ENV */
126 case FS_DYNAMICPOSTBLFMT:
129 /* Matches decl in ufs/fs.h */
130 &newcg->cg_space[0] - (u_char *) (&newcg->cg_link[0]);
132 &newcg->cg_space[0] - (u_char *) (&newcg->cg_link);
134 newcg->cg_boff = newcg->cg_btotoff + fs->fs_cpg * sizeof(afs_int32);
136 newcg->cg_boff + fs->fs_cpg * fs->fs_nrpos * sizeof(short);
137 newcg->cg_freeoff = newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
138 newcg->cg_nextfreeoff =
139 newcg->cg_freeoff + howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs),
141 newcg->cg_magic = CG_MAGIC;
143 /* Matches decl in ufs/fs.h */
144 basesize = &newcg->cg_space[0] - (u_char *) (&newcg->cg_link[0]);
146 basesize = &newcg->cg_space[0] - (u_char *) (&newcg->cg_link);
148 sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
149 mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
153 errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", fs->fs_postblformat);
154 #endif /* AFS_NEWCG_ENV */
157 memset((char *)&idesc[0], 0, sizeof idesc);
158 for (i = 0; i < 3; i++)
159 idesc[i].id_type = ADDR;
160 memset((char *)&cstotal, 0, sizeof(struct csum));
163 /* this is the original from UCB/McKusick, but it is clearly wrong. It is
164 * rounding the # of fragments to the next 1024 (in our case, with a 1K/8K file system),
165 * while instead it should be rounding to the next block.
167 * In addition, we should be sure that we allocate enough space, but that seems to be
168 * ensured by the fact that the bitmap is rounded up to the nearest short, and that there
169 * are never more than 16 frags per block.
171 for (i = fs->fs_size; i < fragroundup(fs, fs->fs_size); i++)
173 c = 1 << fs->fs_fragshift; /* unit to which we want to round */
174 for (i = fs->fs_size; i < roundup(fs->fs_size, c); i++)
177 for (c = 0; c < fs->fs_ncg; c++) {
178 getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
180 if (!cg_chkmagic(cg))
181 pfatal("CG %d: BAD MAGIC NUMBER\n", c);
182 #else /* AFS_NEWCG_ENV */
183 if (cg->cg_magic != CG_MAGIC)
184 pfatal("CG %d: BAD MAGIC NUMBER\n", c);
185 #endif /* AFS_NEWCG_ENV */
186 dbase = cgbase(fs, c);
187 dmax = dbase + fs->fs_fpg;
188 if (dmax > fs->fs_size)
190 if (now > cg->cg_time)
191 newcg->cg_time = cg->cg_time;
193 newcg->cg_time = now;
195 if (c == fs->fs_ncg - 1)
196 newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
198 newcg->cg_ncyl = fs->fs_cpg;
199 newcg->cg_ndblk = dmax - dbase;
200 newcg->cg_cs.cs_ndir = 0;
201 newcg->cg_cs.cs_nffree = 0;
202 newcg->cg_cs.cs_nbfree = 0;
203 newcg->cg_cs.cs_nifree = fs->fs_ipg;
204 if (cg->cg_rotor < newcg->cg_ndblk)
205 newcg->cg_rotor = cg->cg_rotor;
208 if (cg->cg_frotor < newcg->cg_ndblk)
209 newcg->cg_frotor = cg->cg_frotor;
211 newcg->cg_frotor = 0;
212 if (cg->cg_irotor < newcg->cg_niblk)
213 newcg->cg_irotor = cg->cg_irotor;
215 newcg->cg_irotor = 0;
216 memset((char *)&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
218 memset((char *)&cg_blktot(newcg)[0], 0, sumsize + mapsize);
219 #else /* AFS_NEWCG_ENV */
220 memset((char *)newcg->cg_btot, 0, sizeof(newcg->cg_btot));
221 memset((char *)newcg->cg_b, 0, sizeof(newcg->cg_b));
222 memset((char *)newcg->cg_iused, 0, sizeof(newcg->cg_iused));
223 memset((char *)newcg->cg_free, 0, howmany(fs->fs_fpg, NBBY));
224 #endif /* AFS_NEWCG_ENV */
226 if (fs->fs_postblformat == FS_42POSTBLFMT)
227 ocg->cg_magic = CG_MAGIC;
228 #endif /* AFS_NEWCG_ENV */
230 for (i = 0; i < fs->fs_ipg; j++, i++) {
231 #if defined(ACLS) && defined(AFS_HPUX_ENV)
232 switch (statemap[j] & STATE) {
234 switch (statemap[j]) {
242 newcg->cg_cs.cs_ndir++;
250 newcg->cg_cs.cs_nifree--;
252 setbit(cg_inosused(newcg), i);
254 setbit(newcg->cg_iused, i);
255 #endif /* AFS_NEWCG_ENV */
258 #if defined(ACLS) && defined(AFS_HPUX_ENV)
259 /* hpux has more dynamic states (CSTATE, CRSTATE) */
267 errexit("BAD STATE %d FOR INODE I=%d", statemap[j], j);
271 for (i = 0; i < ROOTINO; i++) {
273 setbit(cg_inosused(newcg), i);
275 setbit(newcg->cg_iused, i);
276 #endif /* AFS_NEWCG_ENV */
277 newcg->cg_cs.cs_nifree--;
279 for (i = 0, d = dbase; d < dmax; d += fs->fs_frag, i += fs->fs_frag) {
281 for (j = 0; j < fs->fs_frag; j++) {
285 setbit(cg_blksfree(newcg), i + j);
286 #else /* AFS_NEWCG_ENV */
287 setbit(newcg->cg_free, i + j);
288 #endif /* AFS_NEWCG_ENV */
291 if (frags == fs->fs_frag) {
292 newcg->cg_cs.cs_nbfree++;
293 j = cbtocylno(fs, i);
295 cg_blktot(newcg)[j]++;
296 cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
297 #else /* AFS_NEWCG_ENV */
299 newcg->cg_b[j][cbtorpos(fs, i)]++;
300 #endif /* AFS_NEWCG_ENV */
301 } else if (frags > 0) {
302 newcg->cg_cs.cs_nffree += frags;
304 blk = blkmap(fs, cg_blksfree(newcg), i);
305 #else /* AFS_NEWCG_ENV */
306 blk = blkmap(fs, newcg->cg_free, i);
307 #endif /* AFS_NEWCG_ENV */
308 fragacct(fs, blk, newcg->cg_frsum, 1);
311 cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
312 cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
313 cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
314 cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
315 cs = &fs->fs_cs(fs, c);
316 if (memcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0
318 "FREE BLK COUNT(S) WRONG IN CYL GROUP (SUPERBLK)")) {
319 memcpy((char *)cs, (char *)&newcg->cg_cs, sizeof *cs);
324 memcpy((char *)cg, (char *)newcg, (int)fs->fs_cgsize);
328 #endif /* AFS_NEWCG_ENV */
330 if (memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0
331 && dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
332 memcpy(cg_inosused(cg), cg_inosused(newcg), mapsize);
335 #else /* AFS_NEWCG_ENV */
336 if (memcmp(newcg->cg_iused, cg->cg_iused, mapsize) != 0
337 && dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
338 memcpy(cg->cg_iused, newcg->cg_iused, mapsize);
341 #endif /* AFS_NEWCG_ENV */
342 if ((memcmp((char *)newcg, (char *)cg, basesize) != 0 ||
344 memcmp((char *)&cg_blktot(newcg)[0], (char *)&cg_blktot(cg)[0],
346 #else /* AFS_NEWCG_ENV */
347 memcmp((char *)newcg->cg_btot, (char *)cg->cg_btot,
349 #endif /* AFS_NEWCG_ENV */
350 dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
352 memcpy((char *)cg, (char *)newcg, basesize);
353 memcpy((char *)&cg_blktot(cg)[0], (char *)&cg_blktot(newcg)[0],
355 #else /* AFS_NEWCG_ENV */
356 memcpy((char *)cg, (char *)newcg, basesize);
357 memcpy((char *)cg->cg_btot, (char *)newcg->cg_btot, sumsize);
358 #endif /* AFS_NEWCG_ENV */
363 if (fs->fs_postblformat == FS_42POSTBLFMT)
364 fs->fs_nrpos = savednrpos;
365 #endif /* AFS_NEWCG_ENV */
366 if (memcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0
367 && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
368 memcpy((char *)&fs->fs_cstotal, (char *)&cstotal, sizeof *cs);
375 /* returns true if sbdirty should be called */
377 register struct fs *fs;
381 if (fs->fs_fmod != 0) {