X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Funix.c;h=a43f0c9b7989907b392bddf03a7bbcb04269c60a;hb=931b58e1cb2158c1f5218059cce92e94917ef485;hp=e62960285ed4647391427136559c3c202994d8da;hpb=4efbac6fed75c29d3d5f1b676b932754653a2ac5;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/unix.c b/e2fsck/unix.c index e629602..a43f0c9 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -101,9 +101,9 @@ static void show_stats(e2fsck_t ctx) { ext2_filsys fs = ctx->fs; ext2_ino_t inodes, inodes_used; - blk_t blocks, blocks_used; - int dir_links; - int num_files, num_links; + blk64_t blocks, blocks_used; + unsigned int dir_links; + unsigned int num_files, num_links; int frag_percent_file, frag_percent_dir, frag_percent_total; int i, j; @@ -129,7 +129,7 @@ static void show_stats(e2fsck_t ctx) frag_percent_total = (frag_percent_total + 5) / 10; if (!verbose) { - printf(_("%s: %u/%u files (%0d.%d%% non-contiguous), %u/%u blocks\n"), + printf(_("%s: %u/%u files (%0d.%d%% non-contiguous), %llu/%llu blocks\n"), ctx->device_name, inodes_used, inodes, frag_percent_total / 10, frag_percent_total % 10, blocks_used, blocks); @@ -163,7 +163,8 @@ static void show_stats(e2fsck_t ctx) fputc('\n', stdout); } - printf (P_("%8u block used (%2.2f%%)\n", "%8u blocks used (%2.2f%%)\n", + printf (P_("%8llu block used (%2.2f%%)\n", + "%8llu blocks used (%2.2f%%)\n", blocks_used), blocks_used, 100.0 * blocks_used / blocks); printf (P_("%8u bad block\n", "%8u bad blocks\n", ctx->fs_badblocks_count), ctx->fs_badblocks_count); @@ -230,9 +231,9 @@ static void check_mount(e2fsck_t ctx) if (!ctx->interactive) fatal_error(ctx, _("Cannot continue, aborting.\n\n")); printf(_("\n\n\007\007\007\007WARNING!!! " - "Running e2fsck on a mounted filesystem may cause\n" - "SEVERE filesystem damage.\007\007\007\n\n")); - cont = ask_yn(_("Do you really want to continue"), -1); + "The filesystem is mounted. If you continue you ***WILL***\n" + "cause ***SEVERE*** filesystem damage.\007\007\007\n\n")); + cont = ask_yn(_("Do you really want to continue"), 0); if (!cont) { printf (_("check aborted.\n")); exit (0); @@ -291,8 +292,13 @@ static void check_if_skip(e2fsck_t ctx) long next_check; int batt = is_on_batt(); int defer_check_on_battery; + int broken_system_clock; time_t lastcheck; + profile_get_boolean(ctx->profile, "options", "broken_system_clock", + 0, 0, &broken_system_clock); + if (ctx->flags & E2F_FLAG_TIME_INSANE) + broken_system_clock = 1; profile_get_boolean(ctx->profile, "options", "defer_check_on_battery", 0, 1, &defer_check_on_battery); @@ -302,6 +308,9 @@ static void check_if_skip(e2fsck_t ctx) if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file || cflag) return; + if (ctx->options & E2F_OPT_JOURNAL_ONLY) + goto skip; + lastcheck = fs->super->s_lastcheck; if (lastcheck > ctx->now) lastcheck -= ctx->time_fudge; @@ -320,11 +329,12 @@ static void check_if_skip(e2fsck_t ctx) if (batt && (fs->super->s_mnt_count < (unsigned) fs->super->s_max_mnt_count*2)) reason = 0; - } else if (fs->super->s_checkinterval && (ctx->now < lastcheck)) { + } else if (!broken_system_clock && fs->super->s_checkinterval && + (ctx->now < lastcheck)) { reason = _(" has filesystem last checked time in the future"); if (batt) reason = 0; - } else if (fs->super->s_checkinterval && + } else if (!broken_system_clock && fs->super->s_checkinterval && ((ctx->now - lastcheck) >= ((time_t) fs->super->s_checkinterval))) { reason = _(" has gone %u days without being checked"); @@ -351,7 +361,7 @@ static void check_if_skip(e2fsck_t ctx) if (next_check <= 0) next_check = 1; } - if (fs->super->s_checkinterval && + if (!broken_system_clock && fs->super->s_checkinterval && ((ctx->now - fs->super->s_lastcheck) >= fs->super->s_checkinterval)) next_check = 1; if (next_check <= 5) { @@ -365,6 +375,7 @@ static void check_if_skip(e2fsck_t ctx) printf(_(" (check in %ld mounts)"), next_check); } fputc('\n', stdout); +skip: ext2fs_close(fs); ctx->fs = NULL; e2fsck_free_context(ctx); @@ -587,6 +598,18 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) } else if (strcmp(token, "fragcheck") == 0) { ctx->options |= E2F_OPT_FRAGCHECK; continue; + } else if (strcmp(token, "journal_only") == 0) { + if (arg) { + extended_usage++; + continue; + } + ctx->options |= E2F_OPT_JOURNAL_ONLY; + } else if (strcmp(token, "discard") == 0) { + ctx->options |= E2F_OPT_DISCARD; + continue; + } else if (strcmp(token, "nodiscard") == 0) { + ctx->options &= ~E2F_OPT_DISCARD; + continue; } else { fprintf(stderr, _("Unknown extended option: %s\n"), token); @@ -602,6 +625,9 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) "Valid extended options are:\n"), stderr); fputs(("\tea_ver=\n"), stderr); fputs(("\tfragcheck\n"), stderr); + fputs(("\tjournal_only\n"), stderr); + fputs(("\tdiscard\n"), stderr); + fputs(("\tnodiscard\n"), stderr); fputc('\n', stderr); exit(1); } @@ -660,6 +686,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) ctx->program_name = *argv; else ctx->program_name = "e2fsck"; + while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF) switch (c) { case 'C': @@ -731,7 +758,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) /* What we do by default, anyway! */ break; case 'b': - res = sscanf(optarg, "%u", &ctx->use_superblock); + res = sscanf(optarg, "%llu", &ctx->use_superblock); if (res != 1) goto sscanf_err; ctx->flags |= E2F_FLAG_SB_SPECIFIED; @@ -745,7 +772,14 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) goto sscanf_err; break; case 'j': - ctx->journal_name = string_copy(ctx, optarg, 0); + ctx->journal_name = blkid_get_devname(ctx->blkid, + optarg, NULL); + if (!ctx->journal_name) { + com_err(ctx->program_name, 0, + _("Unable to resolve '%s'"), + optarg); + fatal_error(ctx, 0); + } break; case 'P': res = sscanf(optarg, "%d", &ctx->process_inode_size); @@ -790,8 +824,23 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) return 0; if (optind != argc - 1) usage(ctx); - if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file && - !cflag && !(ctx->options & E2F_OPT_COMPRESS_DIRS)) + if ((ctx->options & E2F_OPT_NO) && + (ctx->options & E2F_OPT_COMPRESS_DIRS)) { + com_err(ctx->program_name, 0, + _("The -n and -D options are incompatible.")); + fatal_error(ctx, 0); + } + if ((ctx->options & E2F_OPT_NO) && cflag) { + com_err(ctx->program_name, 0, + _("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, + _("The -n and -l/-L options are incompatible.")); + fatal_error(ctx, 0); + } + if (ctx->options & E2F_OPT_NO) ctx->options |= E2F_OPT_READONLY; ctx->io_options = strchr(argv[optind], '?'); @@ -921,7 +970,6 @@ static errcode_t try_open_fs(e2fsck_t ctx, int flags, io_manager io_ptr, return retval; } - static const char *my_ver_string = E2FSPROGS_VERSION; static const char *my_ver_date = E2FSPROGS_DATE; @@ -1039,6 +1087,8 @@ restart: orig_retval = retval; retval = try_open_fs(ctx, flags, io_ptr, &fs); if ((orig_retval == 0) && retval != 0) { + if (fs) + ext2fs_close(fs); com_err(ctx->program_name, retval, "when using the backup blocks"); printf(_("%s: going back to original " @@ -1085,6 +1135,8 @@ failure: else if (retval == EBUSY) printf(_("Filesystem mounted or opened exclusively " "by another program?\n")); + else if (retval == ENOENT) + printf(_("Possibly non-existent device?\n")); #ifdef EROFS else if (retval == EROFS) printf(_("Disk write-protected; use the -n option " @@ -1112,9 +1164,9 @@ failure: __u32 blocksize = EXT2_BLOCK_SIZE(fs->super); int need_restart = 0; - pctx.errcode = ext2fs_get_device_size(ctx->filesystem_name, - blocksize, - &ctx->num_blocks); + pctx.errcode = ext2fs_get_device_size2(ctx->filesystem_name, + blocksize, + &ctx->num_blocks); /* * The floppy driver refuses to allow anyone else to * open the device if has been opened with O_EXCL; @@ -1126,9 +1178,9 @@ failure: ext2fs_close(fs); need_restart++; pctx.errcode = - ext2fs_get_device_size(ctx->filesystem_name, - blocksize, - &ctx->num_blocks); + ext2fs_get_device_size2(ctx->filesystem_name, + blocksize, + &ctx->num_blocks); } if (pctx.errcode == EXT2_ET_UNIMPLEMENTED) ctx->num_blocks = 0; @@ -1322,7 +1374,8 @@ print_unsupp_features: * find the default journal size. */ if (sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) - journal_size = sb->s_jnl_blocks[16] >> 20; + journal_size = (sb->s_jnl_blocks[15] << (32 - 20)) | + (sb->s_jnl_blocks[16] >> 20); else journal_size = -1; @@ -1424,12 +1477,16 @@ no_journal: } else sb->s_state &= ~EXT2_VALID_FS; sb->s_mnt_count = 0; - sb->s_lastcheck = ctx->now; + 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 (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM && + 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) {