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