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
);
93 e2fsck_free_dx_dir_info(ctx
);
96 ea_refcount_free(ctx
->refcount
);
99 if (ctx
->refcount_extra
) {
100 ea_refcount_free(ctx
->refcount_extra
);
101 ctx
->refcount_extra
= 0;
103 if (ctx
->block_dup_map
) {
104 ext2fs_free_block_bitmap(ctx
->block_dup_map
);
105 ctx
->block_dup_map
= 0;
107 if (ctx
->block_ea_map
) {
108 ext2fs_free_block_bitmap(ctx
->block_ea_map
);
109 ctx
->block_ea_map
= 0;
111 if (ctx
->block_metadata_map
) {
112 ext2fs_free_block_bitmap(ctx
->block_metadata_map
);
113 ctx
->block_metadata_map
= 0;
115 if (ctx
->inode_bb_map
) {
116 ext2fs_free_inode_bitmap(ctx
->inode_bb_map
);
117 ctx
->inode_bb_map
= 0;
119 if (ctx
->inode_bad_map
) {
120 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
121 ctx
->inode_bad_map
= 0;
123 if (ctx
->inode_imagic_map
) {
124 ext2fs_free_inode_bitmap(ctx
->inode_imagic_map
);
125 ctx
->inode_imagic_map
= 0;
127 if (ctx
->dirs_to_hash
) {
128 ext2fs_u32_list_free(ctx
->dirs_to_hash
);
129 ctx
->dirs_to_hash
= 0;
133 * Clear the array of invalid meta-data flags
135 if (ctx
->invalid_inode_bitmap_flag
) {
136 ext2fs_free_mem(&ctx
->invalid_inode_bitmap_flag
);
137 ctx
->invalid_inode_bitmap_flag
= 0;
139 if (ctx
->invalid_block_bitmap_flag
) {
140 ext2fs_free_mem(&ctx
->invalid_block_bitmap_flag
);
141 ctx
->invalid_block_bitmap_flag
= 0;
143 if (ctx
->invalid_inode_table_flag
) {
144 ext2fs_free_mem(&ctx
->invalid_inode_table_flag
);
145 ctx
->invalid_inode_table_flag
= 0;
148 /* Clear statistic counters */
149 ctx
->fs_directory_count
= 0;
150 ctx
->fs_regular_count
= 0;
151 ctx
->fs_blockdev_count
= 0;
152 ctx
->fs_chardev_count
= 0;
153 ctx
->fs_links_count
= 0;
154 ctx
->fs_symlinks_count
= 0;
155 ctx
->fs_fast_symlinks_count
= 0;
156 ctx
->fs_fifo_count
= 0;
157 ctx
->fs_total_count
= 0;
158 ctx
->fs_badblocks_count
= 0;
159 ctx
->fs_sockets_count
= 0;
160 ctx
->fs_ind_count
= 0;
161 ctx
->fs_dind_count
= 0;
162 ctx
->fs_tind_count
= 0;
163 ctx
->fs_fragmented
= 0;
164 ctx
->fs_fragmented_dir
= 0;
165 ctx
->large_files
= 0;
167 for (i
=0; i
< MAX_EXTENT_DEPTH_COUNT
; i
++)
168 ctx
->extent_depth_count
[i
] = 0;
170 /* Reset the superblock to the user's requested value */
171 ctx
->superblock
= ctx
->use_superblock
;
176 void e2fsck_free_context(e2fsck_t ctx
)
181 e2fsck_reset_context(ctx
);
183 blkid_put_cache(ctx
->blkid
);
186 profile_release(ctx
->profile
);
188 if (ctx
->filesystem_name
)
189 ext2fs_free_mem(&ctx
->filesystem_name
);
191 if (ctx
->device_name
)
192 ext2fs_free_mem(&ctx
->device_name
);
197 ext2fs_free_mem(&ctx
);
201 * This function runs through the e2fsck passes and calls them all,
202 * returning restart, abort, or cancel as necessary...
204 typedef void (*pass_t
)(e2fsck_t ctx
);
206 static pass_t e2fsck_passes
[] = {
207 e2fsck_pass1
, e2fsck_pass2
, e2fsck_pass3
, e2fsck_pass4
,
210 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
212 int e2fsck_run(e2fsck_t ctx
)
218 if (setjmp(ctx
->abort_loc
)) {
219 ctx
->flags
&= ~E2F_FLAG_SETJMP_OK
;
220 return (ctx
->flags
& E2F_FLAG_RUN_RETURN
);
222 ctx
->flags
|= E2F_FLAG_SETJMP_OK
;
225 for (i
=0; (e2fsck_pass
= e2fsck_passes
[i
]); i
++) {
226 if (ctx
->flags
& E2F_FLAG_RUN_RETURN
)
228 if (e2fsck_mmp_update(ctx
->fs
))
232 (void) (ctx
->progress
)(ctx
, 0, 0, 0);
234 ctx
->flags
&= ~E2F_FLAG_SETJMP_OK
;
236 if (ctx
->flags
& E2F_FLAG_RUN_RETURN
)
237 return (ctx
->flags
& E2F_FLAG_RUN_RETURN
);