2 * e2fsck.c - a consistency checker for the new extended file system.
4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Public
19 * This function allocates an e2fsck context
21 errcode_t
e2fsck_allocate_context(e2fsck_t
*ret
)
27 retval
= ext2fs_get_mem(sizeof(struct e2fsck_struct
), &context
);
31 memset(context
, 0, sizeof(struct e2fsck_struct
));
33 context
->process_inode_size
= 256;
34 context
->ext_attr_ver
= 2;
35 context
->blocks_per_page
= 1;
36 context
->htree_slack_percentage
= 255;
38 time_env
= getenv("E2FSCK_TIME");
40 context
->now
= strtoul(time_env
, NULL
, 0);
42 context
->now
= time(0);
43 if (context
->now
< 1262322000) /* January 1 2010 */
44 context
->flags
|= E2F_FLAG_TIME_INSANE
;
52 * This function resets an e2fsck context; it is called when e2fsck
53 * needs to be restarted.
55 errcode_t
e2fsck_reset_context(e2fsck_t ctx
)
59 ctx
->flags
&= E2F_RESET_FLAGS
;
60 ctx
->lost_and_found
= 0;
61 ctx
->bad_lost_and_found
= 0;
62 if (ctx
->inode_used_map
) {
63 ext2fs_free_inode_bitmap(ctx
->inode_used_map
);
64 ctx
->inode_used_map
= 0;
66 if (ctx
->inode_dir_map
) {
67 ext2fs_free_inode_bitmap(ctx
->inode_dir_map
);
68 ctx
->inode_dir_map
= 0;
70 if (ctx
->inode_reg_map
) {
71 ext2fs_free_inode_bitmap(ctx
->inode_reg_map
);
72 ctx
->inode_reg_map
= 0;
74 if (ctx
->block_found_map
) {
75 ext2fs_free_block_bitmap(ctx
->block_found_map
);
76 ctx
->block_found_map
= 0;
78 if (ctx
->inode_link_info
) {
79 ext2fs_free_icount(ctx
->inode_link_info
);
80 ctx
->inode_link_info
= 0;
82 if (ctx
->journal_io
) {
83 if (ctx
->fs
&& ctx
->fs
->io
!= ctx
->journal_io
)
84 io_channel_close(ctx
->journal_io
);
87 if (ctx
->fs
&& ctx
->fs
->dblist
) {
88 ext2fs_free_dblist(ctx
->fs
->dblist
);
91 e2fsck_free_dir_info(ctx
);
92 e2fsck_free_dx_dir_info(ctx
);
94 ea_refcount_free(ctx
->refcount
);
97 if (ctx
->refcount_extra
) {
98 ea_refcount_free(ctx
->refcount_extra
);
99 ctx
->refcount_extra
= 0;
101 if (ctx
->ea_block_quota_blocks
) {
102 ea_refcount_free(ctx
->ea_block_quota_blocks
);
103 ctx
->ea_block_quota_blocks
= 0;
105 if (ctx
->ea_block_quota_inodes
) {
106 ea_refcount_free(ctx
->ea_block_quota_inodes
);
107 ctx
->ea_block_quota_inodes
= 0;
109 if (ctx
->ea_inode_refs
) {
110 ea_refcount_free(ctx
->ea_inode_refs
);
111 ctx
->ea_inode_refs
= 0;
113 if (ctx
->block_dup_map
) {
114 ext2fs_free_block_bitmap(ctx
->block_dup_map
);
115 ctx
->block_dup_map
= 0;
117 if (ctx
->block_ea_map
) {
118 ext2fs_free_block_bitmap(ctx
->block_ea_map
);
119 ctx
->block_ea_map
= 0;
121 if (ctx
->block_metadata_map
) {
122 ext2fs_free_block_bitmap(ctx
->block_metadata_map
);
123 ctx
->block_metadata_map
= 0;
125 if (ctx
->inode_bb_map
) {
126 ext2fs_free_inode_bitmap(ctx
->inode_bb_map
);
127 ctx
->inode_bb_map
= 0;
129 if (ctx
->inode_bad_map
) {
130 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
131 ctx
->inode_bad_map
= 0;
133 if (ctx
->inode_imagic_map
) {
134 ext2fs_free_inode_bitmap(ctx
->inode_imagic_map
);
135 ctx
->inode_imagic_map
= 0;
137 if (ctx
->dirs_to_hash
) {
138 ext2fs_u32_list_free(ctx
->dirs_to_hash
);
139 ctx
->dirs_to_hash
= 0;
143 * Clear the array of invalid meta-data flags
145 if (ctx
->invalid_inode_bitmap_flag
) {
146 ext2fs_free_mem(&ctx
->invalid_inode_bitmap_flag
);
147 ctx
->invalid_inode_bitmap_flag
= 0;
149 if (ctx
->invalid_block_bitmap_flag
) {
150 ext2fs_free_mem(&ctx
->invalid_block_bitmap_flag
);
151 ctx
->invalid_block_bitmap_flag
= 0;
153 if (ctx
->invalid_inode_table_flag
) {
154 ext2fs_free_mem(&ctx
->invalid_inode_table_flag
);
155 ctx
->invalid_inode_table_flag
= 0;
157 if (ctx
->encrypted_dirs
) {
158 ext2fs_u32_list_free(ctx
->encrypted_dirs
);
159 ctx
->encrypted_dirs
= 0;
161 if (ctx
->inode_count
) {
162 ext2fs_free_icount(ctx
->inode_count
);
163 ctx
->inode_count
= 0;
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;
182 ctx
->fs_fragmented_dir
= 0;
183 ctx
->large_files
= 0;
185 for (i
=0; i
< MAX_EXTENT_DEPTH_COUNT
; i
++)
186 ctx
->extent_depth_count
[i
] = 0;
188 /* Reset the superblock to the user's requested value */
189 ctx
->superblock
= ctx
->use_superblock
;
194 void e2fsck_free_context(e2fsck_t ctx
)
199 e2fsck_reset_context(ctx
);
201 blkid_put_cache(ctx
->blkid
);
204 profile_release(ctx
->profile
);
206 if (ctx
->filesystem_name
)
207 ext2fs_free_mem(&ctx
->filesystem_name
);
209 if (ctx
->device_name
)
210 ext2fs_free_mem(&ctx
->device_name
);
218 if (ctx
->problem_log_fn
)
219 free(ctx
->problem_log_fn
);
221 if (ctx
->problem_logf
) {
222 fputs("</problem_log>\n", ctx
->problem_logf
);
223 fclose(ctx
->problem_logf
);
225 ext2fs_free_mem(&ctx
);
229 * This function runs through the e2fsck passes and calls them all,
230 * returning restart, abort, or cancel as necessary...
232 typedef void (*pass_t
)(e2fsck_t ctx
);
234 static pass_t e2fsck_passes
[] = {
235 e2fsck_pass1
, e2fsck_pass1e
, e2fsck_pass2
, e2fsck_pass3
,
236 e2fsck_pass4
, e2fsck_pass5
, 0 };
238 int e2fsck_run(e2fsck_t ctx
)
244 if (setjmp(ctx
->abort_loc
)) {
245 ctx
->flags
&= ~E2F_FLAG_SETJMP_OK
;
246 return (ctx
->flags
& E2F_FLAG_RUN_RETURN
);
248 ctx
->flags
|= E2F_FLAG_SETJMP_OK
;
251 for (i
=0; (e2fsck_pass
= e2fsck_passes
[i
]); i
++) {
252 if (ctx
->flags
& E2F_FLAG_RUN_RETURN
)
254 if (e2fsck_mmp_update(ctx
->fs
))
258 (void) (ctx
->progress
)(ctx
, 0, 0, 0);
260 ctx
->flags
&= ~E2F_FLAG_SETJMP_OK
;
262 if (ctx
->flags
& E2F_FLAG_RUN_RETURN
)
263 return (ctx
->flags
& E2F_FLAG_RUN_RETURN
);