X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;ds=sidebyside;f=e2fsck%2Fe2fsck.c;h=26f7b5e5831ce043ce7cf974a6005f3cb153fe5e;hb=8a8f36540bbf5d4397cf476e216e9a720b5c1d8e;hp=592541b0ff2e7e373d00b1a5ef03e19d02299d68;hpb=1b6bf1759af884957234b7dce768b785f792abd0;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c index 592541b..26f7b5e 100644 --- a/e2fsck/e2fsck.c +++ b/e2fsck/e2fsck.c @@ -1,6 +1,6 @@ /* * e2fsck.c - a consistency checker for the new extended file system. - * + * * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. * * %Begin-Header% @@ -11,25 +11,34 @@ #include -#include "et/com_err.h" - #include "e2fsck.h" #include "problem.h" /* - * This function allocates an e2fsck context + * This function allocates an e2fsck context */ errcode_t e2fsck_allocate_context(e2fsck_t *ret) { e2fsck_t context; + errcode_t retval; + char *time_env; - context = malloc(sizeof(struct e2fsck_struct)); - if (!context) - return ENOMEM; + retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context); + if (retval) + return retval; memset(context, 0, sizeof(struct e2fsck_struct)); context->process_inode_size = 256; + context->ext_attr_ver = 2; + context->blocks_per_page = 1; + context->htree_slack_percentage = 255; + + time_env = getenv("E2FSCK_TIME"); + if (time_env) + context->now = strtoul(time_env, NULL, 0); + else + context->now = time(0); *ret = context; return 0; @@ -41,6 +50,11 @@ errcode_t e2fsck_allocate_context(e2fsck_t *ret) */ errcode_t e2fsck_reset_context(e2fsck_t ctx) { + int i; + + ctx->flags = 0; + ctx->lost_and_found = 0; + ctx->bad_lost_and_found = 0; if (ctx->inode_used_map) { ext2fs_free_inode_bitmap(ctx->inode_used_map); ctx->inode_used_map = 0; @@ -49,6 +63,10 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx) ext2fs_free_inode_bitmap(ctx->inode_dir_map); ctx->inode_dir_map = 0; } + if (ctx->inode_reg_map) { + ext2fs_free_inode_bitmap(ctx->inode_reg_map); + ctx->inode_reg_map = 0; + } if (ctx->block_found_map) { ext2fs_free_block_bitmap(ctx->block_found_map); ctx->block_found_map = 0; @@ -57,15 +75,35 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx) ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0; } - if (ctx->fs->dblist) { + if (ctx->journal_io) { + if (ctx->fs && ctx->fs->io != ctx->journal_io) + io_channel_close(ctx->journal_io); + ctx->journal_io = 0; + } + if (ctx->fs && ctx->fs->dblist) { ext2fs_free_dblist(ctx->fs->dblist); ctx->fs->dblist = 0; } - free_dir_info(ctx->fs); + e2fsck_free_dir_info(ctx); +#ifdef ENABLE_HTREE + e2fsck_free_dx_dir_info(ctx); +#endif + if (ctx->refcount) { + ea_refcount_free(ctx->refcount); + ctx->refcount = 0; + } + if (ctx->refcount_extra) { + ea_refcount_free(ctx->refcount_extra); + ctx->refcount_extra = 0; + } if (ctx->block_dup_map) { ext2fs_free_block_bitmap(ctx->block_dup_map); ctx->block_dup_map = 0; } + if (ctx->block_ea_map) { + ext2fs_free_block_bitmap(ctx->block_ea_map); + ctx->block_ea_map = 0; + } if (ctx->inode_bb_map) { ext2fs_free_inode_bitmap(ctx->inode_bb_map); ctx->inode_bb_map = 0; @@ -74,20 +112,28 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx) ext2fs_free_inode_bitmap(ctx->inode_bad_map); ctx->inode_bad_map = 0; } + if (ctx->inode_imagic_map) { + ext2fs_free_inode_bitmap(ctx->inode_imagic_map); + ctx->inode_imagic_map = 0; + } + if (ctx->dirs_to_hash) { + ext2fs_u32_list_free(ctx->dirs_to_hash); + ctx->dirs_to_hash = 0; + } /* * Clear the array of invalid meta-data flags */ if (ctx->invalid_inode_bitmap_flag) { - free(ctx->invalid_inode_bitmap_flag); + ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag); ctx->invalid_inode_bitmap_flag = 0; } if (ctx->invalid_block_bitmap_flag) { - free(ctx->invalid_block_bitmap_flag); + ext2fs_free_mem(&ctx->invalid_block_bitmap_flag); ctx->invalid_block_bitmap_flag = 0; } if (ctx->invalid_inode_table_flag) { - free(ctx->invalid_inode_table_flag); + ext2fs_free_mem(&ctx->invalid_inode_table_flag); ctx->invalid_inode_table_flag = 0; } @@ -107,10 +153,15 @@ errcode_t e2fsck_reset_context(e2fsck_t ctx) ctx->fs_dind_count = 0; ctx->fs_tind_count = 0; ctx->fs_fragmented = 0; + ctx->fs_fragmented_dir = 0; + ctx->large_files = 0; + + for (i=0; i < MAX_EXTENT_DEPTH_COUNT; i++) + ctx->extent_depth_count[i] = 0; /* Reset the superblock to the user's requested value */ ctx->superblock = ctx->use_superblock; - + return 0; } @@ -118,8 +169,58 @@ void e2fsck_free_context(e2fsck_t ctx) { if (!ctx) return; - + e2fsck_reset_context(ctx); - - free(ctx); + if (ctx->blkid) + blkid_put_cache(ctx->blkid); + + if (ctx->profile) + profile_release(ctx->profile); + + if (ctx->filesystem_name) + ext2fs_free_mem(&ctx->filesystem_name); + + if (ctx->device_name) + ext2fs_free_mem(&ctx->device_name); + + ext2fs_free_mem(&ctx); +} + +/* + * This function runs through the e2fsck passes and calls them all, + * returning restart, abort, or cancel as necessary... + */ +typedef void (*pass_t)(e2fsck_t ctx); + +pass_t e2fsck_passes[] = { + e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4, + e2fsck_pass5, 0 }; + +#define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART) + +int e2fsck_run(e2fsck_t ctx) +{ + int i; + pass_t e2fsck_pass; + +#ifdef HAVE_SETJMP_H + if (setjmp(ctx->abort_loc)) { + ctx->flags &= ~E2F_FLAG_SETJMP_OK; + return (ctx->flags & E2F_FLAG_RUN_RETURN); + } + ctx->flags |= E2F_FLAG_SETJMP_OK; +#endif + + for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) { + if (ctx->flags & E2F_FLAG_RUN_RETURN) + break; + e2fsck_pass(ctx); + if (ctx->progress) + (void) (ctx->progress)(ctx, 0, 0, 0); + } + ctx->flags &= ~E2F_FLAG_SETJMP_OK; + + if (ctx->flags & E2F_FLAG_RUN_RETURN) + return (ctx->flags & E2F_FLAG_RUN_RETURN); + return 0; }