xref: /original-bsd/sbin/fsck/pass4.c (revision 76210d32)
1 /*
2  * Copyright (c) 1980, 1986 The Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)pass4.c	5.9 (Berkeley) 06/01/90";
10 #endif /* not lint */
11 
12 #include <sys/param.h>
13 #include <ufs/dinode.h>
14 #include <ufs/fs.h>
15 #include "fsck.h"
16 
17 int	pass4check();
18 
19 pass4()
20 {
21 	register ino_t inumber;
22 	register struct zlncnt *zlnp;
23 	struct dinode *dp;
24 	struct inodesc idesc;
25 	int n;
26 
27 	bzero((char *)&idesc, sizeof(struct inodesc));
28 	idesc.id_type = ADDR;
29 	idesc.id_func = pass4check;
30 	for (inumber = ROOTINO; inumber <= lastino; inumber++) {
31 		idesc.id_number = inumber;
32 		switch (statemap[inumber]) {
33 
34 		case FSTATE:
35 		case DFOUND:
36 			n = lncntp[inumber];
37 			if (n)
38 				adjust(&idesc, (short)n);
39 			else {
40 				for (zlnp = zlnhead; zlnp; zlnp = zlnp->next)
41 					if (zlnp->zlncnt == inumber) {
42 						zlnp->zlncnt = zlnhead->zlncnt;
43 						zlnp = zlnhead;
44 						zlnhead = zlnhead->next;
45 						free((char *)zlnp);
46 						clri(&idesc, "UNREF", 1);
47 						break;
48 					}
49 			}
50 			break;
51 
52 		case DSTATE:
53 			clri(&idesc, "UNREF", 1);
54 			break;
55 
56 		case DCLEAR:
57 			dp = ginode(inumber);
58 			if (dp->di_size == 0) {
59 				clri(&idesc, "ZERO LENGTH", 1);
60 				break;
61 			}
62 			/* fall through */
63 		case FCLEAR:
64 			clri(&idesc, "BAD/DUP", 1);
65 			break;
66 
67 		case USTATE:
68 			break;
69 
70 		default:
71 			errexit("BAD STATE %d FOR INODE I=%d",
72 			    statemap[inumber], inumber);
73 		}
74 	}
75 }
76 
77 pass4check(idesc)
78 	register struct inodesc *idesc;
79 {
80 	register struct dups *dlp;
81 	int nfrags, res = KEEPON;
82 	daddr_t blkno = idesc->id_blkno;
83 
84 	for (nfrags = idesc->id_numfrags; nfrags > 0; blkno++, nfrags--) {
85 		if (chkrange(blkno, 1)) {
86 			res = SKIP;
87 		} else if (testbmap(blkno)) {
88 			for (dlp = duplist; dlp; dlp = dlp->next) {
89 				if (dlp->dup != blkno)
90 					continue;
91 				dlp->dup = duplist->dup;
92 				dlp = duplist;
93 				duplist = duplist->next;
94 				free((char *)dlp);
95 				break;
96 			}
97 			if (dlp == 0) {
98 				clrbmap(blkno);
99 				n_blks--;
100 			}
101 		}
102 	}
103 	return (res);
104 }
105