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
28 blk_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
test_read_blk(unsigned long block,int count,errcode_t err)38 static 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 */
setup(void)65 static 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 */
iterate(void)134 static 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 */
check_map(void)171 static 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
main(int argc,char ** argv)209 int 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