1 /* $OpenBSD: pass5.c,v 1.18 2015/01/16 06:39:57 deraadt 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> /* setbit isset */ 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 <string.h> 40 #include <stdio.h> 41 #include <stdlib.h> 42 43 #include "fsutil.h" 44 #include "fsck.h" 45 #include "extern.h" 46 47 48 void print_bmap(u_char *,u_int32_t); 49 50 void 51 pass5(void) 52 { 53 int c; 54 struct m_ext2fs *fs = &sblock; 55 daddr32_t dbase, dmax; 56 daddr32_t d; 57 long i, j; 58 struct inodesc idesc[3]; 59 struct bufarea *ino_bitmap = NULL, *blk_bitmap = NULL; 60 char *ibmap, *bbmap; 61 u_int32_t cs_ndir, cs_nbfree, cs_nifree; 62 char msg[255]; 63 64 cs_ndir = 0; 65 cs_nbfree = 0; 66 cs_nifree = 0; 67 68 ibmap = malloc(fs->e2fs_bsize); 69 bbmap = malloc(fs->e2fs_bsize); 70 if (ibmap == NULL || bbmap == NULL) { 71 errexit("out of memory\n"); 72 } 73 74 for (c = 0; c < fs->e2fs_ncg; c++) { 75 u_int32_t nbfree = 0; 76 u_int32_t nifree = 0; 77 u_int32_t ndirs = 0; 78 79 nbfree = 0; 80 nifree = fs->e2fs.e2fs_ipg; 81 ndirs = 0; 82 83 if (blk_bitmap == NULL) { 84 blk_bitmap = getdatablk(letoh32(fs->e2fs_gd[c].ext2bgd_b_bitmap), 85 fs->e2fs_bsize); 86 } else { 87 getblk(blk_bitmap, letoh32(fs->e2fs_gd[c].ext2bgd_b_bitmap), 88 fs->e2fs_bsize); 89 } 90 if (ino_bitmap == NULL) { 91 ino_bitmap = getdatablk(letoh32(fs->e2fs_gd[c].ext2bgd_i_bitmap), 92 fs->e2fs_bsize); 93 } else { 94 getblk(ino_bitmap, letoh32(fs->e2fs_gd[c].ext2bgd_i_bitmap), 95 fs->e2fs_bsize); 96 } 97 memset(bbmap, 0, fs->e2fs_bsize); 98 memset(ibmap, 0, fs->e2fs_bsize); 99 memset(&idesc[0], 0, sizeof idesc); 100 for (i = 0; i < 3; i++) { 101 idesc[i].id_type = ADDR; 102 } 103 104 j = fs->e2fs.e2fs_ipg * c + 1; 105 106 for (i = 0; i < fs->e2fs.e2fs_ipg; j++, i++) { 107 if ((j < EXT2_FIRSTINO) && (j != EXT2_ROOTINO)) { 108 setbit(ibmap, i); 109 nifree--; 110 continue; 111 } 112 if (j > fs->e2fs.e2fs_icount) { 113 setbit(ibmap, i); 114 continue; 115 } 116 switch (statemap[j]) { 117 118 case USTATE: 119 break; 120 121 case DSTATE: 122 case DCLEAR: 123 case DFOUND: 124 ndirs++; 125 /* fall through */ 126 127 case FSTATE: 128 case FCLEAR: 129 nifree--; 130 setbit(ibmap, i); 131 break; 132 133 default: 134 errexit("BAD STATE %d FOR INODE I=%llu\n", 135 statemap[j], (unsigned long long)j); 136 } 137 } 138 139 /* fill in unused par of the inode map */ 140 for (i = fs->e2fs.e2fs_ipg / NBBY; i < fs->e2fs_bsize; i++) 141 ibmap[i] = 0xff; 142 143 dbase = c * sblock.e2fs.e2fs_bpg + 144 sblock.e2fs.e2fs_first_dblock; 145 dmax = (c+1) * sblock.e2fs.e2fs_bpg + 146 sblock.e2fs.e2fs_first_dblock; 147 148 for (i = 0, d = dbase; 149 d < dmax; 150 d ++, i ++) { 151 if (testbmap(d) || d >= sblock.e2fs.e2fs_bcount) { 152 setbit(bbmap, i); 153 continue; 154 } else { 155 nbfree++; 156 } 157 158 } 159 cs_nbfree += nbfree; 160 cs_nifree += nifree; 161 cs_ndir += ndirs; 162 163 if (debug && (letoh16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree || 164 letoh16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree || 165 letoh16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs)) { 166 printf("summary info for cg %d is %d, %d, %d," 167 "should be %d, %d, %d\n", c, 168 letoh16(fs->e2fs_gd[c].ext2bgd_nbfree), 169 letoh16(fs->e2fs_gd[c].ext2bgd_nifree), 170 letoh16(fs->e2fs_gd[c].ext2bgd_ndirs), 171 nbfree, 172 nifree, 173 ndirs); 174 } 175 (void)snprintf(msg, sizeof(msg), 176 "SUMMARY INFORMATIONS WRONG FOR CG #%d", c); 177 if ((letoh16(fs->e2fs_gd[c].ext2bgd_nbfree) != nbfree || 178 letoh16(fs->e2fs_gd[c].ext2bgd_nifree) != nifree || 179 letoh16(fs->e2fs_gd[c].ext2bgd_ndirs) != ndirs) && 180 dofix(&idesc[0], msg)) { 181 fs->e2fs_gd[c].ext2bgd_nbfree = htole16(nbfree); 182 fs->e2fs_gd[c].ext2bgd_nifree = htole16(nifree); 183 fs->e2fs_gd[c].ext2bgd_ndirs = htole16(ndirs); 184 sbdirty(); 185 } 186 187 if (debug && memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize)) { 188 printf("blk_bitmap:\n"); 189 print_bmap(blk_bitmap->b_un.b_buf, fs->e2fs_bsize); 190 printf("bbmap:\n"); 191 print_bmap(bbmap, fs->e2fs_bsize); 192 } 193 194 (void)snprintf(msg, sizeof(msg), 195 "BLK(S) MISSING IN BIT MAPS #%d", c); 196 if (memcmp(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize) && 197 dofix(&idesc[1], msg)) { 198 memcpy(blk_bitmap->b_un.b_buf, bbmap, fs->e2fs_bsize); 199 dirty(blk_bitmap); 200 } 201 if (debug && memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize)) { 202 printf("ino_bitmap:\n"); 203 print_bmap(ino_bitmap->b_un.b_buf, fs->e2fs_bsize); 204 printf("ibmap:\n"); 205 print_bmap(ibmap, fs->e2fs_bsize); 206 } 207 (void)snprintf(msg, sizeof(msg), 208 "INODE(S) MISSING IN BIT MAPS #%d", c); 209 if (memcmp(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize) && 210 dofix(&idesc[1], msg)) { 211 memcpy(ino_bitmap->b_un.b_buf, ibmap, fs->e2fs_bsize); 212 dirty(ino_bitmap); 213 } 214 215 } 216 if (debug && (fs->e2fs.e2fs_fbcount != cs_nbfree || 217 fs->e2fs.e2fs_ficount != cs_nifree)) { 218 printf("summary info bad in superblock: %d, %d should be %d, %d\n", 219 fs->e2fs.e2fs_fbcount, fs->e2fs.e2fs_ficount, 220 cs_nbfree, cs_nifree); 221 } 222 if ((fs->e2fs.e2fs_fbcount != cs_nbfree || 223 fs->e2fs.e2fs_ficount != cs_nifree) 224 && dofix(&idesc[0], "SUPERBLK SUMMARY INFORMATION BAD")) { 225 fs->e2fs.e2fs_fbcount = cs_nbfree; 226 fs->e2fs.e2fs_ficount = cs_nifree; 227 sbdirty(); 228 } 229 free(ibmap); 230 free(bbmap); 231 } 232 233 void 234 print_bmap(u_char *map, u_int32_t size) 235 { 236 int i, j; 237 238 i = 0; 239 while (i < size) { 240 printf("%u: ",i); 241 for (j = 0; j < 16; j++, i++) 242 printf("%2x ", (u_int)map[i] & 0xff); 243 printf("\n"); 244 } 245 } 246