X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Funix.c;h=7b662e49919057a8a4d2a3021847bb78d4842354;hb=49a7360ba6b986242d9f0f33e102291d2e0dfb47;hp=3d91049ccbc8c5f94734b1420dbb70859dcc632f;hpb=1a855cb21f3c5d1c1b0acaf2beab879e9b5cd118;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/unix.c b/e2fsck/unix.c index 3d91049..7b662e4 100644 --- a/e2fsck/unix.c +++ b/e2fsck/unix.c @@ -258,6 +258,7 @@ static void check_if_skip(e2fsck_t ctx) long next_check; int batt = is_on_batt(); int defer_check_on_battery; + time_t lastcheck; profile_get_boolean(ctx->profile, "options", "defer_check_on_battery", 0, 1, @@ -268,11 +269,16 @@ static void check_if_skip(e2fsck_t ctx) if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file || cflag) return; + lastcheck = fs->super->s_lastcheck; + if (lastcheck > ctx->now) + lastcheck -= ctx->time_fudge; if ((fs->super->s_state & EXT2_ERROR_FS) || !ext2fs_test_valid(fs)) reason = _(" contains a file system with errors"); else if ((fs->super->s_state & EXT2_VALID_FS) == 0) reason = _(" was not cleanly unmounted"); + else if (check_backup_super_block(ctx)) + reason = _(" primary superblock features different from backup"); else if ((fs->super->s_max_mnt_count > 0) && (fs->super->s_mnt_count >= (unsigned) fs->super->s_max_mnt_count)) { @@ -282,8 +288,7 @@ static void check_if_skip(e2fsck_t ctx) (unsigned) fs->super->s_max_mnt_count*2)) reason = 0; } else if (fs->super->s_checkinterval && - ((ctx->now - fs->super->s_lastcheck) >= - fs->super->s_checkinterval)) { + ((ctx->now - lastcheck) >= fs->super->s_checkinterval)) { reason = _(" has gone %u days without being checked"); reason_arg = (ctx->now - fs->super->s_lastcheck)/(3600*24); if (batt && ((ctx->now - fs->super->s_lastcheck) < @@ -553,7 +558,9 @@ static void parse_extended_opts(e2fsck_t ctx, const char *opts) "and may take an argument which\n" "is set off by an equals ('=') sign. " "Valid extended options are:\n" - "\tea_ver=\n\n"), stderr); + "\tea_ver=\n" + "\tuninit_groups\n" + "\tinit_groups\n\n"), stderr); exit(1); } } @@ -582,6 +589,10 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) #endif char *extended_opts = 0; char *cp; + int res; /* result of sscanf */ +#ifdef CONFIG_JBD_DEBUG + char *jbd_debug; +#endif retval = e2fsck_allocate_context(&ctx); if (retval) @@ -611,7 +622,10 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) switch (c) { case 'C': ctx->progress = e2fsck_update_progress; - ctx->progress_fd = atoi(optarg); + res = sscanf(optarg, "%d", &ctx->progress_fd); + if (res != 1) + goto sscanf_err; + if (!ctx->progress_fd) break; /* Validate the file descriptor to avoid disasters */ @@ -671,20 +685,26 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) /* What we do by default, anyway! */ break; case 'b': - ctx->use_superblock = atoi(optarg); + res = sscanf(optarg, "%d", &ctx->use_superblock); + if (res != 1) + goto sscanf_err; ctx->flags |= E2F_FLAG_SB_SPECIFIED; break; case 'B': ctx->blocksize = atoi(optarg); break; case 'I': - ctx->inode_buffer_blocks = atoi(optarg); + res = sscanf(optarg, "%d", &ctx->inode_buffer_blocks); + if (res != 1) + goto sscanf_err; break; case 'j': ctx->journal_name = string_copy(ctx, optarg, 0); break; case 'P': - ctx->process_inode_size = atoi(optarg); + res = sscanf(optarg, "%d", &ctx->process_inode_size); + if (res != 1) + goto sscanf_err; break; case 'L': replace_bad_blocks++; @@ -727,6 +747,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file && !cflag && !(ctx->options & E2F_OPT_COMPRESS_DIRS)) ctx->options |= E2F_OPT_READONLY; + ctx->io_options = strchr(argv[optind], '?'); if (ctx->io_options) *ctx->io_options++ = 0; @@ -804,18 +825,31 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) putenv(newpath); } #ifdef CONFIG_JBD_DEBUG - if (getenv("E2FSCK_JBD_DEBUG")) - journal_enable_debug = atoi(getenv("E2FSCK_JBD_DEBUG")); + jbd_debug = getenv("E2FSCK_JBD_DEBUG"); + if (jbd_debug) { + res = sscanf(jbd_debug, "%d", &journal_enable_debug); + if (res != 1) { + fprintf(stderr, + _("E2FSCK_JBD_DEBUG \"%s\" not an integer\n\n"), + jbd_debug); + exit (1); + } + } #endif return 0; + +sscanf_err: + fprintf(stderr, _("\nInvalid non-numeric argument to -%c (\"%s\")\n\n"), + c, optarg); + exit (1); } static const char *my_ver_string = E2FSPROGS_VERSION; static const char *my_ver_date = E2FSPROGS_DATE; - + int main (int argc, char *argv[]) { - errcode_t retval = 0; + errcode_t retval = 0, orig_retval = 0; int exit_value = FSCK_OK; ext2_filsys fs = 0; io_manager io_ptr; @@ -827,6 +861,7 @@ int main (int argc, char *argv[]) int flags, run_result; int journal_size; int sysval, sys_page_size = 4096; + __u32 features[3]; clear_problem_context(&pctx); #ifdef MTRACE @@ -888,7 +923,7 @@ restart: #else io_ptr = unix_io_manager; #endif - flags = 0; + flags = EXT2_FLAG_NOFREE_ON_ERROR; if ((ctx->options & E2F_OPT_READONLY) == 0) flags |= EXT2_FLAG_RW; if ((ctx->mount_flags & EXT2_MF_MOUNTED) == 0) @@ -915,18 +950,40 @@ restart: if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) && !(ctx->flags & E2F_FLAG_SB_SPECIFIED) && ((retval == EXT2_ET_BAD_MAGIC) || + (retval == EXT2_ET_CORRUPT_SUPERBLOCK) || ((retval == 0) && ext2fs_check_desc(fs)))) { + if (fs->flags & EXT2_FLAG_NOFREE_ON_ERROR) { + ext2fs_free(fs); + fs = NULL; + } if (!fs || (fs->group_desc_count > 1)) { - printf(_("%s trying backup blocks...\n"), - retval ? _("Couldn't find ext2 superblock,") : + printf(_("%s: %s trying backup blocks...\n"), + ctx->program_name, + retval ? _("Superblock invalid,") : _("Group descriptors look bad...")); get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr); if (fs) ext2fs_close(fs); + orig_retval = retval; goto restart; } } + if (((retval == EXT2_ET_UNSUPP_FEATURE) || + (retval == EXT2_ET_RO_UNSUPP_FEATURE)) && + fs && fs->super) { + sb = fs->super; + features[0] = (sb->s_feature_compat & + ~EXT2_LIB_FEATURE_COMPAT_SUPP); + features[1] = (sb->s_feature_incompat & + ~EXT2_LIB_FEATURE_INCOMPAT_SUPP); + features[2] = (sb->s_feature_ro_compat & + ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP); + if (features[0] || features[1] || features[2]) + goto print_unsupp_features; + } if (retval) { + if (orig_retval) + retval = orig_retval; com_err(ctx->program_name, retval, _("while trying to open %s"), ctx->filesystem_name); if (retval == EXT2_ET_REV_TOO_HIGH) { @@ -1079,15 +1136,26 @@ restart: * Check for compatibility with the feature sets. We need to * be more stringent than ext2fs_open(). */ - if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) || - (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) { - com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE, - "(%s)", ctx->device_name); - goto get_newer; - } - if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) { - com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE, - "(%s)", ctx->device_name); + features[0] = sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP; + features[1] = sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP; + features[2] = (sb->s_feature_ro_compat & + ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP); +print_unsupp_features: + if (features[0] || features[1] || features[2]) { + int i, j; + __u32 *mask = features, m; + + fprintf(stderr, _("%s has unsupported feature(s):"), + ctx->filesystem_name); + + for (i=0; i <3; i++,mask++) { + for (j=0,m=1; j < 32; j++, m<<=1) { + if (*mask & m) + fprintf(stderr, " %s", + e2p_feature2string(i, m)); + } + } + putc('\n', stderr); goto get_newer; } #ifdef ENABLE_COMPRESSION @@ -1178,6 +1246,7 @@ restart: if (journal_size < 0) { fs->super->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; + fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; com_err(ctx->program_name, 0, _("Couldn't determine journal size")); goto no_journal; @@ -1217,6 +1286,10 @@ no_journal: } 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"); @@ -1266,6 +1339,10 @@ no_journal: } } + if (sb->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM && + !(ctx->options & E2F_OPT_READONLY)) + ext2fs_set_gdt_csum(ctx->fs); + e2fsck_write_bitmaps(ctx); #ifdef RESOURCE_TRACK io_channel_flush(ctx->fs->io);