xref: /csrg-svn/sbin/fsck/pass4.c (revision 16266)
1 #ifndef lint
2 static char version[] = "@(#)pass4.c	3.1 (Berkeley) 03/31/84";
3 #endif
4 
5 #include <sys/param.h>
6 #include <sys/inode.h>
7 #include <sys/fs.h>
8 #include "fsck.h"
9 
10 int	pass4check();
11 
12 pass4()
13 {
14 	register ino_t inumber, *blp;
15 	int n;
16 	struct inodesc idesc;
17 
18 	bzero((char *)&idesc, sizeof(struct inodesc));
19 	idesc.id_type = ADDR;
20 	idesc.id_func = pass4check;
21 	for (inumber = ROOTINO; inumber <= lastino; inumber++) {
22 		idesc.id_number = inumber;
23 		switch (statemap[inumber]) {
24 
25 		case FSTATE:
26 			n = lncntp[inumber];
27 			if (n)
28 				adjust(&idesc, (short)n);
29 			else {
30 				for (blp = badlncnt;blp < badlnp; blp++)
31 					if (*blp == inumber) {
32 						clri(&idesc, "UNREF", 1);
33 						break;
34 					}
35 			}
36 			break;
37 
38 		case DSTATE:
39 			clri(&idesc, "UNREF", 1);
40 			break;
41 
42 		case CLEAR:
43 			clri(&idesc, "BAD/DUP", 1);
44 			break;
45 		}
46 	}
47 	if (imax - ROOTINO - n_files != sblock.fs_cstotal.cs_nifree) {
48 		pwarn("FREE INODE COUNT WRONG IN SUPERBLK");
49 		if (preen)
50 			printf(" (FIXED)\n");
51 		if (preen || reply("FIX") == 1) {
52 			sblock.fs_cstotal.cs_nifree = imax - ROOTINO - n_files;
53 			sbdirty();
54 		}
55 	}
56 	flush(&dfile, &fileblk);
57 }
58 
59 pass4check(idesc)
60 	register struct inodesc *idesc;
61 {
62 	register daddr_t *dlp;
63 	int nfrags, res = KEEPON;
64 	daddr_t blkno = idesc->id_blkno;
65 
66 	for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
67 		if (outrange(blkno, 1))
68 			res = SKIP;
69 		else if (getbmap(blkno)) {
70 			for (dlp = duplist; dlp < enddup; dlp++)
71 				if (*dlp == blkno) {
72 					*dlp = *--enddup;
73 					return (KEEPON);
74 				}
75 			clrbmap(blkno);
76 			n_blks--;
77 		}
78 	}
79 	return (res);
80 }
81