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