Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 1 | /* |
| 2 | * e2fsck.c - a consistency checker for the new extended file system. |
| 3 | * |
Theodore Ts'o | 21c84b7 | 1997-04-29 16:15:03 +0000 | [diff] [blame] | 4 | * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o. |
| 5 | * |
| 6 | * %Begin-Header% |
| 7 | * This file may be redistributed under the terms of the GNU Public |
| 8 | * License. |
| 9 | * %End-Header% |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 10 | */ |
| 11 | |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 12 | #include <errno.h> |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 13 | |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 14 | #include "e2fsck.h" |
Theodore Ts'o | 21c84b7 | 1997-04-29 16:15:03 +0000 | [diff] [blame] | 15 | #include "problem.h" |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 16 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 17 | /* |
| 18 | * This function allocates an e2fsck context |
| 19 | */ |
| 20 | errcode_t e2fsck_allocate_context(e2fsck_t *ret) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 21 | { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 22 | e2fsck_t context; |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 23 | errcode_t retval; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 24 | |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 25 | retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), |
| 26 | (void **) &context); |
| 27 | if (retval) |
| 28 | return retval; |
| 29 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 30 | memset(context, 0, sizeof(struct e2fsck_struct)); |
Theodore Ts'o | 7f88b04 | 1997-04-26 14:48:50 +0000 | [diff] [blame] | 31 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 32 | context->process_inode_size = 256; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 33 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 34 | *ret = context; |
| 35 | return 0; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 36 | } |
| 37 | |
| 38 | /* |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 39 | * This function resets an e2fsck context; it is called when e2fsck |
| 40 | * needs to be restarted. |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 41 | */ |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 42 | errcode_t e2fsck_reset_context(e2fsck_t ctx) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 43 | { |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 44 | ctx->flags = 0; |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 45 | if (ctx->inode_used_map) { |
| 46 | ext2fs_free_inode_bitmap(ctx->inode_used_map); |
| 47 | ctx->inode_used_map = 0; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 48 | } |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 49 | if (ctx->inode_dir_map) { |
| 50 | ext2fs_free_inode_bitmap(ctx->inode_dir_map); |
| 51 | ctx->inode_dir_map = 0; |
| 52 | } |
Theodore Ts'o | aa4115a | 1999-10-21 19:33:18 +0000 | [diff] [blame] | 53 | if (ctx->inode_reg_map) { |
| 54 | ext2fs_free_inode_bitmap(ctx->inode_reg_map); |
Theodore Ts'o | 7142db0 | 1999-11-08 18:46:54 +0000 | [diff] [blame] | 55 | ctx->inode_reg_map = 0; |
Theodore Ts'o | aa4115a | 1999-10-21 19:33:18 +0000 | [diff] [blame] | 56 | } |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 57 | if (ctx->block_found_map) { |
| 58 | ext2fs_free_block_bitmap(ctx->block_found_map); |
| 59 | ctx->block_found_map = 0; |
| 60 | } |
| 61 | if (ctx->inode_link_info) { |
| 62 | ext2fs_free_icount(ctx->inode_link_info); |
| 63 | ctx->inode_link_info = 0; |
| 64 | } |
Theodore Ts'o | 1dde43f | 1998-11-14 04:18:28 +0000 | [diff] [blame] | 65 | if (ctx->fs && ctx->fs->dblist) { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 66 | ext2fs_free_dblist(ctx->fs->dblist); |
| 67 | ctx->fs->dblist = 0; |
| 68 | } |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 69 | e2fsck_free_dir_info(ctx); |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 70 | if (ctx->block_dup_map) { |
| 71 | ext2fs_free_block_bitmap(ctx->block_dup_map); |
| 72 | ctx->block_dup_map = 0; |
| 73 | } |
| 74 | if (ctx->inode_bb_map) { |
| 75 | ext2fs_free_inode_bitmap(ctx->inode_bb_map); |
| 76 | ctx->inode_bb_map = 0; |
| 77 | } |
| 78 | if (ctx->inode_bad_map) { |
| 79 | ext2fs_free_inode_bitmap(ctx->inode_bad_map); |
| 80 | ctx->inode_bad_map = 0; |
| 81 | } |
Theodore Ts'o | aa4115a | 1999-10-21 19:33:18 +0000 | [diff] [blame] | 82 | if (ctx->inode_imagic_map) { |
| 83 | ext2fs_free_inode_bitmap(ctx->inode_imagic_map); |
| 84 | ctx->inode_imagic_map = 0; |
| 85 | } |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 86 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 87 | /* |
| 88 | * Clear the array of invalid meta-data flags |
| 89 | */ |
| 90 | if (ctx->invalid_inode_bitmap_flag) { |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 91 | ext2fs_free_mem((void **) &ctx->invalid_inode_bitmap_flag); |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 92 | ctx->invalid_inode_bitmap_flag = 0; |
| 93 | } |
| 94 | if (ctx->invalid_block_bitmap_flag) { |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 95 | ext2fs_free_mem((void **) &ctx->invalid_block_bitmap_flag); |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 96 | ctx->invalid_block_bitmap_flag = 0; |
| 97 | } |
| 98 | if (ctx->invalid_inode_table_flag) { |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 99 | ext2fs_free_mem((void **) &ctx->invalid_inode_table_flag); |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 100 | ctx->invalid_inode_table_flag = 0; |
| 101 | } |
Theodore Ts'o | 50e1e10 | 1997-04-26 13:58:21 +0000 | [diff] [blame] | 102 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 103 | /* Clear statistic counters */ |
| 104 | ctx->fs_directory_count = 0; |
| 105 | ctx->fs_regular_count = 0; |
| 106 | ctx->fs_blockdev_count = 0; |
| 107 | ctx->fs_chardev_count = 0; |
| 108 | ctx->fs_links_count = 0; |
| 109 | ctx->fs_symlinks_count = 0; |
| 110 | ctx->fs_fast_symlinks_count = 0; |
| 111 | ctx->fs_fifo_count = 0; |
| 112 | ctx->fs_total_count = 0; |
| 113 | ctx->fs_badblocks_count = 0; |
| 114 | ctx->fs_sockets_count = 0; |
| 115 | ctx->fs_ind_count = 0; |
| 116 | ctx->fs_dind_count = 0; |
| 117 | ctx->fs_tind_count = 0; |
| 118 | ctx->fs_fragmented = 0; |
Theodore Ts'o | 246501c | 1998-03-24 16:22:38 +0000 | [diff] [blame] | 119 | ctx->large_files = 0; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 120 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 121 | /* Reset the superblock to the user's requested value */ |
| 122 | ctx->superblock = ctx->use_superblock; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 123 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 124 | return 0; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 125 | } |
Theodore Ts'o | 521e368 | 1997-04-29 17:48:10 +0000 | [diff] [blame] | 126 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 127 | void e2fsck_free_context(e2fsck_t ctx) |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 128 | { |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 129 | if (!ctx) |
| 130 | return; |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 131 | |
Theodore Ts'o | 1b6bf17 | 1997-10-03 17:48:10 +0000 | [diff] [blame] | 132 | e2fsck_reset_context(ctx); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 133 | |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 134 | ext2fs_free_mem((void **) &ctx); |
Theodore Ts'o | 3839e65 | 1997-04-26 13:21:57 +0000 | [diff] [blame] | 135 | } |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 136 | |
| 137 | /* |
| 138 | * This function runs through the e2fsck passes and calls them all, |
| 139 | * returning restart, abort, or cancel as necessary... |
| 140 | */ |
| 141 | typedef void (*pass_t)(e2fsck_t ctx); |
| 142 | |
| 143 | pass_t e2fsck_passes[] = { |
| 144 | e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4, |
| 145 | e2fsck_pass5, 0 }; |
| 146 | |
Theodore Ts'o | 2df1f6a | 1998-02-27 05:03:48 +0000 | [diff] [blame] | 147 | #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART) |
| 148 | |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 149 | int e2fsck_run(e2fsck_t ctx) |
| 150 | { |
| 151 | int i; |
| 152 | pass_t e2fsck_pass; |
| 153 | |
| 154 | #ifdef HAVE_SETJMP_H |
| 155 | if (setjmp(ctx->abort_loc)) |
Theodore Ts'o | 2df1f6a | 1998-02-27 05:03:48 +0000 | [diff] [blame] | 156 | return (ctx->flags & E2F_FLAG_RUN_RETURN); |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 157 | ctx->flags |= E2F_FLAG_SETJMP_OK; |
| 158 | #endif |
| 159 | |
| 160 | for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) { |
Theodore Ts'o | 2df1f6a | 1998-02-27 05:03:48 +0000 | [diff] [blame] | 161 | if (ctx->flags & E2F_FLAG_RUN_RETURN) |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 162 | break; |
| 163 | e2fsck_pass(ctx); |
Theodore Ts'o | f75c28d | 1998-08-01 04:18:06 +0000 | [diff] [blame] | 164 | if (ctx->progress) |
| 165 | (void) (ctx->progress)(ctx, 0, 0, 0); |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 166 | } |
| 167 | ctx->flags &= ~E2F_FLAG_SETJMP_OK; |
| 168 | |
Theodore Ts'o | 2df1f6a | 1998-02-27 05:03:48 +0000 | [diff] [blame] | 169 | if (ctx->flags & E2F_FLAG_RUN_RETURN) |
| 170 | return (ctx->flags & E2F_FLAG_RUN_RETURN); |
Theodore Ts'o | 08b2130 | 1997-11-03 19:42:40 +0000 | [diff] [blame] | 171 | return 0; |
| 172 | } |
| 173 | |
| 174 | |
| 175 | |
| 176 | |
| 177 | |
| 178 | |