iscan.c revision d0ff90d5202428583c78a60c3042e7b60d88bc45
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#ifdef HAVE_MNTENT_H
1950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <mntent.h>
2050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
2150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/ioctl.h>
22e71d87317ac095fa08079f0cc9040da16952eb93Theodore Ts'o#ifdef HAVE_MALLOC_H
2350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <malloc.h>
24e71d87317ac095fa08079f0cc9040da16952eb93Theodore Ts'o#endif
2550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
2650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "et/com_err.h"
2750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "e2fsck.h"
2850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include "../version.h"
2950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
3050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oextern int isatty(int);
3150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
3250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oconst char * program_name = "iscan";
3350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oconst char * device_name = NULL;
3450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
3550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint yflag = 0;
3650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint nflag = 0;
3750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint preen = 0;
3850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint inode_buffer_blocks = 0;
3950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint invalid_bitmaps = 0;
4050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
4150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostruct resource_track	global_rtrack;
4250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
435ba23cb149f2ff629446fb8cb5f1012c05f7a4f4Theodore Ts'ostatic void usage(void)
4450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
4550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	fprintf(stderr,
460c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		_("Usage: %s [-F] [-I inode_buffer_blocks] device\n"),
4750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		program_name);
4850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	exit(1);
4950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
5050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
5150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'ostatic void PRS(int argc, char *argv[])
5250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
5350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	int		flush = 0;
5450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	char		c;
5550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef MTRACE
5650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	extern void	*mallwatch;
5750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
58d4cac023c2540aea6a2791bcd10da95ea8ee3d28Theodore Ts'o	errcode_t	retval;
5950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
6050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	setbuf(stdout, NULL);
6150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	setbuf(stderr, NULL);
6250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	initialize_ext2_error_table();
6350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
6450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (argc && *argv)
6550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		program_name = *argv;
6650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	while ((c = getopt (argc, argv, "FI")) != EOF)
6750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		switch (c) {
6850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		case 'F':
6950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			flush = 1;
7050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
7150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		case 'I':
7250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			inode_buffer_blocks = atoi(optarg);
7350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
7450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		default:
7550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			usage ();
7650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
7750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	device_name = argv[optind];
7850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (flush) {
7950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		int	fd = open(device_name, O_RDONLY, 0);
8050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
8150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		if (fd < 0) {
820c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			com_err("open", errno,
830c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			    _("while opening %s for flushing"), device_name);
8450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			exit(FSCK_ERROR);
8550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
865ba23cb149f2ff629446fb8cb5f1012c05f7a4f4Theodore Ts'o		if ((retval = ext2fs_sync_device(fd, 1))) {
875ba23cb149f2ff629446fb8cb5f1012c05f7a4f4Theodore Ts'o			com_err("ext2fs_sync_device", retval,
880c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o				_("while trying to flush %s"), device_name);
8950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			exit(FSCK_ERROR);
9050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
9150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		close(fd);
9250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
9350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
9450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
9550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'oint main (int argc, char *argv[])
9650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o{
9750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	errcode_t	retval = 0;
9850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	int		exit_value = FSCK_OK;
9950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	ext2_filsys	fs;
10086c627ec1136446409a0170d439e60c148e6eb48Theodore Ts'o	ext2_ino_t	ino;
101d0ff90d5202428583c78a60c3042e7b60d88bc45Eric Sandeen	__u32	num_inodes = 0;
10250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	struct ext2_inode inode;
10350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	ext2_inode_scan	scan;
10450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
10550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	init_resource_track(&global_rtrack);
10650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
10750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	PRS(argc, argv);
10850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
10950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	retval = ext2fs_open(device_name, 0,
11050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			     0, 0, unix_io_manager, &fs);
11150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (retval) {
1120c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		com_err(program_name, retval, _("while trying to open %s"),
11350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			device_name);
11450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		exit(1);
11550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
11650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
11750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	ehandler_init(fs->io);
11850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
11950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	retval = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan);
12050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (retval) {
1210c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		com_err(program_name, retval, _("while opening inode scan"));
122f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o		exit(1);
12350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
12450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
12550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	while (1) {
12650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		retval = ext2fs_get_next_inode(scan, &ino, &inode);
12750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		if (retval) {
12850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			com_err(program_name, retval,
1290c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o				_("while getting next inode"));
130f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o			exit(1);
13150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		}
13250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		if (ino == 0)
13350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o			break;
13450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		num_inodes++;
13550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
13650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
1371b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	print_resource_track(NULL, &global_rtrack);
138d0ff90d5202428583c78a60c3042e7b60d88bc45Eric Sandeen	printf(_("%u inodes scanned.\n"), num_inodes);
13950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
14050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	exit(0);
14150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o}
142