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>
27 #include <sys/vnode.h>
28 #include <sys/mount.h>
29 #include <ufs/inode.h>
36 #else /* AFS_OSF_ENV */
37 #ifdef AFS_VFSINCL_ENV
38 #include <sys/vnode.h>
40 #include <sys/fs/ufs_inode.h>
41 #include <sys/fs/ufs_fs.h>
43 #include <sys/fs/ufs_fsdir.h>
45 #include <sys/fs/ufs_mount.h>
47 #include <ufs/inode.h>
50 #else /* AFS_VFSINCL_ENV */
51 #include <sys/inode.h>
53 #define LONGFILENAMES 1
54 #include <sys/sysmacros.h>
58 #endif /* AFS_VFSINCL_ENV */
59 #endif /* AFS_OSF_ENV */
60 #include <afs/osi_inode.h>
64 #if defined(AFS_SUN_ENV) || defined(AFS_OSF_ENV)
71 /* define enough so this thing compiles! */
72 #define FS_42POSTBLFMT 1
73 #define FS_DYNAMICPOSTBLFMT 2
74 #endif /* AFS_NEWCG_ENV */
78 int c
, blk
, frags
, basesize
, sumsize
, mapsize
, savednrpos
;
79 struct fs
*fs
= &sblock
;
80 struct cg
*cg
= &cgrp
;
87 struct inodesc idesc
[3];
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 */
100 memset(newcg
, 0, (int)fs
->fs_cgsize
);
101 newcg
->cg_niblk
= fs
->fs_ipg
;
103 postype
= (int)fs
->fs_postblformat
;
104 #else /* AFS_NEWCG_ENV */
105 postype
= FS_42POSTBLFMT
;
106 #endif /* AFS_NEWCG_ENV */
110 basesize
= (char *)(&ocg
->cg_btot
[0]) - (char *)(&ocg
->cg_link
);
111 sumsize
= &ocg
->cg_iused
[0] - (char *)(&ocg
->cg_btot
[0]);
113 &ocg
->cg_free
[howmany(fs
->fs_fpg
, NBBY
)] -
114 (u_char
*) & ocg
->cg_iused
[0];
115 ocg
->cg_magic
= CG_MAGIC
;
117 savednrpos
= fs
->fs_nrpos
;
119 #endif /* AFS_NEWCG_ENV */
123 case FS_DYNAMICPOSTBLFMT
:
126 /* Matches decl in ufs/fs.h */
127 &newcg
->cg_space
[0] - (u_char
*) (&newcg
->cg_link
[0]);
129 &newcg
->cg_space
[0] - (u_char
*) (&newcg
->cg_link
);
131 newcg
->cg_boff
= newcg
->cg_btotoff
+ fs
->fs_cpg
* sizeof(afs_int32
);
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
),
138 newcg
->cg_magic
= CG_MAGIC
;
140 /* Matches decl in ufs/fs.h */
141 basesize
= &newcg
->cg_space
[0] - (u_char
*) (&newcg
->cg_link
[0]);
143 basesize
= &newcg
->cg_space
[0] - (u_char
*) (&newcg
->cg_link
);
145 sumsize
= newcg
->cg_iusedoff
- newcg
->cg_btotoff
;
146 mapsize
= newcg
->cg_nextfreeoff
- newcg
->cg_iusedoff
;
150 errexit("UNKNOWN ROTATIONAL TABLE FORMAT %d\n", fs
->fs_postblformat
);
151 #endif /* AFS_NEWCG_ENV */
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
));
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.
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.
168 for (i
= fs
->fs_size
; i
< fragroundup(fs
, fs
->fs_size
); i
++)
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
++)
174 for (c
= 0; c
< fs
->fs_ncg
; c
++) {
175 getblk(&cgblk
, cgtod(fs
, c
), fs
->fs_cgsize
);
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
)
187 if (now
> cg
->cg_time
)
188 newcg
->cg_time
= cg
->cg_time
;
190 newcg
->cg_time
= now
;
192 if (c
== fs
->fs_ncg
- 1)
193 newcg
->cg_ncyl
= fs
->fs_ncyl
% fs
->fs_cpg
;
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
;
205 if (cg
->cg_frotor
< newcg
->cg_ndblk
)
206 newcg
->cg_frotor
= cg
->cg_frotor
;
208 newcg
->cg_frotor
= 0;
209 if (cg
->cg_irotor
< newcg
->cg_niblk
)
210 newcg
->cg_irotor
= cg
->cg_irotor
;
212 newcg
->cg_irotor
= 0;
213 memset(&newcg
->cg_frsum
[0], 0, sizeof newcg
->cg_frsum
);
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 */
223 if (fs
->fs_postblformat
== FS_42POSTBLFMT
)
224 ocg
->cg_magic
= CG_MAGIC
;
225 #endif /* AFS_NEWCG_ENV */
227 for (i
= 0; i
< fs
->fs_ipg
; j
++, i
++) {
228 #if defined(ACLS) && defined(AFS_HPUX_ENV)
229 switch (statemap
[j
] & STATE
) {
231 switch (statemap
[j
]) {
239 newcg
->cg_cs
.cs_ndir
++;
247 newcg
->cg_cs
.cs_nifree
--;
249 setbit(cg_inosused(newcg
), i
);
251 setbit(newcg
->cg_iused
, i
);
252 #endif /* AFS_NEWCG_ENV */
255 #if defined(ACLS) && defined(AFS_HPUX_ENV)
256 /* hpux has more dynamic states (CSTATE, CRSTATE) */
264 errexit("BAD STATE %d FOR INODE I=%d", statemap
[j
], j
);
268 for (i
= 0; i
< ROOTINO
; i
++) {
270 setbit(cg_inosused(newcg
), i
);
272 setbit(newcg
->cg_iused
, i
);
273 #endif /* AFS_NEWCG_ENV */
274 newcg
->cg_cs
.cs_nifree
--;
276 for (i
= 0, d
= dbase
; d
< dmax
; d
+= fs
->fs_frag
, i
+= fs
->fs_frag
) {
278 for (j
= 0; j
< fs
->fs_frag
; j
++) {
282 setbit(cg_blksfree(newcg
), i
+ j
);
283 #else /* AFS_NEWCG_ENV */
284 setbit(newcg
->cg_free
, i
+ j
);
285 #endif /* AFS_NEWCG_ENV */
288 if (frags
== fs
->fs_frag
) {
289 newcg
->cg_cs
.cs_nbfree
++;
290 j
= cbtocylno(fs
, i
);
292 cg_blktot(newcg
)[j
]++;
293 cg_blks(fs
, newcg
, j
)[cbtorpos(fs
, i
)]++;
294 #else /* AFS_NEWCG_ENV */
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
;
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);
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
315 "FREE BLK COUNT(S) WRONG IN CYL GROUP (SUPERBLK)")) {
316 memcpy((char *)cs
, (char *)&newcg
->cg_cs
, sizeof *cs
);
321 memcpy((char *)cg
, (char *)newcg
, (int)fs
->fs_cgsize
);
325 #endif /* 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
);
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
);
338 #endif /* AFS_NEWCG_ENV */
339 if ((memcmp((char *)newcg
, (char *)cg
, basesize
) != 0 ||
341 memcmp((char *)&cg_blktot(newcg
)[0], (char *)&cg_blktot(cg
)[0],
343 #else /* AFS_NEWCG_ENV */
344 memcmp((char *)newcg
->cg_btot
, (char *)cg
->cg_btot
,
346 #endif /* AFS_NEWCG_ENV */
347 dofix(&idesc
[2], "SUMMARY INFORMATION BAD")) {
349 memcpy((char *)cg
, (char *)newcg
, basesize
);
350 memcpy((char *)&cg_blktot(cg
)[0], (char *)&cg_blktot(newcg
)[0],
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 */
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
);
372 /* returns true if sbdirty should be called */
378 if (fs
->fs_fmod
!= 0) {