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