1 /* 2 * tst_inode.c --- this function tests the inode scan function 3 * 4 * Copyright (C) 1996 by Theodore Ts'o. 5 * 6 * %Begin-Header% 7 * This file may be redistributed under the terms of the GNU Library 8 * General Public License, version 2. 9 * %End-Header% 10 */ 11 12 #include <stdio.h> 13 #include <string.h> 14 #if HAVE_UNISTD_H 15 #include <unistd.h> 16 #endif 17 #include <fcntl.h> 18 #include <time.h> 19 #include <sys/stat.h> 20 #include <sys/types.h> 21 #if HAVE_ERRNO_H 22 #include <errno.h> 23 #endif 24 25 #include "ext2_fs.h" 26 #include "ext2fs.h" 27 28 blk64_t test_vec[] = { 8, 12, 24, 34, 43, 44, 100, 0 }; 29 30 ext2_filsys test_fs; 31 ext2fs_block_bitmap bad_block_map, touched_map; 32 ext2fs_inode_bitmap bad_inode_map; 33 badblocks_list test_badblocks; 34 35 int first_no_comma = 1; 36 int failed = 0; 37 38 static void iscan_test_read_blk64(unsigned long long block, int count, errcode_t err) 39 { 40 int i; 41 42 if (first_no_comma) 43 first_no_comma = 0; 44 else 45 printf(", "); 46 47 if (count > 1) 48 printf("%llu-%llu", block, block+count-1); 49 else 50 printf("%llu", block); 51 52 for (i=0; i < count; i++, block++) { 53 if (ext2fs_test_block_bitmap2(touched_map, block)) { 54 printf("\nDuplicate block?!? --- %llu\n", block); 55 failed++; 56 first_no_comma = 1; 57 } 58 ext2fs_mark_block_bitmap2(touched_map, block); 59 } 60 } 61 62 static void iscan_test_read_blk(unsigned long block, int count, errcode_t err) 63 { 64 iscan_test_read_blk64(block, count, err); 65 } 66 67 /* 68 * Setup the variables for doing the inode scan test. 69 */ 70 static void setup(void) 71 { 72 errcode_t retval; 73 int i; 74 struct ext2_super_block param; 75 76 initialize_ext2_error_table(); 77 78 memset(¶m, 0, sizeof(param)); 79 ext2fs_blocks_count_set(¶m, 12000); 80 81 82 test_io_cb_read_blk = iscan_test_read_blk; 83 test_io_cb_read_blk64 = iscan_test_read_blk64; 84 85 retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, ¶m, 86 test_io_manager, &test_fs); 87 if (retval) { 88 com_err("setup", retval, 89 "While initializing filesystem"); 90 exit(1); 91 } 92 retval = ext2fs_allocate_tables(test_fs); 93 if (retval) { 94 com_err("setup", retval, 95 "While allocating tables for test filesystem"); 96 exit(1); 97 } 98 retval = ext2fs_allocate_block_bitmap(test_fs, "bad block map", 99 &bad_block_map); 100 if (retval) { 101 com_err("setup", retval, 102 "While allocating bad_block bitmap"); 103 exit(1); 104 } 105 retval = ext2fs_allocate_block_bitmap(test_fs, "touched map", 106 &touched_map); 107 if (retval) { 108 com_err("setup", retval, 109 "While allocating touched block bitmap"); 110 exit(1); 111 } 112 retval = ext2fs_allocate_inode_bitmap(test_fs, "bad inode map", 113 &bad_inode_map); 114 if (retval) { 115 com_err("setup", retval, 116 "While allocating bad inode bitmap"); 117 exit(1); 118 } 119 120 retval = ext2fs_badblocks_list_create(&test_badblocks, 5); 121 if (retval) { 122 com_err("setup", retval, "while creating badblocks list"); 123 exit(1); 124 } 125 for (i=0; test_vec[i]; i++) { 126 retval = ext2fs_badblocks_list_add(test_badblocks, test_vec[i]); 127 if (retval) { 128 com_err("setup", retval, 129 "while adding test vector %d", i); 130 exit(1); 131 } 132 ext2fs_mark_block_bitmap2(bad_block_map, test_vec[i]); 133 } 134 test_fs->badblocks = test_badblocks; 135 } 136 137 /* 138 * Iterate using inode_scan 139 */ 140 static void iterate(void) 141 { 142 struct ext2_inode inode; 143 ext2_inode_scan scan; 144 errcode_t retval; 145 ext2_ino_t ino; 146 147 retval = ext2fs_open_inode_scan(test_fs, 8, &scan); 148 if (retval) { 149 com_err("iterate", retval, "While opening inode scan"); 150 exit(1); 151 } 152 printf("Reading blocks: "); 153 retval = ext2fs_get_next_inode(scan, &ino, &inode); 154 if (retval) { 155 com_err("iterate", retval, "while reading first inode"); 156 exit(1); 157 } 158 while (ino) { 159 retval = ext2fs_get_next_inode(scan, &ino, &inode); 160 if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { 161 ext2fs_mark_inode_bitmap2(bad_inode_map, ino); 162 continue; 163 } 164 if (retval) { 165 com_err("iterate", retval, 166 "while getting next inode"); 167 exit(1); 168 } 169 } 170 printf("\n"); 171 ext2fs_close_inode_scan(scan); 172 } 173 174 /* 175 * Verify the touched map 176 */ 177 static void check_map(void) 178 { 179 int i, j, first=1; 180 blk64_t blk; 181 182 for (i=0; test_vec[i]; i++) { 183 if (ext2fs_test_block_bitmap2(touched_map, test_vec[i])) { 184 printf("Bad block was touched --- %llu\n", test_vec[i]); 185 failed++; 186 first_no_comma = 1; 187 } 188 ext2fs_mark_block_bitmap2(touched_map, test_vec[i]); 189 } 190 for (i = 0; i < test_fs->group_desc_count; i++) { 191 for (j=0, blk = ext2fs_inode_table_loc(test_fs, i); 192 j < test_fs->inode_blocks_per_group; 193 j++, blk++) { 194 if (!ext2fs_test_block_bitmap2(touched_map, blk) && 195 !ext2fs_test_block_bitmap2(bad_block_map, blk)) { 196 printf("Missing block --- %llu\n", blk); 197 failed++; 198 } 199 } 200 } 201 printf("Bad inodes: "); 202 for (i=1; i <= test_fs->super->s_inodes_count; i++) { 203 if (ext2fs_test_inode_bitmap2(bad_inode_map, i)) { 204 if (first) 205 first = 0; 206 else 207 printf(", "); 208 printf("%u", i); 209 } 210 } 211 printf("\n"); 212 } 213 214 215 int main(int argc, char **argv) 216 { 217 setup(); 218 iterate(); 219 check_map(); 220 if (!failed) 221 printf("Inode scan tested OK!\n"); 222 return failed; 223 } 224 225