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