119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * unix.c - The unix-specific code for e2fsck
33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header%
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the GNU Public
819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * License.
919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header%
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define _XOPEN_SOURCE 600 /* for inclusion of sa_handler in Solaris */
133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdio.h>
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_STDLIB_H
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h>
1719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
1819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
1919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <fcntl.h>
2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h>
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <time.h>
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SIGNAL_H
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <signal.h>
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETOPT_H
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <getopt.h>
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern char *optarg;
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern int optind;
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h>
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_ERRNO_H
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <errno.h>
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MNTENT_H
3619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <mntent.h>
3719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SYS_IOCTL_H
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/ioctl.h>
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MALLOC_H
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <malloc.h>
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SYS_TYPES_H
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/types.h>
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_DIRENT_H
4819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <dirent.h>
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "e2p/e2p.h"
5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "et/com_err.h"
533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include "e2p/e2p.h"
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "e2fsck.h"
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "problem.h"
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "../version.h"
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/* Command line options */
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int cflag;		/* check disk */
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int show_version_only;
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int verbose;
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int replace_bad_blocks;
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int keep_bad_blocks;
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic char *bad_blocks_file;
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projecte2fsck_t e2fsck_global_ctx;	/* Try your very best not to use this! */
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef CONFIG_JBD_DEBUG		/* Enabled by configure --enable-jfs-debug */
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint journal_enable_debug = -1;
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef ROOT_SYSCONFDIR
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define ROOT_SYSCONFDIR "/etc/"
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void usage(e2fsck_t ctx)
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fprintf(stderr,
803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		_("Usage: %s [-panyrcdfvtDFV] [-b superblock] [-B blocksize]\n"
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t\t[-l|-L bad_blocks_file] [-C fd] [-j external_journal]\n"
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"\t\t[-E extended-options] device\n"),
8419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->program_name);
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fprintf(stderr, _("\nEmergency help:\n"
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -p                   Automatic repair (no questions)\n"
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -n                   Make no changes to the filesystem\n"
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -y                   Assume \"yes\" to all questions\n"
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -c                   Check for bad blocks and add them to the badblock list\n"
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -f                   Force checking even if filesystem is marked clean\n"));
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fprintf(stderr, _(""
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -v                   Be verbose\n"
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -b superblock        Use alternative superblock\n"
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -B blocksize         Force blocksize when looking for superblock\n"
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -j external_journal  Set location of the external journal\n"
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -l bad_blocks_file   Add to badblocks list\n"
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		" -L bad_blocks_file   Set badblocks list\n"
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		));
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(FSCK_USAGE);
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void show_stats(e2fsck_t	ctx)
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2_filsys fs = ctx->fs;
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2_ino_t inodes, inodes_used;
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blk_t blocks, blocks_used;
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int dir_links;
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int num_files, num_links;
1113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int frag_percent_file, frag_percent_dir, frag_percent_total;
1123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int i, j;
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	dir_links = 2 * ctx->fs_directory_count - 1;
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	num_files = ctx->fs_total_count - dir_links;
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	num_links = ctx->fs_links_count - dir_links;
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	inodes = fs->super->s_inodes_count;
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	inodes_used = (fs->super->s_inodes_count -
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       fs->super->s_free_inodes_count);
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blocks = fs->super->s_blocks_count;
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blocks_used = (fs->super->s_blocks_count -
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       fs->super->s_free_blocks_count);
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	frag_percent_file = (10000 * ctx->fs_fragmented) / inodes_used;
1253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	frag_percent_file = (frag_percent_file + 5) / 10;
1263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	frag_percent_dir = (10000 * ctx->fs_fragmented_dir) / inodes_used;
1283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	frag_percent_dir = (frag_percent_dir + 5) / 10;
1293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	frag_percent_total = ((10000 * (ctx->fs_fragmented +
1313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					ctx->fs_fragmented_dir))
1323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			      / inodes_used);
1333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	frag_percent_total = (frag_percent_total + 5) / 10;
1343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!verbose) {
13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf(_("%s: %u/%u files (%0d.%d%% non-contiguous), %u/%u blocks\n"),
13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       ctx->device_name, inodes_used, inodes,
1383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       frag_percent_total / 10, frag_percent_total % 10,
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       blocks_used, blocks);
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("\n%8u inode used (%2.2f%%)\n", "\n%8u inodes used (%2.2f%%)\n",
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   inodes_used), inodes_used, 100.0 * inodes_used / inodes);
1443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	printf (P_("%8u non-contiguous file (%0d.%d%%)\n",
1453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		   "%8u non-contiguous files (%0d.%d%%)\n",
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_fragmented),
1473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		ctx->fs_fragmented, frag_percent_file / 10,
1483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		frag_percent_file % 10);
1493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	printf (P_("%8u non-contiguous directory (%0d.%d%%)\n",
1503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		   "%8u non-contiguous directories (%0d.%d%%)\n",
1513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		   ctx->fs_fragmented_dir),
1523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		ctx->fs_fragmented_dir, frag_percent_dir / 10,
1533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		frag_percent_dir % 10);
15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (_("         # of inodes with ind/dind/tind blocks: %u/%u/%u\n"),
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
1563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
1573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (j=MAX_EXTENT_DEPTH_COUNT-1; j >=0; j--)
1583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (ctx->extent_depth_count[j])
1593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			break;
1603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (++j) {
1613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		printf (_("         Extent depth histogram: "));
1623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		for (i=0; i < j; i++) {
1633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (i)
1643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				fputc('/', stdout);
1653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			printf("%u", ctx->extent_depth_count[i]);
1663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
1673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fputc('\n', stdout);
1683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
1693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u block used (%2.2f%%)\n", "%8u blocks used (%2.2f%%)\n",
17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   blocks_used), blocks_used, 100.0 * blocks_used / blocks);
17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u bad block\n", "%8u bad blocks\n",
17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_badblocks_count), ctx->fs_badblocks_count);
17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u large file\n", "%8u large files\n",
17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->large_files), ctx->large_files);
17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("\n%8u regular file\n", "\n%8u regular files\n",
17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_regular_count), ctx->fs_regular_count);
17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u directory\n", "%8u directories\n",
17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_directory_count), ctx->fs_directory_count);
18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u character device file\n",
18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   "%8u character device files\n", ctx->fs_chardev_count),
18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->fs_chardev_count);
18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u block device file\n", "%8u block device files\n",
18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_blockdev_count), ctx->fs_blockdev_count);
18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u fifo\n", "%8u fifos\n", ctx->fs_fifo_count),
18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->fs_fifo_count);
18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u link\n", "%8u links\n",
18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_links_count - dir_links),
18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->fs_links_count - dir_links);
19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u symbolic link", "%8u symbolic links",
19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_symlinks_count), ctx->fs_symlinks_count);
19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_(" (%u fast symbolic link)\n", " (%u fast symbolic links)\n",
19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_fast_symlinks_count), ctx->fs_fast_symlinks_count);
19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u socket\n", "%8u sockets\n", ctx->fs_sockets_count),
19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->fs_sockets_count);
19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf ("--------\n");
19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf (P_("%8u file\n", "%8u files\n",
19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   ctx->fs_total_count - dir_links),
19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->fs_total_count - dir_links);
20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void check_mount(e2fsck_t ctx)
20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	errcode_t	retval;
20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		cont;
20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = ext2fs_check_if_mounted(ctx->filesystem_name,
20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					 &ctx->mount_flags);
20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err("ext2fs_check_if_mount", retval,
21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("while determining whether %s is mounted."),
21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->filesystem_name);
21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * If the filesystem isn't mounted, or it's the root
21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * filesystem and it's mounted read-only, and we're not doing
21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * a read/write check, then everything's fine.
22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    ((ctx->mount_flags & EXT2_MF_ISROOT) &&
22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     (ctx->mount_flags & EXT2_MF_READONLY) &&
22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     !(ctx->options & E2F_OPT_WRITECHECK)))
22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((ctx->options & E2F_OPT_READONLY) &&
22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !(ctx->options & E2F_OPT_WRITECHECK)) {
22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf(_("Warning!  %s is mounted.\n"), ctx->filesystem_name);
23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf(_("%s is mounted.  "), ctx->filesystem_name);
23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ctx->interactive)
23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf(_("\n\n\007\007\007\007WARNING!!!  "
2373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	       "The filesystem is mounted.   If you continue you ***WILL***\n"
2383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	       "cause ***SEVERE*** filesystem damage.\007\007\007\n\n"));
23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	cont = ask_yn(_("Do you really want to continue"), -1);
24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!cont) {
24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf (_("check aborted.\n"));
24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit (0);
24319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
24419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return;
24519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
24619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
24719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int is_on_batt(void)
24819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
24919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	FILE	*f;
25019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	DIR	*d;
25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	tmp[80], tmp2[80], fname[80];
25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int	acflag;
25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct dirent*	de;
25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	f = fopen("/proc/apm", "r");
25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (f) {
2573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			acflag = 1;
25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fclose(f);
26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return (acflag != 1);
26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	d = opendir("/proc/acpi/ac_adapter");
26319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (d) {
26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		while ((de=readdir(d)) != NULL) {
26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!strncmp(".", de->d_name, 1))
26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
2673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 de->d_name);
26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			f = fopen(fname, "r");
27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!f)
27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (fscanf(f, "%s %s", tmp2, tmp) != 2)
27319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				tmp[0] = 0;
27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fclose(f);
27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (strncmp(tmp, "off-line", 8) == 0) {
27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				closedir(d);
27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				return 1;
27819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
27919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		closedir(d);
28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
28419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This routine checks to see if a filesystem can be skipped; if so,
28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * it will exit with E2FSCK_OK.  Under some conditions it will print a
28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * message explaining why a check is being forced.
28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void check_if_skip(e2fsck_t ctx)
29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2_filsys fs = ctx->fs;
29319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *reason = NULL;
29419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int reason_arg = 0;
29519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	long next_check;
29619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int batt = is_on_batt();
29719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int defer_check_on_battery;
2988558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	int broken_system_clock;
29919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	time_t lastcheck;
30019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3018558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	profile_get_boolean(ctx->profile, "options", "broken_system_clock",
3028558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			    0, 0, &broken_system_clock);
3038558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	if (ctx->flags & E2F_FLAG_TIME_INSANE)
3048558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall		broken_system_clock = 1;
30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	profile_get_boolean(ctx->profile, "options",
3063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			    "defer_check_on_battery", 0, 1,
30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			    &defer_check_on_battery);
30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!defer_check_on_battery)
30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		batt = 0;
31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file || cflag)
31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
3133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3148558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	if (ctx->options & E2F_OPT_JOURNAL_ONLY)
3158558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall		goto skip;
3168558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall
31719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	lastcheck = fs->super->s_lastcheck;
31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (lastcheck > ctx->now)
31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		lastcheck -= ctx->time_fudge;
32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((fs->super->s_state & EXT2_ERROR_FS) ||
32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !ext2fs_test_valid(fs))
32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		reason = _(" contains a file system with errors");
32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		reason = _(" was not cleanly unmounted");
32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else if (check_backup_super_block(ctx))
32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		reason = _(" primary superblock features different from backup");
32719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else if ((fs->super->s_max_mnt_count > 0) &&
32819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 (fs->super->s_mnt_count >=
32919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		  (unsigned) fs->super->s_max_mnt_count)) {
33019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		reason = _(" has been mounted %u times without being checked");
33119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		reason_arg = fs->super->s_mnt_count;
3323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (batt && (fs->super->s_mnt_count <
33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			     (unsigned) fs->super->s_max_mnt_count*2))
33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			reason = 0;
3358558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	} else if (!broken_system_clock && fs->super->s_checkinterval &&
3368558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall		   (ctx->now < lastcheck)) {
3373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		reason = _(" has filesystem last checked time in the future");
3383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (batt)
3393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			reason = 0;
3408558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	} else if (!broken_system_clock && fs->super->s_checkinterval &&
3413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		   ((ctx->now - lastcheck) >=
3423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		    ((time_t) fs->super->s_checkinterval))) {
34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		reason = _(" has gone %u days without being checked");
34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		reason_arg = (ctx->now - fs->super->s_lastcheck)/(3600*24);
3453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (batt && ((ctx->now - fs->super->s_lastcheck) <
34619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			     fs->super->s_checkinterval*2))
34719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			reason = 0;
34819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (reason) {
35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputs(ctx->device_name, stdout);
35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf(reason, reason_arg);
35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputs(_(", check forced.\n"), stdout);
35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf(_("%s: clean, %u/%u files, %u/%u blocks"), ctx->device_name,
35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       fs->super->s_inodes_count - fs->super->s_free_inodes_count,
35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       fs->super->s_inodes_count,
35819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       fs->super->s_blocks_count - fs->super->s_free_blocks_count,
35919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       fs->super->s_blocks_count);
36019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	next_check = 100000;
36119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (fs->super->s_max_mnt_count > 0) {
36219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
3633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (next_check <= 0)
36419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			next_check = 1;
36519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
3668558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	if (!broken_system_clock && fs->super->s_checkinterval &&
36719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    ((ctx->now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
36819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		next_check = 1;
36919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (next_check <= 5) {
37019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (next_check == 1) {
3713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (batt)
37219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fputs(_(" (check deferred; on battery)"),
37319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				      stdout);
37419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			else
37519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fputs(_(" (check after next mount)"), stdout);
37619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		} else
37719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_(" (check in %ld mounts)"), next_check);
37819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
37919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fputc('\n', stdout);
3808558eab78390d1924cd6b255686ceef133f294d5Ken Sumrallskip:
38119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2fs_close(fs);
38219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->fs = NULL;
38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_free_context(ctx);
38419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(FSCK_OK);
38519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
38619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
38719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * For completion notice
38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct percent_tbl {
39119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	max_pass;
39219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	table[32];
39319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
39419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstruct percent_tbl e2fsck_tbl = {
39519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	5, { 0, 70, 90, 92,  95, 100 }
39619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project};
39719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic char bar[128], spaces[128];
39819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
39919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic float calc_percent(struct percent_tbl *tbl, int pass, int curr,
40019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			  int max)
40119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
40219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	float	percent;
4033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
40419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (pass <= 0)
40519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0.0;
40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (pass > tbl->max_pass || max == 0)
40719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 100.0;
40819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	percent = ((float) curr) / ((float) max);
40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		+ tbl->table[pass-1]);
41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
41219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
41319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern void e2fsck_clear_progbar(e2fsck_t ctx)
41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(ctx->flags & E2F_FLAG_PROG_BAR))
41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
4173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
41819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
41919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       ctx->stop_meta);
42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fflush(stdout);
42119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->flags &= ~E2F_FLAG_PROG_BAR;
42219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
42319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			   unsigned int dpynum)
42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
42719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	static const char spinner[] = "\\|/-";
42819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	i;
42919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	unsigned int	tick;
43019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct timeval	tv;
43119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int dpywidth;
43219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int fixed_percent;
43319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
43419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
43519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
43619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
43719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
43819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Calculate the new progress position.  If the
43919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * percentage hasn't changed, then we skip out right
4403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	 * away.
44119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
44219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fixed_percent = (int) ((10 * percent) + 0.5);
44319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->progress_last_percent == fixed_percent)
44419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
44519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->progress_last_percent = fixed_percent;
44619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
44719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
44819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * If we've already updated the spinner once within
44919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * the last 1/8th of a second, no point doing it
45019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * again.
45119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
45219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	gettimeofday(&tv, NULL);
45319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
45419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((tick == ctx->progress_last_time) &&
45519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    (fixed_percent != 0) && (fixed_percent != 1000))
45619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
45719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->progress_last_time = tick;
45819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
45919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
46019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Advance the spinner, and note that the progress bar
46119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * will be on the screen
46219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
46319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->progress_pos = (ctx->progress_pos+1) & 3;
46419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->flags |= E2F_FLAG_PROG_BAR;
46519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
46619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	dpywidth = 66 - strlen(label);
46719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	dpywidth = 8 * (dpywidth / 8);
46819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (dpynum)
46919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		dpywidth -= 8;
47019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
47119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	i = ((percent * dpywidth) + 50) / 100;
47219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf("%s%s: |%s%s", ctx->start_meta, label,
47319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       bar + (sizeof(bar) - (i+1)),
47419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       spaces + (sizeof(spaces) - (dpywidth - i + 1)));
47519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (fixed_percent == 1000)
47619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputc('|', stdout);
47719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else
47819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputc(spinner[ctx->progress_pos & 3], stdout);
47919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf(" %4.1f%%  ", percent);
48019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (dpynum)
48119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf("%u\r", dpynum);
48219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else
48319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputs(" \r", stdout);
48419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fputs(ctx->stop_meta, stdout);
4853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
48619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (fixed_percent == 1000)
48719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		e2fsck_clear_progbar(ctx);
48819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fflush(stdout);
48919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
49019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
49119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
49219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
49319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int e2fsck_update_progress(e2fsck_t ctx, int pass,
49419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				  unsigned long cur, unsigned long max)
49519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
4963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char buf[1024];
49719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	float percent;
49819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
49919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (pass == 0)
50019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
5013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
50219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->progress_fd) {
5033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		snprintf(buf, sizeof(buf), "%d %lu %lu %s\n",
5043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			 pass, cur, max, ctx->device_name);
5053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		write_all(ctx->progress_fd, buf, strlen(buf));
50619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
50719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		percent = calc_percent(&e2fsck_tbl, pass, cur, max);
50819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		e2fsck_simple_progress(ctx, ctx->device_name,
50919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				       percent, 0);
51019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
51119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
51219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
51319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
51419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define PATH_SET "PATH=/sbin"
51519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
51619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void reserve_stdio_fds(void)
51719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
51819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	fd;
51919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
52019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (1) {
52119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fd = open("/dev/null", O_RDWR);
52219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fd > 2)
52319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
52419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fd < 0) {
52519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fprintf(stderr, _("ERROR: Couldn't open "
52619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				"/dev/null (%s)\n"),
52719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				strerror(errno));
52819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
52919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
53019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
53119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	close(fd);
53219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
53319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
53419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SIGNAL_H
53519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void signal_progress_on(int sig EXT2FS_ATTR((unused)))
53619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
53719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_t ctx = e2fsck_global_ctx;
53819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
53919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ctx)
54019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
54119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
54219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->progress = e2fsck_update_progress;
54319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
54419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
54519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void signal_progress_off(int sig EXT2FS_ATTR((unused)))
54619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
54719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_t ctx = e2fsck_global_ctx;
54819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
54919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ctx)
55019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
55119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
55219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_clear_progbar(ctx);
55319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->progress = 0;
55419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
55519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
55619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void signal_cancel(int sig EXT2FS_ATTR((unused)))
55719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
55819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_t ctx = e2fsck_global_ctx;
55919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
56019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ctx)
56119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(FSCK_CANCELED);
56219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
56319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->flags |= E2F_FLAG_CANCEL;
56419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
56519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
56619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
56719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void parse_extended_opts(e2fsck_t ctx, const char *opts)
56819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
56919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	*buf, *token, *next, *p, *arg;
57019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	ea_ver;
57119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	extended_usage = 0;
57219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
57319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	buf = string_copy(ctx, opts, 0);
57419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (token = buf; token && *token; token = next) {
57519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		p = strchr(token, ',');
57619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		next = 0;
57719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (p) {
57819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*p = 0;
57919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			next = p+1;
58019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
58119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		arg = strchr(token, '=');
58219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (arg) {
58319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			*arg = 0;
58419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			arg++;
58519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
58619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strcmp(token, "ea_ver") == 0) {
58719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!arg) {
58819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				extended_usage++;
58919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
59019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
59119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ea_ver = strtoul(arg, &p, 0);
59219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (*p ||
59319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			    ((ea_ver != 1) && (ea_ver != 2))) {
59419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fprintf(stderr,
59519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					_("Invalid EA version.\n"));
59619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				extended_usage++;
59719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				continue;
59819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
59919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->ext_attr_ver = ea_ver;
6003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		} else if (strcmp(token, "fragcheck") == 0) {
6013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			ctx->options |= E2F_OPT_FRAGCHECK;
6023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			continue;
6038558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall		} else if (strcmp(token, "journal_only") == 0) {
6048558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			if (arg) {
6058558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall				extended_usage++;
6068558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall				continue;
6078558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			}
6088558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			ctx->options |= E2F_OPT_JOURNAL_ONLY;
60919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		} else {
61019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fprintf(stderr, _("Unknown extended option: %s\n"),
61119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				token);
61219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			extended_usage++;
61319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
61419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
61519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	free(buf);
61619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
61719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (extended_usage) {
61819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fputs(("\nExtended options are separated by commas, "
61919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       "and may take an argument which\n"
62019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       "is set off by an equals ('=') sign.  "
6213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       "Valid extended options are:\n"), stderr);
6223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fputs(("\tea_ver=<ea_version (1 or 2)>\n"), stderr);
6233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fputs(("\tfragcheck\n"), stderr);
6248558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall		fputs(("\tjournal_only\n"), stderr);
6253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fputc('\n', stderr);
62619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(1);
62719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
62819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
62919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
63019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic void syntax_err_report(const char *filename, long err, int line_num)
63119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
6323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	fprintf(stderr,
63319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		_("Syntax error in e2fsck config file (%s, line #%d)\n\t%s\n"),
63419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		filename, line_num, error_message(err));
63519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(FSCK_ERROR);
63619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
63719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
63819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const char *config_fn[] = { ROOT_SYSCONFDIR "/e2fsck.conf", 0 };
63919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
64019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
64119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
64219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		flush = 0;
64319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		c, fd;
64419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef MTRACE
64519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	extern void	*mallwatch;
64619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
64719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_t	ctx;
64819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	errcode_t	retval;
64919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SIGNAL_H
65019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct sigaction	sa;
65119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
65219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char		*extended_opts = 0;
65319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char		*cp;
65419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int 		res;		/* result of sscanf */
65519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef CONFIG_JBD_DEBUG
65619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char 		*jbd_debug;
65719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
65819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
65919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = e2fsck_allocate_context(&ctx);
66019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval)
66119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return retval;
66219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
66319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	*ret_ctx = ctx;
66419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
66519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	setvbuf(stdout, NULL, _IONBF, BUFSIZ);
66619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	setvbuf(stderr, NULL, _IONBF, BUFSIZ);
66719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (isatty(0) && isatty(1)) {
66819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->interactive = 1;
66919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
67019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->start_meta[0] = '\001';
67119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->stop_meta[0] = '\002';
67219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
67319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	memset(bar, '=', sizeof(bar)-1);
67419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	memset(spaces, ' ', sizeof(spaces)-1);
67519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	add_error_table(&et_ext2_error_table);
67619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	add_error_table(&et_prof_error_table);
67719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blkid_get_cache(&ctx->blkid, NULL);
6783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
67919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (argc && *argv)
68019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->program_name = *argv;
68119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else
68219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->program_name = "e2fsck";
68319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
68419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		switch (c) {
68519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'C':
68619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->progress = e2fsck_update_progress;
68719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			res = sscanf(optarg, "%d", &ctx->progress_fd);
68819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (res != 1)
68919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto sscanf_err;
69019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (ctx->progress_fd < 0) {
6923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				ctx->progress = 0;
6933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				ctx->progress_fd = ctx->progress_fd * -1;
6943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			}
69519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (!ctx->progress_fd)
69619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				break;
69719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			/* Validate the file descriptor to avoid disasters */
69819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fd = dup(ctx->progress_fd);
69919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (fd < 0) {
70019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fprintf(stderr,
70119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				_("Error validating file descriptor %d: %s\n"),
70219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					ctx->progress_fd,
70319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					error_message(errno));
70419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fatal_error(ctx,
70519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("Invalid completion information file descriptor"));
70619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			} else
70719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				close(fd);
70819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
70919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'D':
71019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->options |= E2F_OPT_COMPRESS_DIRS;
71119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
71219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'E':
71319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			extended_opts = optarg;
71419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
71519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'p':
71619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'a':
71719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
71819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			conflict_opt:
7193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				fatal_error(ctx,
72019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	_("Only one of the options -p/-a, -n or -y may be specified."));
72119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
72219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->options |= E2F_OPT_PREEN;
72319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
72419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'n':
72519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
72619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto conflict_opt;
72719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->options |= E2F_OPT_NO;
72819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
72919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'y':
73019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
73119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto conflict_opt;
73219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->options |= E2F_OPT_YES;
73319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
73419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 't':
73519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef RESOURCE_TRACK
73619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ctx->options & E2F_OPT_TIME)
73719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ctx->options |= E2F_OPT_TIME2;
73819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			else
73919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ctx->options |= E2F_OPT_TIME;
74019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
74119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fprintf(stderr, _("The -t option is not "
74219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				"supported on this version of e2fsck.\n"));
74319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
74419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
74519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'c':
74619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (cflag++)
74719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ctx->options |= E2F_OPT_WRITECHECK;
74819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->options |= E2F_OPT_CHECKBLOCKS;
74919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
75019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'r':
75119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			/* What we do by default, anyway! */
75219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
75319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'b':
7543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			res = sscanf(optarg, "%u", &ctx->use_superblock);
75519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (res != 1)
75619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto sscanf_err;
75719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->flags |= E2F_FLAG_SB_SPECIFIED;
75819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
75919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'B':
76019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->blocksize = atoi(optarg);
76119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
76219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'I':
76319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			res = sscanf(optarg, "%d", &ctx->inode_buffer_blocks);
76419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (res != 1)
76519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto sscanf_err;
76619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
76719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'j':
7688558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			ctx->journal_name = blkid_get_devname(ctx->blkid,
7698558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall							      optarg, NULL);
7708558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			if (!ctx->journal_name) {
7718558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall				com_err(ctx->program_name, 0,
7728558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall					_("Unable to resolve '%s'"),
7738558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall					optarg);
7748558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall				fatal_error(ctx, 0);
7758558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			}
77619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
77719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'P':
77819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			res = sscanf(optarg, "%d", &ctx->process_inode_size);
77919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (res != 1)
78019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto sscanf_err;
78119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
78219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'L':
78319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			replace_bad_blocks++;
78419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'l':
78519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			bad_blocks_file = string_copy(ctx, optarg, 0);
78619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
78719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'd':
78819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->options |= E2F_OPT_DEBUG;
78919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
79019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'f':
79119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->options |= E2F_OPT_FORCE;
79219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
79319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'F':
79419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			flush = 1;
79519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
79619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'v':
79719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			verbose = 1;
79819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
79919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'V':
80019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			show_version_only = 1;
80119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
80219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef MTRACE
80319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'M':
80419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			mallwatch = (void *) strtol(optarg, NULL, 0);
80519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
80619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
80719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'N':
8083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			ctx->device_name = string_copy(ctx, optarg, 0);
80919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
81019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		case 'k':
81119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			keep_bad_blocks++;
81219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
81319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		default:
81419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			usage(ctx);
81519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
81619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (show_version_only)
81719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
81819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (optind != argc - 1)
81919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		usage(ctx);
8203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((ctx->options & E2F_OPT_NO) &&
8213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    (ctx->options & E2F_OPT_COMPRESS_DIRS)) {
8223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		com_err(ctx->program_name, 0,
8233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			_("The -n and -D options are incompatible."));
8243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fatal_error(ctx, 0);
8253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
8263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((ctx->options & E2F_OPT_NO) && cflag) {
8273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		com_err(ctx->program_name, 0,
8283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			_("The -n and -c options are incompatible."));
8293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fatal_error(ctx, 0);
8303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
8313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((ctx->options & E2F_OPT_NO) && bad_blocks_file) {
8323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		com_err(ctx->program_name, 0,
8333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			_("The -n and -l/-L options are incompatible."));
8343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fatal_error(ctx, 0);
8353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
8363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ctx->options & E2F_OPT_NO)
83719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->options |= E2F_OPT_READONLY;
8383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
83919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->io_options = strchr(argv[optind], '?');
8403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ctx->io_options)
84119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		*ctx->io_options++ = 0;
84219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
84319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ctx->filesystem_name) {
8443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
84519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			argv[optind]);
84619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
84719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
84819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (extended_opts)
84919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		parse_extended_opts(ctx, extended_opts);
85019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
85119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((cp = getenv("E2FSCK_CONFIG")) != NULL)
85219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		config_fn[0] = cp;
85319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	profile_set_syntax_err_cb(syntax_err_report);
85419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	profile_init(config_fn, &ctx->profile);
85519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
85619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (flush) {
85719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fd = open(ctx->filesystem_name, O_RDONLY, 0);
85819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fd < 0) {
85919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			com_err("open", errno,
86019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				_("while opening %s for flushing"),
86119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ctx->filesystem_name);
86219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fatal_error(ctx, 0);
86319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
86419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((retval = ext2fs_sync_device(fd, 1))) {
86519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			com_err("ext2fs_sync_device", retval,
86619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				_("while trying to flush %s"),
86719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ctx->filesystem_name);
86819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fatal_error(ctx, 0);
86919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
87019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		close(fd);
87119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
87219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (cflag && bad_blocks_file) {
87319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf(stderr, _("The -c and the -l/-L options may "
87419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				  "not be both used at the same time.\n"));
87519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(FSCK_USAGE);
87619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
87719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_SIGNAL_H
87819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
87919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Set up signal action
88019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
88119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	memset(&sa, 0, sizeof(struct sigaction));
88219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sa.sa_handler = signal_cancel;
88319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sigaction(SIGINT, &sa, 0);
88419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sigaction(SIGTERM, &sa, 0);
88519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef SA_RESTART
88619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sa.sa_flags = SA_RESTART;
88719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
88819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_global_ctx = ctx;
88919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sa.sa_handler = signal_progress_on;
89019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sigaction(SIGUSR1, &sa, 0);
89119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sa.sa_handler = signal_progress_off;
89219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sigaction(SIGUSR2, &sa, 0);
89319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
89419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
89519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/* Update our PATH to include /sbin if we need to run badblocks  */
89619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (cflag) {
89719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		char *oldpath = getenv("PATH");
89819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		char *newpath;
89919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		int len = sizeof(PATH_SET) + 1;
90019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
90119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (oldpath)
90219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			len += strlen(oldpath);
90319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
90419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		newpath = malloc(len);
90519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!newpath)
90619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fatal_error(ctx, "Couldn't malloc() newpath");
90719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		strcpy(newpath, PATH_SET);
90819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
90919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (oldpath) {
91019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			strcat(newpath, ":");
91119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			strcat(newpath, oldpath);
91219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
91319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		putenv(newpath);
91419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
91519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef CONFIG_JBD_DEBUG
91619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	jbd_debug = getenv("E2FSCK_JBD_DEBUG");
91719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (jbd_debug) {
91819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		res = sscanf(jbd_debug, "%d", &journal_enable_debug);
91919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (res != 1) {
92019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fprintf(stderr,
92119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			        _("E2FSCK_JBD_DEBUG \"%s\" not an integer\n\n"),
92219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			        jbd_debug);
92319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			exit (1);
92419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
92519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
92619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
92719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
92819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
92919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectsscanf_err:
93019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fprintf(stderr, _("\nInvalid non-numeric argument to -%c (\"%s\")\n\n"),
93119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	        c, optarg);
93219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit (1);
93319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
93419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtstatic errcode_t try_open_fs(e2fsck_t ctx, int flags, io_manager io_ptr,
9363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			     ext2_filsys *ret_fs)
9373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
9383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	errcode_t retval;
9393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
9403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	*ret_fs = NULL;
9413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (ctx->superblock && ctx->blocksize) {
9423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
9433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				      flags, ctx->superblock, ctx->blocksize,
9443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				      io_ptr, ret_fs);
9453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	} else if (ctx->superblock) {
9463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		int blocksize;
9473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		for (blocksize = EXT2_MIN_BLOCK_SIZE;
9483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		     blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
9493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (*ret_fs) {
9503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				ext2fs_free(*ret_fs);
9513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				*ret_fs = NULL;
9523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			}
9533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			retval = ext2fs_open2(ctx->filesystem_name,
9543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					      ctx->io_options, flags,
9553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					      ctx->superblock, blocksize,
9563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					      io_ptr, ret_fs);
9573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (!retval)
9583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				break;
9593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
9603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	} else
9613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
9623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				      flags, 0, 0, io_ptr, ret_fs);
9633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return retval;
9643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
9653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
9663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
96719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const char *my_ver_string = E2FSPROGS_VERSION;
96819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic const char *my_ver_date = E2FSPROGS_DATE;
9693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
97019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint main (int argc, char *argv[])
97119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
9723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	errcode_t	retval = 0, retval2 = 0, orig_retval = 0;
97319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		exit_value = FSCK_OK;
97419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2_filsys	fs = 0;
97519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	io_manager	io_ptr;
97619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ext2_super_block *sb;
97719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char	*lib_ver_date;
97819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		my_ver, lib_ver;
97919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_t	ctx;
9803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	blk_t		orig_superblock;
98119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct problem_context pctx;
98219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int flags, run_result;
98319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int journal_size;
98419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int sysval, sys_page_size = 4096;
98519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	__u32 features[3];
9863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char *cp;
9873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
98819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	clear_problem_context(&pctx);
98919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef MTRACE
99019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	mtrace();
99119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
99219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef MCHECK
99319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	mcheck(0);
99419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
99519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_NLS
99619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	setlocale(LC_MESSAGES, "");
99719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	setlocale(LC_CTYPE, "");
99819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
99919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	textdomain(NLS_CAT_NAME);
100019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
100119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	my_ver = ext2fs_parse_version_string(my_ver_string);
100219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
100319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (my_ver > lib_ver) {
100419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf( stderr, _("Error: ext2fs library version "
100519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			"out of date!\n"));
100619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		show_version_only++;
100719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
10083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
100919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = PRS(argc, argv, &ctx);
101019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
101119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err("e2fsck", retval,
101219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("while trying to initialize program"));
101319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(FSCK_ERROR);
101419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
101519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	reserve_stdio_fds();
101619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	init_resource_track(&ctx->global_rtrack, NULL);
101819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
101919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
102019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 my_ver_date);
102119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
102219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (show_version_only) {
102319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf(stderr, _("\tUsing %s, %s\n"),
102419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			error_message(EXT2_ET_BASE), lib_ver_date);
102519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit(FSCK_OK);
102619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
10273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
102819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	check_mount(ctx);
10293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
103019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(ctx->options & E2F_OPT_PREEN) &&
103119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !(ctx->options & E2F_OPT_NO) &&
103219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !(ctx->options & E2F_OPT_YES)) {
103319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!ctx->interactive)
103419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fatal_error(ctx,
103519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				    _("need terminal for interactive repairs"));
103619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
103719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->superblock = ctx->use_superblock;
103819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectrestart:
103919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef CONFIG_TESTIO_DEBUG
10403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) {
10413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		io_ptr = test_io_manager;
10423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		test_io_backing_manager = unix_io_manager;
10433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	} else
104419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
10453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		io_ptr = unix_io_manager;
104619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	flags = EXT2_FLAG_NOFREE_ON_ERROR;
104719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((ctx->options & E2F_OPT_READONLY) == 0)
104819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		flags |= EXT2_FLAG_RW;
104919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if ((ctx->mount_flags & EXT2_MF_MOUNTED) == 0)
105019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		flags |= EXT2_FLAG_EXCLUSIVE;
105119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	retval = try_open_fs(ctx, flags, io_ptr, &fs);
10533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
105419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
105519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
105619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    ((retval == EXT2_ET_BAD_MAGIC) ||
105719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     (retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
10583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	     ((retval == 0) && (retval2 = ext2fs_check_desc(fs))))) {
10593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (retval2 == ENOMEM) {
10603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			retval = retval2;
10613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			goto failure;
10623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
106319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fs->flags & EXT2_FLAG_NOFREE_ON_ERROR) {
106419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ext2fs_free(fs);
106519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fs = NULL;
106619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
106719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!fs || (fs->group_desc_count > 1)) {
106819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("%s: %s trying backup blocks...\n"),
10693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			       ctx->program_name,
107019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       retval ? _("Superblock invalid,") :
107119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       _("Group descriptors look bad..."));
10723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			orig_superblock = ctx->superblock;
107319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
107419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (fs)
107519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ext2fs_close(fs);
107619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			orig_retval = retval;
10773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			retval = try_open_fs(ctx, flags, io_ptr, &fs);
10783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if ((orig_retval == 0) && retval != 0) {
10798558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall				if (fs)
10808558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall					ext2fs_close(fs);
10813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				com_err(ctx->program_name, retval,
10823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					"when using the backup blocks");
10833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				printf(_("%s: going back to original "
10843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					 "superblock\n"), ctx->program_name);
10853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				ctx->superblock = orig_superblock;
10863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				retval = try_open_fs(ctx, flags, io_ptr, &fs);
10873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			}
108819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
108919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
109019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (((retval == EXT2_ET_UNSUPP_FEATURE) ||
109119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     (retval == EXT2_ET_RO_UNSUPP_FEATURE)) &&
109219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    fs && fs->super) {
109319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		sb = fs->super;
10943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		features[0] = (sb->s_feature_compat &
109519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       ~EXT2_LIB_FEATURE_COMPAT_SUPP);
10963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		features[1] = (sb->s_feature_incompat &
109719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       ~EXT2_LIB_FEATURE_INCOMPAT_SUPP);
10983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		features[2] = (sb->s_feature_ro_compat &
109919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP);
110019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (features[0] || features[1] || features[2])
110119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			goto print_unsupp_features;
110219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
11033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtfailure:
110419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
110519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (orig_retval)
110619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			retval = orig_retval;
110719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err(ctx->program_name, retval, _("while trying to open %s"),
110819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->filesystem_name);
110919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (retval == EXT2_ET_REV_TOO_HIGH) {
111019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("The filesystem revision is apparently "
111119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       "too high for this version of e2fsck.\n"
111219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       "(Or the filesystem superblock "
111319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       "is corrupt)\n\n"));
111419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
111519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		} else if (retval == EXT2_ET_SHORT_READ)
111619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("Could this be a zero-length partition?\n"));
111719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else if ((retval == EPERM) || (retval == EACCES))
111819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("You must have %s access to the "
111919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       "filesystem or be root\n"),
112019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       (ctx->options & E2F_OPT_READONLY) ?
112119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       "r/o" : "r/w");
112219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else if (retval == ENXIO)
112319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("Possibly non-existent or swap device?\n"));
112419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else if (retval == EBUSY)
112519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("Filesystem mounted or opened exclusively "
112619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 "by another program?\n"));
11278558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall		else if (retval == ENOENT)
11288558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			printf(_("Possibly non-existent device?\n"));
112919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef EROFS
113019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else if (retval == EROFS)
113119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("Disk write-protected; use the -n option "
113219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       "to do a read-only\n"
113319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       "check of the device.\n"));
113419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
113519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else
113619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
113719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
113819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
113919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
114019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * We only update the master superblock because (a) paranoia;
114119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * we don't want to corrupt the backup superblocks, and (b) we
114219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * don't need to update the mount count and last checked
114319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * fields in the backup superblock (the kernel doesn't update
114419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * the backup superblocks anyway).  With newer versions of the
114519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * library this flag is set by ext2fs_open2(), but we set this
114619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * here just to be sure.  (No, we don't support e2fsck running
114719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * with some other libext2fs than the one that it was shipped
114819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * with, but just in case....)
114919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
115019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
115119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
115219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(ctx->flags & E2F_FLAG_GOT_DEVSIZE)) {
115319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		__u32 blocksize = EXT2_BLOCK_SIZE(fs->super);
115419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		int need_restart = 0;
115519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		pctx.errcode = ext2fs_get_device_size2(ctx->filesystem_name,
11573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt						       blocksize,
11583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt						       &ctx->num_blocks);
115919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		/*
116019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * The floppy driver refuses to allow anyone else to
116119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * open the device if has been opened with O_EXCL;
116219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * this is unlike other block device drivers in Linux.
116319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * To handle this, we close the filesystem and then
116419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 * reopen the filesystem after we get the device size.
116519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		 */
116619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (pctx.errcode == EBUSY) {
116719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ext2fs_close(fs);
116819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			need_restart++;
11693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			pctx.errcode =
11703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				ext2fs_get_device_size2(ctx->filesystem_name,
11713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt							blocksize,
11723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt							&ctx->num_blocks);
117319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
117419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (pctx.errcode == EXT2_ET_UNIMPLEMENTED)
117519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->num_blocks = 0;
117619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else if (pctx.errcode) {
117719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
117819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->flags |= E2F_FLAG_ABORT;
117919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fatal_error(ctx, 0);
118019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
118119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->flags |= E2F_FLAG_GOT_DEVSIZE;
118219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (need_restart)
118319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			goto restart;
118419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
118519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
118619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->fs = fs;
118719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fs->priv_data = ctx;
118819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fs->now = ctx->now;
118919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sb = fs->super;
119019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
119119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
119219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("while trying to open %s"),
119319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->filesystem_name);
119419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	get_newer:
119519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, _("Get a newer version of e2fsck!"));
119619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
119719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
119819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
119919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Set the device name, which is used whenever we print error
120019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * or informational messages to the user.
120119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
120219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->device_name == 0 &&
120319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    (sb->s_volume_name[0] != 0)) {
120419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->device_name = string_copy(ctx, sb->s_volume_name,
120519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					       sizeof(sb->s_volume_name));
120619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
120719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->device_name == 0)
12083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		ctx->device_name = string_copy(ctx, ctx->filesystem_name, 0);
12093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (cp = ctx->device_name; *cp; cp++)
12103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (isspace(*cp) || *cp == ':')
12113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			*cp = '_';
12123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	ehandler_init(fs->io);
12143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
12153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((ctx->mount_flags & EXT2_MF_MOUNTED) &&
12163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER))
12173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		goto skip_journal;
121819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
121919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
122019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Make sure the ext3 superblock fields are consistent.
122119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
122219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = e2fsck_check_ext3_journal(ctx);
122319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
122419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err(ctx->program_name, retval,
122519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("while checking ext3 journal for %s"),
122619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->device_name);
122719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
122819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
122919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
123019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
123119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Check to see if we need to do ext3-style recovery.  If so,
123219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * do it, and then restart the fsck.
123319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
123419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
123519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (ctx->options & E2F_OPT_READONLY) {
123619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("Warning: skipping journal recovery "
123719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 "because doing a read-only filesystem "
123819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 "check.\n"));
123919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			io_channel_flush(ctx->fs->io);
124019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		} else {
124119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ctx->flags & E2F_FLAG_RESTARTED) {
124219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				/*
124319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 * Whoops, we attempted to run the
124419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 * journal twice.  This should never
124519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 * happen, unless the hardware or
124619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 * device driver is being bogus.
124719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				 */
124819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				com_err(ctx->program_name, 0,
124919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					_("unable to set superblock flags on %s\n"), ctx->device_name);
125019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fatal_error(ctx, 0);
125119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
125219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			retval = e2fsck_run_ext3_journal(ctx);
125319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (retval) {
125419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				com_err(ctx->program_name, retval,
125519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				_("while recovering ext3 journal of %s"),
125619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					ctx->device_name);
125719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fatal_error(ctx, 0);
125819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
125919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ext2fs_close(ctx->fs);
126019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->fs = 0;
126119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->flags |= E2F_FLAG_RESTARTED;
126219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			goto restart;
126319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
126419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
126519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtskip_journal:
126719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
126819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Check for compatibility with the feature sets.  We need to
126919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * be more stringent than ext2fs_open().
127019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
127119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	features[0] = sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP;
127219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	features[1] = sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP;
12733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	features[2] = (sb->s_feature_ro_compat &
127419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP);
127519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectprint_unsupp_features:
127619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (features[0] || features[1] || features[2]) {
127719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		int	i, j;
127819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		__u32	*mask = features, m;
127919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
12803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fprintf(stderr, _("%s has unsupported feature(s):"),
128119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->filesystem_name);
128219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
128319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		for (i=0; i <3; i++,mask++) {
128419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			for (j=0,m=1; j < 32; j++, m<<=1) {
128519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (*mask & m)
12863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt					fprintf(stderr, " %s",
128719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project						e2p_feature2string(i, m));
128819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
128919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
129019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		putc('\n', stderr);
129119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto get_newer;
129219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
129319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef ENABLE_COMPRESSION
129419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
129519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err(ctx->program_name, 0,
129619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("Warning: compression support is experimental.\n"));
129719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
129819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef ENABLE_HTREE
129919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
130019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err(ctx->program_name, 0,
130119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("E2fsck not compiled with HTREE support,\n\t"
130219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			  "but filesystem %s has HTREE directories.\n"),
130319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->device_name);
130419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto get_newer;
130519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
130619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
130719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
130819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
130919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * If the user specified a specific superblock, presumably the
131019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * master superblock has been trashed.  So we mark the
131119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * superblock as dirty, so it can be written out.
131219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
131319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->superblock &&
131419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	    !(ctx->options & E2F_OPT_READONLY))
131519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ext2fs_mark_super_dirty(fs);
131619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
131719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
131819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Calculate the number of filesystem blocks per pagesize.  If
131919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * fs->blocksize > page_size, set the number of blocks per
132019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * pagesize to 1 to avoid division by zero errors.
132119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
132219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef _SC_PAGESIZE
132319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sysval = sysconf(_SC_PAGESIZE);
132419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sysval > 0)
132519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		sys_page_size = sysval;
132619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* _SC_PAGESIZE */
132719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->blocks_per_page = sys_page_size / fs->blocksize;
132819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->blocks_per_page == 0)
132919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->blocks_per_page = 1;
133019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
133119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->superblock)
133219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
133319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2fs_mark_valid(fs);
133419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	check_super_block(ctx);
133519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
133619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
133719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	check_if_skip(ctx);
13383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	check_resize_inode(ctx);
133919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (bad_blocks_file)
134019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
134119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else if (cflag)
134219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
134319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
134419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
134519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
134619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
134719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Mark the system as valid, 'til proven otherwise
134819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
134919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2fs_mark_valid(fs);
135019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
135119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
135219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
135319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err(ctx->program_name, retval,
135419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("while reading bad blocks inode"));
135519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		preenhalt(ctx);
135619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf(_("This doesn't bode well,"
135719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 " but we'll try to go on...\n"));
135819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
135919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
136019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	/*
136119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Save the journal size in megabytes.
136219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * Try and use the journal size from the backup else let e2fsck
136319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 * find the default journal size.
136419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	 */
136519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS)
136619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		journal_size = sb->s_jnl_blocks[16] >> 20;
136719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else
136819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		journal_size = -1;
136919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
137019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	run_result = e2fsck_run(ctx);
137119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_clear_progbar(ctx);
137219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
137319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->flags & E2F_FLAG_JOURNAL_INODE) {
137419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fix_problem(ctx, PR_6_RECREATE_JOURNAL, &pctx)) {
137519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (journal_size < 1024)
137619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				journal_size = ext2fs_default_journal_size(fs->super->s_blocks_count);
137719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (journal_size < 0) {
137819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fs->super->s_feature_compat &=
137919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
138019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
13813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				com_err(ctx->program_name, 0,
138219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					_("Couldn't determine journal size"));
138319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto no_journal;
138419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
138519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("Creating journal (%d blocks): "),
138619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       journal_size);
138719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fflush(stdout);
138819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			retval = ext2fs_add_journal_inode(fs,
138919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project							  journal_size, 0);
139019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (retval) {
139119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				com_err("Error ", retval,
139219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					_("\n\twhile trying to create journal"));
139319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				goto no_journal;
139419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
139519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_(" Done.\n"));
139619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("\n*** journal has been re-created - "
139719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				       "filesystem is now ext3 again ***\n"));
139819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
139919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
140019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectno_journal:
140119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
140219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (run_result == E2F_FLAG_RESTART) {
140319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf(_("Restarting e2fsck from the beginning...\n"));
140419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		retval = e2fsck_reset_context(ctx);
140519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (retval) {
140619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			com_err(ctx->program_name, retval,
140719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				_("while resetting context"));
140819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fatal_error(ctx, 0);
140919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
141019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ext2fs_close(fs);
141119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto restart;
141219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
141319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (run_result & E2F_FLAG_CANCEL) {
141419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
141519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		       ctx->device_name : ctx->filesystem_name);
141619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit_value |= FSCK_CANCELED;
141719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
141819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (run_result & E2F_FLAG_ABORT)
141919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, _("aborted"));
142019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (check_backup_super_block(ctx)) {
142119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
142219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ext2fs_mark_super_dirty(fs);
142319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
142419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
142519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef MTRACE
142619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	mtrace_print("Cleanup");
142719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
142819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ext2fs_test_changed(fs)) {
142919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit_value |= FSCK_NONDESTRUCT;
143019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!(ctx->options & E2F_OPT_PREEN))
143119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
143219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       ctx->device_name);
143319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (ctx->mount_flags & EXT2_MF_ISROOT) {
143419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			printf(_("%s: ***** REBOOT LINUX *****\n"),
143519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       ctx->device_name);
143619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			exit_value |= FSCK_REBOOT;
143719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
143819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
143919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ext2fs_test_valid(fs) ||
14403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    ((exit_value & FSCK_CANCELED) &&
144119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     (sb->s_state & EXT2_ERROR_FS))) {
144219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf(_("\n%s: ********** WARNING: Filesystem still has "
144319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			 "errors **********\n\n"), ctx->device_name);
144419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit_value |= FSCK_UNCORRECTED;
144519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit_value &= ~FSCK_NONDESTRUCT;
144619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
144719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (exit_value & FSCK_CANCELED) {
144819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		int	allow_cancellation;
144919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
145019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		profile_get_boolean(ctx->profile, "options",
14513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				    "allow_cancellation", 0, 0,
145219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				    &allow_cancellation);
145319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		exit_value &= ~FSCK_NONDESTRUCT;
145419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (allow_cancellation && ext2fs_test_valid(fs) &&
14553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		    (sb->s_state & EXT2_VALID_FS) &&
145619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    !(sb->s_state & EXT2_ERROR_FS))
145719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			exit_value = 0;
145819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	} else {
145919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		show_stats(ctx);
146019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (!(ctx->options & E2F_OPT_READONLY)) {
146119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ext2fs_test_valid(fs)) {
146219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				if (!(sb->s_state & EXT2_VALID_FS))
146319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					exit_value |= FSCK_NONDESTRUCT;
146419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				sb->s_state = EXT2_VALID_FS;
146519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			} else
146619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				sb->s_state &= ~EXT2_VALID_FS;
146719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			sb->s_mnt_count = 0;
14688558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			if (!(ctx->flags & E2F_FLAG_TIME_INSANE))
14698558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall				sb->s_lastcheck = ctx->now;
14708558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			memset(((char *) sb) + EXT4_S_ERR_START, 0,
14718558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall			       EXT4_S_ERR_LEN);
147219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ext2fs_mark_super_dirty(fs);
147319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
147419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
147519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14768558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	if ((run_result & E2F_FLAG_CANCEL) == 0 &&
14778558eab78390d1924cd6b255686ceef133f294d5Ken Sumrall	    sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM &&
14783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    !(ctx->options & E2F_OPT_READONLY)) {
14793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		retval = ext2fs_set_gdt_csum(ctx->fs);
14803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (retval) {
14813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			com_err(ctx->program_name, retval,
14823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				_("while setting block group checksum info"));
14833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			fatal_error(ctx, 0);
14843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
14853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
14863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
148719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_write_bitmaps(ctx);
14883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	io_channel_flush(ctx->fs->io);
14893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	print_resource_track(ctx, NULL, &ctx->global_rtrack, ctx->fs->io);
14903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
149119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2fs_close(fs);
149219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->fs = NULL;
149319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	free(ctx->journal_name);
149419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
149519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	e2fsck_free_context(ctx);
149619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	remove_error_table(&et_ext2_error_table);
149719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	remove_error_table(&et_prof_error_table);
149819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return exit_value;
149919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
1500