unix.c revision c0a849660d1aea86b9f3ff986aae7b705a059e3e
1eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch/* 2eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * unix.c - The unix-specific code for e2fsck 3eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * 4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. 5eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * 6f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * %Begin-Header% 7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) * This file may be redistributed under the terms of the GNU Public 8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * License. 9f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) * %End-Header% 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 12424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#define _XOPEN_SOURCE 600 /* for inclusion of sa_handler in Solaris */ 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "config.h" 155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <stdio.h> 165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef HAVE_STDLIB_H 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <stdlib.h> 18424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#endif 19424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <string.h> 20424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <fcntl.h> 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <ctype.h> 225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <time.h> 235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef HAVE_SIGNAL_H 245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include <signal.h> 254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef HAVE_GETOPT_H 274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <getopt.h> 284e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#else 294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)extern char *optarg; 304e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)extern int optind; 314e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <unistd.h> 334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef HAVE_ERRNO_H 344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <errno.h> 354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef HAVE_SYS_IOCTL_H 374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/ioctl.h> 384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef HAVE_MALLOC_H 404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <malloc.h> 414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef HAVE_SYS_TYPES_H 434e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <sys/types.h> 444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#ifdef HAVE_DIRENT_H 464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include <dirent.h> 474e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 484e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "e2p/e2p.h" 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "et/com_err.h" 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "e2p/e2p.h" 52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "e2fsck.h" 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "problem.h" 54558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch#include "../version.h" 55558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch 56558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch/* Command line options */ 57558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdochstatic int cflag; /* check disk */ 58f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int show_version_only; 59f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static int verbose; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic int replace_bad_blocks; 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic int keep_bad_blocks; 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static char *bad_blocks_file; 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 65f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */ 66f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifdef CONFIG_JBD_DEBUG /* Enabled by configure --enable-jfs-debug */ 68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)int journal_enable_debug = -1; 69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic void usage(e2fsck_t ctx) 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fprintf(stderr, 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci _("Usage: %s [-panyrcdfvtDFV] [-b superblock] [-B blocksize]\n" 75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n" 76424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "\t\t[-l|-L bad_blocks_file] [-C fd] [-j external_journal]\n" 77424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "\t\t[-E extended-options] device\n"), 78424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ctx->program_name); 79424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(stderr, _("\nEmergency help:\n" 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) " -p Automatic repair (no questions)\n" 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) " -n Make no changes to the filesystem\n" 83424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) " -y Assume \"yes\" to all questions\n" 84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) " -c Check for bad blocks and add them to the badblock list\n" 85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) " -f Force checking even if filesystem is marked clean\n")); 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) fprintf(stderr, _("" 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " -v Be verbose\n" 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " -b superblock Use alternative superblock\n" 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " -B blocksize Force blocksize when looking for superblock\n" 90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch " -j external_journal Set location of the external journal\n" 91558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch " -l bad_blocks_file Add to badblocks list\n" 92558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch " -L bad_blocks_file Set badblocks list\n" 93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch )); 94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 95ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch exit(FSCK_USAGE); 96eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 97eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 98ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdochstatic void show_stats(e2fsck_t ctx) 99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 100ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ext2_filsys fs = ctx->fs; 101ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ext2_ino_t inodes, inodes_used; 102eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blk64_t blocks, blocks_used; 103eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int dir_links; 104eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int num_files, num_links; 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) __u32 *mask, m; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int frag_percent_file, frag_percent_dir, frag_percent_total; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int i, j, printed = 0; 108ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 109ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch dir_links = 2 * ctx->fs_directory_count - 1; 110ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch num_files = ctx->fs_total_count - dir_links; 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci num_links = ctx->fs_links_count - dir_links; 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) inodes = fs->super->s_inodes_count; 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) inodes_used = (fs->super->s_inodes_count - 114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fs->super->s_free_inodes_count); 115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blocks = ext2fs_blocks_count(fs->super); 116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blocks_used = (ext2fs_blocks_count(fs->super) - 117f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ext2fs_free_blocks_count(fs->super)); 118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) frag_percent_file = (10000 * ctx->fs_fragmented) / inodes_used; 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frag_percent_file = (frag_percent_file + 5) / 10; 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frag_percent_dir = (10000 * ctx->fs_fragmented_dir) / inodes_used; 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frag_percent_dir = (frag_percent_dir + 5) / 10; 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frag_percent_total = ((10000 * (ctx->fs_fragmented + 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->fs_fragmented_dir)) 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) / inodes_used); 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frag_percent_total = (frag_percent_total + 5) / 10; 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!verbose) { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, _("%s: %u/%u files (%0d.%d%% non-contiguous), " 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "%llu/%llu blocks\n"), 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->device_name, inodes_used, inodes, 1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) frag_percent_total / 10, frag_percent_total % 10, 1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) blocks_used, blocks); 1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_get_boolean(ctx->profile, "options", "report_features", 0, 0, 139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &i); 1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (verbose && i) { 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, "\nFilesystem features:"); 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mask = &ctx->fs->super->s_feature_compat; 1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (i = 0; i < 3; i++, mask++) { 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (j = 0, m = 1; j < 32; j++, m <<= 1) { 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (*mask & m) { 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, " %s", 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e2p_feature2string(i, m)); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) printed++; 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (printed == 0) 153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, " (none)"); 154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, "\n"); 155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("\n%8u inode used (%2.2f%%)\n", 158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "\n%8u inodes used (%2.2f%%)\n", 159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch inodes_used), inodes_used, 160424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 100.0 * inodes_used / inodes); 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch log_out(ctx, P_("%8u non-contiguous file (%0d.%d%%)\n", 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "%8u non-contiguous files (%0d.%d%%)\n", 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ctx->fs_fragmented), 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ctx->fs_fragmented, frag_percent_file / 10, 165424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) frag_percent_file % 10); 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) log_out(ctx, P_("%8u non-contiguous directory (%0d.%d%%)\n", 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "%8u non-contiguous directories (%0d.%d%%)\n", 168424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ctx->fs_fragmented_dir), 169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_fragmented_dir, frag_percent_dir / 10, 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch frag_percent_dir % 10); 171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _(" # of inodes with ind/dind/tind blocks: " 172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "%u/%u/%u\n"), 173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count); 174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 175424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (j=MAX_EXTENT_DEPTH_COUNT-1; j >=0; j--) 176424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (ctx->extent_depth_count[j]) 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 178424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (++j) { 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) log_out(ctx, _(" Extent depth histogram: ")); 180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (i=0; i < j; i++) { 181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (i) 182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fputc('/', stdout); 183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, "%u", ctx->extent_depth_count[i]); 184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, "\n"); 186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci log_out(ctx, P_("%8llu block used (%2.2f%%)\n", 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) "%8llu blocks used (%2.2f%%)\n", 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) blocks_used), blocks_used, 100.0 * blocks_used / blocks); 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) log_out(ctx, P_("%8u bad block\n", "%8u bad blocks\n", 192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_badblocks_count), ctx->fs_badblocks_count); 193eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("%8u large file\n", "%8u large files\n", 194eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->large_files), ctx->large_files); 195eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("\n%8u regular file\n", "\n%8u regular files\n", 196eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_regular_count), ctx->fs_regular_count); 197eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("%8u directory\n", "%8u directories\n", 198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_directory_count), ctx->fs_directory_count); 199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("%8u character device file\n", 200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "%8u character device files\n", ctx->fs_chardev_count), 201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_chardev_count); 202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("%8u block device file\n", "%8u block device files\n", 203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_blockdev_count), ctx->fs_blockdev_count); 204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("%8u fifo\n", "%8u fifos\n", ctx->fs_fifo_count), 205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_fifo_count); 206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("%8u link\n", "%8u links\n", 207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_links_count - dir_links), 2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ctx->fs_links_count - dir_links); 209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, P_("%8u symbolic link", "%8u symbolic links", 210ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch ctx->fs_symlinks_count), ctx->fs_symlinks_count); 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, P_(" (%u fast symbolic link)\n", 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) " (%u fast symbolic links)\n", 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->fs_fast_symlinks_count), 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->fs_fast_symlinks_count); 215effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch log_out(ctx, P_("%8u socket\n", "%8u sockets\n", ctx->fs_sockets_count), 216effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ctx->fs_sockets_count); 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, "--------\n"); 218ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch log_out(ctx, P_("%8u file\n", "%8u files\n", 219eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_total_count - dir_links), 220eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs_total_count - dir_links); 221eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 222424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 223424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static void check_mount(e2fsck_t ctx) 224424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles){ 2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci errcode_t retval; 2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int cont; 227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 228eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_check_if_mounted(ctx->filesystem_name, 2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &ctx->mount_flags); 2305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (retval) { 2315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) com_err("ext2fs_check_if_mount", retval, 2325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _("while determining whether %s is mounted."), 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->filesystem_name); 2345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return; 2355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* 2385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * If the filesystem isn't mounted, or it's the root 2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * filesystem and it's mounted read-only, and we're not doing 2405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * a read/write check, then everything's fine. 241f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) */ 242f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if ((!(ctx->mount_flags & (EXT2_MF_MOUNTED | EXT2_MF_BUSY))) || 243f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ((ctx->mount_flags & EXT2_MF_ISROOT) && 244f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (ctx->mount_flags & EXT2_MF_READONLY) && 245f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !(ctx->options & E2F_OPT_WRITECHECK))) 246f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 247f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 248f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (((ctx->options & E2F_OPT_READONLY) || 249f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ((ctx->options & E2F_OPT_FORCE) && 250f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) (ctx->mount_flags & EXT2_MF_READONLY))) && 251f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) !(ctx->options & E2F_OPT_WRITECHECK)) { 252f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) log_out(ctx, _("Warning! %s is %s.\n"), 253f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ctx->filesystem_name, 254f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ctx->mount_flags & EXT2_MF_MOUNTED ? 255f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) "mounted" : "in use"); 256f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return; 257f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 258f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 259f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) log_out(ctx, _("%s is %s.\n"), ctx->filesystem_name, 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ctx->mount_flags & EXT2_MF_MOUNTED ? "mounted" : "in use"); 261f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!ctx->interactive || ctx->mount_flags & EXT2_MF_BUSY) 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fatal_error(ctx, _("Cannot continue, aborting.\n\n")); 263116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch puts("\007\007\007\007"); 264116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch log_out(ctx, _("\n\nWARNING!!! " 265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "The filesystem is mounted. " 266116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "If you continue you ***WILL***\n" 267116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch "cause ***SEVERE*** filesystem damage.\n\n")); 268116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch puts("\007\007\007"); 269116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch cont = ask_yn(ctx, _("Do you really want to continue"), 0); 270116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (!cont) { 271f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) printf (_("check aborted.\n")); 272f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) exit (0); 273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return; 275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic int is_on_batt(void) 2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci{ 2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci FILE *f; 280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DIR *d; 281f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) char tmp[80], tmp2[80], fname[80]; 282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int acflag; 283f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) struct dirent* de; 284f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 285f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) f = fopen("/sys/class/power_supply/AC/online", "r"); 286f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (f) { 287f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (fscanf(f, "%u\n", &acflag) == 1) { 288f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) fclose(f); 289f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return (!acflag); 290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fclose(f); 292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch f = fopen("/proc/apm", "r"); 294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (f) { 295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4) 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch acflag = 1; 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fclose(f); 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return (acflag != 1); 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) d = opendir("/proc/acpi/ac_adapter"); 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (d) { 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) while ((de=readdir(d)) != NULL) { 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!strncmp(".", de->d_name, 1)) 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state", 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) de->d_name); 3075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) f = fopen(fname, "r"); 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!f) 3095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 3105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fscanf(f, "%s %s", tmp2, tmp) != 2) 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) tmp[0] = 0; 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fclose(f); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (strncmp(tmp, "off-line", 8) == 0) { 314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch closedir(d); 315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 1; 316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 3185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) closedir(d); 319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/* 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * This routine checks to see if a filesystem can be skipped; if so, 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * it will exit with E2FSCK_OK. Under some conditions it will print a 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * message explaining why a check is being forced. 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static void check_if_skip(e2fsck_t ctx) 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles){ 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2_filsys fs = ctx->fs; 3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci struct problem_context pctx; 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char *reason = NULL; 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int reason_arg = 0; 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch long next_check; 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int batt = is_on_batt(); 336424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int defer_check_on_battery; 337424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int broken_system_clock; 338424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) time_t lastcheck; 339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profile_get_boolean(ctx->profile, "options", "broken_system_clock", 341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 0, 0, &broken_system_clock); 342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ctx->flags & E2F_FLAG_TIME_INSANE) 343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch broken_system_clock = 1; 344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profile_get_boolean(ctx->profile, "options", 3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "defer_check_on_battery", 0, 1, 346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &defer_check_on_battery); 347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!defer_check_on_battery) 348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch batt = 0; 349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 350424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file || cflag) 351424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 352424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ctx->options & E2F_OPT_JOURNAL_ONLY) 354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto skip; 355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch lastcheck = fs->super->s_lastcheck; 357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (lastcheck > ctx->now) 358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch lastcheck -= ctx->time_fudge; 359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((fs->super->s_state & EXT2_ERROR_FS) || 3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci !ext2fs_test_valid(fs)) 361424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reason = _(" contains a file system with errors"); 362424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else if ((fs->super->s_state & EXT2_VALID_FS) == 0) 363424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reason = _(" was not cleanly unmounted"); 364424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else if (check_backup_super_block(ctx)) 365424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reason = _(" primary superblock features different from backup"); 366424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else if ((fs->super->s_max_mnt_count > 0) && 367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (fs->super->s_mnt_count >= 368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (unsigned) fs->super->s_max_mnt_count)) { 369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reason = _(" has been mounted %u times without being checked"); 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reason_arg = fs->super->s_mnt_count; 371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (batt && (fs->super->s_mnt_count < 372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (unsigned) fs->super->s_max_mnt_count*2)) 373116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reason = 0; 374116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } else if (!broken_system_clock && fs->super->s_checkinterval && 375116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch (ctx->now < lastcheck)) { 376116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch reason = _(" has filesystem last checked time in the future"); 377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (batt) 378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reason = 0; 379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (!broken_system_clock && fs->super->s_checkinterval && 380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ((ctx->now - lastcheck) >= 381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ((time_t) fs->super->s_checkinterval))) { 382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reason = _(" has gone %u days without being checked"); 383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reason_arg = (ctx->now - fs->super->s_lastcheck)/(3600*24); 384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (batt && ((ctx->now - fs->super->s_lastcheck) < 385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fs->super->s_checkinterval*2)) 386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reason = 0; 3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (reason) { 389ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch log_out(ctx, "%s", ctx->device_name); 390ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch log_out(ctx, reason, reason_arg); 391effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch log_out(ctx, _(", check forced.\n")); 392ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return; 393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Update the global counts from the block group counts. This 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * is needed since modern kernels don't update the global 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * counts so as to avoid locking the entire file system. So 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * if the filesystem is not unmounted cleanly, the global 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * counts may not be accurate. Update them here if we can, 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * for the benefit of users who might examine the file system 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * using dumpe2fs. (This is for cosmetic reasons only.) 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) clear_problem_context(&pctx); 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pctx.ino = fs->super->s_free_inodes_count; 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pctx.ino2 = ctx->free_inodes; 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((pctx.ino != pctx.ino2) && 4085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !(ctx->options & E2F_OPT_READONLY) && 409a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fix_problem(ctx, PR_0_FREE_INODE_COUNT, &pctx)) { 410a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fs->super->s_free_inodes_count = ctx->free_inodes; 411a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ext2fs_mark_super_dirty(fs); 412a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 413a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) clear_problem_context(&pctx); 4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pctx.blk = ext2fs_free_blocks_count(fs->super); 4155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pctx.blk2 = ctx->free_blocks; 4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((pctx.blk != pctx.blk2) && 4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) !(ctx->options & E2F_OPT_READONLY) && 4185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fix_problem(ctx, PR_0_FREE_BLOCK_COUNT, &pctx)) { 4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ext2fs_free_blocks_count_set(fs->super, ctx->free_blocks); 4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ext2fs_mark_super_dirty(fs); 4215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* Print the summary message when we're skipping a full check */ 4245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, _("%s: clean, %u/%u files, %llu/%llu blocks"), 4255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->device_name, 4265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fs->super->s_inodes_count - fs->super->s_free_inodes_count, 4275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fs->super->s_inodes_count, 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext2fs_blocks_count(fs->super) - 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext2fs_free_blocks_count(fs->super), 4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext2fs_blocks_count(fs->super)); 4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) next_check = 100000; 4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fs->super->s_max_mnt_count > 0) { 4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count; 4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (next_check <= 0) 4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) next_check = 1; 4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!broken_system_clock && fs->super->s_checkinterval && 4385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ((ctx->now - fs->super->s_lastcheck) >= fs->super->s_checkinterval)) 4395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) next_check = 1; 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (next_check <= 5) { 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (next_check == 1) { 4425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (batt) 4435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, _(" (check deferred; " 4445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "on battery)")); 4455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 4465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, _(" (check after next mount)")); 4475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else 4485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, _(" (check in %ld mounts)"), next_check); 4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) log_out(ctx, "\n"); 4515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)skip: 4525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ext2fs_close(fs); 4535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->fs = NULL; 4545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e2fsck_free_context(ctx); 455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch exit(FSCK_OK); 456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 4575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch/* 459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * For completion notice 4605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 4615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct percent_tbl { 4625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int max_pass; 4635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int table[32]; 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)struct percent_tbl e2fsck_tbl = { 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 5, { 0, 70, 90, 92, 95, 100 } 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)static char bar[128], spaces[128]; 469eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccistatic float calc_percent(struct percent_tbl *tbl, int pass, int curr, 471eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int max) 472eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 473eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch float percent; 474eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 475eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (pass <= 0) 4765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0.0; 4775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (pass > tbl->max_pass || max == 0) 4785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 100.0; 4795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) percent = ((float) curr) / ((float) max); 4805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return ((percent * (tbl->table[pass] - tbl->table[pass-1])) 4815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) + tbl->table[pass-1]); 4825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciextern void e2fsck_clear_progbar(e2fsck_t ctx) 4855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 4865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!(ctx->flags & E2F_FLAG_PROG_BAR)) 4875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 4885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80), 4905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->stop_meta); 4915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fflush(stdout); 4925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->flags &= ~E2F_FLAG_PROG_BAR; 4935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent, 4965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned int dpynum) 4975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 4985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static const char spinner[] = "\\|/-"; 4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci int i; 5005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned int tick; 5015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct timeval tv; 5025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int dpywidth; 5035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int fixed_percent; 5045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ctx->flags & E2F_FLAG_PROG_SUPPRESS) 5065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 5075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /* 5095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Calculate the new progress position. If the 5105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * percentage hasn't changed, then we skip out right 5115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * away. 5125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 5135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fixed_percent = (int) ((10 * percent) + 0.5); 5145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ctx->progress_last_percent == fixed_percent) 5155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 5165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress_last_percent = fixed_percent; 5175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /* 5195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * If we've already updated the spinner once within 5205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * the last 1/8th of a second, no point doing it 5215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * again. 5225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 5235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) gettimeofday(&tv, NULL); 5245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8)); 5255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if ((tick == ctx->progress_last_time) && 5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci (fixed_percent != 0) && (fixed_percent != 1000)) 5275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 5285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress_last_time = tick; 5295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /* 5315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Advance the spinner, and note that the progress bar 5325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * will be on the screen 5335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 5345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress_pos = (ctx->progress_pos+1) & 3; 5355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->flags |= E2F_FLAG_PROG_BAR; 5365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dpywidth = 66 - strlen(label); 5385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dpywidth = 8 * (dpywidth / 8); 5395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (dpynum) 5405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) dpywidth -= 8; 5415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) i = ((percent * dpywidth) + 50) / 100; 5435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) printf("%s%s: |%s%s", ctx->start_meta, label, 5445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bar + (sizeof(bar) - (i+1)), 5455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) spaces + (sizeof(spaces) - (dpywidth - i + 1))); 5465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (fixed_percent == 1000) 5475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputc('|', stdout); 5485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 5495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputc(spinner[ctx->progress_pos & 3], stdout); 5505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) printf(" %4.1f%% ", percent); 5515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (dpynum) 5525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) printf("%u\r", dpynum); 5535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 5545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputs(" \r", stdout); 5555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputs(ctx->stop_meta, stdout); 5565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (fixed_percent == 1000) 5581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci e2fsck_clear_progbar(ctx); 5591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fflush(stdout); 5605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 5625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static int e2fsck_update_progress(e2fsck_t ctx, int pass, 5655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) unsigned long cur, unsigned long max) 5665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 5675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char buf[1024]; 5685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) float percent; 5695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (pass == 0) 5715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 5725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ctx->progress_fd) { 5745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) snprintf(buf, sizeof(buf), "%d %lu %lu %s\n", 5755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) pass, cur, max, ctx->device_name); 5765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) write_all(ctx->progress_fd, buf, strlen(buf)); 5775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 5785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) percent = calc_percent(&e2fsck_tbl, pass, cur, max); 5795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e2fsck_simple_progress(ctx, ctx->device_name, 5805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) percent, 0); 5815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 5825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return 0; 5835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 5845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#define PATH_SET "PATH=/sbin" 5865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)/* 5885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Make sure 0,1,2 file descriptors are open, so that we don't open 5895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * the filesystem using the same file descriptor as stdout or stderr. 5905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) */ 5915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static void reserve_stdio_fds(void) 5925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 5935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int fd = 0; 5945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 5955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while (fd <= 2) { 5965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fd = open("/dev/null", O_RDWR); 5975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (fd < 0) { 5985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fprintf(stderr, _("ERROR: Couldn't open " 5995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "/dev/null (%s)\n"), 6005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) strerror(errno)); 6015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 6025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 6055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef HAVE_SIGNAL_H 6075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static void signal_progress_on(int sig EXT2FS_ATTR((unused))) 6085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci e2fsck_t ctx = e2fsck_global_ctx; 6105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ctx) 6125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 6135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress = e2fsck_update_progress; 6155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 6165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static void signal_progress_off(int sig EXT2FS_ATTR((unused))) 6185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 6195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e2fsck_t ctx = e2fsck_global_ctx; 6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 6215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ctx) 6225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return; 6235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e2fsck_clear_progbar(ctx); 6255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress = 0; 6265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 6275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static void signal_cancel(int sig EXT2FS_ATTR((unused))) 6295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 6305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e2fsck_t ctx = e2fsck_global_ctx; 6315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ctx) 6335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exit(FSCK_CANCELED); 6345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ctx->flags |= E2F_FLAG_CANCEL; 6365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 6375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 6385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static void parse_extended_opts(e2fsck_t ctx, const char *opts) 6405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 6415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char *buf, *token, *next, *p, *arg; 6425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int ea_ver; 6435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int extended_usage = 0; 6445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 6455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) buf = string_copy(ctx, opts, 0); 6465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (token = buf; token && *token; token = next) { 6475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) p = strchr(token, ','); 6485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) next = 0; 6495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (p) { 6505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *p = 0; 6515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) next = p+1; 6525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg = strchr(token, '='); 6545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (arg) { 6555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *arg = 0; 6565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) arg++; 6575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (strcmp(token, "ea_ver") == 0) { 6595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!arg) { 6605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extended_usage++; 6615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 6635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ea_ver = strtoul(arg, &p, 0); 6645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (*p || 6655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ((ea_ver != 1) && (ea_ver != 2))) { 6665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fprintf(stderr, 6675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _("Invalid EA version.\n")); 6685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extended_usage++; 6695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 6705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->ext_attr_ver = ea_ver; 6725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (strcmp(token, "fragcheck") == 0) { 6735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_FRAGCHECK; 6745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 6755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (strcmp(token, "journal_only") == 0) { 6765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (arg) { 6775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extended_usage++; 6785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 6795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_JOURNAL_ONLY; 6815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (strcmp(token, "discard") == 0) { 6825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_DISCARD; 6835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 6845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (strcmp(token, "nodiscard") == 0) { 6855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options &= ~E2F_OPT_DISCARD; 6865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 6875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (strcmp(token, "log_filename") == 0) { 6885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!arg) 6895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extended_usage++; 6905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 6915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->log_fn = string_copy(ctx, arg, 0); 6925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) continue; 6935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 6941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fprintf(stderr, _("Unknown extended option: %s\n"), 6951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci token); 6965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extended_usage++; 6975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 6995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) free(buf); 7005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (extended_usage) { 7025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputs(("\nExtended options are separated by commas, " 7035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "and may take an argument which\n" 7045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "is set off by an equals ('=') sign. " 7055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "Valid extended options are:\n"), stderr); 7065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputs(("\tea_ver=<ea_version (1 or 2)>\n"), stderr); 7075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputs(("\tfragcheck\n"), stderr); 7085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputs(("\tjournal_only\n"), stderr); 7095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputs(("\tdiscard\n"), stderr); 7105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputs(("\tnodiscard\n"), stderr); 7115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fputc('\n', stderr); 7125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exit(1); 7135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 7145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 7155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static void syntax_err_report(const char *filename, long err, int line_num) 7175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 7185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fprintf(stderr, 7195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _("Syntax error in e2fsck config file (%s, line #%d)\n\t%s\n"), 7205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) filename, line_num, error_message(err)); 7215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) exit(FSCK_ERROR); 7225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 7235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static const char *config_fn[] = { ROOT_SYSCONFDIR "/e2fsck.conf", 0 }; 7255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) 7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles){ 7285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int flush = 0; 7295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int c, fd; 7305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef MTRACE 7315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extern void *mallwatch; 7325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 7335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) e2fsck_t ctx; 7345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) errcode_t retval; 7355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef HAVE_SIGNAL_H 7365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) struct sigaction sa; 7375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 7385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char *extended_opts = 0; 7395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char *cp; 7405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int res; /* result of sscanf */ 7415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef CONFIG_JBD_DEBUG 7425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) char *jbd_debug; 7435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#endif 7445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci retval = e2fsck_allocate_context(&ctx); 7465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (retval) 7475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return retval; 7485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ret_ctx = ctx; 7505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) setvbuf(stdout, NULL, _IONBF, BUFSIZ); 7525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) setvbuf(stderr, NULL, _IONBF, BUFSIZ); 7535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (isatty(0) && isatty(1)) { 7545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->interactive = 1; 7555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else { 7561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ctx->start_meta[0] = '\001'; 7575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->stop_meta[0] = '\002'; 7585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 7595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) memset(bar, '=', sizeof(bar)-1); 7605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) memset(spaces, ' ', sizeof(spaces)-1); 7615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) add_error_table(&et_ext2_error_table); 7625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) add_error_table(&et_prof_error_table); 7635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) blkid_get_cache(&ctx->blkid, NULL); 7645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (argc && *argv) 7665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->program_name = *argv; 7675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 7685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->program_name = "e2fsck"; 7695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF) 7711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci switch (c) { 7725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'C': 7735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress = e2fsck_update_progress; 7745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res = sscanf(optarg, "%d", &ctx->progress_fd); 7755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (res != 1) 7765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto sscanf_err; 7775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 7785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ctx->progress_fd < 0) { 7795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress = 0; 7805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress_fd = ctx->progress_fd * -1; 7815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 7825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ctx->progress_fd) 7835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 7845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /* Validate the file descriptor to avoid disasters */ 7855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fd = dup(ctx->progress_fd); 7865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (fd < 0) { 7875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fprintf(stderr, 7885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _("Error validating file descriptor %d: %s\n"), 7895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->progress_fd, 7905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) error_message(errno)); 7915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fatal_error(ctx, 7925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _("Invalid completion information file descriptor")); 7935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else 7945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) close(fd); 7955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 7965f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'D': 7975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_COMPRESS_DIRS; 7981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 7995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'E': 8005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) extended_opts = optarg; 8015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'p': 8035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'a': 8045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) { 8055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) conflict_opt: 8065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fatal_error(ctx, 8075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _("Only one of the options -p/-a, -n or -y may be specified.")); 8085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 8095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_PREEN; 8105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'n': 8125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN)) 8135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto conflict_opt; 8145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_NO; 8155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'y': 8175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO)) 8185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto conflict_opt; 8195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_YES; 8205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 't': 8225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#ifdef RESOURCE_TRACK 8235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (ctx->options & E2F_OPT_TIME) 8245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_TIME2; 8255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) else 8265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_TIME; 8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#else 8285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fprintf(stderr, _("The -t option is not " 8295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) "supported on this version of e2fsck.\n")); 8301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 8311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci break; 8325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'c': 8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (cflag++) 8345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_WRITECHECK; 8355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_CHECKBLOCKS; 8365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'r': 8385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) /* What we do by default, anyway! */ 8395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'b': 8415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res = sscanf(optarg, "%llu", &ctx->use_superblock); 8425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (res != 1) 8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto sscanf_err; 8445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->flags |= E2F_FLAG_SB_SPECIFIED; 8455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'B': 8475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->blocksize = atoi(optarg); 8485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'I': 8505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res = sscanf(optarg, "%d", &ctx->inode_buffer_blocks); 8515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (res != 1) 8525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto sscanf_err; 8535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'j': 8555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->journal_name = blkid_get_devname(ctx->blkid, 8565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) optarg, NULL); 8575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!ctx->journal_name) { 8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) com_err(ctx->program_name, 0, 8595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) _("Unable to resolve '%s'"), 8605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) optarg); 8615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) fatal_error(ctx, 0); 8625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 8635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'P': 8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) res = sscanf(optarg, "%d", &ctx->process_inode_size); 8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (res != 1) 8675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) goto sscanf_err; 8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'L': 8705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) replace_bad_blocks++; 8715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'l': 8725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bad_blocks_file = string_copy(ctx, optarg, 0); 8735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'd': 8755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_DEBUG; 8765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'f': 8785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ctx->options |= E2F_OPT_FORCE; 8795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'F': 8815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) flush = 1; 8825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) break; 8835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 'v': 884eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch verbose = 1; 885eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 886eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case 'V': 887eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch show_version_only = 1; 888eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 889eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifdef MTRACE 890eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case 'M': 891eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mallwatch = (void *) strtol(optarg, NULL, 0); 892eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 893eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 894424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) case 'N': 895424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ctx->device_name = string_copy(ctx, optarg, 0); 896424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) break; 897eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch case 'k': 898eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch keep_bad_blocks++; 899eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch break; 900eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch default: 901eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch usage(ctx); 902424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 903424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (show_version_only) 904424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return 0; 905424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (optind != argc - 1) 906424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) usage(ctx); 907424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if ((ctx->options & E2F_OPT_NO) && 908eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (ctx->options & E2F_OPT_COMPRESS_DIRS)) { 909eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch com_err(ctx->program_name, 0, 910eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("The -n and -D options are incompatible.")); 911eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fatal_error(ctx, 0); 912eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 913eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((ctx->options & E2F_OPT_NO) && cflag) { 914116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch com_err(ctx->program_name, 0, 915116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch _("The -n and -c options are incompatible.")); 916116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fatal_error(ctx, 0); 917116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 918eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((ctx->options & E2F_OPT_NO) && bad_blocks_file) { 919eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch com_err(ctx->program_name, 0, 920eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("The -n and -l/-L options are incompatible.")); 921eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fatal_error(ctx, 0); 922eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 923eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ctx->options & E2F_OPT_NO) 924eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->options |= E2F_OPT_READONLY; 9251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 926eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->io_options = strchr(argv[optind], '?'); 927eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ctx->io_options) 9281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *ctx->io_options++ = 0; 929eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0); 930ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (!ctx->filesystem_name) { 931ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch com_err(ctx->program_name, 0, _("Unable to resolve '%s'"), 932effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch argv[optind]); 933ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch fatal_error(ctx, 0); 934eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 935eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (extended_opts) 936eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch parse_extended_opts(ctx, extended_opts); 937eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 9385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((cp = getenv("E2FSCK_CONFIG")) != NULL) 9395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) config_fn[0] = cp; 9405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_set_syntax_err_cb(syntax_err_report); 9415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_init(config_fn, &ctx->profile); 9425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_get_boolean(ctx->profile, "options", "report_time", 0, 0, 9445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &c); 9455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (c) 9465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->options |= E2F_OPT_TIME | E2F_OPT_TIME2; 9475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) profile_get_boolean(ctx->profile, "options", "report_verbose", 0, 0, 9485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &c); 9495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (c) 950a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) verbose = 1; 951a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 952a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) /* Turn off discard in read-only mode */ 953a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if ((ctx->options & E2F_OPT_NO) && 954a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) (ctx->options & E2F_OPT_DISCARD)) 9555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->options &= ~E2F_OPT_DISCARD; 9565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (flush) { 9585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fd = open(ctx->filesystem_name, O_RDONLY, 0); 9595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (fd < 0) { 9601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci com_err("open", errno, 9611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci _("while opening %s for flushing"), 9625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->filesystem_name); 9635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fatal_error(ctx, 0); 9645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 9655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((retval = ext2fs_sync_device(fd, 1))) { 9665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) com_err("ext2fs_sync_device", retval, 9675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) _("while trying to flush %s"), 9685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->filesystem_name); 9695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fatal_error(ctx, 0); 9705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 9715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) close(fd); 9725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 9735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (cflag && bad_blocks_file) { 9745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fprintf(stderr, _("The -c and the -l/-L options may " 9755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "not be both used at the same time.\n")); 9765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) exit(FSCK_USAGE); 9775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 9785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef HAVE_SIGNAL_H 9795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* 9805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Set up signal action 9815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */ 9825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) memset(&sa, 0, sizeof(struct sigaction)); 9835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sa.sa_handler = signal_cancel; 9845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sigaction(SIGINT, &sa, 0); 9855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sigaction(SIGTERM, &sa, 0); 9865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#ifdef SA_RESTART 9875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sa.sa_flags = SA_RESTART; 9885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 9895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e2fsck_global_ctx = ctx; 9905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sa.sa_handler = signal_progress_on; 9915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sigaction(SIGUSR1, &sa, 0); 9925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sa.sa_handler = signal_progress_off; 9935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sigaction(SIGUSR2, &sa, 0); 9945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif 9955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 9965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) /* Update our PATH to include /sbin if we need to run badblocks */ 997eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (cflag) { 998eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch char *oldpath = getenv("PATH"); 999eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch char *newpath; 1000eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int len = sizeof(PATH_SET) + 1; 1001eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 10025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (oldpath) 10035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) len += strlen(oldpath); 10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) newpath = malloc(len); 10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!newpath) 10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fatal_error(ctx, "Couldn't malloc() newpath"); 10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) strcpy(newpath, PATH_SET); 10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (oldpath) { 1011eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch strcat(newpath, ":"); 1012eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch strcat(newpath, oldpath); 1013eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1014eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch putenv(newpath); 1015eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1016eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifdef CONFIG_JBD_DEBUG 1017eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jbd_debug = getenv("E2FSCK_JBD_DEBUG"); 1018eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (jbd_debug) { 1019eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch res = sscanf(jbd_debug, "%d", &journal_enable_debug); 1020eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (res != 1) { 1021eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fprintf(stderr, 1022eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("E2FSCK_JBD_DEBUG \"%s\" not an integer\n\n"), 1023eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jbd_debug); 1024eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch exit (1); 1025eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1026eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1027eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1028eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 1029eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1030eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochsscanf_err: 1031116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch fprintf(stderr, _("\nInvalid non-numeric argument to -%c (\"%s\")\n\n"), 1032116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch c, optarg); 1033116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch exit (1); 1034116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1035eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1036eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic errcode_t try_open_fs(e2fsck_t ctx, int flags, io_manager io_ptr, 1037eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2_filsys *ret_fs) 1038eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 1039eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errcode_t retval; 1040eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1041eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *ret_fs = NULL; 10421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (ctx->superblock && ctx->blocksize) { 1043eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options, 1044eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch flags, ctx->superblock, ctx->blocksize, 10451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci io_ptr, ret_fs); 1046eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (ctx->superblock) { 1047ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch int blocksize; 1048ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (blocksize = EXT2_MIN_BLOCK_SIZE; 1049effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) { 1050ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch if (*ret_fs) { 1051eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_free(*ret_fs); 1052eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *ret_fs = NULL; 1053eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1054eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_open2(ctx->filesystem_name, 10555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->io_options, flags, 10565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ctx->superblock, blocksize, 10575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) io_ptr, ret_fs); 10585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!retval) 10595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 10605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else 10625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options, 10635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) flags, 0, 0, io_ptr, ret_fs); 10645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 10655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (ret_fs) 10665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) e2fsck_set_bitmap_type(*ret_fs, EXT2FS_BMAP64_RBTREE, 1067a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "default", NULL); 1068a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) return retval; 1069a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)} 1070a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1071a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)static const char *my_ver_string = E2FSPROGS_VERSION; 1072eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic const char *my_ver_date = E2FSPROGS_DATE; 1073eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1074eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochstatic int e2fsck_check_mmp(ext2_filsys fs, e2fsck_t ctx) 1075eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 1076eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch struct mmp_struct *mmp_s; 1077eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int mmp_check_interval; 1078eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errcode_t retval = 0; 1079eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch struct problem_context pctx; 1080eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch unsigned int wait_time = 0; 1081eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1082eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch clear_problem_context(&pctx); 1083eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (fs->mmp_buf == NULL) { 1084eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = ext2fs_get_mem(fs->blocksize, &fs->mmp_buf); 1085eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 1086eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto check_error; 1087eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1088116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 1089116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch retval = ext2fs_mmp_read(fs, fs->super->s_mmp_block, fs->mmp_buf); 1090116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (retval) 1091116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch goto check_error; 1092eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1093eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mmp_s = fs->mmp_buf; 1094eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1095eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mmp_check_interval = fs->super->s_mmp_update_interval; 1096eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (mmp_check_interval < EXT4_MMP_MIN_CHECK_INTERVAL) 1097eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mmp_check_interval = EXT4_MMP_MIN_CHECK_INTERVAL; 1098eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1099eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 1100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * If check_interval in MMP block is larger, use that instead of 1101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * check_interval from the superblock. 1102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) */ 1103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (mmp_s->mmp_check_interval > mmp_check_interval) 1104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) mmp_check_interval = mmp_s->mmp_check_interval; 1105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) wait_time = mmp_check_interval * 2 + 1; 1107eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (mmp_s->mmp_seq == EXT4_MMP_SEQ_CLEAN) 1109eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = 0; 1110eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else if (mmp_s->mmp_seq == EXT4_MMP_SEQ_FSCK) 1111eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = EXT2_ET_MMP_FSCK_ON; 1112eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else if (mmp_s->mmp_seq > EXT4_MMP_SEQ_MAX) 1113eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = EXT2_ET_MMP_UNKNOWN_SEQ; 1114eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1115eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) 1116eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto check_error; 1117eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1118eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* Print warning if e2fck will wait for more than 20 secs. */ 1119eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (verbose || wait_time > EXT4_MMP_MIN_CHECK_INTERVAL * 4) { 1120eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("MMP interval is %u seconds and total wait " 1121eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "time is %u seconds. Please wait...\n"), 1122eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mmp_check_interval, wait_time * 2); 1123eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1124eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1125eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return 0; 1126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1127eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochcheck_error: 1128eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1129eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval == EXT2_ET_MMP_BAD_BLOCK) { 1130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (fix_problem(ctx, PR_0_MMP_INVALID_BLK, &pctx)) { 1131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fs->super->s_mmp_block = 0; 1132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_mark_super_dirty(fs); 1133a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) retval = 0; 1134a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1135a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else if (retval == EXT2_ET_MMP_FAILED) { 1136a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) com_err(ctx->program_name, retval, 1137a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) _("while checking MMP block")); 1138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dump_mmp_msg(fs->mmp_buf, NULL); 1139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (retval == EXT2_ET_MMP_FSCK_ON || 1140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval == EXT2_ET_MMP_UNKNOWN_SEQ) { 1141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch com_err(ctx->program_name, retval, 1142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("while checking MMP block")); 1143eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch dump_mmp_msg(fs->mmp_buf, 1144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("If you are sure the filesystem is not " 1145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "in use on any node, run:\n" 1146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "'tune2fs -f -E clear_mmp {device}'\n")); 1147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (retval == EXT2_ET_MMP_MAGIC_INVALID) { 1148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (fix_problem(ctx, PR_0_MMP_INVALID_MAGIC, &pctx)) { 1149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_mmp_clear(fs); 1150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = 0; 1151eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1152eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1153eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return retval; 1154eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 1155eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1156eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint main (int argc, char *argv[]) 1157eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch{ 1158eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch errcode_t retval = 0, retval2 = 0, orig_retval = 0; 1159eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int exit_value = FSCK_OK; 1160eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2_filsys fs = 0; 1161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch io_manager io_ptr; 1162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch struct ext2_super_block *sb; 1163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch const char *lib_ver_date; 1164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int my_ver, lib_ver; 1165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) e2fsck_t ctx; 1166a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) blk_t orig_superblock; 1167a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) struct problem_context pctx; 1168a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int flags, run_result; 1169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) int journal_size; 1170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int sysval, sys_page_size = 4096; 1171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int old_bitmaps; 1172eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch __u32 features[3]; 1173eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch char *cp; 1174eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int qtype; /* quota type */ 1175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1176eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch clear_problem_context(&pctx); 1177eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sigcatcher_setup(); 1178eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifdef MTRACE 1179eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mtrace(); 1180eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1181eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifdef MCHECK 1182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch mcheck(0); 1183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifdef ENABLE_NLS 1185eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch setlocale(LC_MESSAGES, ""); 1186eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch setlocale(LC_CTYPE, ""); 1187eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bindtextdomain(NLS_CAT_NAME, LOCALEDIR); 1188eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch textdomain(NLS_CAT_NAME); 1189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch set_com_err_gettext(gettext); 1190eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch my_ver = ext2fs_parse_version_string(my_ver_string); 1192eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch lib_ver = ext2fs_get_library_version(0, &lib_ver_date); 1193a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (my_ver > lib_ver) { 1194a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) fprintf( stderr, _("Error: ext2fs library version " 1195a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) "out of date!\n")); 1196a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) show_version_only++; 1197a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1198eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1199eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = PRS(argc, argv, &ctx); 1200eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) { 1201eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch com_err("e2fsck", retval, 1202eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("while trying to initialize program")); 1203eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch exit(FSCK_ERROR); 1204eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1205eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch reserve_stdio_fds(); 1206eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1207eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch set_up_logging(ctx); 1208eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ctx->logf) { 1209eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int i; 1210eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fputs("E2fsck run: ", ctx->logf); 1211eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (i = 0; i < argc; i++) { 1212eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (i) 1213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fputc(' ', ctx->logf); 1214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fputs(argv[i], ctx->logf); 1215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fputc('\n', ctx->logf); 1217eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1219a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) init_resource_track(&ctx->global_rtrack, NULL); 1220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!(ctx->options & E2F_OPT_PREEN) || show_version_only) 1221a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) log_err(ctx, "e2fsck %s (%s)\n", my_ver_string, 1222a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) my_ver_date); 1223eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1224eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (show_version_only) { 1225eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_err(ctx, _("\tUsing %s, %s\n"), 1226eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error_message(EXT2_ET_BASE), lib_ver_date); 1227eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch exit(FSCK_OK); 1228ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch } 12291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1230ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch check_mount(ctx); 1231eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1232eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!(ctx->options & E2F_OPT_PREEN) && 1233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !(ctx->options & E2F_OPT_NO) && 1234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch !(ctx->options & E2F_OPT_YES)) { 1235eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!ctx->interactive) 1236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fatal_error(ctx, 1237eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("need terminal for interactive repairs")); 1238eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1239eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->superblock = ctx->use_superblock; 1240a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1241a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) flags = EXT2_FLAG_SKIP_MMP; 1242a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)restart: 1243a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#ifdef CONFIG_TESTIO_DEBUG 1244a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (getenv("TEST_IO_FLAGS") || getenv("TEST_IO_BLOCK")) { 1245eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch io_ptr = test_io_manager; 1246eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch test_io_backing_manager = unix_io_manager; 1247eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else 1248eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1249eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch io_ptr = unix_io_manager; 1250eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch flags |= EXT2_FLAG_NOFREE_ON_ERROR; 1251eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch profile_get_boolean(ctx->profile, "options", "old_bitmaps", 0, 0, 1252a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) &old_bitmaps); 1253a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!old_bitmaps) 1254a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) flags |= EXT2_FLAG_64BITS; 1255a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if ((ctx->options & E2F_OPT_READONLY) == 0) { 1256a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) flags |= EXT2_FLAG_RW; 1257a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!(ctx->mount_flags & EXT2_MF_ISROOT && 1258a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ctx->mount_flags & EXT2_MF_READONLY)) 1259eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch flags |= EXT2_FLAG_EXCLUSIVE; 1260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((ctx->mount_flags & EXT2_MF_READONLY) && 1261eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (ctx->options & E2F_OPT_FORCE)) 1262eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch flags &= ~EXT2_FLAG_EXCLUSIVE; 1263a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 1264a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1265a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) retval = try_open_fs(ctx, flags, io_ptr, &fs); 1266a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 1267a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) && 1268a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !(ctx->flags & E2F_FLAG_SB_SPECIFIED) && 1269a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) ((retval == EXT2_ET_BAD_MAGIC) || 1270eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (retval == EXT2_ET_CORRUPT_SUPERBLOCK) || 1271eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ((retval == 0) && (retval2 = ext2fs_check_desc(fs))))) { 1272eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) { 1273eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pctx.errcode = retval; 1274eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fix_problem(ctx, PR_0_OPEN_FAILED, &pctx); 1275eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval2) { 1277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pctx.errcode = retval2; 1278eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fix_problem(ctx, PR_0_CHECK_DESC_FAILED, &pctx); 1279eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1280eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pctx.errcode = 0; 1281eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval2 == ENOMEM || retval2 == EXT2_ET_NO_MEMORY) { 1282eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = retval2; 1283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto failure; 1284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1285eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (fs->flags & EXT2_FLAG_NOFREE_ON_ERROR) { 1286eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_free(fs); 1287eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fs = NULL; 1288eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1289eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!fs || (fs->group_desc_count > 1)) { 1290eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("%s: %s trying backup blocks...\n"), 1291eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->program_name, 1292eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval ? _("Superblock invalid,") : 1293eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("Group descriptors look bad...")); 1294eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch orig_superblock = ctx->superblock; 1295eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr); 1296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (fs) 1297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_close(fs); 1298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch orig_retval = retval; 1299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = try_open_fs(ctx, flags, io_ptr, &fs); 1300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((orig_retval == 0) && retval != 0) { 1301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (fs) 1302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_close(fs); 1303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("%s: %s while using the " 1304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "backup blocks"), 1305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->program_name, 1306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch error_message(retval)); 1307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("%s: going back to original " 1308eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "superblock\n"), 1309eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->program_name); 1310eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->superblock = orig_superblock; 1311eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = try_open_fs(ctx, flags, io_ptr, &fs); 1312eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1313eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1314eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1315eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (((retval == EXT2_ET_UNSUPP_FEATURE) || 1316eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (retval == EXT2_ET_RO_UNSUPP_FEATURE)) && 1317eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fs && fs->super) { 1318eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sb = fs->super; 1319eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch features[0] = (sb->s_feature_compat & 1320eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ~EXT2_LIB_FEATURE_COMPAT_SUPP); 1321eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch features[1] = (sb->s_feature_incompat & 1322eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ~EXT2_LIB_FEATURE_INCOMPAT_SUPP); 1323eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch features[2] = (sb->s_feature_ro_compat & 1324eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP); 1325eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (features[0] || features[1] || features[2]) 1326eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto print_unsupp_features; 1327eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1328eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochfailure: 1329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval) { 1330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (orig_retval) 1331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch retval = orig_retval; 1332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch com_err(ctx->program_name, retval, _("while trying to open %s"), 1333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->filesystem_name); 1334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (retval == EXT2_ET_REV_TOO_HIGH) { 1335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("The filesystem revision is apparently " 1336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "too high for this version of e2fsck.\n" 1337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "(Or the filesystem superblock " 1338eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "is corrupt)\n\n")); 1339eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); 1340eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } else if (retval == EXT2_ET_SHORT_READ) 1341eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("Could this be a zero-length " 1342eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "partition?\n")); 1343eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else if ((retval == EPERM) || (retval == EACCES)) 1344eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("You must have %s access to the " 1345eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "filesystem or be root\n"), 1346eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (ctx->options & E2F_OPT_READONLY) ? 1347eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "r/o" : "r/w"); 1348eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else if (retval == ENXIO) 1349eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("Possibly non-existent or " 1350eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "swap device?\n")); 1351eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else if (retval == EBUSY) 1352eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("Filesystem mounted or opened " 1353eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "exclusively by another program?\n")); 1354eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else if (retval == ENOENT) 1355eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("Possibly non-existent device?\n")); 1356eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#ifdef EROFS 1357eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else if (retval == EROFS) 1358eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch log_out(ctx, _("Disk write-protected; use the -n " 1359eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "option to do a read-only\n" 1360eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "check of the device.\n")); 1361eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif 1362eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else 1363eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); 1364eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fatal_error(ctx, 0); 1365eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1366eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 1367eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * We only update the master superblock because (a) paranoia; 1368eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * we don't want to corrupt the backup superblocks, and (b) we 1369eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * don't need to update the mount count and last checked 1370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * fields in the backup superblock (the kernel doesn't update 1371eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * the backup superblocks anyway). With newer versions of the 1372eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * library this flag is set by ext2fs_open2(), but we set this 1373eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * here just to be sure. (No, we don't support e2fsck running 1374eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * with some other libext2fs than the one that it was shipped 1375eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * with, but just in case....) 1376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 1377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; 1378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (!(ctx->flags & E2F_FLAG_GOT_DEVSIZE)) { 1380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch __u32 blocksize = EXT2_BLOCK_SIZE(fs->super); 1381eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int need_restart = 0; 1382eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pctx.errcode = ext2fs_get_device_size2(ctx->filesystem_name, 1384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blocksize, 1385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &ctx->num_blocks); 1386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 1387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * The floppy driver refuses to allow anyone else to 1388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * open the device if has been opened with O_EXCL; 1389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * this is unlike other block device drivers in Linux. 1390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * To handle this, we close the filesystem and then 1391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * reopen the filesystem after we get the device size. 1392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 1393eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (pctx.errcode == EBUSY) { 1394eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_close(fs); 1395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch need_restart++; 1396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch pctx.errcode = 1397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_get_device_size2(ctx->filesystem_name, 1398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch blocksize, 1399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch &ctx->num_blocks); 1400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (pctx.errcode == EXT2_ET_UNIMPLEMENTED) 1402eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->num_blocks = 0; 1403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch else if (pctx.errcode) { 1404eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx); 1405eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->flags |= E2F_FLAG_ABORT; 1406eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fatal_error(ctx, 0); 1407eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1408eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->flags |= E2F_FLAG_GOT_DEVSIZE; 1409eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (need_restart) 1410eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto restart; 1411eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1412eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1413eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs = fs; 1414eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fs->priv_data = ctx; 1415eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fs->now = ctx->now; 1416eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sb = fs->super; 1417eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1418eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (sb->s_rev_level > E2FSCK_CURRENT_REV) { 1419eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH, 1420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch _("while trying to open %s"), 1421eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->filesystem_name); 1422eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch get_newer: 1423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fatal_error(ctx, _("Get a newer version of e2fsck!")); 1424eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1425eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1426eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 1427eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Set the device name, which is used whenever we print error 1428eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * or informational messages to the user. 1429eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 1430eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ctx->device_name == 0 && 1431eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (sb->s_volume_name[0] != 0)) { 1432eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->device_name = string_copy(ctx, sb->s_volume_name, 1433eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch sizeof(sb->s_volume_name)); 1434eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1435eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ctx->device_name == 0) 1436eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->device_name = string_copy(ctx, ctx->filesystem_name, 0); 1437eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (cp = ctx->device_name; *cp; cp++) 1438eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (isspace(*cp) || *cp == ':') 1439eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch *cp = '_'; 1440eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1441eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ehandler_init(fs->io); 1442eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_MMP) && 1444eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch (flags & EXT2_FLAG_SKIP_MMP)) { 1445eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (e2fsck_check_mmp(fs, ctx)) 1446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fatal_error(ctx, 0); 1447eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1448eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 1449eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Restart in order to reopen fs but this time start mmp. 1450eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 1451eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ext2fs_close(fs); 1452eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ctx->fs = NULL; 1453eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch flags &= ~EXT2_FLAG_SKIP_MMP; 1454eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch goto restart; 1455eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 1456eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1457eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ctx->logf) 1458eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch fprintf(ctx->logf, "Filesystem UUID: %s\n", 1459eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch e2p_uuid2str(sb->s_uuid)); 1460eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 1461eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch /* 1462eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch * Make sure the ext3 superblock fields are consistent. 1463eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch */ 1464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) retval = e2fsck_check_ext3_journal(ctx); 1465 if (retval) { 1466 com_err(ctx->program_name, retval, 1467 _("while checking ext3 journal for %s"), 1468 ctx->device_name); 1469 fatal_error(ctx, 0); 1470 } 1471 1472 /* 1473 * Check to see if we need to do ext3-style recovery. If so, 1474 * do it, and then restart the fsck. 1475 */ 1476 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { 1477 if (ctx->options & E2F_OPT_READONLY) { 1478 log_out(ctx, _("Warning: skipping journal recovery " 1479 "because doing a read-only filesystem " 1480 "check.\n")); 1481 io_channel_flush(ctx->fs->io); 1482 } else { 1483 if (ctx->flags & E2F_FLAG_RESTARTED) { 1484 /* 1485 * Whoops, we attempted to run the 1486 * journal twice. This should never 1487 * happen, unless the hardware or 1488 * device driver is being bogus. 1489 */ 1490 com_err(ctx->program_name, 0, 1491 _("unable to set superblock flags on %s\n"), ctx->device_name); 1492 fatal_error(ctx, 0); 1493 } 1494 retval = e2fsck_run_ext3_journal(ctx); 1495 if (retval) { 1496 com_err(ctx->program_name, retval, 1497 _("while recovering ext3 journal of %s"), 1498 ctx->device_name); 1499 fatal_error(ctx, 0); 1500 } 1501 ext2fs_close(ctx->fs); 1502 ctx->fs = 0; 1503 ctx->flags |= E2F_FLAG_RESTARTED; 1504 goto restart; 1505 } 1506 } 1507 1508 /* 1509 * Check for compatibility with the feature sets. We need to 1510 * be more stringent than ext2fs_open(). 1511 */ 1512 features[0] = sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP; 1513 features[1] = sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP; 1514 features[2] = (sb->s_feature_ro_compat & 1515 ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP); 1516print_unsupp_features: 1517 if (features[0] || features[1] || features[2]) { 1518 int i, j; 1519 __u32 *mask = features, m; 1520 1521 log_err(ctx, _("%s has unsupported feature(s):"), 1522 ctx->filesystem_name); 1523 1524 for (i=0; i <3; i++,mask++) { 1525 for (j=0,m=1; j < 32; j++, m<<=1) { 1526 if (*mask & m) 1527 log_err(ctx, " %s", 1528 e2p_feature2string(i, m)); 1529 } 1530 } 1531 log_err(ctx, "\n"); 1532 goto get_newer; 1533 } 1534#ifdef ENABLE_COMPRESSION 1535 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) 1536 log_err(ctx, _("%s: warning: compression support " 1537 "is experimental.\n"), 1538 ctx->program_name); 1539#endif 1540#ifndef ENABLE_HTREE 1541 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) { 1542 log_err(ctx, _("%s: e2fsck not compiled with HTREE support,\n\t" 1543 "but filesystem %s has HTREE directories.\n"), 1544 ctx->program_name, ctx->device_name); 1545 goto get_newer; 1546 } 1547#endif 1548 1549 /* 1550 * If the user specified a specific superblock, presumably the 1551 * master superblock has been trashed. So we mark the 1552 * superblock as dirty, so it can be written out. 1553 */ 1554 if (ctx->superblock && 1555 !(ctx->options & E2F_OPT_READONLY)) 1556 ext2fs_mark_super_dirty(fs); 1557 1558 /* 1559 * Calculate the number of filesystem blocks per pagesize. If 1560 * fs->blocksize > page_size, set the number of blocks per 1561 * pagesize to 1 to avoid division by zero errors. 1562 */ 1563#ifdef _SC_PAGESIZE 1564 sysval = sysconf(_SC_PAGESIZE); 1565 if (sysval > 0) 1566 sys_page_size = sysval; 1567#endif /* _SC_PAGESIZE */ 1568 ctx->blocks_per_page = sys_page_size / fs->blocksize; 1569 if (ctx->blocks_per_page == 0) 1570 ctx->blocks_per_page = 1; 1571 1572 if (ctx->superblock) 1573 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0); 1574 ext2fs_mark_valid(fs); 1575 check_super_block(ctx); 1576 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 1577 fatal_error(ctx, 0); 1578 check_if_skip(ctx); 1579 check_resize_inode(ctx); 1580 if (bad_blocks_file) 1581 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks); 1582 else if (cflag) 1583 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */ 1584 if (ctx->flags & E2F_FLAG_SIGNAL_MASK) 1585 fatal_error(ctx, 0); 1586 1587 /* 1588 * Mark the system as valid, 'til proven otherwise 1589 */ 1590 ext2fs_mark_valid(fs); 1591 1592 retval = ext2fs_read_bb_inode(fs, &fs->badblocks); 1593 if (retval) { 1594 log_out(ctx, _("%s: %s while reading bad blocks inode\n"), 1595 ctx->program_name, error_message(retval)); 1596 preenhalt(ctx); 1597 log_out(ctx, _("This doesn't bode well, " 1598 "but we'll try to go on...\n")); 1599 } 1600 1601 /* 1602 * Save the journal size in megabytes. 1603 * Try and use the journal size from the backup else let e2fsck 1604 * find the default journal size. 1605 */ 1606 if (sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) 1607 journal_size = (sb->s_jnl_blocks[15] << (32 - 20)) | 1608 (sb->s_jnl_blocks[16] >> 20); 1609 else 1610 journal_size = -1; 1611 1612 if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_QUOTA) { 1613 /* Quotas were enabled. Do quota accounting during fsck. */ 1614 if ((sb->s_usr_quota_inum && sb->s_grp_quota_inum) || 1615 (!sb->s_usr_quota_inum && !sb->s_grp_quota_inum)) 1616 qtype = -1; 1617 else 1618 qtype = sb->s_usr_quota_inum ? USRQUOTA : GRPQUOTA; 1619 1620 quota_init_context(&ctx->qctx, ctx->fs, qtype); 1621 } 1622 1623 run_result = e2fsck_run(ctx); 1624 e2fsck_clear_progbar(ctx); 1625 1626 if (ctx->flags & E2F_FLAG_JOURNAL_INODE) { 1627 if (fix_problem(ctx, PR_6_RECREATE_JOURNAL, &pctx)) { 1628 if (journal_size < 1024) 1629 journal_size = ext2fs_default_journal_size(ext2fs_blocks_count(fs->super)); 1630 if (journal_size < 0) { 1631 fs->super->s_feature_compat &= 1632 ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; 1633 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 1634 log_out(ctx, "%s: Couldn't determine " 1635 "journal size\n", ctx->program_name); 1636 goto no_journal; 1637 } 1638 log_out(ctx, _("Creating journal (%d blocks): "), 1639 journal_size); 1640 fflush(stdout); 1641 retval = ext2fs_add_journal_inode(fs, 1642 journal_size, 0); 1643 if (retval) { 1644 log_out(ctx, "%s: while trying to create " 1645 "journal\n", error_message(retval)); 1646 goto no_journal; 1647 } 1648 log_out(ctx, _(" Done.\n")); 1649 log_out(ctx, _("\n*** journal has been re-created - " 1650 "filesystem is now ext3 again ***\n")); 1651 } 1652 } 1653no_journal: 1654 1655 if (ctx->qctx) { 1656 int i, needs_writeout; 1657 for (i = 0; i < MAXQUOTAS; i++) { 1658 if (qtype != -1 && qtype != i) 1659 continue; 1660 needs_writeout = 0; 1661 pctx.num = i; 1662 retval = quota_compare_and_update(ctx->qctx, i, 1663 &needs_writeout); 1664 if ((retval || needs_writeout) && 1665 fix_problem(ctx, PR_6_UPDATE_QUOTAS, &pctx)) 1666 quota_write_inode(ctx->qctx, i); 1667 } 1668 quota_release_context(&ctx->qctx); 1669 } 1670 1671 if (run_result == E2F_FLAG_RESTART) { 1672 log_out(ctx, _("Restarting e2fsck from the beginning...\n")); 1673 retval = e2fsck_reset_context(ctx); 1674 if (retval) { 1675 com_err(ctx->program_name, retval, 1676 _("while resetting context")); 1677 fatal_error(ctx, 0); 1678 } 1679 ext2fs_close(fs); 1680 goto restart; 1681 } 1682 if (run_result & E2F_FLAG_CANCEL) { 1683 log_out(ctx, _("%s: e2fsck canceled.\n"), ctx->device_name ? 1684 ctx->device_name : ctx->filesystem_name); 1685 exit_value |= FSCK_CANCELED; 1686 } 1687 if (run_result & E2F_FLAG_ABORT) 1688 fatal_error(ctx, _("aborted")); 1689 if (check_backup_super_block(ctx)) { 1690 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; 1691 ext2fs_mark_super_dirty(fs); 1692 } 1693 1694#ifdef MTRACE 1695 mtrace_print("Cleanup"); 1696#endif 1697 if (ext2fs_test_changed(fs)) { 1698 exit_value |= FSCK_NONDESTRUCT; 1699 if (!(ctx->options & E2F_OPT_PREEN)) 1700 log_out(ctx, _("\n%s: ***** FILE SYSTEM WAS " 1701 "MODIFIED *****\n"), 1702 ctx->device_name); 1703 if (ctx->mount_flags & EXT2_MF_ISROOT) { 1704 log_out(ctx, _("%s: ***** REBOOT LINUX *****\n"), 1705 ctx->device_name); 1706 exit_value |= FSCK_REBOOT; 1707 } 1708 } 1709 if (!ext2fs_test_valid(fs) || 1710 ((exit_value & FSCK_CANCELED) && 1711 (sb->s_state & EXT2_ERROR_FS))) { 1712 log_out(ctx, _("\n%s: ********** WARNING: Filesystem still has " 1713 "errors **********\n\n"), ctx->device_name); 1714 exit_value |= FSCK_UNCORRECTED; 1715 exit_value &= ~FSCK_NONDESTRUCT; 1716 } 1717 if (exit_value & FSCK_CANCELED) { 1718 int allow_cancellation; 1719 1720 profile_get_boolean(ctx->profile, "options", 1721 "allow_cancellation", 0, 0, 1722 &allow_cancellation); 1723 exit_value &= ~FSCK_NONDESTRUCT; 1724 if (allow_cancellation && ext2fs_test_valid(fs) && 1725 (sb->s_state & EXT2_VALID_FS) && 1726 !(sb->s_state & EXT2_ERROR_FS)) 1727 exit_value = 0; 1728 } else { 1729 show_stats(ctx); 1730 if (!(ctx->options & E2F_OPT_READONLY)) { 1731 if (ext2fs_test_valid(fs)) { 1732 if (!(sb->s_state & EXT2_VALID_FS)) 1733 exit_value |= FSCK_NONDESTRUCT; 1734 sb->s_state = EXT2_VALID_FS; 1735 } else 1736 sb->s_state &= ~EXT2_VALID_FS; 1737 sb->s_mnt_count = 0; 1738 if (!(ctx->flags & E2F_FLAG_TIME_INSANE)) 1739 sb->s_lastcheck = ctx->now; 1740 memset(((char *) sb) + EXT4_S_ERR_START, 0, 1741 EXT4_S_ERR_LEN); 1742 ext2fs_mark_super_dirty(fs); 1743 } 1744 } 1745 1746 if ((run_result & E2F_FLAG_CANCEL) == 0 && 1747 sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM && 1748 !(ctx->options & E2F_OPT_READONLY)) { 1749 retval = ext2fs_set_gdt_csum(ctx->fs); 1750 if (retval) { 1751 com_err(ctx->program_name, retval, 1752 _("while setting block group checksum info")); 1753 fatal_error(ctx, 0); 1754 } 1755 } 1756 1757 e2fsck_write_bitmaps(ctx); 1758 io_channel_flush(ctx->fs->io); 1759 print_resource_track(ctx, NULL, &ctx->global_rtrack, ctx->fs->io); 1760 1761 ext2fs_close(fs); 1762 ctx->fs = NULL; 1763 free(ctx->journal_name); 1764 1765 e2fsck_free_context(ctx); 1766 remove_error_table(&et_ext2_error_table); 1767 remove_error_table(&et_prof_error_table); 1768 return exit_value; 1769} 1770