xref: /csrg-svn/sbin/fsck/pass5.c (revision 26480)
122053Sdist /*
222053Sdist  * Copyright (c) 1980 Regents of the University of California.
322053Sdist  * All rights reserved.  The Berkeley software License Agreement
422053Sdist  * specifies the terms and conditions for redistribution.
522053Sdist  */
622053Sdist 
716267Smckusick #ifndef lint
8*26480Smckusick static char sccsid[] = "@(#)pass5.c	5.2 (Berkeley) 03/05/86";
922053Sdist #endif not lint
1016267Smckusick 
1116267Smckusick #include <sys/param.h>
1216267Smckusick #include <sys/inode.h>
1316267Smckusick #include <sys/fs.h>
1416267Smckusick #include "fsck.h"
1516267Smckusick 
1616267Smckusick pass5()
1716267Smckusick {
1817937Smckusick 	int c, blk, frags, sumsize, mapsize;
1917937Smckusick 	daddr_t dbase, dmax, d;
2017937Smckusick 	register long i, j;
2117937Smckusick 	struct csum *cs;
2217937Smckusick 	time_t now;
2317937Smckusick 	struct csum cstotal;
2417937Smckusick 	struct inodesc idesc;
2517937Smckusick 	char buf[MAXBSIZE];
2617937Smckusick 	register struct cg *newcg = (struct cg *)buf;
2716267Smckusick 
2817937Smckusick 	bzero((char *)newcg, sblock.fs_cgsize);
2917937Smckusick 	newcg->cg_magic = CG_MAGIC;
3017937Smckusick 	bzero((char *)&idesc, sizeof(struct inodesc));
3117937Smckusick 	idesc.id_type = ADDR;
3217937Smckusick 	bzero((char *)&cstotal, sizeof(struct csum));
3317937Smckusick 	sumsize = cgrp.cg_iused - (char *)(&cgrp);
3418667Smckusick 	mapsize = &cgrp.cg_free[howmany(sblock.fs_fpg, NBBY)] -
3518667Smckusick 		(u_char *)cgrp.cg_iused;
3617937Smckusick 	(void)time(&now);
3716267Smckusick 	for (c = 0; c < sblock.fs_ncg; c++) {
3821540Smckusick 		getblk(&cgblk, cgtod(&sblock, c), sblock.fs_cgsize);
3917937Smckusick 		if (cgrp.cg_magic != CG_MAGIC)
4016267Smckusick 			pfatal("CG %d: BAD MAGIC NUMBER\n", c);
4117937Smckusick 		dbase = cgbase(&sblock, c);
4217937Smckusick 		dmax = dbase + sblock.fs_fpg;
4317937Smckusick 		if (dmax > sblock.fs_size)
4417937Smckusick 			dmax = sblock.fs_size;
4517937Smckusick 		if (now > cgrp.cg_time)
4617937Smckusick 			newcg->cg_time = cgrp.cg_time;
4717937Smckusick 		else
4817937Smckusick 			newcg->cg_time = now;
4917937Smckusick 		newcg->cg_cgx = c;
5017937Smckusick 		if (c == sblock.fs_ncg - 1)
5117937Smckusick 			newcg->cg_ncyl = sblock.fs_ncyl % sblock.fs_cpg;
5217937Smckusick 		else
5317937Smckusick 			newcg->cg_ncyl = sblock.fs_cpg;
5417937Smckusick 		newcg->cg_niblk = sblock.fs_ipg;
5517937Smckusick 		newcg->cg_ndblk = dmax - dbase;
5617937Smckusick 		newcg->cg_cs.cs_ndir = 0;
5717937Smckusick 		newcg->cg_cs.cs_nffree = 0;
5817937Smckusick 		newcg->cg_cs.cs_nbfree = 0;
5917937Smckusick 		newcg->cg_cs.cs_nifree = sblock.fs_ipg;
6017937Smckusick 		if (cgrp.cg_rotor < newcg->cg_ndblk)
6117937Smckusick 			newcg->cg_rotor = cgrp.cg_rotor;
6217937Smckusick 		else
6317937Smckusick 			newcg->cg_rotor = 0;
6417937Smckusick 		if (cgrp.cg_frotor < newcg->cg_ndblk)
6517937Smckusick 			newcg->cg_frotor = cgrp.cg_frotor;
6617937Smckusick 		else
6717937Smckusick 			newcg->cg_frotor = 0;
6817937Smckusick 		if (cgrp.cg_irotor < newcg->cg_niblk)
6917937Smckusick 			newcg->cg_irotor = cgrp.cg_irotor;
7017937Smckusick 		else
7117937Smckusick 			newcg->cg_irotor = 0;
7217937Smckusick 		bzero((char *)newcg->cg_frsum, sizeof newcg->cg_frsum);
7317937Smckusick 		bzero((char *)newcg->cg_btot, sizeof newcg->cg_btot);
7417937Smckusick 		bzero((char *)newcg->cg_b, sizeof newcg->cg_b);
7517937Smckusick 		bzero((char *)newcg->cg_free, howmany(sblock.fs_fpg, NBBY));
7617937Smckusick 		bzero((char *)newcg->cg_iused, howmany(sblock.fs_ipg, NBBY));
7717937Smckusick 		j = sblock.fs_ipg * c;
7817937Smckusick 		for (i = 0; i < sblock.fs_ipg; j++, i++) {
7917937Smckusick 			switch (statemap[j]) {
8017937Smckusick 
8117937Smckusick 			case USTATE:
8217937Smckusick 				break;
8317937Smckusick 
8417937Smckusick 			case DSTATE:
8517937Smckusick 			case DCLEAR:
8617937Smckusick 			case DFOUND:
8717937Smckusick 				newcg->cg_cs.cs_ndir++;
8817937Smckusick 				/* fall through */
8917937Smckusick 
9017937Smckusick 			case FSTATE:
9117937Smckusick 			case FCLEAR:
9217937Smckusick 				newcg->cg_cs.cs_nifree--;
9317937Smckusick 				setbit(newcg->cg_iused, i);
9417937Smckusick 				break;
95*26480Smckusick 
96*26480Smckusick 			default:
97*26480Smckusick 				if (j < ROOTINO)
98*26480Smckusick 					break;
99*26480Smckusick 				errexit("BAD STATE %d FOR INODE I=%d",
100*26480Smckusick 				    statemap[j], j);
10117937Smckusick 			}
10216267Smckusick 		}
10317937Smckusick 		if (c == 0)
10417937Smckusick 			for (i = 0; i < ROOTINO; i++) {
10517937Smckusick 				setbit(newcg->cg_iused, i);
10617937Smckusick 				newcg->cg_cs.cs_nifree--;
10716267Smckusick 			}
10817937Smckusick 		for (i = 0, d = dbase;
10917937Smckusick 		     d <= dmax - sblock.fs_frag;
11017937Smckusick 		     d += sblock.fs_frag, i += sblock.fs_frag) {
11117937Smckusick 			frags = 0;
11217937Smckusick 			for (j = 0; j < sblock.fs_frag; j++) {
11317937Smckusick 				if (getbmap(d + j))
11417937Smckusick 					continue;
11517937Smckusick 				setbit(newcg->cg_free, i + j);
11617937Smckusick 				frags++;
11717937Smckusick 			}
11817937Smckusick 			if (frags == sblock.fs_frag) {
11917937Smckusick 				newcg->cg_cs.cs_nbfree++;
12017937Smckusick 				j = cbtocylno(&sblock, i);
12117937Smckusick 				newcg->cg_btot[j]++;
12217937Smckusick 				newcg->cg_b[j][cbtorpos(&sblock, i)]++;
12317937Smckusick 			} else if (frags > 0) {
12417937Smckusick 				newcg->cg_cs.cs_nffree += frags;
12517937Smckusick 				blk = blkmap(&sblock, newcg->cg_free, i);
12617937Smckusick 				fragacct(&sblock, blk, newcg->cg_frsum, 1);
12717937Smckusick 			}
12816267Smckusick 		}
12917937Smckusick 		for (frags = d; d < dmax; d++) {
13017937Smckusick 			if (getbmap(d))
13117937Smckusick 				continue;
13217937Smckusick 			setbit(newcg->cg_free, d - dbase);
13317937Smckusick 			newcg->cg_cs.cs_nffree++;
13416267Smckusick 		}
13517937Smckusick 		if (frags != d) {
13617937Smckusick 			blk = blkmap(&sblock, newcg->cg_free, (frags - dbase));
13717937Smckusick 			fragacct(&sblock, blk, newcg->cg_frsum, 1);
13816267Smckusick 		}
13917937Smckusick 		cstotal.cs_nffree += newcg->cg_cs.cs_nffree;
14017937Smckusick 		cstotal.cs_nbfree += newcg->cg_cs.cs_nbfree;
14117937Smckusick 		cstotal.cs_nifree += newcg->cg_cs.cs_nifree;
14217937Smckusick 		cstotal.cs_ndir += newcg->cg_cs.cs_ndir;
14317937Smckusick 		if (bcmp(newcg->cg_iused, cgrp.cg_iused, mapsize) != 0 &&
14417937Smckusick 		    dofix(&idesc, "BLK(S) MISSING IN BIT MAPS")) {
14517937Smckusick 			bcopy(newcg->cg_iused, cgrp.cg_iused, mapsize);
14617937Smckusick 			cgdirty();
14716267Smckusick 		}
14817937Smckusick 		if (bcmp((char *)newcg, (char *)&cgrp, sumsize) != 0 &&
14917937Smckusick 		    dofix(&idesc, "SUMMARY INFORMATION BAD")) {
15017937Smckusick 			bcopy((char *)newcg, (char *)&cgrp, sumsize);
15117937Smckusick 			cgdirty();
15216267Smckusick 		}
15317937Smckusick 		cs = &sblock.fs_cs(&sblock, c);
15417937Smckusick 		if (bcmp((char *)&newcg->cg_cs, (char *)cs, sizeof *cs) != 0 &&
15517937Smckusick 		    dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
15617937Smckusick 			bcopy((char *)&newcg->cg_cs, (char *)cs, sizeof *cs);
15717937Smckusick 			sbdirty();
15817937Smckusick 		}
15916267Smckusick 	}
16017937Smckusick 	if (bcmp((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs) != 0
16117937Smckusick 	    && dofix(&idesc, "FREE BLK COUNT(S) WRONG IN SUPERBLK")) {
16217937Smckusick 		bcopy((char *)&cstotal, (char *)&sblock.fs_cstotal, sizeof *cs);
16317937Smckusick 		sblock.fs_ronly = 0;
16417937Smckusick 		sblock.fs_fmod = 0;
16517937Smckusick 		sbdirty();
16616267Smckusick 	}
16716267Smckusick }
168