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>
26 #ifdef AFS_VFSINCL_ENV
27 #include <sys/vnode.h>
29 #include <sys/fs/ufs_inode.h>
30 #include <sys/fs/ufs_fs.h>
32 #include <sys/fs/ufs_fsdir.h>
34 #include <sys/fs/ufs_mount.h>
36 #include <ufs/inode.h>
39 #else /* AFS_VFSINCL_ENV */
40 #include <sys/inode.h>
42 #define LONGFILENAMES 1
43 #include <sys/sysmacros.h>
47 #endif /* AFS_VFSINCL_ENV */
48 #include <afs/osi_inode.h>
52 #if defined(AFS_SUN_ENV)
59 /* define enough so this thing compiles! */
60 #define FS_42POSTBLFMT 1
61 #define FS_DYNAMICPOSTBLFMT 2
62 #endif /* AFS_NEWCG_ENV */
66 int c, blk, frags, basesize, sumsize, mapsize, savednrpos;
67 struct fs *fs = &sblock;
68 struct cg *cg = &cgrp;
75 struct inodesc idesc[3];
80 struct cg *newcg = (struct cg *)buf;
81 struct ocg *ocg = (struct ocg *)buf;
82 #else /* AFS_NEWCG_ENV */
83 /* don't bother with newcg format yet, most systems don't support it */
84 struct cg *newcg = (struct cg *)buf;
85 struct cg *ocg = (struct cg *)buf;
86 #endif /* AFS_NEWCG_ENV */
88 memset(newcg, 0, (int)fs->fs_cgsize);
89 newcg->cg_niblk = fs->fs_ipg;
91 postype = (int)fs->fs_postblformat;
92 #else /* AFS_NEWCG_ENV */
93 postype = FS_42POSTBLFMT;
94 #endif /* AFS_NEWCG_ENV */
98 basesize = (char *)(&ocg->cg_btot[0]) - (char *)(&ocg->cg_link);
99 sumsize = &ocg->cg_iused[0] - (char *)(&ocg->cg_btot[0]);
101 &ocg->cg_free[howmany(fs->fs_fpg, NBBY)] -
102 (u_char *) & ocg->cg_iused[0];
103 ocg->cg_magic = CG_MAGIC;
105 savednrpos = fs->fs_nrpos;
107 #endif /* AFS_NEWCG_ENV */
111 case FS_DYNAMICPOSTBLFMT:
114 /* Matches decl in ufs/fs.h */
115 &newcg->cg_space[0] - (u_char *) (&newcg->cg_link[0]);
117 &newcg->cg_space[0] - (u_char *) (&newcg->cg_link);
119 newcg->cg_boff = newcg->cg_btotoff + fs->fs_cpg * sizeof(afs_int32);
121 newcg->cg_boff + fs->fs_cpg * fs->fs_nrpos * sizeof(short);
122 newcg->cg_freeoff = newcg->cg_iusedoff + howmany(fs->fs_ipg, NBBY);
123 newcg->cg_nextfreeoff =
124 newcg->cg_freeoff + howmany(fs->fs_cpg * fs->fs_spc / NSPF(fs),
126 newcg->cg_magic = CG_MAGIC;
128 /* Matches decl in ufs/fs.h */
129 basesize = &newcg->cg_space[0] - (u_char *) (&newcg->cg_link[0]);
131 basesize = &newcg->cg_space[0] - (u_char *) (&newcg->cg_link);
133 sumsize = newcg->cg_iusedoff - newcg->cg_btotoff;
134 mapsize = newcg->cg_nextfreeoff - newcg->cg_iusedoff;
138 errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", fs->fs_postblformat);
139 #endif /* AFS_NEWCG_ENV */
142 memset(&idesc[0], 0, sizeof idesc);
143 for (i = 0; i < 3; i++)
144 idesc[i].id_type = ADDR;
145 memset(&cstotal, 0, sizeof(struct csum));
147 c = 1 << fs->fs_fragshift; /* unit to which we want to round */
148 for (i = fs->fs_size; i < roundup(fs->fs_size, c); i++)
150 for (c = 0; c < fs->fs_ncg; c++) {
151 getblk(&cgblk, cgtod(fs, c), fs->fs_cgsize);
153 if (!cg_chkmagic(cg))
154 pfatal("CG %d: BAD MAGIC NUMBER\n", c);
155 #else /* AFS_NEWCG_ENV */
156 if (cg->cg_magic != CG_MAGIC)
157 pfatal("CG %d: BAD MAGIC NUMBER\n", c);
158 #endif /* AFS_NEWCG_ENV */
159 dbase = cgbase(fs, c);
160 dmax = dbase + fs->fs_fpg;
161 if (dmax > fs->fs_size)
163 if (now > cg->cg_time)
164 newcg->cg_time = cg->cg_time;
166 newcg->cg_time = now;
168 if (c == fs->fs_ncg - 1)
169 newcg->cg_ncyl = fs->fs_ncyl % fs->fs_cpg;
171 newcg->cg_ncyl = fs->fs_cpg;
172 newcg->cg_ndblk = dmax - dbase;
173 newcg->cg_cs.cs_ndir = 0;
174 newcg->cg_cs.cs_nffree = 0;
175 newcg->cg_cs.cs_nbfree = 0;
176 newcg->cg_cs.cs_nifree = fs->fs_ipg;
177 if (cg->cg_rotor < newcg->cg_ndblk)
178 newcg->cg_rotor = cg->cg_rotor;
181 if (cg->cg_frotor < newcg->cg_ndblk)
182 newcg->cg_frotor = cg->cg_frotor;
184 newcg->cg_frotor = 0;
185 if (cg->cg_irotor < newcg->cg_niblk)
186 newcg->cg_irotor = cg->cg_irotor;
188 newcg->cg_irotor = 0;
189 memset(&newcg->cg_frsum[0], 0, sizeof newcg->cg_frsum);
191 memset(&cg_blktot(newcg)[0], 0, sumsize + mapsize);
192 #else /* AFS_NEWCG_ENV */
193 memset(newcg->cg_btot, 0, sizeof(newcg->cg_btot));
194 memset(newcg->cg_b, 0, sizeof(newcg->cg_b));
195 memset(newcg->cg_iused, 0, sizeof(newcg->cg_iused));
196 memset(newcg->cg_free, 0, howmany(fs->fs_fpg, NBBY));
197 #endif /* AFS_NEWCG_ENV */
199 if (fs->fs_postblformat == FS_42POSTBLFMT)
200 ocg->cg_magic = CG_MAGIC;
201 #endif /* AFS_NEWCG_ENV */
203 for (i = 0; i < fs->fs_ipg; j++, i++) {
204 #if defined(ACLS) && defined(AFS_HPUX_ENV)
205 switch (statemap[j] & STATE) {
207 switch (statemap[j]) {
215 newcg->cg_cs.cs_ndir++;
223 newcg->cg_cs.cs_nifree--;
225 setbit(cg_inosused(newcg), i);
227 setbit(newcg->cg_iused, i);
228 #endif /* AFS_NEWCG_ENV */
231 #if defined(ACLS) && defined(AFS_HPUX_ENV)
232 /* hpux has more dynamic states (CSTATE, CRSTATE) */
240 errexit("BAD STATE %d FOR INODE I=%d", statemap[j], j);
244 for (i = 0; i < ROOTINO; i++) {
246 setbit(cg_inosused(newcg), i);
248 setbit(newcg->cg_iused, i);
249 #endif /* AFS_NEWCG_ENV */
250 newcg->cg_cs.cs_nifree--;
252 for (i = 0, d = dbase; d < dmax; d += fs->fs_frag, i += fs->fs_frag) {
254 for (j = 0; j < fs->fs_frag; j++) {
258 setbit(cg_blksfree(newcg), i + j);
259 #else /* AFS_NEWCG_ENV */
260 setbit(newcg->cg_free, i + j);
261 #endif /* AFS_NEWCG_ENV */
264 if (frags == fs->fs_frag) {
265 newcg->cg_cs.cs_nbfree++;
266 j = cbtocylno(fs, i);
268 cg_blktot(newcg)[j]++;
269 cg_blks(fs, newcg, j)[cbtorpos(fs, i)]++;
270 #else /* AFS_NEWCG_ENV */
272 newcg->cg_b[j][cbtorpos(fs, i)]++;
273 #endif /* AFS_NEWCG_ENV */
274 } else if (frags > 0) {
275 newcg->cg_cs.cs_nffree += frags;
277 blk = blkmap(fs, cg_blksfree(newcg), i);
278 #else /* AFS_NEWCG_ENV */
279 blk = blkmap(fs, newcg->cg_free, i);
280 #endif /* AFS_NEWCG_ENV */
281 fragacct(fs, blk, newcg->cg_frsum, 1);
284 cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
285 cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
286 cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
287 cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
288 cs = &fs->fs_cs(fs, c);
289 if (memcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0
291 "FREE BLK COUNT(S) WRONG IN CYL GROUP (SUPERBLK)")) {
292 memcpy((char *)cs, (char *)&newcg->cg_cs, sizeof *cs);
297 memcpy((char *)cg, (char *)newcg, (int)fs->fs_cgsize);
301 #endif /* AFS_NEWCG_ENV */
303 if (memcmp(cg_inosused(newcg), cg_inosused(cg), mapsize) != 0
304 && dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
305 memcpy(cg_inosused(cg), cg_inosused(newcg), mapsize);
308 #else /* AFS_NEWCG_ENV */
309 if (memcmp(newcg->cg_iused, cg->cg_iused, mapsize) != 0
310 && dofix(&idesc[1], "BLK(S) MISSING IN BIT MAPS")) {
311 memcpy(cg->cg_iused, newcg->cg_iused, mapsize);
314 #endif /* AFS_NEWCG_ENV */
315 if ((memcmp((char *)newcg, (char *)cg, basesize) != 0 ||
317 memcmp((char *)&cg_blktot(newcg)[0], (char *)&cg_blktot(cg)[0],
319 #else /* AFS_NEWCG_ENV */
320 memcmp((char *)newcg->cg_btot, (char *)cg->cg_btot,
322 #endif /* AFS_NEWCG_ENV */
323 dofix(&idesc[2], "SUMMARY INFORMATION BAD")) {
325 memcpy((char *)cg, (char *)newcg, basesize);
326 memcpy((char *)&cg_blktot(cg)[0], (char *)&cg_blktot(newcg)[0],
328 #else /* AFS_NEWCG_ENV */
329 memcpy((char *)cg, (char *)newcg, basesize);
330 memcpy((char *)cg->cg_btot, (char *)newcg->cg_btot, sumsize);
331 #endif /* AFS_NEWCG_ENV */
336 if (fs->fs_postblformat == FS_42POSTBLFMT)
337 fs->fs_nrpos = savednrpos;
338 #endif /* AFS_NEWCG_ENV */
339 if (memcmp((char *)&cstotal, (char *)&fs->fs_cstotal, sizeof *cs) != 0
340 && dofix(&idesc[0], "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
341 memcpy((char *)&fs->fs_cstotal, (char *)&cstotal, sizeof *cs);
348 /* returns true if sbdirty should be called */
354 if (fs->fs_fmod != 0) {