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