]>
Commit | Line | Data |
---|---|---|
3839e657 TT |
1 | /* |
2 | * e2fsck.c - a consistency checker for the new extended file system. | |
efc6f628 | 3 | * |
21c84b71 TT |
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% | |
3839e657 TT |
10 | */ |
11 | ||
d1154eb4 | 12 | #include "config.h" |
50e1e10f | 13 | #include <errno.h> |
3839e657 | 14 | |
3839e657 | 15 | #include "e2fsck.h" |
21c84b71 | 16 | #include "problem.h" |
3839e657 TT |
17 | |
18 | /* | |
efc6f628 | 19 | * This function allocates an e2fsck context |
3839e657 | 20 | */ |
1b6bf175 | 21 | errcode_t e2fsck_allocate_context(e2fsck_t *ret) |
3839e657 | 22 | { |
1b6bf175 | 23 | e2fsck_t context; |
08b21301 | 24 | errcode_t retval; |
1f3ad14a | 25 | char *time_env; |
3839e657 | 26 | |
c4e3d3f3 | 27 | retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context); |
08b21301 TT |
28 | if (retval) |
29 | return retval; | |
efc6f628 | 30 | |
1b6bf175 | 31 | memset(context, 0, sizeof(struct e2fsck_struct)); |
3839e657 | 32 | |
1b6bf175 | 33 | context->process_inode_size = 256; |
0684a4f3 | 34 | context->ext_attr_ver = 2; |
9f0288d3 | 35 | context->blocks_per_page = 1; |
7dca4c88 | 36 | context->htree_slack_percentage = 255; |
efc6f628 | 37 | |
1f3ad14a TT |
38 | time_env = getenv("E2FSCK_TIME"); |
39 | if (time_env) | |
40 | context->now = strtoul(time_env, NULL, 0); | |
177839e2 | 41 | else { |
1f3ad14a | 42 | context->now = time(0); |
177839e2 TT |
43 | if (context->now < 1262322000) /* January 1 2010 */ |
44 | context->flags |= E2F_FLAG_TIME_INSANE; | |
45 | } | |
3839e657 | 46 | |
1b6bf175 TT |
47 | *ret = context; |
48 | return 0; | |
3839e657 | 49 | } |
521e3685 | 50 | |
1b6bf175 TT |
51 | /* |
52 | * This function resets an e2fsck context; it is called when e2fsck | |
53 | * needs to be restarted. | |
54 | */ | |
55 | errcode_t e2fsck_reset_context(e2fsck_t ctx) | |
3839e657 | 56 | { |
8da6d1a1 TT |
57 | int i; |
58 | ||
177839e2 | 59 | ctx->flags &= E2F_RESET_FLAGS; |
850d05e9 TT |
60 | ctx->lost_and_found = 0; |
61 | ctx->bad_lost_and_found = 0; | |
1b6bf175 TT |
62 | if (ctx->inode_used_map) { |
63 | ext2fs_free_inode_bitmap(ctx->inode_used_map); | |
64 | ctx->inode_used_map = 0; | |
5c576477 | 65 | } |
1b6bf175 TT |
66 | if (ctx->inode_dir_map) { |
67 | ext2fs_free_inode_bitmap(ctx->inode_dir_map); | |
68 | ctx->inode_dir_map = 0; | |
3839e657 | 69 | } |
aa4115a4 TT |
70 | if (ctx->inode_reg_map) { |
71 | ext2fs_free_inode_bitmap(ctx->inode_reg_map); | |
7142db08 | 72 | ctx->inode_reg_map = 0; |
aa4115a4 | 73 | } |
1b6bf175 TT |
74 | if (ctx->block_found_map) { |
75 | ext2fs_free_block_bitmap(ctx->block_found_map); | |
76 | ctx->block_found_map = 0; | |
21c84b71 | 77 | } |
1b6bf175 TT |
78 | if (ctx->inode_link_info) { |
79 | ext2fs_free_icount(ctx->inode_link_info); | |
80 | ctx->inode_link_info = 0; | |
3839e657 | 81 | } |
adee8d75 | 82 | if (ctx->journal_io) { |
1e16526b | 83 | if (ctx->fs && ctx->fs->io != ctx->journal_io) |
adee8d75 TT |
84 | io_channel_close(ctx->journal_io); |
85 | ctx->journal_io = 0; | |
86 | } | |
1dde43f0 | 87 | if (ctx->fs && ctx->fs->dblist) { |
1b6bf175 TT |
88 | ext2fs_free_dblist(ctx->fs->dblist); |
89 | ctx->fs->dblist = 0; | |
21c84b71 | 90 | } |
08b21301 | 91 | e2fsck_free_dir_info(ctx); |
8fdc9985 | 92 | e2fsck_free_dx_dir_info(ctx); |
342d847d TT |
93 | if (ctx->refcount) { |
94 | ea_refcount_free(ctx->refcount); | |
95 | ctx->refcount = 0; | |
96 | } | |
97 | if (ctx->refcount_extra) { | |
98 | ea_refcount_free(ctx->refcount_extra); | |
99 | ctx->refcount_extra = 0; | |
100 | } | |
0b4ffc27 TE |
101 | if (ctx->ea_block_quota_blocks) { |
102 | ea_refcount_free(ctx->ea_block_quota_blocks); | |
103 | ctx->ea_block_quota_blocks = 0; | |
104 | } | |
105 | if (ctx->ea_block_quota_inodes) { | |
106 | ea_refcount_free(ctx->ea_block_quota_inodes); | |
107 | ctx->ea_block_quota_inodes = 0; | |
b0f457bd | 108 | } |
5c5685d1 TE |
109 | if (ctx->ea_inode_refs) { |
110 | ea_refcount_free(ctx->ea_inode_refs); | |
111 | ctx->ea_inode_refs = 0; | |
112 | } | |
1b6bf175 TT |
113 | if (ctx->block_dup_map) { |
114 | ext2fs_free_block_bitmap(ctx->block_dup_map); | |
115 | ctx->block_dup_map = 0; | |
f3db3566 | 116 | } |
342d847d TT |
117 | if (ctx->block_ea_map) { |
118 | ext2fs_free_block_bitmap(ctx->block_ea_map); | |
119 | ctx->block_ea_map = 0; | |
120 | } | |
35c8faaf DW |
121 | if (ctx->block_metadata_map) { |
122 | ext2fs_free_block_bitmap(ctx->block_metadata_map); | |
123 | ctx->block_metadata_map = 0; | |
124 | } | |
1b6bf175 TT |
125 | if (ctx->inode_bb_map) { |
126 | ext2fs_free_inode_bitmap(ctx->inode_bb_map); | |
127 | ctx->inode_bb_map = 0; | |
521e3685 | 128 | } |
1b6bf175 TT |
129 | if (ctx->inode_bad_map) { |
130 | ext2fs_free_inode_bitmap(ctx->inode_bad_map); | |
131 | ctx->inode_bad_map = 0; | |
1e3472c5 | 132 | } |
aa4115a4 TT |
133 | if (ctx->inode_imagic_map) { |
134 | ext2fs_free_inode_bitmap(ctx->inode_imagic_map); | |
135 | ctx->inode_imagic_map = 0; | |
136 | } | |
b7a00563 TT |
137 | if (ctx->dirs_to_hash) { |
138 | ext2fs_u32_list_free(ctx->dirs_to_hash); | |
139 | ctx->dirs_to_hash = 0; | |
140 | } | |
1e3472c5 | 141 | |
3839e657 | 142 | /* |
1b6bf175 | 143 | * Clear the array of invalid meta-data flags |
3839e657 | 144 | */ |
1b6bf175 | 145 | if (ctx->invalid_inode_bitmap_flag) { |
c4e3d3f3 | 146 | ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag); |
1b6bf175 TT |
147 | ctx->invalid_inode_bitmap_flag = 0; |
148 | } | |
149 | if (ctx->invalid_block_bitmap_flag) { | |
c4e3d3f3 | 150 | ext2fs_free_mem(&ctx->invalid_block_bitmap_flag); |
1b6bf175 TT |
151 | ctx->invalid_block_bitmap_flag = 0; |
152 | } | |
153 | if (ctx->invalid_inode_table_flag) { | |
c4e3d3f3 | 154 | ext2fs_free_mem(&ctx->invalid_inode_table_flag); |
1b6bf175 TT |
155 | ctx->invalid_inode_table_flag = 0; |
156 | } | |
dbff534e TT |
157 | if (ctx->encrypted_dirs) { |
158 | ext2fs_u32_list_free(ctx->encrypted_dirs); | |
159 | ctx->encrypted_dirs = 0; | |
160 | } | |
a54733d2 TT |
161 | if (ctx->inode_count) { |
162 | ext2fs_free_icount(ctx->inode_count); | |
163 | ctx->inode_count = 0; | |
164 | } | |
1b6bf175 TT |
165 | |
166 | /* Clear statistic counters */ | |
167 | ctx->fs_directory_count = 0; | |
168 | ctx->fs_regular_count = 0; | |
169 | ctx->fs_blockdev_count = 0; | |
170 | ctx->fs_chardev_count = 0; | |
171 | ctx->fs_links_count = 0; | |
172 | ctx->fs_symlinks_count = 0; | |
173 | ctx->fs_fast_symlinks_count = 0; | |
174 | ctx->fs_fifo_count = 0; | |
175 | ctx->fs_total_count = 0; | |
176 | ctx->fs_badblocks_count = 0; | |
177 | ctx->fs_sockets_count = 0; | |
178 | ctx->fs_ind_count = 0; | |
179 | ctx->fs_dind_count = 0; | |
180 | ctx->fs_tind_count = 0; | |
181 | ctx->fs_fragmented = 0; | |
ce44d8ca | 182 | ctx->fs_fragmented_dir = 0; |
246501c6 | 183 | ctx->large_files = 0; |
1b6bf175 | 184 | |
8da6d1a1 TT |
185 | for (i=0; i < MAX_EXTENT_DEPTH_COUNT; i++) |
186 | ctx->extent_depth_count[i] = 0; | |
187 | ||
1b6bf175 TT |
188 | /* Reset the superblock to the user's requested value */ |
189 | ctx->superblock = ctx->use_superblock; | |
efc6f628 | 190 | |
1b6bf175 TT |
191 | return 0; |
192 | } | |
3839e657 | 193 | |
1b6bf175 TT |
194 | void e2fsck_free_context(e2fsck_t ctx) |
195 | { | |
196 | if (!ctx) | |
197 | return; | |
efc6f628 | 198 | |
1b6bf175 | 199 | e2fsck_reset_context(ctx); |
f364093b TT |
200 | if (ctx->blkid) |
201 | blkid_put_cache(ctx->blkid); | |
1017f651 TT |
202 | |
203 | if (ctx->profile) | |
204 | profile_release(ctx->profile); | |
1dc506cb TT |
205 | |
206 | if (ctx->filesystem_name) | |
207 | ext2fs_free_mem(&ctx->filesystem_name); | |
efc6f628 | 208 | |
1dc506cb TT |
209 | if (ctx->device_name) |
210 | ext2fs_free_mem(&ctx->device_name); | |
efc6f628 | 211 | |
b0e91c89 TT |
212 | if (ctx->log_fn) |
213 | free(ctx->log_fn); | |
214 | ||
7a2a0145 TT |
215 | if (ctx->logf) |
216 | fclose(ctx->logf); | |
217 | ||
d2dd606f TT |
218 | if (ctx->problem_log_fn) |
219 | free(ctx->problem_log_fn); | |
220 | ||
7cc9cdea TT |
221 | if (ctx->problem_logf) { |
222 | fputs("</problem_log>\n", ctx->problem_logf); | |
d2dd606f | 223 | fclose(ctx->problem_logf); |
7cc9cdea | 224 | } |
c4e3d3f3 | 225 | ext2fs_free_mem(&ctx); |
3839e657 | 226 | } |
08b21301 TT |
227 | |
228 | /* | |
229 | * This function runs through the e2fsck passes and calls them all, | |
230 | * returning restart, abort, or cancel as necessary... | |
231 | */ | |
232 | typedef void (*pass_t)(e2fsck_t ctx); | |
233 | ||
f404167d | 234 | static pass_t e2fsck_passes[] = { |
e228d700 DW |
235 | e2fsck_pass1, e2fsck_pass1e, e2fsck_pass2, e2fsck_pass3, |
236 | e2fsck_pass4, e2fsck_pass5, 0 }; | |
08b21301 TT |
237 | |
238 | int e2fsck_run(e2fsck_t ctx) | |
239 | { | |
240 | int i; | |
241 | pass_t e2fsck_pass; | |
242 | ||
243 | #ifdef HAVE_SETJMP_H | |
bbbc92f2 TT |
244 | if (setjmp(ctx->abort_loc)) { |
245 | ctx->flags &= ~E2F_FLAG_SETJMP_OK; | |
2df1f6aa | 246 | return (ctx->flags & E2F_FLAG_RUN_RETURN); |
bbbc92f2 | 247 | } |
08b21301 TT |
248 | ctx->flags |= E2F_FLAG_SETJMP_OK; |
249 | #endif | |
efc6f628 | 250 | |
08b21301 | 251 | for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) { |
2df1f6aa | 252 | if (ctx->flags & E2F_FLAG_RUN_RETURN) |
08b21301 | 253 | break; |
0f5eba75 AD |
254 | if (e2fsck_mmp_update(ctx->fs)) |
255 | fatal_error(ctx, 0); | |
08b21301 | 256 | e2fsck_pass(ctx); |
f75c28de TT |
257 | if (ctx->progress) |
258 | (void) (ctx->progress)(ctx, 0, 0, 0); | |
08b21301 TT |
259 | } |
260 | ctx->flags &= ~E2F_FLAG_SETJMP_OK; | |
efc6f628 | 261 | |
2df1f6aa TT |
262 | if (ctx->flags & E2F_FLAG_RUN_RETURN) |
263 | return (ctx->flags & E2F_FLAG_RUN_RETURN); | |
08b21301 TT |
264 | return 0; |
265 | } |