• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * e2fsck.c - a consistency checker for the new extended file system.
3  *
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%
10  */
11 
12 #include <errno.h>
13 
14 #include "e2fsck.h"
15 #include "problem.h"
16 
17 /*
18  * This function allocates an e2fsck context
19  */
e2fsck_allocate_context(e2fsck_t * ret)20 errcode_t e2fsck_allocate_context(e2fsck_t *ret)
21 {
22 	e2fsck_t	context;
23 	errcode_t	retval;
24 	char		*time_env;
25 
26 	retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
27 	if (retval)
28 		return retval;
29 
30 	memset(context, 0, sizeof(struct e2fsck_struct));
31 
32 	context->process_inode_size = 256;
33 	context->ext_attr_ver = 2;
34 	context->blocks_per_page = 1;
35 	context->htree_slack_percentage = 255;
36 
37 	time_env = getenv("E2FSCK_TIME");
38 	if (time_env)
39 		context->now = strtoul(time_env, NULL, 0);
40 	else
41 		context->now = time(0);
42 
43 	*ret = context;
44 	return 0;
45 }
46 
47 /*
48  * This function resets an e2fsck context; it is called when e2fsck
49  * needs to be restarted.
50  */
e2fsck_reset_context(e2fsck_t ctx)51 errcode_t e2fsck_reset_context(e2fsck_t ctx)
52 {
53 	int	i;
54 
55 	ctx->flags = 0;
56 	ctx->lost_and_found = 0;
57 	ctx->bad_lost_and_found = 0;
58 	if (ctx->inode_used_map) {
59 		ext2fs_free_inode_bitmap(ctx->inode_used_map);
60 		ctx->inode_used_map = 0;
61 	}
62 	if (ctx->inode_dir_map) {
63 		ext2fs_free_inode_bitmap(ctx->inode_dir_map);
64 		ctx->inode_dir_map = 0;
65 	}
66 	if (ctx->inode_reg_map) {
67 		ext2fs_free_inode_bitmap(ctx->inode_reg_map);
68 		ctx->inode_reg_map = 0;
69 	}
70 	if (ctx->block_found_map) {
71 		ext2fs_free_block_bitmap(ctx->block_found_map);
72 		ctx->block_found_map = 0;
73 	}
74 	if (ctx->inode_link_info) {
75 		ext2fs_free_icount(ctx->inode_link_info);
76 		ctx->inode_link_info = 0;
77 	}
78 	if (ctx->journal_io) {
79 		if (ctx->fs && ctx->fs->io != ctx->journal_io)
80 			io_channel_close(ctx->journal_io);
81 		ctx->journal_io = 0;
82 	}
83 	if (ctx->fs && ctx->fs->dblist) {
84 		ext2fs_free_dblist(ctx->fs->dblist);
85 		ctx->fs->dblist = 0;
86 	}
87 	e2fsck_free_dir_info(ctx);
88 #ifdef ENABLE_HTREE
89 	e2fsck_free_dx_dir_info(ctx);
90 #endif
91 	if (ctx->refcount) {
92 		ea_refcount_free(ctx->refcount);
93 		ctx->refcount = 0;
94 	}
95 	if (ctx->refcount_extra) {
96 		ea_refcount_free(ctx->refcount_extra);
97 		ctx->refcount_extra = 0;
98 	}
99 	if (ctx->block_dup_map) {
100 		ext2fs_free_block_bitmap(ctx->block_dup_map);
101 		ctx->block_dup_map = 0;
102 	}
103 	if (ctx->block_ea_map) {
104 		ext2fs_free_block_bitmap(ctx->block_ea_map);
105 		ctx->block_ea_map = 0;
106 	}
107 	if (ctx->inode_bb_map) {
108 		ext2fs_free_inode_bitmap(ctx->inode_bb_map);
109 		ctx->inode_bb_map = 0;
110 	}
111 	if (ctx->inode_bad_map) {
112 		ext2fs_free_inode_bitmap(ctx->inode_bad_map);
113 		ctx->inode_bad_map = 0;
114 	}
115 	if (ctx->inode_imagic_map) {
116 		ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
117 		ctx->inode_imagic_map = 0;
118 	}
119 	if (ctx->dirs_to_hash) {
120 		ext2fs_u32_list_free(ctx->dirs_to_hash);
121 		ctx->dirs_to_hash = 0;
122 	}
123 
124 	/*
125 	 * Clear the array of invalid meta-data flags
126 	 */
127 	if (ctx->invalid_inode_bitmap_flag) {
128 		ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
129 		ctx->invalid_inode_bitmap_flag = 0;
130 	}
131 	if (ctx->invalid_block_bitmap_flag) {
132 		ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
133 		ctx->invalid_block_bitmap_flag = 0;
134 	}
135 	if (ctx->invalid_inode_table_flag) {
136 		ext2fs_free_mem(&ctx->invalid_inode_table_flag);
137 		ctx->invalid_inode_table_flag = 0;
138 	}
139 
140 	/* Clear statistic counters */
141 	ctx->fs_directory_count = 0;
142 	ctx->fs_regular_count = 0;
143 	ctx->fs_blockdev_count = 0;
144 	ctx->fs_chardev_count = 0;
145 	ctx->fs_links_count = 0;
146 	ctx->fs_symlinks_count = 0;
147 	ctx->fs_fast_symlinks_count = 0;
148 	ctx->fs_fifo_count = 0;
149 	ctx->fs_total_count = 0;
150 	ctx->fs_badblocks_count = 0;
151 	ctx->fs_sockets_count = 0;
152 	ctx->fs_ind_count = 0;
153 	ctx->fs_dind_count = 0;
154 	ctx->fs_tind_count = 0;
155 	ctx->fs_fragmented = 0;
156 	ctx->fs_fragmented_dir = 0;
157 	ctx->large_files = 0;
158 
159 	for (i=0; i < MAX_EXTENT_DEPTH_COUNT; i++)
160 		ctx->extent_depth_count[i] = 0;
161 
162 	/* Reset the superblock to the user's requested value */
163 	ctx->superblock = ctx->use_superblock;
164 
165 	return 0;
166 }
167 
e2fsck_free_context(e2fsck_t ctx)168 void e2fsck_free_context(e2fsck_t ctx)
169 {
170 	if (!ctx)
171 		return;
172 
173 	e2fsck_reset_context(ctx);
174 	if (ctx->blkid)
175 		blkid_put_cache(ctx->blkid);
176 
177 	if (ctx->profile)
178 		profile_release(ctx->profile);
179 
180 	if (ctx->filesystem_name)
181 		ext2fs_free_mem(&ctx->filesystem_name);
182 
183 	if (ctx->device_name)
184 		ext2fs_free_mem(&ctx->device_name);
185 
186 	ext2fs_free_mem(&ctx);
187 }
188 
189 /*
190  * This function runs through the e2fsck passes and calls them all,
191  * returning restart, abort, or cancel as necessary...
192  */
193 typedef void (*pass_t)(e2fsck_t ctx);
194 
195 pass_t e2fsck_passes[] = {
196 	e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
197 	e2fsck_pass5, 0 };
198 
199 #define E2F_FLAG_RUN_RETURN	(E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
200 
e2fsck_run(e2fsck_t ctx)201 int e2fsck_run(e2fsck_t ctx)
202 {
203 	int	i;
204 	pass_t	e2fsck_pass;
205 
206 #ifdef HAVE_SETJMP_H
207 	if (setjmp(ctx->abort_loc)) {
208 		ctx->flags &= ~E2F_FLAG_SETJMP_OK;
209 		return (ctx->flags & E2F_FLAG_RUN_RETURN);
210 	}
211 	ctx->flags |= E2F_FLAG_SETJMP_OK;
212 #endif
213 
214 	for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
215 		if (ctx->flags & E2F_FLAG_RUN_RETURN)
216 			break;
217 		e2fsck_pass(ctx);
218 		if (ctx->progress)
219 			(void) (ctx->progress)(ctx, 0, 0, 0);
220 	}
221 	ctx->flags &= ~E2F_FLAG_SETJMP_OK;
222 
223 	if (ctx->flags & E2F_FLAG_RUN_RETURN)
224 		return (ctx->flags & E2F_FLAG_RUN_RETURN);
225 	return 0;
226 }
227