util.c revision 53ef44c40a3e425d2c700d8fd77a6b655aa121fe
13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/*
23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * util.c --- miscellaneous utilities
33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o *
421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
521c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o *
621c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %Begin-Header%
721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * This file may be redistributed under the terms of the GNU Public
821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * License.
921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o * %End-Header%
103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */
113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h>
133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h>
143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <string.h>
153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <ctype.h>
169ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o
179ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#ifdef HAVE_CONIO_H
189ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#undef HAVE_TERMIOS_H
199ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#include <conio.h>
20e6597048d9d1637c9f997363a7f45c74b98fd0e2Theodore Ts'o#define read_a_char()	getch()
219ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#else
229ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#ifdef HAVE_TERMIOS_H
233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <termios.h>
249ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#endif
25e6597048d9d1637c9f997363a7f45c74b98fd0e2Theodore Ts'o#include <stdio.h>
26c81c6ce57efe7324551a96ce55bc877cf215c1caTheodore Ts'o#define read_a_char()	getchar()
279ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#endif
289ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o
294a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#ifdef HAVE_MALLOC_H
304a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#include <malloc.h>
314a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#endif
323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "e2fsck.h"
343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
3550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/time.h>
3650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#include <sys/resource.h>
3750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o
38f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'ovoid fatal_error(e2fsck_t ctx, const char *msg)
393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (msg)
411b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o		fprintf (stderr, "e2fsck: %s\n", msg);
42cc96b2b0fe3ab012f716e1fc6955b8530480fec8Theodore Ts'o	if (ctx->fs && ctx->fs->io)
43cc96b2b0fe3ab012f716e1fc6955b8530480fec8Theodore Ts'o		io_channel_flush(ctx->fs->io);
44f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o	ctx->flags |= E2F_FLAG_ABORT;
45f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o	if (ctx->flags & E2F_FLAG_SETJMP_OK)
46f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o		longjmp(ctx->abort_loc, 1);
473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	exit(FSCK_ERROR);
483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
50f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'ovoid *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
51f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o			     const char *description)
523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	void *ret;
543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	char buf[256];
553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#ifdef DEBUG_ALLOCATE_MEMORY
573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	printf("Allocating %d bytes for %s...\n", size, description);
583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#endif
593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	ret = malloc(size);
603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (!ret) {
617f88b04341d88c5df0360d930832c38040303b61Theodore Ts'o		sprintf(buf, "Can't allocate %s\n", description);
62f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o		fatal_error(ctx, buf);
633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	memset(ret, 0, size);
653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return ret;
663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oint ask_yn(const char * string, int def)
693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	int		c;
713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	const char	*defstr;
7253ef44c40a3e425d2c700d8fd77a6b655aa121feTheodore Ts'o	const char	*short_yes = _("yY");
7353ef44c40a3e425d2c700d8fd77a6b655aa121feTheodore Ts'o	const char	*short_no = _("nN");
743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
759ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#ifdef HAVE_TERMIOS_H
769ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o	struct termios	termios, tmp;
779ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o
783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	tcgetattr (0, &termios);
793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	tmp = termios;
803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	tmp.c_lflag &= ~(ICANON | ECHO);
8150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	tmp.c_cc[VMIN] = 1;
8250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	tmp.c_cc[VTIME] = 0;
833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	tcsetattr (0, TCSANOW, &tmp);
849ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#endif
853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (def == 1)
870c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		defstr = _("<y>");
883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else if (def == 0)
890c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		defstr = _("<n>");
903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
910c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		defstr = _(" (y/n)");
923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	printf("%s%s? ", string, defstr);
933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	while (1) {
943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		fflush (stdout);
95e6597048d9d1637c9f997363a7f45c74b98fd0e2Theodore Ts'o		if ((c = read_a_char()) == EOF)
963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			break;
970c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		if (strchr(short_yes, (char) c)) {
983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			def = 1;
993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			break;
1003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1010c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		else if (strchr(short_no, (char) c)) {
1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			def = 0;
1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			break;
1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		else if ((c == ' ' || c == '\n') && (def != -1))
1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o			break;
1073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (def)
1093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		printf ("yes\n\n");
1103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	else
1113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		printf ("no\n\n");
1129ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#ifdef HAVE_TERMIOS_H
1133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	tcsetattr (0, TCSANOW, &termios);
1149ecd8becf46c32ed18e468fe647947b359d25cdbTheodore Ts'o#endif
1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return def;
1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1181b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'oint ask (e2fsck_t ctx, const char * string, int def)
1193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1201b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	if (ctx->options & E2F_OPT_NO) {
1210c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		printf (_("%s? no\n\n"), string);
1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return 0;
1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1241b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	if (ctx->options & E2F_OPT_YES) {
1250c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		printf (_("%s? yes\n\n"), string);
1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return 1;
1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1281b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	if (ctx->options & E2F_OPT_PREEN) {
1290c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return def;
1313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return ask_yn(string, def);
1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
135f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'ovoid e2fsck_read_bitmaps(e2fsck_t ctx)
1363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1371b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	ext2_filsys fs = ctx->fs;
1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	errcode_t	retval;
1393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1401b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	if (ctx->invalid_bitmaps) {
1411b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o		com_err(ctx->program_name, 0,
1420c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		    _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
1431b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o			ctx->device_name);
144f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o		fatal_error(ctx, 0);
1453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
146f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
1470c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o	ehandler_operation(_("reading inode and block bitmaps"));
148f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	retval = ext2fs_read_bitmaps(fs);
149f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	ehandler_operation(0);
150f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (retval) {
1511b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o		com_err(ctx->program_name, retval,
1520c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			_("while retrying to read bitmaps for %s"),
1531b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o			ctx->device_name);
154f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o		fatal_error(ctx, 0);
1553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
158f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'ovoid e2fsck_write_bitmaps(e2fsck_t ctx)
1593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1601b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	ext2_filsys fs = ctx->fs;
1613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	errcode_t	retval;
1623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (ext2fs_test_bb_dirty(fs)) {
1640c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		ehandler_operation(_("writing block bitmaps"));
1653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		retval = ext2fs_write_block_bitmap(fs);
1663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ehandler_operation(0);
1673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (retval) {
1681b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o			com_err(ctx->program_name, retval,
1690c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			    _("while retrying to write block bitmaps for %s"),
1701b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o				ctx->device_name);
171f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o			fatal_error(ctx, 0);
1723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (ext2fs_test_ib_dirty(fs)) {
1760c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		ehandler_operation(_("writing inode bitmaps"));
1773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		retval = ext2fs_write_inode_bitmap(fs);
1783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		ehandler_operation(0);
1793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		if (retval) {
1801b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o			com_err(ctx->program_name, retval,
1810c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			    _("while retrying to write inode bitmaps for %s"),
1821b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o				ctx->device_name);
183f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o			fatal_error(ctx, 0);
1843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		}
1853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	}
1863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
1873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
1881b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'ovoid preenhalt(e2fsck_t ctx)
1893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
1901b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	ext2_filsys fs = ctx->fs;
1911b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o
1921b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	if (!(ctx->options & E2F_OPT_PREEN))
1933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		return;
1940c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o	fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
1950c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o		"RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
1961b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	       ctx->device_name);
19750e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	if (fs != NULL) {
19850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		fs->super->s_state |= EXT2_ERROR_FS;
19950e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		ext2fs_mark_super_dirty(fs);
20050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o		ext2fs_close(fs);
20150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	}
2023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	exit(FSCK_UNCORRECTED);
2033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
2058bf191e8660939687ef35c013066d2082cb16722Theodore Ts'o#ifdef RESOURCE_TRACK
2063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid init_resource_track(struct resource_track *track)
2073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
20850e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETRUSAGE
2093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct rusage r;
21050e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
2113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
2123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	track->brk_start = sbrk(0);
2133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	gettimeofday(&track->time_start, 0);
21450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETRUSAGE
21553ef44c40a3e425d2c700d8fd77a6b655aa121feTheodore Ts'o#ifdef sun
21653ef44c40a3e425d2c700d8fd77a6b655aa121feTheodore Ts'o	memset(&r, 0, sizeof(struct rusage));
2171b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o#endif
2183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	getrusage(RUSAGE_SELF, &r);
2193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	track->user_start = r.ru_utime;
2203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	track->system_start = r.ru_stime;
22150e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#else
22250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	track->user_start.tv_sec = track->user_start.tv_usec = 0;
22350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	track->system_start.tv_sec = track->system_start.tv_usec = 0;
22450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
2253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
22721c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#ifdef __GNUC__
22821c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#define _INLINE_ __inline__
22921c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#else
23021c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#define _INLINE_
23121c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o#endif
23221c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o
23321c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'ostatic _INLINE_ float timeval_subtract(struct timeval *tv1,
23421c84b71e205b5ab13f14343da5645dcc985856dTheodore Ts'o				       struct timeval *tv2)
2353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
2363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	return ((tv1->tv_sec - tv2->tv_sec) +
2373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
2383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
2401b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'ovoid print_resource_track(const char *desc, struct resource_track *track)
2413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
24250e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETRUSAGE
2433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct rusage r;
24450e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
2454a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#ifdef HAVE_MALLINFO
2464a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o	struct mallinfo	malloc_info;
2474a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#endif
2483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	struct timeval time_end;
2493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
2503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	gettimeofday(&time_end, 0);
2511b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o
2521b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	if (desc)
2537fdfabd3217ebe23b36063d561fc79960275db42Theodore Ts'o		printf("%s: ", desc);
2544a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o
2554a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#ifdef HAVE_MALLINFO
25680c5d7e45ffa2d2e6d95eef99598c64e9a96d9c0Theodore Ts'o#define kbytes(x)	(((x) + 1023) / 1024)
25780c5d7e45ffa2d2e6d95eef99598c64e9a96d9c0Theodore Ts'o
2584a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o	malloc_info = mallinfo();
25980c5d7e45ffa2d2e6d95eef99598c64e9a96d9c0Theodore Ts'o	printf(_("Memory used: %dk/%dk (%dk/%dk), "),
26080c5d7e45ffa2d2e6d95eef99598c64e9a96d9c0Theodore Ts'o	       kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd),
26180c5d7e45ffa2d2e6d95eef99598c64e9a96d9c0Theodore Ts'o	       kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks));
2624a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#else
2630c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o	printf(_("Memory used: %d, "),
2644a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o	       (int) (((char *) sbrk(0)) - ((char *) track->brk_start)));
2654a9f59366b3c5503bde40e9566dc996a0a40626fTheodore Ts'o#endif
26650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#ifdef HAVE_GETRUSAGE
2673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	getrusage(RUSAGE_SELF, &r);
2683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
26980c5d7e45ffa2d2e6d95eef99598c64e9a96d9c0Theodore Ts'o	printf(_("time: %5.2f/%5.2f/%5.2f\n"),
2703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	       timeval_subtract(&time_end, &track->time_start),
2713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	       timeval_subtract(&r.ru_utime, &track->user_start),
2723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	       timeval_subtract(&r.ru_stime, &track->system_start));
27350e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#else
2740c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o	printf(_("elapsed time: %6.3f\n"),
27550e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o	       timeval_subtract(&time_end, &track->time_start));
27650e1e10fa0ac12a3e2a9d20a75ee9041873cda96Theodore Ts'o#endif
2773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
2788bf191e8660939687ef35c013066d2082cb16722Theodore Ts'o#endif /* RESOURCE_TRACK */
2793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
28008b213017f8371ce4b56ad4d368eb0f92211d04eTheodore Ts'ovoid e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
281f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o			      struct ext2_inode * inode, const char *proc)
282f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{
283f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	int retval;
284f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
28508b213017f8371ce4b56ad4d368eb0f92211d04eTheodore Ts'o	retval = ext2fs_read_inode(ctx->fs, ino, inode);
286f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (retval) {
287f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		com_err("ext2fs_read_inode", retval,
2880c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			_("while reading inode %ld in %s"), ino, proc);
289f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o		fatal_error(ctx, 0);
290f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	}
291f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o}
292f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
29308b213017f8371ce4b56ad4d368eb0f92211d04eTheodore Ts'oextern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
294f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o			       struct ext2_inode * inode, const char *proc)
295f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{
296f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	int retval;
297f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
29808b213017f8371ce4b56ad4d368eb0f92211d04eTheodore Ts'o	retval = ext2fs_write_inode(ctx->fs, ino, inode);
299f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	if (retval) {
300f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o		com_err("ext2fs_write_inode", retval,
3010c4a07264e55b42c6e30230e66b1dea7d4b94ea9Theodore Ts'o			_("while writing inode %ld in %s"), ino, proc);
302f8188fff23dc2d9c9f858fb21264e46b17672825Theodore Ts'o		fatal_error(ctx, 0);
303f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o	}
304f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o}
305f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o
3063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#ifdef MTRACE
3073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid mtrace_print(char *mesg)
3083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{
3093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	FILE	*malloc_get_mallstream();
3103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	FILE	*f = malloc_get_mallstream();
3113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
3123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o	if (f)
3133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o		fprintf(f, "============= %s\n", mesg);
3143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o}
3153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#endif
3163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
3171b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'oblk_t get_backup_sb(ext2_filsys fs)
3181b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o{
3191b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o	if (!fs || !fs->super)
3201b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o		return 8193;
3213f65f1acaa1f32740fdbc03affe3dc95f9668badTheodore Ts'o	return fs->super->s_blocks_per_group + fs->super->s_first_data_block;
3221b6bf1759af884957234b7dce768b785f792abd0Theodore Ts'o}
3233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o
3246fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o/*
3256fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o * Given a mode, return the ext2 file type
3266fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o */
3276fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'oint ext2_file_type(unsigned int mode)
3286fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o{
3296fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o	if (LINUX_S_ISREG(mode))
3306fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o		return EXT2_FT_REG_FILE;
3316fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o
3326fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o	if (LINUX_S_ISDIR(mode))
3336fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o		return EXT2_FT_DIR;
3346fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o
3356fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o	if (LINUX_S_ISCHR(mode))
3366fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o		return EXT2_FT_CHRDEV;
3376fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o
3386fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o	if (LINUX_S_ISBLK(mode))
3396fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o		return EXT2_FT_BLKDEV;
3406fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o
3416fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o	if (LINUX_S_ISLNK(mode))
3426fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o		return EXT2_FT_SYMLINK;
3436fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o
3446fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o	if (LINUX_S_ISFIFO(mode))
3456fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o		return EXT2_FT_FIFO;
3466fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o
3476fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o	if (LINUX_S_ISSOCK(mode))
3486fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o		return EXT2_FT_SOCK;
3496fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o
3506fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o	return 0;
3516fdc7a325c8bff67fc3a0489d0858bc7c48dc1a3Theodore Ts'o}
352