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 #pragma ident "%Z%%M% %I% %E% SMI" 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <unistd.h> 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> 39 #include "fsck.h" 40 41 void 42 pass4(void) 43 { 44 fsck_ino_t inumber; 45 struct dinode *dp; 46 struct inodesc idesc; 47 int n, was_dir; 48 int need_rescan; 49 int scan_pass = 0; 50 51 /* 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 56 * directory. 57 */ 58 do { 59 if (debug) 60 (void) printf("pass4 scan %d\n", scan_pass++); 61 62 need_rescan = 0; 63 for (inumber = UFSROOTINO; inumber <= lastino; inumber++) { 64 init_inodesc(&idesc); 65 idesc.id_type = ADDR; 66 idesc.id_func = pass4check; 67 idesc.id_number = inumber; 68 69 was_dir = (statemap[inumber] & DSTATE) == DSTATE; 70 71 switch (statemap[inumber] & ~(INORPHAN | INDELAYD 72 | INZLINK)) { 73 74 case FZLINK: 75 case DZLINK: 76 /* 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[]. 84 */ 85 if (lncntp[inumber] == 0) { 86 clri(&idesc, "UNREF", CLRI_VERBOSE, 87 CLRI_NOP_OK); 88 if (was_dir && 89 (statemap[inumber] == USTATE)) 90 need_rescan = 1; 91 break; 92 } 93 /* FALLTHROUGH */ 94 95 case FSTATE: 96 case DFOUND: 97 case SSTATE: 98 n = lncntp[inumber]; 99 if (n || (statemap[inumber] & 100 (INDELAYD | INZLINK))) { 101 /* 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 107 * on a rescan. 108 */ 109 adjust(&idesc, n); 110 if (was_dir && 111 (statemap[inumber] == USTATE)) { 112 need_rescan = 1; 113 } else { 114 TRACK_LNCNTP(inumber, 115 lncntp[inumber] = 0); 116 } 117 } 118 break; 119 120 case DSTATE: 121 clri(&idesc, "UNREF", CLRI_VERBOSE, 122 CLRI_NOP_OK); 123 if (was_dir && (statemap[inumber] == USTATE)) 124 need_rescan = 1; 125 break; 126 127 case DCLEAR: 128 dp = ginode(inumber); 129 if (dp->di_size == 0) { 130 clri(&idesc, "ZERO LENGTH", 131 CLRI_VERBOSE, CLRI_NOP_CORRUPT); 132 break; 133 } 134 /* FALLTHROUGH */ 135 136 case FCLEAR: 137 clri(&idesc, "BAD/DUP", CLRI_VERBOSE, 138 CLRI_NOP_CORRUPT); 139 break; 140 141 case SCLEAR: 142 clri(&idesc, "BAD", CLRI_VERBOSE, 143 CLRI_NOP_CORRUPT); 144 break; 145 146 case USTATE: 147 break; 148 149 default: 150 errexit("BAD STATE 0x%x FOR INODE I=%d", 151 (int)statemap[inumber], inumber); 152 } 153 } 154 } while (need_rescan); 155 } 156 157 int 158 pass4check(struct inodesc *idesc) 159 { 160 int fragnum, cg_frag; 161 int res = KEEPON; 162 daddr32_t blkno = idesc->id_blkno; 163 int cylno; 164 struct cg *cgp = &cgrp; 165 caddr_t err; 166 167 if ((idesc->id_truncto >= 0) && (idesc->id_lbn < idesc->id_truncto)) { 168 if (debug) 169 (void) printf( 170 "pass4check: skipping inode %d lbn %d with truncto %d\n", 171 idesc->id_number, idesc->id_lbn, 172 idesc->id_truncto); 173 return (KEEPON); 174 } 175 176 for (fragnum = 0; fragnum < idesc->id_numfrags; fragnum++) { 177 if (chkrange(blkno + fragnum, 1)) { 178 res = SKIP; 179 } else if (testbmap(blkno + fragnum)) { 180 /* 181 * The block's in use. Remove our reference 182 * from it. 183 * 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. 187 * 188 * We depend on pass 5 resolving the on-disk bitmap 189 * effects. 190 */ 191 cg_frag = blkno + fragnum; 192 if (!find_dup_ref(cg_frag, idesc->id_number, 193 idesc->id_lbn * sblock.fs_frag + fragnum, 194 DB_DECR)) { 195 196 if (debug) 197 (void) printf("p4c marking %d avail\n", 198 cg_frag); 199 clrbmap(cg_frag); 200 n_blks--; 201 202 /* 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 207 * accounting. 208 */ 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); 213 if (err != NULL) { 214 pfatal("CG %d: %s\n", cylno, err); 215 free((void *)err); 216 if (reply("REPAIR") == 0) 217 errexit("Program terminated."); 218 fix_cg(cgp, cylno); 219 } 220 clrbit(cg_blksfree(cgp), 221 dtogd(&sblock, cg_frag)); 222 cgdirty(); 223 224 res |= ALTERED; 225 } 226 } 227 } 228 return (res); 229 } 230