1 /* $OpenBSD: pass5.c,v 1.13 2006/03/20 21:35:37 dhill Exp $ */ 2 /* $NetBSD: pass5.c,v 1.7 2000/01/28 16:01:46 bouyer Exp $ */ 3 4 /* 5 * Copyright (c) 1997 Manuel Bouyer. 6 * Copyright (c) 1980, 1986, 1993 7 * The Regents of the University of California. All rights reserved. 8 * 9 * Redistribution and use in source and binary forms, with or without 10 * modification, are permitted provided that the following conditions 11 * are met: 12 * 1. Redistributions of source code must retain the above copyright 13 * notice, this list of conditions and the following disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 3. Neither the name of the University nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/time.h> 36 #include <ufs/ufs/dinode.h> 37 #include <ufs/ext2fs/ext2fs_dinode.h> 38 #include <ufs/ext2fs/ext2fs.h> 39 #include <ufs/ext2fs/ext2fs_extern.h> 40 #include <string.h> 41 #include <stdio.h> 42 #include <stdlib.h> 43 44 #include "fsutil.h" 45 #include "fsck.h" 46 #include "extern.h" 47 48 49 void print_bmap(u_char *,u_int32_t); 50 51 void 52 pass5(void) 53 { 54 int c; 55 struct m_ext2fs *fs = &sblock; 56 daddr_t dbase, dmax; 57 daddr_t d; 58 long i, j; 59 struct inodesc idesc[3]; 60 struct bufarea *ino_bitmap = NULL, *blk_bitmap = NULL; 61 char *ibmap, *bbmap; 62 u_int32_t cs_ndir, cs_nbfree, cs_nifree; 63 char msg[255]; 64 65 cs_ndir = 0; 66 cs_nbfree = 0; 67 cs_nifree = 0; 68 69 ibmap = malloc(fs->e2fs_bsize); 70 bbmap = malloc(fs->e2fs_bsize); 71 if (ibmap == NULL || bbmap == NULL) { 72 errexit("out of memory\n"); 73 } 74 75 for (c = 0; c < fs->e2fs_ncg; c++) { 76 u_int32_t nbfree = 0; 77 u_int32_t nifree = 0; 78 u_int32_t ndirs = 0; 79 80 nbfree = 0; 81 nifree = fs->e2fs.e2fs_ipg; 82 ndirs = 0; 83 84 if (blk_bitmap == NULL) { 85 blk_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap), 86 fs->e2fs_bsize); 87 } else { 88 getblk(blk_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_b_bitmap), 89 fs->e2fs_bsize); 90 } 91 if (ino_bitmap == NULL) { 92 ino_bitmap = getdatablk(fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap), 93 fs->e2fs_bsize); 94 } else { 95 getblk(ino_bitmap, fs2h32(fs->e2fs_gd[c].ext2bgd_i_bitmap), 96 fs->e2fs_bsize); 97 } 98 memset(bbmap, 0, fs->e2fs_bsize); 99 memset(ibmap, 0, fs->e2fs_bsize); 100 memset(&idesc[0], 0, sizeof idesc); 101 for (i = 0; i < 3; i++) { 102 idesc[i].id_type = ADDR; 103 } 104 105 j = fs->e2fs.e2fs_ipg * c + 1; 106 107 for (i = 0; i < fs->e2fs.e2fs_ipg; j++, i++) { 108 if ((j < EXT2_FIRSTINO) && (j != EXT2_ROOTINO)) { 109 setbit(ibmap, i); 110 nifree--; 111 continue; 112 } 113 if (j > fs->e2fs.e2fs_icount) { 114 setbit(ibmap, i); 115 continue; 116 } 117 switch (statemap[j]) { 118 119 case USTATE: 120 break; 121 122 case DSTATE: 123 case DCLEAR: 124 case DFOUND: 125 ndirs++; 126 /* fall through */ 127 128 case FSTATE: 129 case FCLEAR: 130 nifree--; 131 setbit(ibmap, i); 132 break; 133 134 default: 135 errexit("BAD STATE %d FOR INODE I=%ld\n", 136 statemap[j], j); 137 } 138 } 139 140 /* fill in unused par of the inode map */ 141 for (i = fs->e2fs.e2fs_ipg / NBBY; i < fs->e2fs_bsize; i++) 142 ibmap[i] = 0xff; 143 144 dbase = c * sblock.e2fs.e2fs_bpg + 145 sblock.e2fs.e2fs_first_dblock; 146 dmax = (c+1) * sblock.e2fs.e2fs_bpg + 147 sblock.e2fs.e2fs_first_dblock; 148 149 for (i = 0, d = dbase; 150 d < dmax; 151 d ++, i ++) { 152 if (testbmap(d) || d >= sblock.e2fs.e2fs_bcount) { 153 setbit(bbmap, i); 154 continue; 155 } else { 156 nbfree++; 157 } 158 159 } 160 cs_nbfree += nbfree; 161 cs_nifree += nifree; 162 cs_ndir += ndirs; 163 164 if (debug && (fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree || 165 fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree || 166 fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs)) { 167 printf("summary info for cg %d is %d, %d, %d," 168 "should be %d, %d, %d\n", c, 169 fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree), 170 fs2h16(fs->e2fs_gd[c].ext2bgd_nifree), 171 fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs), 172 nbfree, 173 nifree, 174 ndirs); 175 } 176 (void)snprintf(msg, sizeof(msg), 177 "SUMMARY INFORMATIONS WRONG FOR CG #%d", c); 178 if ((fs2h16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree || 179 fs2h16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree || 180 fs2h16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs) && 181 dofix(&idesc[0], msg)) { 182 fs->e2fs_gd[c].ext2bgd_nbfree = h2fs16(nbfree); 183 fs->e2fs_gd[c].ext2bgd_nifree = h2fs16(nifree); 184 fs->e2fs_gd[c].ext2bgd_ndirs = h2fs16(ndirs); 185 sbdirty(); 186 } 187 188 if (debug && memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize)) { 189 printf("blk_bitmap:\n"); 190 print_bmap(blk_bitmap->b_un.b_buf, fs->e2fs_bsize); 191 printf("bbmap:\n"); 192 print_bmap(bbmap, fs->e2fs_bsize); 193 } 194 195 (void)snprintf(msg, sizeof(msg), 196 "BLK(S) MISSING IN BIT MAPS #%d", c); 197 if (memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize) && 198 dofix(&idesc[1], msg)) { 199 memcpy(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize); 200 dirty(blk_bitmap); 201 } 202 if (debug && memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize)) { 203 printf("ino_bitmap:\n"); 204 print_bmap(ino_bitmap->b_un.b_buf, fs->e2fs_bsize); 205 printf("ibmap:\n"); 206 print_bmap(ibmap, fs->e2fs_bsize); 207 } 208 (void)snprintf(msg, sizeof(msg), 209 "INODE(S) MISSING IN BIT MAPS #%d", c); 210 if (memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize) && 211 dofix(&idesc[1], msg)) { 212 memcpy(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize); 213 dirty(ino_bitmap); 214 } 215 216 } 217 if (debug && (fs->e2fs.e2fs_fbcount != cs_nbfree || 218 fs->e2fs.e2fs_ficount != cs_nifree)) { 219 printf("summary info bad in superblock: %d, %d should be %d, %d\n", 220 fs->e2fs.e2fs_fbcount, fs->e2fs.e2fs_ficount, 221 cs_nbfree, cs_nifree); 222 } 223 if ((fs->e2fs.e2fs_fbcount != cs_nbfree || 224 fs->e2fs.e2fs_ficount != cs_nifree) 225 && dofix(&idesc[0], "SUPERBLK SUMMARY INFORMATION BAD")) { 226 fs->e2fs.e2fs_fbcount = cs_nbfree; 227 fs->e2fs.e2fs_ficount = cs_nifree; 228 sbdirty(); 229 } 230 free(ibmap); 231 free(bbmap); 232 } 233 234 void 235 print_bmap(u_char *map, u_int32_t size) 236 { 237 int i, j; 238 239 i = 0; 240 while (i < size) { 241 printf("%u: ",i); 242 for (j = 0; j < 16; j++, i++) 243 printf("%2x ", (u_int)map[i] & 0xff); 244 printf("\n"); 245 } 246 } 247