1 /*
2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
8
9 /*
10 * Copyright (c) 1980, 1986, 1990 The Regents of the University of California.
11 * All rights reserved.
12 *
13 * Redistribution and use in source and binary forms are permitted
14 * provided that: (1) source distributions retain this entire copyright
15 * notice and comment, and (2) distributions including binaries display
16 * the following acknowledgement: ``This product includes software
17 * developed by the University of California, Berkeley and its contributors''
18 * in the documentation or other materials provided with the distribution
19 * and in all advertising materials mentioning features or use of this
20 * software. Neither the name of the University nor the names of its
21 * contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
24 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <sys/param.h>
32 #include <sys/types.h>
33 #include <sys/mntent.h>
34 #include <sys/fs/ufs_fs.h>
35 #include <sys/vnode.h>
36 #include <sys/fs/ufs_inode.h>
37 #include "fsck.h"
38
39 void
pass4(void)40 pass4(void)
41 {
42 fsck_ino_t inumber;
43 struct dinode *dp;
44 struct inodesc idesc;
45 int n, was_dir;
46 int need_rescan;
47 int scan_pass = 0;
48
49 /*
50 * If we clear a directory, it may have produced orphans which
51 * we need to go pick up. So, do this until done. It can be
52 * proven that the loop terminates because at most there can
53 * be lastino directories, and we only rescan if we clear a
54 * directory.
55 */
56 do {
57 if (debug)
58 (void) printf("pass4 scan %d\n", scan_pass++);
59
60 need_rescan = 0;
61 for (inumber = UFSROOTINO; inumber <= lastino; inumber++) {
62 init_inodesc(&idesc);
63 idesc.id_type = ADDR;
64 idesc.id_func = pass4check;
65 idesc.id_number = inumber;
66
67 was_dir = (statemap[inumber] & DSTATE) == DSTATE;
68
69 switch (statemap[inumber] & ~(INORPHAN | INDELAYD
70 | INZLINK)) {
71
72 case FZLINK:
73 case DZLINK:
74 /*
75 * INZLINK gets set if the inode claimed zero
76 * links when we first looked at it in pass 1.
77 * If lncntp[] also claims it has zero links,
78 * it really is unreferenced. However, we
79 * could have found a link to it during one of
80 * the other passes, so we have to check the
81 * final count in lncntp[].
82 */
83 if (lncntp[inumber] == 0) {
84 clri(&idesc, "UNREF", CLRI_VERBOSE,
85 CLRI_NOP_OK);
86 if (was_dir &&
87 (statemap[inumber] == USTATE))
88 need_rescan = 1;
89 break;
90 }
91 /* FALLTHROUGH */
92
93 case FSTATE:
94 case DFOUND:
95 case SSTATE:
96 n = lncntp[inumber];
97 if (n || (statemap[inumber] &
98 (INDELAYD | INZLINK))) {
99 /*
100 * adjust() will clear the inode if
101 * the link count goes to zero. If
102 * it isn't cleared, we need to note
103 * that we've adjusted the count
104 * already, so we don't do it again
105 * on a rescan.
106 */
107 adjust(&idesc, n);
108 if (was_dir &&
109 (statemap[inumber] == USTATE)) {
110 need_rescan = 1;
111 } else {
112 TRACK_LNCNTP(inumber,
113 lncntp[inumber] = 0);
114 }
115 }
116 break;
117
118 case DSTATE:
119 clri(&idesc, "UNREF", CLRI_VERBOSE,
120 CLRI_NOP_OK);
121 if (was_dir && (statemap[inumber] == USTATE))
122 need_rescan = 1;
123 break;
124
125 case DCLEAR:
126 dp = ginode(inumber);
127 if (dp->di_size == 0) {
128 clri(&idesc, "ZERO LENGTH",
129 CLRI_VERBOSE, CLRI_NOP_CORRUPT);
130 break;
131 }
132 /* FALLTHROUGH */
133
134 case FCLEAR:
135 clri(&idesc, "BAD/DUP", CLRI_VERBOSE,
136 CLRI_NOP_CORRUPT);
137 break;
138
139 case SCLEAR:
140 clri(&idesc, "BAD", CLRI_VERBOSE,
141 CLRI_NOP_CORRUPT);
142 break;
143
144 case USTATE:
145 break;
146
147 default:
148 errexit("BAD STATE 0x%x FOR INODE I=%d",
149 (int)statemap[inumber], inumber);
150 }
151 }
152 } while (need_rescan);
153 }
154
155 int
pass4check(struct inodesc * idesc)156 pass4check(struct inodesc *idesc)
157 {
158 int fragnum, cg_frag;
159 int res = KEEPON;
160 daddr32_t blkno = idesc->id_blkno;
161 int cylno;
162 struct cg *cgp = &cgrp;
163 caddr_t err;
164
165 if ((idesc->id_truncto >= 0) && (idesc->id_lbn < idesc->id_truncto)) {
166 if (debug)
167 (void) printf(
168 "pass4check: skipping inode %d lbn %d with truncto %d\n",
169 idesc->id_number, idesc->id_lbn,
170 idesc->id_truncto);
171 return (KEEPON);
172 }
173
174 for (fragnum = 0; fragnum < idesc->id_numfrags; fragnum++) {
175 if (chkrange(blkno + fragnum, 1)) {
176 res = SKIP;
177 } else if (testbmap(blkno + fragnum)) {
178 /*
179 * The block's in use. Remove our reference
180 * from it.
181 *
182 * If it wasn't a dup, or everybody's done with
183 * it, then this is the last reference and it's
184 * safe to actually deallocate the on-disk block.
185 *
186 * We depend on pass 5 resolving the on-disk bitmap
187 * effects.
188 */
189 cg_frag = blkno + fragnum;
190 if (!find_dup_ref(cg_frag, idesc->id_number,
191 idesc->id_lbn * sblock.fs_frag + fragnum,
192 DB_DECR)) {
193
194 if (debug)
195 (void) printf("p4c marking %d avail\n",
196 cg_frag);
197 clrbmap(cg_frag);
198 n_blks--;
199
200 /*
201 * Do the same for the on-disk bitmap, so
202 * that we don't need another pass to figure
203 * out what's really being used. We'll let
204 * pass5() work out the fragment/block
205 * accounting.
206 */
207 cylno = dtog(&sblock, cg_frag);
208 (void) getblk(&cgblk, cgtod(&sblock, cylno),
209 (size_t)sblock.fs_cgsize);
210 err = cg_sanity(cgp, cylno);
211 if (err != NULL) {
212 pfatal("CG %d: %s\n", cylno, err);
213 free((void *)err);
214 if (reply("REPAIR") == 0)
215 errexit("Program terminated.");
216 fix_cg(cgp, cylno);
217 }
218 clrbit(cg_blksfree(cgp),
219 dtogd(&sblock, cg_frag));
220 cgdirty();
221
222 res |= ALTERED;
223 }
224 }
225 }
226 return (res);
227 }
228