| /* |
| * tst_inode.c --- this function tests the inode scan function |
| * |
| * Copyright (C) 1996 by Theodore Ts'o. |
| * |
| * %Begin-Header% |
| * This file may be redistributed under the terms of the GNU Public |
| * License. |
| * %End-Header% |
| */ |
| |
| #include <stdio.h> |
| #include <string.h> |
| #if HAVE_UNISTD_H |
| #include <unistd.h> |
| #endif |
| #include <fcntl.h> |
| #include <time.h> |
| #include <sys/stat.h> |
| #include <sys/types.h> |
| #if HAVE_ERRNO_H |
| #include <errno.h> |
| #endif |
| |
| #include <linux/ext2_fs.h> |
| |
| #include "ext2fs.h" |
| |
| blk_t test_vec[] = { 8, 12, 24, 34, 43, 44, 100, 0 }; |
| |
| ext2_filsys test_fs; |
| ext2fs_block_bitmap bad_block_map, touched_map; |
| ext2fs_inode_bitmap bad_inode_map; |
| badblocks_list test_badblocks; |
| |
| int first_no_comma = 1; |
| int failed = 0; |
| |
| static void test_read_blk(unsigned long block, int count, errcode_t err) |
| { |
| int i; |
| |
| if (first_no_comma) |
| first_no_comma = 0; |
| else |
| printf(", "); |
| |
| if (count > 1) |
| printf("%lu-%lu", block, block+count-1); |
| else |
| printf("%lu", block); |
| |
| for (i=0; i < count; i++, block++) { |
| if (ext2fs_test_block_bitmap(touched_map, block)) { |
| printf("\nDuplicate block?!? --- %lu\n", block); |
| failed++; |
| first_no_comma = 1; |
| } |
| ext2fs_mark_block_bitmap(touched_map, block); |
| } |
| } |
| |
| /* |
| * Setup the variables for doing the inode scan test. |
| */ |
| static void setup(void) |
| { |
| errcode_t retval; |
| int i; |
| struct ext2_super_block param; |
| |
| initialize_ext2_error_table(); |
| |
| memset(¶m, 0, sizeof(param)); |
| param.s_blocks_count = 12000; |
| |
| |
| test_io_cb_read_blk = test_read_blk; |
| |
| retval = ext2fs_initialize("test fs", 0, ¶m, |
| test_io_manager, &test_fs); |
| if (retval) { |
| com_err("setup", retval, |
| "While initializing filesystem"); |
| exit(1); |
| } |
| retval = ext2fs_allocate_tables(test_fs); |
| if (retval) { |
| com_err("setup", retval, |
| "While allocating tables for test filesystem"); |
| exit(1); |
| } |
| retval = ext2fs_allocate_block_bitmap(test_fs, "bad block map", |
| &bad_block_map); |
| if (retval) { |
| com_err("setup", retval, |
| "While allocating bad_block bitmap"); |
| exit(1); |
| } |
| retval = ext2fs_allocate_block_bitmap(test_fs, "touched map", |
| &touched_map); |
| if (retval) { |
| com_err("setup", retval, |
| "While allocating touched block bitmap"); |
| exit(1); |
| } |
| retval = ext2fs_allocate_inode_bitmap(test_fs, "bad inode map", |
| &bad_inode_map); |
| if (retval) { |
| com_err("setup", retval, |
| "While allocating bad inode bitmap"); |
| exit(1); |
| } |
| |
| retval = badblocks_list_create(&test_badblocks, 5); |
| if (retval) { |
| com_err("setup", retval, "while creating badblocks list"); |
| exit(1); |
| } |
| for (i=0; test_vec[i]; i++) { |
| retval = badblocks_list_add(test_badblocks, test_vec[i]); |
| if (retval) { |
| com_err("setup", retval, |
| "while adding test vector %d", i); |
| exit(1); |
| } |
| ext2fs_mark_block_bitmap(bad_block_map, test_vec[i]); |
| } |
| test_fs->badblocks = test_badblocks; |
| } |
| |
| /* |
| * Iterate using inode_scan |
| */ |
| static void iterate(void) |
| { |
| struct ext2_inode inode; |
| ext2_inode_scan scan; |
| errcode_t retval; |
| ino_t ino; |
| |
| retval = ext2fs_open_inode_scan(test_fs, 8, &scan); |
| if (retval) { |
| com_err("iterate", retval, "While opening inode scan"); |
| exit(1); |
| } |
| printf("Reading blocks: "); |
| retval = ext2fs_get_next_inode(scan, &ino, &inode); |
| if (retval) { |
| com_err("iterate", retval, "while reading first inode"); |
| exit(1); |
| } |
| while (ino) { |
| retval = ext2fs_get_next_inode(scan, &ino, &inode); |
| if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { |
| ext2fs_mark_inode_bitmap(bad_inode_map, ino); |
| continue; |
| } |
| if (retval) { |
| com_err("iterate", retval, |
| "while getting next inode"); |
| exit(1); |
| } |
| } |
| printf("\n"); |
| ext2fs_close_inode_scan(scan); |
| } |
| |
| /* |
| * Verify the touched map |
| */ |
| static void check_map(void) |
| { |
| int i, j, first=1; |
| unsigned long blk; |
| |
| for (i=0; test_vec[i]; i++) { |
| if (ext2fs_test_block_bitmap(touched_map, test_vec[i])) { |
| printf("Bad block was touched --- %d\n", test_vec[i]); |
| failed++; |
| first_no_comma = 1; |
| } |
| ext2fs_mark_block_bitmap(touched_map, test_vec[i]); |
| } |
| for (i = 0; i < test_fs->group_desc_count; i++) { |
| for (j=0, blk = test_fs->group_desc[i].bg_inode_table; |
| j < test_fs->inode_blocks_per_group; |
| j++, blk++) { |
| if (!ext2fs_test_block_bitmap(touched_map, blk) && |
| !ext2fs_test_block_bitmap(bad_block_map, blk)) { |
| printf("Missing block --- %lu\n", blk); |
| failed++; |
| } |
| } |
| } |
| printf("Bad inodes: "); |
| for (i=1; i <= test_fs->super->s_inodes_count; i++) { |
| if (ext2fs_test_inode_bitmap(bad_inode_map, i)) { |
| if (first) |
| first = 0; |
| else |
| printf(", "); |
| printf("%d", i); |
| } |
| } |
| printf("\n"); |
| } |
| |
| |
| int main(int argc, char **argv) |
| { |
| setup(); |
| iterate(); |
| check_map(); |
| if (!failed) |
| printf("Inode scan tested OK!\n"); |
| return failed; |
| } |
| |