tst_bitmaps.c revision b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537
1b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o/*
2b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * tst_bitmaps.c
3b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o *
4b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * Copyright (C) 2011 Theodore Ts'o.
5b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o *
6b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * %Begin-Header%
7b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * This file may be redistributed under the terms of the GNU Library
8b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * General Public License, version 2.
9b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * %End-Header%
10b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o */
11b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
12b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include "config.h"
13b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <unistd.h>
14b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <stdlib.h>
15b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <stdio.h>
16b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#ifdef HAVE_GETOPT_H
17b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <getopt.h>
18b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#endif
19b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <string.h>
20b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <fcntl.h>
21b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <time.h>
22b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <sys/stat.h>
23b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include <sys/types.h>
24b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include "ss/ss.h"
25b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
26b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include "ext2_fs.h"
27b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include "ext2fs.h"
28b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#include "ext2fsP.h"
29b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
30b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'oextern ss_request_table tst_bitmaps_cmds;
31b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
32b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ostatic char subsystem_name[] = "tst_bitmaps";
33b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ostatic char version[] = "1.0";
34b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
35b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'oext2_filsys	test_fs;
36b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'oint		exit_status = 0;
37b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
38b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ostatic int source_file(const char *cmd_file, int sci_idx)
39b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
40b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	FILE		*f;
41b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	char		buf[256];
42b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	char		*cp;
43b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int		retval;
44b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int 		noecho;
45b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
46b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (strcmp(cmd_file, "-") == 0)
47b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		f = stdin;
48b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	else {
49b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		f = fopen(cmd_file, "r");
50b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (!f) {
51b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			perror(cmd_file);
52b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			exit(1);
53b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		}
54b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
55b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	fflush(stdout);
56b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	fflush(stderr);
57b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	setbuf(stdout, NULL);
58b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	setbuf(stderr, NULL);
59b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	while (!feof(f)) {
60b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (fgets(buf, sizeof(buf), f) == NULL)
61b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
62b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (buf[0] == '#')
63b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			continue;
64b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		noecho = 0;
65b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (buf[0] == '-') {
66b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			noecho = 1;
67b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			buf[0] = ' ';
68b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		}
69b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		cp = strchr(buf, '\n');
70b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (cp)
71b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			*cp = 0;
72b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		cp = strchr(buf, '\r');
73b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (cp)
74b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			*cp = 0;
75b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (!noecho)
76b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			printf("%s: %s\n", subsystem_name, buf);
77b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		retval = ss_execute_line(sci_idx, buf);
78b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (retval) {
79b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			ss_perror(sci_idx, retval, buf);
80b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			exit_status++;
81b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		}
82b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
83b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	return exit_status;
84b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
85b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
86b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
87b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o/*
88b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * This function resets the libc getopt() function, which keeps
89b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * internal state.  Bad design!  Stupid libc API designers!  No
90b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * biscuit!
91b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o *
92b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * BSD-derived getopt() functions require that optind be reset to 1 in
93b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * order to reset getopt() state.  This used to be generally accepted
94b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * way of resetting getopt().  However, glibc's getopt()
95b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * has additional getopt() state beyond optind, and requires that
96b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * optind be set zero to reset its state.  So the unfortunate state of
97b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * affairs is that BSD-derived versions of getopt() misbehave if
98b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * optind is set to 0 in order to reset getopt(), and glibc's getopt()
99b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * will core dump if optind is set 1 in order to reset getopt().
100b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o *
101b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * More modern versions of BSD require that optreset be set to 1 in
102b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * order to reset getopt().   Sigh.  Standards, anyone?
103b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o *
104b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * We hide the hair here.
105b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o */
106b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid reset_getopt(void)
107b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
108b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#if defined(__GLIBC__) || defined(__linux__)
109b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	optind = 0;
110b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#else
111b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	optind = 1;
112b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#endif
113b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#ifdef HAVE_OPTRESET
114b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	optreset = 1;		/* Makes BSD getopt happy */
115b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o#endif
116b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
117b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
118b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o/*
119b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * This function will convert a string to an unsigned long, printing
120b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o * an error message if it fails, and returning success or failure in err.
121b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o */
122b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ounsigned long parse_ulong(const char *str, const char *cmd,
123b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			  const char *descr, int *err)
124b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
125b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	char		*tmp;
126b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned long	ret;
127b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
128b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	ret = strtoul(str, &tmp, 0);
129b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (*tmp == 0) {
130b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (err)
131b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			*err = 0;
132b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return ret;
133b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
134b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	com_err(cmd, 0, "Bad %s - %s", descr, str);
135b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (err)
136b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		*err = 1;
137b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	else
138b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		exit(1);
139b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	return 0;
140b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
141b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
142b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
143b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'oint check_fs_open(char *name)
144b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
145b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (!test_fs) {
146b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(name, 0, "Filesystem not open");
147b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return 1;
148b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
149b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	return 0;
150b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
151b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
152b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ostatic void setup_filesystem(const char *name,
153b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			     unsigned int blocks, unsigned int inodes,
154b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			     unsigned int type)
155b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
156b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	struct ext2_super_block param;
157b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	errcode_t retval;
158b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
159b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	memset(&param, 0, sizeof(param));
160b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	ext2fs_blocks_count_set(&param, blocks);
161b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	param.s_inodes_count = inodes;
162b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
163b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	retval = ext2fs_initialize("test fs", EXT2_FLAG_64BITS, &param,
164b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				   test_io_manager, &test_fs);
165b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
166b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (retval) {
167b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(name, retval, "while initializing filesystem");
168b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
169b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
170b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_fs->default_bitmap_type = type;
171b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	ext2fs_free_block_bitmap(test_fs->block_map);
172b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_fs->block_map = 0;
173b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	ext2fs_free_inode_bitmap(test_fs->inode_map);
174b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_fs->inode_map = 0;
175b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	retval = ext2fs_allocate_block_bitmap(test_fs, "block bitmap",
176b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o					      &test_fs->block_map);
177b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (retval) {
178b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(name, retval, "while allocating block bitmap");
179b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		goto errout;
180b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
181b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	retval = ext2fs_allocate_inode_bitmap(test_fs, "inode bitmap",
182b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o					      &test_fs->inode_map);
183b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (retval) {
184b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(name, retval, "while allocating inode bitmap");
185b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		goto errout;
186b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
187b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	return;
188b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
189b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'oerrout:
190b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	ext2fs_close(test_fs);
191b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_fs = 0;
192b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
193b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
194b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid setup_cmd(int argc, char **argv)
195b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
196b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	errcode_t	retval;
197b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int		i, c, err;
198b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int	blocks = 128;
199b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int	inodes = 0;
200b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int	type = EXT2FS_BMAP64_BITARRAY;
201b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
202b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (test_fs) {
203b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		ext2fs_close(test_fs);
204b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		test_fs = 0;
205b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
206b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
207b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	reset_getopt();
208b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	while ((c = getopt(argc, argv, "b:i:t:")) != EOF) {
209b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		switch (c) {
210b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		case 'b':
211b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			blocks = parse_ulong(optarg, argv[0],
212b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o					     "number of blocks", &err);
213b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			if (err)
214b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				return;
215b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
216b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		case 'i':
217b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			inodes = parse_ulong(optarg, argv[0],
218b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o					     "number of blocks", &err);
219b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			if (err)
220b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				return;
221b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
222b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		case 't':
223b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			type = parse_ulong(optarg, argv[0],
224b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o					   "bitmap backend type", &err);
225b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			if (err)
226b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				return;
227b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
228b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		default:
229b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			fprintf(stderr, "%s: usage: setup [-b blocks] "
230b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				"[-i inodes] [-t type]\n", argv[0]);
231b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			return;
232b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		}
233b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
234b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	setup_filesystem(argv[0], blocks, inodes, type);
235b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
236b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
237b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid close_cmd(int argc, char **argv)
238b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
239b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
240b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
241b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
242b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	ext2fs_close(test_fs);
243b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_fs = 0;
244b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
245b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
246b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
247b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid dump_bitmap(ext2fs_generic_bitmap bmap, unsigned int start, unsigned num)
248b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
249b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned char	*buf;
250b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	errcode_t	retval;
251b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int		i, len = (num - start + 7) / 8;
252b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
253b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	buf = malloc(len);
254b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (!buf) {
255b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err("dump_bitmap", 0, "couldn't allocate buffer");
256b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
257b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
258b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	memset(buf, 0, len);
259b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	retval = ext2fs_get_generic_bmap_range(bmap, (__u64) start, num, buf);
260b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (retval) {
261b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err("dump_bitmap", retval,
262b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			"while calling ext2fs_generic_bmap_range");
263b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		free(buf);
264b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
265b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
266b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	for (i=0; i < len; i++)
267b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		printf("%02x", buf[i]);
268b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("\n");
269b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	free(buf);
270b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
271b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
272b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid dump_inode_bitmap_cmd(int argc, char **argv)
273b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
274b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
275b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
276b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
277b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("inode bitmap: ");
278b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	dump_bitmap(test_fs->inode_map, 1, test_fs->super->s_inodes_count);
279b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
280b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
281b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid dump_block_bitmap_cmd(int argc, char **argv)
282b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
283b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
284b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
285b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
286b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("block bitmap: ");
287b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	dump_bitmap(test_fs->block_map, test_fs->super->s_first_data_block,
288b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		    test_fs->super->s_blocks_count);
289b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
290b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
291b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid do_setb(int argc, char *argv[])
292b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
293b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int block, num;
294b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int err;
295b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int test_result, op_result;
296b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
297b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
298b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
299b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
300b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc != 2 && argc != 3) {
301b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "Usage: setb <block> [num]");
302b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
303b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
304b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
305b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	block = parse_ulong(argv[1], argv[0], "block", &err);
306b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (err)
307b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
308b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
309b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc == 3) {
310b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		num = parse_ulong(argv[2], argv[0], "num", &err);
311b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (err)
312b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			return;
313b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
314b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		ext2fs_mark_block_bitmap_range2(test_fs->block_map,
315b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o						block, num);
316b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		printf("Marking blocks %u to %u\n", block, block + num - 1);
317b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
318b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
319b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
320b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_result = ext2fs_test_block_bitmap2(test_fs->block_map, block);
321b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	op_result = ext2fs_mark_block_bitmap2(test_fs->block_map, block);
322b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("Setting block %u, was %s before\n", block, op_result ?
323b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	       "set" : "clear");
324b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (!test_result != !op_result)
325b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "*ERROR* test_result different! (%d, %d)",
326b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			test_result, op_result);
327b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
328b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
329b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid do_clearb(int argc, char *argv[])
330b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
331b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int block, num;
332b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int err;
333b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int test_result, op_result;
334b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
335b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
336b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
337b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
338b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc != 2 && argc != 3) {
339b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "Usage: clearb <block> [num]");
340b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
341b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
342b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
343b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	block = parse_ulong(argv[1], argv[0], "block", &err);
344b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (err)
345b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
346b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
347b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc == 3) {
348b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		num = parse_ulong(argv[2], argv[0], "num", &err);
349b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (err)
350b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			return;
351b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
352b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		ext2fs_unmark_block_bitmap_range2(test_fs->block_map,
353b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o						block, num);
354b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		printf("Clearing blocks %u to %u\n", block, block + num - 1);
355b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
356b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
357b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
358b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_result = ext2fs_test_block_bitmap2(test_fs->block_map, block);
359b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	op_result = ext2fs_unmark_block_bitmap2(test_fs->block_map, block);
360b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("Clearing block %u, was %s before\n", block, op_result ?
361b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	       "set" : "clear");
362b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (!test_result != !op_result)
363b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "*ERROR* test_result different! (%d, %d)",
364b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			test_result, op_result);
365b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
366b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
367b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid do_testb(int argc, char *argv[])
368b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
369b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int block, num;
370b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int err;
371b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int test_result, op_result;
372b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
373b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
374b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
375b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
376b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc != 2 && argc != 3) {
377b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "Usage: testb <block> [num]");
378b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
379b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
380b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
381b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	block = parse_ulong(argv[1], argv[0], "block", &err);
382b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (err)
383b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
384b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
385b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc == 3) {
386b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		num = parse_ulong(argv[2], argv[0], "num", &err);
387b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (err)
388b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			return;
389b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
390b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		test_result =
391b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			ext2fs_test_block_bitmap_range2(test_fs->block_map,
392b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o							block, num);
393b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		printf("Blocks %u to %u are %sall clear.\n",
394b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		       block, block + num - 1, test_result ? "" : "NOT ");
395b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
396b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
397b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
398b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_result = ext2fs_test_block_bitmap2(test_fs->block_map, block);
399b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("Block %u is %s\n", block, test_result ? "set" : "clear");
400b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
401b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
402b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid do_zerob(int argc, char *argv[])
403b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
404b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
405b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
406b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
407b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("Clearing block bitmap.\n");
408b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	ext2fs_clear_block_bitmap(test_fs->block_map);
409b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
410b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
411b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid do_seti(int argc, char *argv[])
412b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
413b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int inode;
414b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int err;
415b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int test_result, op_result;
416b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
417b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
418b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
419b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
420b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc != 2) {
421b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "Usage: seti <inode>");
422b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
423b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
424b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
425b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	inode = parse_ulong(argv[1], argv[0], "inode", &err);
426b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (err)
427b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
428b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
429b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_result = ext2fs_test_inode_bitmap2(test_fs->inode_map, inode);
430b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	op_result = ext2fs_mark_inode_bitmap2(test_fs->inode_map, inode);
431b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("Setting inode %u, was %s before\n", inode, op_result ?
432b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	       "set" : "clear");
433b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (!test_result != !op_result) {
434b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "*ERROR* test_result different! (%d, %d)",
435b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			test_result, op_result);
436b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		exit_status++;
437b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
438b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
439b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
440b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid do_cleari(int argc, char *argv[])
441b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
442b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int inode;
443b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int err;
444b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int test_result, op_result;
445b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
446b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
447b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
448b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
449b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc != 2) {
450b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "Usage: clearb <inode>");
451b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
452b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
453b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
454b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	inode = parse_ulong(argv[1], argv[0], "inode", &err);
455b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (err)
456b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
457b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
458b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_result = ext2fs_test_inode_bitmap2(test_fs->inode_map, inode);
459b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	op_result = ext2fs_unmark_inode_bitmap2(test_fs->inode_map, inode);
460b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("Clearing inode %u, was %s before\n", inode, op_result ?
461b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	       "set" : "clear");
462b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (!test_result != !op_result) {
463b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "*ERROR* test_result different! (%d, %d)",
464b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			test_result, op_result);
465b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		exit_status++;
466b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
467b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
468b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
469b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid do_testi(int argc, char *argv[])
470b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
471b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int inode;
472b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int err;
473b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int test_result, op_result;
474b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
475b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
476b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
477b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
478b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (argc != 2) {
479b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		com_err(argv[0], 0, "Usage: testb <inode>");
480b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
481b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
482b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
483b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	inode = parse_ulong(argv[1], argv[0], "inode", &err);
484b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (err)
485b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
486b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
487b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	test_result = ext2fs_test_inode_bitmap2(test_fs->inode_map, inode);
488b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("Inode %u is %s\n", inode, test_result ? "set" : "clear");
489b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
490b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
491b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'ovoid do_zeroi(int argc, char *argv[])
492b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
493b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (check_fs_open(argv[0]))
494b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		return;
495b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
496b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("Clearing inode bitmap.\n");
497b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	ext2fs_clear_inode_bitmap(test_fs->inode_map);
498b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
499b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
500b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'oint main(int argc, char **argv)
501b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o{
502b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int	blocks = 128;
503b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int	inodes = 0;
504b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	unsigned int	type = EXT2FS_BMAP64_BITARRAY;
505b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int		c, err, code;
506b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	char		*request = (char *)NULL;
507b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	char		*cmd_file = 0;
508b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	int		sci_idx;
509b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
510b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	add_error_table(&et_ss_error_table);
511b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	add_error_table(&et_ext2_error_table);
512b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	while ((c = getopt (argc, argv, "b:i:t:R:f:")) != EOF) {
513b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		switch (c) {
514b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		case 'b':
515b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			blocks = parse_ulong(optarg, argv[0],
516b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o					     "number of blocks", &err);
517b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			if (err)
518b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				return;
519b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
520b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		case 'i':
521b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			inodes = parse_ulong(optarg, argv[0],
522b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o					     "number of blocks", &err);
523b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			if (err)
524b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				return;
525b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
526b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		case 't':
527b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			type = parse_ulong(optarg, argv[0],
528b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o					   "bitmap backend type", &err);
529b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			if (err)
530b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				return;
531b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
532b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		case 'R':
533b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			request = optarg;
534b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
535b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		case 'f':
536b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			cmd_file = optarg;
537b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			break;
538b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		default:
539b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			com_err(argv[0], 0, "Usage: %s [-R request] "
540b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				"[-f cmd_file]", subsystem_name);
541b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			exit(1);
542b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		}
543b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
544b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
545b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	sci_idx = ss_create_invocation(subsystem_name, version,
546b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o				       (char *)NULL, &tst_bitmaps_cmds, &code);
547b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (code) {
548b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		ss_perror(sci_idx, code, "creating invocation");
549b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		exit(1);
550b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
551b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
552b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	(void) ss_add_request_table (sci_idx, &ss_std_requests, 1, &code);
553b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (code) {
554b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		ss_perror(sci_idx, code, "adding standard requests");
555b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		exit (1);
556b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
557b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
558b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	printf("%s %s.  Type '?' for a list of commands.\n\n",
559b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	       subsystem_name, version);
560b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
561b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	setup_filesystem(argv[0], blocks, inodes, type);
562b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
563b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	if (request) {
564b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		code = ss_execute_line(sci_idx, request);
565b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		if (code) {
566b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			ss_perror(sci_idx, code, request);
567b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o			exit_status++;
568b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		}
569b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	} else if (cmd_file) {
570b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		exit_status = source_file(cmd_file, sci_idx);
571b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	} else {
572b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o		ss_listen(sci_idx);
573b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	}
574b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
575b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o	exit(exit_status);
576b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o}
577b8ad88b3e746b0c37dfb61e0fe7ad7a7636f9537Theodore Ts'o
578