tst_iscan.c revision d7cca6b06f366f998ed43346f9b6fca9e163692f
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 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
62static 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 */
70static 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(&param, 0, sizeof(param));
79	ext2fs_blocks_count_set(&param, 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, &param,
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 */
140static 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 */
177static 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 --- %u\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
215int 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