X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Funix.c;h=9d9ba04fed14e26c5016e5c237ba26e05260d3c8;hb=db3d8718be6ad3bdd252b242827fa54914b8ec2e;hp=190deaf9b25f294aeb1f64f50fb6ee638752eddc;hpb=010c49cf499738c7a06de13077f31f2a12ecadeb;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 190deaf..9d9ba04 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -33,9 +33,6 @@ extern int optind; #ifdef HAVE_ERRNO_H #include #endif -#ifdef HAVE_MNTENT_H -#include -#endif #ifdef HAVE_SYS_IOCTL_H #include #endif @@ -80,13 +77,13 @@ static void usage(e2fsck_t ctx) "\t\t[-E extended-options] device\n"), ctx->program_name); - fprintf(stderr, _("\nEmergency help:\n" + fprintf(stderr, "%s", _("\nEmergency help:\n" " -p Automatic repair (no questions)\n" " -n Make no changes to the filesystem\n" " -y Assume \"yes\" to all questions\n" " -c Check for bad blocks and add them to the badblock list\n" " -f Force checking even if filesystem is marked clean\n")); - fprintf(stderr, _("" + fprintf(stderr, "%s", _("" " -v Be verbose\n" " -b superblock Use alternative superblock\n" " -B blocksize Force blocksize when looking for superblock\n" @@ -105,8 +102,9 @@ static void show_stats(e2fsck_t ctx) blk64_t blocks, blocks_used; unsigned int dir_links; unsigned int num_files, num_links; + __u32 *mask, m; int frag_percent_file, frag_percent_dir, frag_percent_total; - int i, j; + int i, j, printed = 0; dir_links = 2 * ctx->fs_directory_count - 1; num_files = ctx->fs_total_count - dir_links; @@ -137,21 +135,40 @@ static void show_stats(e2fsck_t ctx) blocks_used, blocks); return; } - log_out(ctx, P_("\n%8u inode used (%2.2f%%)\n", - "\n%8u inodes used (%2.2f%%)\n", + profile_get_boolean(ctx->profile, "options", "report_features", 0, 0, + &i); + if (verbose && i) { + log_out(ctx, "\nFilesystem features:"); + mask = &ctx->fs->super->s_feature_compat; + for (i = 0; i < 3; i++, mask++) { + for (j = 0, m = 1; j < 32; j++, m <<= 1) { + if (*mask & m) { + log_out(ctx, " %s", + e2p_feature2string(i, m)); + printed++; + } + } + } + if (printed == 0) + log_out(ctx, " (none)"); + log_out(ctx, "\n"); + } + + log_out(ctx, P_("\n%12u inode used (%2.2f%%, out of %u)\n", + "\n%12u inodes used (%2.2f%%, out of %u)\n", inodes_used), inodes_used, - 100.0 * inodes_used / inodes); - log_out(ctx, P_("%8u non-contiguous file (%0d.%d%%)\n", - "%8u non-contiguous files (%0d.%d%%)\n", + 100.0 * inodes_used / inodes, inodes); + log_out(ctx, P_("%12u non-contiguous file (%0d.%d%%)\n", + "%12u non-contiguous files (%0d.%d%%)\n", ctx->fs_fragmented), ctx->fs_fragmented, frag_percent_file / 10, frag_percent_file % 10); - log_out(ctx, P_("%8u non-contiguous directory (%0d.%d%%)\n", - "%8u non-contiguous directories (%0d.%d%%)\n", + log_out(ctx, P_("%12u non-contiguous directory (%0d.%d%%)\n", + "%12u non-contiguous directories (%0d.%d%%)\n", ctx->fs_fragmented_dir), ctx->fs_fragmented_dir, frag_percent_dir / 10, frag_percent_dir % 10); - log_out(ctx, _(" # of inodes with ind/dind/tind blocks: " + log_out(ctx, _(" # of inodes with ind/dind/tind blocks: " "%u/%u/%u\n"), ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count); @@ -159,7 +176,7 @@ static void show_stats(e2fsck_t ctx) if (ctx->extent_depth_count[j]) break; if (++j) { - log_out(ctx, _(" Extent depth histogram: ")); + log_out(ctx, "%s", _(" Extent depth histogram: ")); for (i=0; i < j; i++) { if (i) fputc('/', stdout); @@ -168,39 +185,39 @@ static void show_stats(e2fsck_t ctx) log_out(ctx, "\n"); } - log_out(ctx, P_("%8llu block used (%2.2f%%)\n", - "%8llu blocks used (%2.2f%%)\n", - blocks_used), blocks_used, 100.0 * blocks_used / blocks); - log_out(ctx, P_("%8u bad block\n", "%8u bad blocks\n", + log_out(ctx, P_("%12llu block used (%2.2f%%, out of %llu)\n", + "%12llu blocks used (%2.2f%%, out of %llu)\n", + blocks_used), + blocks_used, 100.0 * blocks_used / blocks, blocks); + log_out(ctx, P_("%12u bad block\n", "%12u bad blocks\n", ctx->fs_badblocks_count), ctx->fs_badblocks_count); - log_out(ctx, P_("%8u large file\n", "%8u large files\n", + log_out(ctx, P_("%12u large file\n", "%12u large files\n", ctx->large_files), ctx->large_files); - log_out(ctx, P_("\n%8u regular file\n", "\n%8u regular files\n", + log_out(ctx, P_("\n%12u regular file\n", "\n%12u regular files\n", ctx->fs_regular_count), ctx->fs_regular_count); - log_out(ctx, P_("%8u directory\n", "%8u directories\n", + log_out(ctx, P_("%12u directory\n", "%12u directories\n", ctx->fs_directory_count), ctx->fs_directory_count); - log_out(ctx, P_("%8u character device file\n", - "%8u character device files\n", ctx->fs_chardev_count), + log_out(ctx, P_("%12u character device file\n", + "%12u character device files\n", ctx->fs_chardev_count), ctx->fs_chardev_count); - log_out(ctx, P_("%8u block device file\n", "%8u block device files\n", + log_out(ctx, P_("%12u block device file\n", "%12u block device files\n", ctx->fs_blockdev_count), ctx->fs_blockdev_count); - log_out(ctx, P_("%8u fifo\n", "%8u fifos\n", ctx->fs_fifo_count), + log_out(ctx, P_("%12u fifo\n", "%12u fifos\n", ctx->fs_fifo_count), ctx->fs_fifo_count); - log_out(ctx, P_("%8u link\n", "%8u links\n", - ctx->fs_links_count - dir_links), + log_out(ctx, P_("%12u link\n", "%12u links\n", num_links), ctx->fs_links_count - dir_links); - log_out(ctx, P_("%8u symbolic link", "%8u symbolic links", + log_out(ctx, P_("%12u symbolic link", "%12u symbolic links", ctx->fs_symlinks_count), ctx->fs_symlinks_count); log_out(ctx, P_(" (%u fast symbolic link)\n", " (%u fast symbolic links)\n", ctx->fs_fast_symlinks_count), ctx->fs_fast_symlinks_count); - log_out(ctx, P_("%8u socket\n", "%8u sockets\n", ctx->fs_sockets_count), + log_out(ctx, P_("%12u socket\n", "%12u sockets\n", + ctx->fs_sockets_count), ctx->fs_sockets_count); - log_out(ctx, "--------\n"); - log_out(ctx, P_("%8u file\n", "%8u files\n", - ctx->fs_total_count - dir_links), - ctx->fs_total_count - dir_links); + log_out(ctx, "------------\n"); + log_out(ctx, P_("%12u file\n", "%12u files\n", num_files), + num_files); } static void check_mount(e2fsck_t ctx) @@ -222,31 +239,40 @@ static void check_mount(e2fsck_t ctx) * filesystem and it's mounted read-only, and we're not doing * a read/write check, then everything's fine. */ - if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) || + if ((!(ctx->mount_flags & (EXT2_MF_MOUNTED | EXT2_MF_BUSY))) || ((ctx->mount_flags & EXT2_MF_ISROOT) && (ctx->mount_flags & EXT2_MF_READONLY) && !(ctx->options & E2F_OPT_WRITECHECK))) return; - if ((ctx->options & E2F_OPT_READONLY) && + if (((ctx->options & E2F_OPT_READONLY) || + ((ctx->options & E2F_OPT_FORCE) && + (ctx->mount_flags & EXT2_MF_READONLY))) && !(ctx->options & E2F_OPT_WRITECHECK)) { - log_out(ctx, _("Warning! %s is mounted.\n"), - ctx->filesystem_name); + if (ctx->mount_flags & EXT2_MF_MOUNTED) + log_out(ctx, _("Warning! %s is mounted.\n"), + ctx->filesystem_name); + else + log_out(ctx, _("Warning! %s is in use.\n"), + ctx->filesystem_name); return; } - log_out(ctx, _("%s is mounted. "), ctx->filesystem_name); - if (!ctx->interactive) + if (ctx->mount_flags & EXT2_MF_MOUNTED) + log_out(ctx, _("%s is mounted.\n"), ctx->filesystem_name); + else + log_out(ctx, _("%s is in use.\n"), ctx->filesystem_name); + if (!ctx->interactive || ctx->mount_flags & EXT2_MF_BUSY) fatal_error(ctx, _("Cannot continue, aborting.\n\n")); puts("\007\007\007\007"); - log_out(ctx, _("\n\nWARNING!!! " + log_out(ctx, "%s", _("\n\nWARNING!!! " "The filesystem is mounted. " "If you continue you ***WILL***\n" "cause ***SEVERE*** filesystem damage.\n\n")); puts("\007\007\007"); cont = ask_yn(ctx, _("Do you really want to continue"), 0); if (!cont) { - printf (_("check aborted.\n")); + printf("%s", _("check aborted.\n")); exit (0); } return; @@ -262,7 +288,7 @@ static int is_on_batt(void) f = fopen("/sys/class/power_supply/AC/online", "r"); if (f) { - if (fscanf(f, "%d\n", &acflag) == 1) { + if (fscanf(f, "%u\n", &acflag) == 1) { fclose(f); return (!acflag); } @@ -315,6 +341,9 @@ static void check_if_skip(e2fsck_t ctx) int broken_system_clock; time_t lastcheck; + if (ctx->flags & E2F_FLAG_PROBLEMS_FIXED) + return; + profile_get_boolean(ctx->profile, "options", "broken_system_clock", 0, 0, &broken_system_clock); if (ctx->flags & E2F_FLAG_TIME_INSANE) @@ -366,7 +395,7 @@ static void check_if_skip(e2fsck_t ctx) if (reason) { log_out(ctx, "%s", ctx->device_name); log_out(ctx, reason, reason_arg); - log_out(ctx, _(", check forced.\n")); + log_out(ctx, "%s", _(", check forced.\n")); return; } @@ -418,17 +447,18 @@ static void check_if_skip(e2fsck_t ctx) if (next_check <= 5) { if (next_check == 1) { if (batt) - log_out(ctx, _(" (check deferred; " - "on battery)")); + log_out(ctx, "%s", + _(" (check deferred; on battery)")); else - log_out(ctx, _(" (check after next mount)")); + log_out(ctx, "%s", + _(" (check after next mount)")); } else - log_out(ctx, _(" (check in %ld mounts)"), next_check); + log_out(ctx, _(" (check in %ld mounts)"), + next_check); } log_out(ctx, "\n"); skip: - ext2fs_close(fs); - ctx->fs = NULL; + ext2fs_close_free(&ctx->fs); e2fsck_free_context(ctx); exit(FSCK_OK); } @@ -440,7 +470,7 @@ struct percent_tbl { int max_pass; int table[32]; }; -struct percent_tbl e2fsck_tbl = { +static struct percent_tbl e2fsck_tbl = { 5, { 0, 70, 90, 92, 95, 100 } }; static char bar[128], spaces[128]; @@ -459,7 +489,7 @@ static float calc_percent(struct percent_tbl *tbl, int pass, int curr, + tbl->table[pass-1]); } -extern void e2fsck_clear_progbar(e2fsck_t ctx) +void e2fsck_clear_progbar(e2fsck_t ctx) { if (!(ctx->flags & E2F_FLAG_PROG_BAR)) return; @@ -641,7 +671,7 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) ea_ver = strtoul(arg, &p, 0); if (*p || ((ea_ver != 1) && (ea_ver != 2))) { - fprintf(stderr, + fprintf(stderr, "%s", _("Invalid EA version.\n")); extended_usage++; continue; @@ -725,6 +755,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) return retval; *ret_ctx = ctx; + e2fsck_global_ctx = ctx; setvbuf(stdout, NULL, _IONBF, BUFSIZ); setvbuf(stderr, NULL, _IONBF, BUFSIZ); @@ -847,6 +878,8 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) case 'L': replace_bad_blocks++; case 'l': + if (bad_blocks_file) + free(bad_blocks_file); bad_blocks_file = string_copy(ctx, optarg, 0); break; case 'd': @@ -884,17 +917,17 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) usage(ctx); if ((ctx->options & E2F_OPT_NO) && (ctx->options & E2F_OPT_COMPRESS_DIRS)) { - com_err(ctx->program_name, 0, + com_err(ctx->program_name, 0, "%s", _("The -n and -D options are incompatible.")); fatal_error(ctx, 0); } if ((ctx->options & E2F_OPT_NO) && cflag) { - com_err(ctx->program_name, 0, + com_err(ctx->program_name, 0, "%s", _("The -n and -c options are incompatible.")); fatal_error(ctx, 0); } if ((ctx->options & E2F_OPT_NO) && bad_blocks_file) { - com_err(ctx->program_name, 0, + com_err(ctx->program_name, 0, "%s", _("The -n and -l/-L options are incompatible.")); fatal_error(ctx, 0); } @@ -918,6 +951,15 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) profile_set_syntax_err_cb(syntax_err_report); profile_init(config_fn, &ctx->profile); + profile_get_boolean(ctx->profile, "options", "report_time", 0, 0, + &c); + if (c) + ctx->options |= E2F_OPT_TIME | E2F_OPT_TIME2; + profile_get_boolean(ctx->profile, "options", "report_verbose", 0, 0, + &c); + if (c) + verbose = 1; + /* Turn off discard in read-only mode */ if ((ctx->options & E2F_OPT_NO) && (ctx->options & E2F_OPT_DISCARD)) @@ -940,8 +982,8 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) close(fd); } if (cflag && bad_blocks_file) { - fprintf(stderr, _("The -c and the -l/-L options may " - "not be both used at the same time.\n")); + fprintf(stderr, "%s", _("The -c and the -l/-L options may not " + "be both used at the same time.\n")); exit(FSCK_USAGE); } #ifdef HAVE_SIGNAL_H @@ -955,7 +997,6 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) #ifdef SA_RESTART sa.sa_flags = SA_RESTART; #endif - e2fsck_global_ctx = ctx; sa.sa_handler = signal_progress_on; sigaction(SIGUSR1, &sa, 0); sa.sa_handler = signal_progress_off; @@ -1031,16 +1072,18 @@ static errcode_t try_open_fs(e2fsck_t ctx, int flags, io_manager io_ptr, retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options, flags, 0, 0, io_ptr, ret_fs); - if (ret_fs) + if (retval == 0) { + (*ret_fs)->priv_data = ctx; e2fsck_set_bitmap_type(*ret_fs, EXT2FS_BMAP64_RBTREE, "default", NULL); + } return retval; } static const char *my_ver_string = E2FSPROGS_VERSION; static const char *my_ver_date = E2FSPROGS_DATE; -int e2fsck_check_mmp(ext2_filsys fs, e2fsck_t ctx) +static errcode_t e2fsck_check_mmp(ext2_filsys fs, e2fsck_t ctx) { struct mmp_struct *mmp_s; unsigned int mmp_check_interval; @@ -1102,12 +1145,12 @@ check_error: retval = 0; } } else if (retval == EXT2_ET_MMP_FAILED) { - com_err(ctx->program_name, retval, + com_err(ctx->program_name, retval, "%s", _("while checking MMP block")); dump_mmp_msg(fs->mmp_buf, NULL); } else if (retval == EXT2_ET_MMP_FSCK_ON || retval == EXT2_ET_MMP_UNKNOWN_SEQ) { - com_err(ctx->program_name, retval, + com_err(ctx->program_name, retval, "%s", _("while checking MMP block")); dump_mmp_msg(fs->mmp_buf, _("If you are sure the filesystem is not " @@ -1132,14 +1175,15 @@ int main (int argc, char *argv[]) const char *lib_ver_date; int my_ver, lib_ver; e2fsck_t ctx; - blk_t orig_superblock; + blk64_t orig_superblock; struct problem_context pctx; - int flags, run_result; + int flags, run_result, was_changed; int journal_size; int sysval, sys_page_size = 4096; int old_bitmaps; __u32 features[3]; char *cp; + int qtype = -99; /* quota type */ clear_problem_context(&pctx); sigcatcher_setup(); @@ -1159,14 +1203,14 @@ int main (int argc, char *argv[]) my_ver = ext2fs_parse_version_string(my_ver_string); lib_ver = ext2fs_get_library_version(0, &lib_ver_date); if (my_ver > lib_ver) { - fprintf( stderr, _("Error: ext2fs library version " - "out of date!\n")); + fprintf( stderr, "%s", + _("Error: ext2fs library version out of date!\n")); show_version_only++; } retval = PRS(argc, argv, &ctx); if (retval) { - com_err("e2fsck", retval, + com_err("e2fsck", retval, "%s", _("while trying to initialize program")); exit(FSCK_ERROR); } @@ -1220,11 +1264,17 @@ restart: &old_bitmaps); if (!old_bitmaps) flags |= EXT2_FLAG_64BITS; - if ((ctx->options & E2F_OPT_READONLY) == 0) + if ((ctx->options & E2F_OPT_READONLY) == 0) { flags |= EXT2_FLAG_RW; - if ((ctx->mount_flags & EXT2_MF_MOUNTED) == 0) - flags |= EXT2_FLAG_EXCLUSIVE; + if (!(ctx->mount_flags & EXT2_MF_ISROOT && + ctx->mount_flags & EXT2_MF_READONLY)) + flags |= EXT2_FLAG_EXCLUSIVE; + if ((ctx->mount_flags & EXT2_MF_READONLY) && + (ctx->options & E2F_OPT_FORCE)) + flags &= ~EXT2_FLAG_EXCLUSIVE; + } + ctx->openfs_flags = flags; retval = try_open_fs(ctx, flags, io_ptr, &fs); if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) && @@ -1257,12 +1307,12 @@ restart: orig_superblock = ctx->superblock; get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr); if (fs) - ext2fs_close(fs); + ext2fs_close_free(&fs); orig_retval = retval; retval = try_open_fs(ctx, flags, io_ptr, &fs); if ((orig_retval == 0) && retval != 0) { if (fs) - ext2fs_close(fs); + ext2fs_close_free(&fs); log_out(ctx, _("%s: %s while using the " "backup blocks"), ctx->program_name, @@ -1295,32 +1345,34 @@ failure: com_err(ctx->program_name, retval, _("while trying to open %s"), ctx->filesystem_name); if (retval == EXT2_ET_REV_TOO_HIGH) { - log_out(ctx, _("The filesystem revision is apparently " - "too high for this version of e2fsck.\n" - "(Or the filesystem superblock " - "is corrupt)\n\n")); + log_out(ctx, "%s", + _("The filesystem revision is apparently " + "too high for this version of e2fsck.\n" + "(Or the filesystem superblock " + "is corrupt)\n\n")); fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); } else if (retval == EXT2_ET_SHORT_READ) - log_out(ctx, _("Could this be a zero-length " - "partition?\n")); + log_out(ctx, "%s", + _("Could this be a zero-length partition?\n")); else if ((retval == EPERM) || (retval == EACCES)) log_out(ctx, _("You must have %s access to the " - "filesystem or be root\n"), + "filesystem or be root\n"), (ctx->options & E2F_OPT_READONLY) ? "r/o" : "r/w"); else if (retval == ENXIO) - log_out(ctx, _("Possibly non-existent or " - "swap device?\n")); + log_out(ctx, "%s", + _("Possibly non-existent or swap device?\n")); else if (retval == EBUSY) - log_out(ctx, _("Filesystem mounted or opened " - "exclusively by another program?\n")); + log_out(ctx, "%s", _("Filesystem mounted or opened " + "exclusively by another program?\n")); else if (retval == ENOENT) - log_out(ctx, _("Possibly non-existent device?\n")); + log_out(ctx, "%s", + _("Possibly non-existent device?\n")); #ifdef EROFS else if (retval == EROFS) - log_out(ctx, _("Disk write-protected; use the -n " - "option to do a read-only\n" - "check of the device.\n")); + log_out(ctx, "%s", _("Disk write-protected; use the " + "-n option to do a read-only\n" + "check of the device.\n")); #endif else fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); @@ -1354,7 +1406,7 @@ failure: * reopen the filesystem after we get the device size. */ if (pctx.errcode == EBUSY) { - ext2fs_close(fs); + ext2fs_close_free(&fs); need_restart++; pctx.errcode = ext2fs_get_device_size2(ctx->filesystem_name, @@ -1374,7 +1426,6 @@ failure: } ctx->fs = fs; - fs->priv_data = ctx; fs->now = ctx->now; sb = fs->super; @@ -1411,8 +1462,7 @@ failure: /* * Restart in order to reopen fs but this time start mmp. */ - ext2fs_close(fs); - ctx->fs = NULL; + ext2fs_close_free(&ctx->fs); flags &= ~EXT2_FLAG_SKIP_MMP; goto restart; } @@ -1421,10 +1471,6 @@ failure: fprintf(ctx->logf, "Filesystem UUID: %s\n", e2p_uuid2str(sb->s_uuid)); - if ((ctx->mount_flags & EXT2_MF_MOUNTED) && - !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) - goto skip_journal; - /* * Make sure the ext3 superblock fields are consistent. */ @@ -1442,9 +1488,9 @@ failure: */ if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { if (ctx->options & E2F_OPT_READONLY) { - log_out(ctx, _("Warning: skipping journal recovery " - "because doing a read-only filesystem " - "check.\n")); + log_out(ctx, "%s", + _("Warning: skipping journal recovery because " + "doing a read-only filesystem check.\n")); io_channel_flush(ctx->fs->io); } else { if (ctx->flags & E2F_FLAG_RESTARTED) { @@ -1455,7 +1501,8 @@ failure: * device driver is being bogus. */ com_err(ctx->program_name, 0, - _("unable to set superblock flags on %s\n"), ctx->device_name); + _("unable to set superblock flags " + "on %s\n"), ctx->device_name); fatal_error(ctx, 0); } retval = e2fsck_run_ext3_journal(ctx); @@ -1465,14 +1512,12 @@ failure: ctx->device_name); fatal_error(ctx, 0); } - ext2fs_close(ctx->fs); - ctx->fs = 0; + ext2fs_close_free(&ctx->fs); ctx->flags |= E2F_FLAG_RESTARTED; goto restart; } } -skip_journal: /* * Check for compatibility with the feature sets. We need to * be more stringent than ext2fs_open(). @@ -1562,8 +1607,8 @@ print_unsupp_features: log_out(ctx, _("%s: %s while reading bad blocks inode\n"), ctx->program_name, error_message(retval)); preenhalt(ctx); - log_out(ctx, _("This doesn't bode well, " - "but we'll try to go on...\n")); + log_out(ctx, "%s", _("This doesn't bode well, " + "but we'll try to go on...\n")); } /* @@ -1578,7 +1623,6 @@ print_unsupp_features: journal_size = -1; if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_QUOTA) { - int qtype; /* Quotas were enabled. Do quota accounting during fsck. */ if ((sb->s_usr_quota_inum && sb->s_grp_quota_inum) || (!sb->s_usr_quota_inum && !sb->s_grp_quota_inum)) @@ -1592,7 +1636,8 @@ print_unsupp_features: run_result = e2fsck_run(ctx); e2fsck_clear_progbar(ctx); - if (ctx->flags & E2F_FLAG_JOURNAL_INODE) { + if (!ctx->invalid_bitmaps && + (ctx->flags & E2F_FLAG_JOURNAL_INODE)) { if (fix_problem(ctx, PR_6_RECREATE_JOURNAL, &pctx)) { if (journal_size < 1024) journal_size = ext2fs_default_journal_size(ext2fs_blocks_count(fs->super)); @@ -1614,45 +1659,85 @@ print_unsupp_features: "journal\n", error_message(retval)); goto no_journal; } - log_out(ctx, _(" Done.\n")); - log_out(ctx, _("\n*** journal has been re-created - " - "filesystem is now ext3 again ***\n")); + log_out(ctx, "%s", _(" Done.\n")); + log_out(ctx, "%s", + _("\n*** journal has been re-created - " + "filesystem is now ext3 again ***\n")); } } no_journal: - if (ctx->qctx) { - quota_write_inode(ctx->qctx, -1); + if (run_result & E2F_FLAG_ABORT) { + fatal_error(ctx, _("aborted")); + } else if (run_result & E2F_FLAG_CANCEL) { + log_out(ctx, _("%s: e2fsck canceled.\n"), ctx->device_name ? + ctx->device_name : ctx->filesystem_name); + exit_value |= FSCK_CANCELED; + } else if (ctx->qctx && !ctx->invalid_bitmaps) { + int i, needs_writeout; + + for (i = 0; i < MAXQUOTAS; i++) { + if (qtype != -1 && qtype != i) + continue; + needs_writeout = 0; + pctx.num = i; + retval = quota_compare_and_update(ctx->qctx, i, + &needs_writeout); + if ((retval || needs_writeout) && + fix_problem(ctx, PR_6_UPDATE_QUOTAS, &pctx)) + quota_write_inode(ctx->qctx, i); + } quota_release_context(&ctx->qctx); } if (run_result == E2F_FLAG_RESTART) { - log_out(ctx, _("Restarting e2fsck from the beginning...\n")); + log_out(ctx, "%s", + _("Restarting e2fsck from the beginning...\n")); retval = e2fsck_reset_context(ctx); if (retval) { - com_err(ctx->program_name, retval, + com_err(ctx->program_name, retval, "%s", _("while resetting context")); fatal_error(ctx, 0); } - ext2fs_close(fs); + ext2fs_close_free(&ctx->fs); goto restart; } - if (run_result & E2F_FLAG_CANCEL) { - log_out(ctx, _("%s: e2fsck canceled.\n"), ctx->device_name ? - ctx->device_name : ctx->filesystem_name); - exit_value |= FSCK_CANCELED; - } - if (run_result & E2F_FLAG_ABORT) - fatal_error(ctx, _("aborted")); - if (check_backup_super_block(ctx)) { - fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; - ext2fs_mark_super_dirty(fs); - } #ifdef MTRACE mtrace_print("Cleanup"); #endif - if (ext2fs_test_changed(fs)) { + was_changed = ext2fs_test_changed(fs); + if (!(ctx->flags & E2F_FLAG_RUN_RETURN) && + !(ctx->options & E2F_OPT_READONLY)) { + if (ext2fs_test_valid(fs)) { + if (!(sb->s_state & EXT2_VALID_FS)) + exit_value |= FSCK_NONDESTRUCT; + sb->s_state = EXT2_VALID_FS; + if (check_backup_super_block(ctx)) + fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; + } else + sb->s_state &= ~EXT2_VALID_FS; + if (!(ctx->flags & E2F_FLAG_TIME_INSANE)) + sb->s_lastcheck = ctx->now; + sb->s_mnt_count = 0; + memset(((char *) sb) + EXT4_S_ERR_START, 0, EXT4_S_ERR_LEN); + pctx.errcode = ext2fs_set_gdt_csum(ctx->fs); + if (pctx.errcode) + fix_problem(ctx, PR_6_SET_BG_CHECKSUM, &pctx); + ext2fs_mark_super_dirty(fs); + } + + e2fsck_write_bitmaps(ctx); + if (fs->flags & EXT2_FLAG_DIRTY) { + pctx.errcode = ext2fs_flush(ctx->fs); + if (pctx.errcode) + fix_problem(ctx, PR_6_FLUSH_FILESYSTEM, &pctx); + } + pctx.errcode = io_channel_flush(ctx->fs->io); + if (pctx.errcode) + fix_problem(ctx, PR_6_IO_FLUSH, &pctx); + + if (was_changed) { exit_value |= FSCK_NONDESTRUCT; if (!(ctx->options & E2F_OPT_PREEN)) log_out(ctx, _("\n%s: ***** FILE SYSTEM WAS " @@ -1683,41 +1768,12 @@ no_journal: (sb->s_state & EXT2_VALID_FS) && !(sb->s_state & EXT2_ERROR_FS)) exit_value = 0; - } else { + } else show_stats(ctx); - if (!(ctx->options & E2F_OPT_READONLY)) { - if (ext2fs_test_valid(fs)) { - if (!(sb->s_state & EXT2_VALID_FS)) - exit_value |= FSCK_NONDESTRUCT; - sb->s_state = EXT2_VALID_FS; - } else - sb->s_state &= ~EXT2_VALID_FS; - sb->s_mnt_count = 0; - if (!(ctx->flags & E2F_FLAG_TIME_INSANE)) - sb->s_lastcheck = ctx->now; - memset(((char *) sb) + EXT4_S_ERR_START, 0, - EXT4_S_ERR_LEN); - ext2fs_mark_super_dirty(fs); - } - } - if ((run_result & E2F_FLAG_CANCEL) == 0 && - sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM && - !(ctx->options & E2F_OPT_READONLY)) { - retval = ext2fs_set_gdt_csum(ctx->fs); - if (retval) { - com_err(ctx->program_name, retval, - _("while setting block group checksum info")); - fatal_error(ctx, 0); - } - } - - e2fsck_write_bitmaps(ctx); - io_channel_flush(ctx->fs->io); print_resource_track(ctx, NULL, &ctx->global_rtrack, ctx->fs->io); - ext2fs_close(fs); - ctx->fs = NULL; + ext2fs_close_free(&ctx->fs); free(ctx->journal_name); e2fsck_free_context(ctx);