150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o/*
250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * Test to see how quickly we can scan the inode table (not doing
350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o * anything else)
450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o */
550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <string.h>
750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <fcntl.h>
850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <ctype.h>
950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <termios.h>
1050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <time.h>
1150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETOPT_H
1250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <getopt.h>
1350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
1450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <unistd.h>
1550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_ERRNO_H
1650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <errno.h>
1750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
1850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/ioctl.h>
19e71d87317ac095fa08079f0cc9040da16952eb93Theodore Ts'o#ifdef HAVE_MALLOC_H
2050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <malloc.h>
21e71d87317ac095fa08079f0cc9040da16952eb93Theodore Ts'o#endif
2250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
2350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "et/com_err.h"
2450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "e2fsck.h"
2550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "../version.h"
2650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
2750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oextern int isatty(int);
2850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
2950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oconst char * program_name = "iscan";
3050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oconst char * device_name = NULL;
3150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
3250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint yflag = 0;
3350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint nflag = 0;
3450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint preen = 0;
3550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint inode_buffer_blocks = 0;
3650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint invalid_bitmaps = 0;
3750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
3850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostruct resource_track	global_rtrack;
3950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
405ba23cb149f2ff629446fb8cb5f1012c05f7a4f4Theodore Ts'ostatic void usage(void)
4150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
4250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	fprintf(stderr,
430c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		_("Usage: %s [-F] [-I inode_buffer_blocks] device\n"),
4450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		program_name);
4550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	exit(1);
4650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
4750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
4850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic void PRS(int argc, char *argv[])
4950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
5050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	int		flush = 0;
51b887f08f959fa3ef4ead9b6e2fd71becf4877a40Mike Frysinger	int		c;
5250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef MTRACE
5350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	extern void	*mallwatch;
5450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
55d4cac023c2540aea6a2791bcd10da95ea8ee3d28Theodore Ts'o	errcode_t	retval;
5650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
5750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	setbuf(stdout, NULL);
5850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	setbuf(stderr, NULL);
5950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	initialize_ext2_error_table();
60efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
6150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (argc && *argv)
6250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		program_name = *argv;
6350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	while ((c = getopt (argc, argv, "FI")) != EOF)
6450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		switch (c) {
6550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		case 'F':
6650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			flush = 1;
6750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
6850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		case 'I':
6950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			inode_buffer_blocks = atoi(optarg);
7050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
7150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		default:
7250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			usage ();
7350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
7450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	device_name = argv[optind];
7550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (flush) {
7650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		int	fd = open(device_name, O_RDONLY, 0);
7750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
7850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		if (fd < 0) {
790c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			com_err("open", errno,
800c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			    _("while opening %s for flushing"), device_name);
8150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			exit(FSCK_ERROR);
8250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
835ba23cb149f2ff629446fb8cb5f1012c05f7a4f4Theodore Ts'o		if ((retval = ext2fs_sync_device(fd, 1))) {
845ba23cb149f2ff629446fb8cb5f1012c05f7a4f4Theodore Ts'o			com_err("ext2fs_sync_device", retval,
850c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o				_("while trying to flush %s"), device_name);
8650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			exit(FSCK_ERROR);
8750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
8850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		close(fd);
8950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
9050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
91efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
9250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint main (int argc, char *argv[])
9350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
9450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	errcode_t	retval = 0;
9550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	int		exit_value = FSCK_OK;
9650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	ext2_filsys	fs;
9786c627ec1136446409a0170d439e60c148e6eb48Theodore Ts'o	ext2_ino_t	ino;
98d0ff90d5202428583c78a60c3042e7b60d88bc45Eric Sandeen	__u32	num_inodes = 0;
9950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	struct ext2_inode inode;
10050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	ext2_inode_scan	scan;
101efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
10250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	init_resource_track(&global_rtrack);
10350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
10450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	PRS(argc, argv);
10550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
10650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	retval = ext2fs_open(device_name, 0,
10750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			     0, 0, unix_io_manager, &fs);
10850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (retval) {
109e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall		com_err(program_name, retval, _("while trying to open '%s'"),
11050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			device_name);
11150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		exit(1);
11250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
11350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
11450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	ehandler_init(fs->io);
115efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
11650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	retval = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan);
11750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (retval) {
1180c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		com_err(program_name, retval, _("while opening inode scan"));
119f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o		exit(1);
12050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
12150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
12250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	while (1) {
12350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		retval = ext2fs_get_next_inode(scan, &ino, &inode);
12450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		if (retval) {
12550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			com_err(program_name, retval,
1260c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o				_("while getting next inode"));
127f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o			exit(1);
12850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
12950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		if (ino == 0)
13050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
13150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		num_inodes++;
13250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
133efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
1341b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	print_resource_track(NULL, &global_rtrack);
135d0ff90d5202428583c78a60c3042e7b60d88bc45Eric Sandeen	printf(_("%u inodes scanned.\n"), num_inodes);
136efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o
13750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	exit(0);
13850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
139