2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
6 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
7 /* All Rights Reserved */
10 * Copyright (c) 1980, 1986, 1990 The Regents of the University of California.
11 * All rights reserved.
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.
28 #pragma ident "%Z%%M% %I% %E% SMI"
33 #include <sys/param.h>
34 #include <sys/types.h>
35 #include <sys/mntent.h>
36 #include <sys/fs/ufs_fs.h>
37 #include <sys/vnode.h>
38 #include <sys/fs/ufs_inode.h>
52 * If we clear a directory, it may have produced orphans which
53 * we need to go pick up. So, do this until done. It can be
54 * proven that the loop terminates because at most there can
55 * be lastino directories, and we only rescan if we clear a
60 (void) printf("pass4 scan %d\n", scan_pass
++);
63 for (inumber
= UFSROOTINO
; inumber
<= lastino
; inumber
++) {
66 idesc
.id_func
= pass4check
;
67 idesc
.id_number
= inumber
;
69 was_dir
= (statemap
[inumber
] & DSTATE
) == DSTATE
;
71 switch (statemap
[inumber
] & ~(INORPHAN
| INDELAYD
77 * INZLINK gets set if the inode claimed zero
78 * links when we first looked at it in pass 1.
79 * If lncntp[] also claims it has zero links,
80 * it really is unreferenced. However, we
81 * could have found a link to it during one of
82 * the other passes, so we have to check the
83 * final count in lncntp[].
85 if (lncntp
[inumber
] == 0) {
86 clri(&idesc
, "UNREF", CLRI_VERBOSE
,
89 (statemap
[inumber
] == USTATE
))
99 if (n
|| (statemap
[inumber
] &
100 (INDELAYD
| INZLINK
))) {
102 * adjust() will clear the inode if
103 * the link count goes to zero. If
104 * it isn't cleared, we need to note
105 * that we've adjusted the count
106 * already, so we don't do it again
111 (statemap
[inumber
] == USTATE
)) {
114 TRACK_LNCNTP(inumber
,
115 lncntp
[inumber
] = 0);
121 clri(&idesc
, "UNREF", CLRI_VERBOSE
,
123 if (was_dir
&& (statemap
[inumber
] == USTATE
))
128 dp
= ginode(inumber
);
129 if (dp
->di_size
== 0) {
130 clri(&idesc
, "ZERO LENGTH",
131 CLRI_VERBOSE
, CLRI_NOP_CORRUPT
);
137 clri(&idesc
, "BAD/DUP", CLRI_VERBOSE
,
142 clri(&idesc
, "BAD", CLRI_VERBOSE
,
150 errexit("BAD STATE 0x%x FOR INODE I=%d",
151 (int)statemap
[inumber
], inumber
);
154 } while (need_rescan
);
158 pass4check(struct inodesc
*idesc
)
160 int fragnum
, cg_frag
;
162 daddr32_t blkno
= idesc
->id_blkno
;
164 struct cg
*cgp
= &cgrp
;
167 if ((idesc
->id_truncto
>= 0) && (idesc
->id_lbn
< idesc
->id_truncto
)) {
170 "pass4check: skipping inode %d lbn %d with truncto %d\n",
171 idesc
->id_number
, idesc
->id_lbn
,
176 for (fragnum
= 0; fragnum
< idesc
->id_numfrags
; fragnum
++) {
177 if (chkrange(blkno
+ fragnum
, 1)) {
179 } else if (testbmap(blkno
+ fragnum
)) {
181 * The block's in use. Remove our reference
184 * If it wasn't a dup, or everybody's done with
185 * it, then this is the last reference and it's
186 * safe to actually deallocate the on-disk block.
188 * We depend on pass 5 resolving the on-disk bitmap
191 cg_frag
= blkno
+ fragnum
;
192 if (!find_dup_ref(cg_frag
, idesc
->id_number
,
193 idesc
->id_lbn
* sblock
.fs_frag
+ fragnum
,
197 (void) printf("p4c marking %d avail\n",
203 * Do the same for the on-disk bitmap, so
204 * that we don't need another pass to figure
205 * out what's really being used. We'll let
206 * pass5() work out the fragment/block
209 cylno
= dtog(&sblock
, cg_frag
);
210 (void) getblk(&cgblk
, cgtod(&sblock
, cylno
),
211 (size_t)sblock
.fs_cgsize
);
212 err
= cg_sanity(cgp
, cylno
);
214 pfatal("CG %d: %s\n", cylno
, err
);
216 if (reply("REPAIR") == 0)
217 errexit("Program terminated.");
220 clrbit(cg_blksfree(cgp
),
221 dtogd(&sblock
, cg_frag
));