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