2 * e2fsck.c - superblock checks
4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Public
16 #ifndef EXT2_SKIP_UUID
17 #include "uuid/uuid.h"
25 static void check_super_value(e2fsck_t ctx, const char *descr,
26 unsigned long value, int flags,
27 unsigned long min_val, unsigned long max_val)
29 struct problem_context pctx;
31 if (((flags & MIN_CHECK) && (value < min_val)) ||
32 ((flags & MAX_CHECK) && (value > max_val))) {
33 clear_problem_context(&pctx);
36 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
37 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
42 * This routine may get stubbed out in special compilations of the
45 #ifndef EXT2_SPECIAL_DEVICE_SIZE
46 errcode_t e2fsck_get_device_size(e2fsck_t ctx)
48 return (ext2fs_get_device_size(ctx->filesystem_name,
49 EXT2_BLOCK_SIZE(ctx->fs->super),
55 * helper function to release an inode
57 struct process_block_struct {
60 struct problem_context *pctx;
69 static int release_inode_block(ext2_filsys fs,
74 struct process_block_struct *pb;
76 struct problem_context *pctx;
77 blk_t blk = *block_nr;
80 pb = (struct process_block_struct *) priv_data;
85 pctx->blkcount = blockcnt;
87 if (HOLE_BLKADDR(blk))
90 if ((blk < fs->super->s_first_data_block) ||
91 (blk >= fs->super->s_blocks_count)) {
92 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
98 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
99 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
104 * If we are deleting an orphan, then we leave the fields alone.
105 * If we are truncating an orphan, then update the inode fields
106 * and clean up any partial block data.
108 if (pb->truncating) {
110 * We only remove indirect blocks if they are
117 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
122 limit = fs->blocksize >> 2;
123 for (i = 0, bp = (blk_t *) pb->buf;
124 i < limit; i++, bp++)
129 * We don't remove direct blocks until we've reached
130 * the truncation block.
132 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
135 * If part of the last block needs truncating, we do
138 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
139 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
143 memset(pb->buf + pb->truncate_offset, 0,
144 fs->blocksize - pb->truncate_offset);
145 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
150 pb->truncated_blocks++;
152 retval |= BLOCK_CHANGED;
155 ext2fs_unmark_block_bitmap(fs->block_map, blk);
156 fs->group_desc[ext2fs_group_of_blk(fs, blk)].bg_free_blocks_count++;
157 fs->super->s_free_blocks_count++;
163 * This function releases an inode. Returns 1 if an inconsistency was
164 * found. If the inode has a link count, then it is being truncated and
167 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
168 struct ext2_inode *inode, char *block_buf,
169 struct problem_context *pctx)
171 ext2_filsys fs = ctx->fs;
173 struct process_block_struct pb;
175 if (!ext2fs_inode_has_valid_blocks(inode))
178 pb.buf = block_buf + 3 * ctx->fs->blocksize;
183 if (inode->i_links_count) {
185 pb.truncate_block = (blk_t)
186 ((((long long)inode->i_size_high << 32) +
187 inode->i_size + fs->blocksize - 1) /
189 pb.truncate_offset = inode->i_size % fs->blocksize;
192 pb.truncate_block = 0;
193 pb.truncate_offset = 0;
195 pb.truncated_blocks = 0;
196 retval = ext2fs_block_iterate(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
197 block_buf, release_inode_block, &pb);
199 com_err("release_inode_blocks", retval,
200 _("while calling ext2fs_block_iterate for inode %d"),
207 /* Refresh the inode since ext2fs_block_iterate may have changed it */
208 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
210 if (pb.truncated_blocks)
211 inode->i_blocks -= pb.truncated_blocks *
212 (fs->blocksize / 512);
214 ext2fs_mark_bb_dirty(fs);
219 * This function releases all of the orphan inodes. It returns 1 if
220 * it hit some error, and 0 on success.
222 static int release_orphan_inodes(e2fsck_t ctx)
224 ext2_filsys fs = ctx->fs;
226 ext2_ino_t ino, next_ino;
227 struct ext2_inode inode;
228 struct problem_context pctx;
231 if ((ino = fs->super->s_last_orphan) == 0)
235 * Win or lose, we won't be using the head of the orphan inode
238 fs->super->s_last_orphan = 0;
239 ext2fs_mark_super_dirty(fs);
241 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
242 (ino > fs->super->s_inodes_count)) {
243 clear_problem_context(&pctx);
245 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
249 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
250 "block iterate buffer");
251 e2fsck_read_bitmaps(ctx);
254 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
255 clear_problem_context(&pctx);
258 pctx.str = inode.i_links_count ? _("Truncating") :
261 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
263 next_ino = inode.i_dtime;
265 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
266 (next_ino > fs->super->s_inodes_count))) {
268 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
272 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
275 if (!inode.i_links_count) {
276 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
277 ext2fs_mark_ib_dirty(fs);
278 group = ext2fs_group_of_ino(fs, ino);
279 fs->group_desc[group].bg_free_inodes_count++;
280 fs->super->s_free_inodes_count++;
281 if (LINUX_S_ISDIR(inode.i_mode))
282 fs->group_desc[group].bg_used_dirs_count--;
284 inode.i_dtime = time(0);
286 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
291 ext2fs_free_mem((void **) &block_buf);
296 void check_super_block(e2fsck_t ctx)
298 ext2_filsys fs = ctx->fs;
299 blk_t first_block, last_block;
300 struct ext2_super_block *sb = fs->super;
301 blk_t blocks_per_group = fs->super->s_blocks_per_group;
302 int inodes_per_block;
305 struct problem_context pctx;
307 inodes_per_block = (EXT2_BLOCK_SIZE(fs->super) /
308 EXT2_INODE_SIZE(fs->super));
310 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
311 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
312 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
313 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
314 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
315 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
317 clear_problem_context(&pctx);
320 * Verify the super block constants...
322 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
324 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
326 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
327 MAX_CHECK, 0, sb->s_blocks_count);
328 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
330 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
331 MIN_CHECK | MAX_CHECK, sb->s_log_frag_size,
333 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
334 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
335 8 * EXT2_BLOCK_SIZE(sb));
336 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
337 MIN_CHECK | MAX_CHECK, 8, 8 * EXT2_BLOCK_SIZE(sb));
338 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
339 MIN_CHECK | MAX_CHECK, inodes_per_block,
340 inodes_per_block * (blocks_per_group-4));
341 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
342 MAX_CHECK, 0, sb->s_blocks_count / 4);
344 if (!ctx->num_blocks) {
345 pctx.errcode = e2fsck_get_device_size(ctx);
346 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
347 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
348 ctx->flags |= E2F_FLAG_ABORT;
351 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
352 (ctx->num_blocks < sb->s_blocks_count)) {
353 pctx.blk = sb->s_blocks_count;
354 pctx.blk2 = ctx->num_blocks;
355 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
356 ctx->flags |= E2F_FLAG_ABORT;
362 if (sb->s_log_block_size != sb->s_log_frag_size) {
363 pctx.blk = EXT2_BLOCK_SIZE(sb);
364 pctx.blk2 = EXT2_FRAG_SIZE(sb);
365 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
366 ctx->flags |= E2F_FLAG_ABORT;
370 should_be = sb->s_frags_per_group >>
371 (sb->s_log_block_size - sb->s_log_frag_size);
372 if (sb->s_blocks_per_group != should_be) {
373 pctx.blk = sb->s_blocks_per_group;
374 pctx.blk2 = should_be;
375 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
376 ctx->flags |= E2F_FLAG_ABORT;
380 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
381 if (sb->s_first_data_block != should_be) {
382 pctx.blk = sb->s_first_data_block;
383 pctx.blk2 = should_be;
384 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
385 ctx->flags |= E2F_FLAG_ABORT;
389 should_be = sb->s_inodes_per_group * fs->group_desc_count;
390 if (sb->s_inodes_count != should_be) {
391 pctx.ino = sb->s_inodes_count;
392 pctx.ino2 = should_be;
393 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
394 sb->s_inodes_count = should_be;
395 ext2fs_mark_super_dirty(fs);
400 * Verify the group descriptors....
402 first_block = fs->super->s_first_data_block;
403 last_block = first_block + blocks_per_group;
405 for (i = 0; i < fs->group_desc_count; i++) {
408 if (i == fs->group_desc_count - 1)
409 last_block = fs->super->s_blocks_count;
410 if ((fs->group_desc[i].bg_block_bitmap < first_block) ||
411 (fs->group_desc[i].bg_block_bitmap >= last_block)) {
412 pctx.blk = fs->group_desc[i].bg_block_bitmap;
413 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx)) {
414 fs->group_desc[i].bg_block_bitmap = 0;
415 ctx->invalid_block_bitmap_flag[i]++;
416 ctx->invalid_bitmaps++;
419 if ((fs->group_desc[i].bg_inode_bitmap < first_block) ||
420 (fs->group_desc[i].bg_inode_bitmap >= last_block)) {
421 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
422 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx)) {
423 fs->group_desc[i].bg_inode_bitmap = 0;
424 ctx->invalid_inode_bitmap_flag[i]++;
425 ctx->invalid_bitmaps++;
428 if ((fs->group_desc[i].bg_inode_table < first_block) ||
429 ((fs->group_desc[i].bg_inode_table +
430 fs->inode_blocks_per_group - 1) >= last_block)) {
431 pctx.blk = fs->group_desc[i].bg_inode_table;
432 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx)) {
433 fs->group_desc[i].bg_inode_table = 0;
434 ctx->invalid_inode_table_flag[i]++;
435 ctx->invalid_bitmaps++;
438 first_block += fs->super->s_blocks_per_group;
439 last_block += fs->super->s_blocks_per_group;
442 * If we have invalid bitmaps, set the error state of the
445 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
446 fs->super->s_state &= ~EXT2_VALID_FS;
447 ext2fs_mark_super_dirty(fs);
450 clear_problem_context(&pctx);
452 #ifndef EXT2_SKIP_UUID
454 * If the UUID field isn't assigned, assign it.
456 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
457 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
458 uuid_generate(sb->s_uuid);
459 ext2fs_mark_super_dirty(fs);
465 * For the Hurd, check to see if the filetype option is set,
466 * since it doesn't support it.
468 if (!(ctx->options & E2F_OPT_READONLY) &&
469 fs->super->s_creator_os == EXT2_OS_HURD &&
470 (fs->super->s_feature_incompat &
471 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
472 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
473 fs->super->s_feature_incompat &=
474 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
475 ext2fs_mark_super_dirty(fs);
481 * If we have any of the compatibility flags set, we need to have a
482 * revision 1 filesystem. Most kernels will not check the flags on
483 * a rev 0 filesystem and we may have corruption issues because of
484 * the incompatible changes to the filesystem.
486 if (!(ctx->options & E2F_OPT_READONLY) &&
487 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
488 (fs->super->s_feature_compat ||
489 fs->super->s_feature_ro_compat ||
490 fs->super->s_feature_incompat) &&
491 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
492 ext2fs_update_dynamic_rev(fs);
493 ext2fs_mark_super_dirty(fs);
497 * Clean up any orphan inodes, if present.
499 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
500 fs->super->s_state &= ~EXT2_VALID_FS;
501 ext2fs_mark_super_dirty(fs);