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
pass4()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
pass4check(idesc)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