Many files:
Checked in e2fsprogs-1.07
diff --git a/e2fsck/e2fsck.c b/e2fsck/e2fsck.c
index f081d66..9cebae4 100644
--- a/e2fsck/e2fsck.c
+++ b/e2fsck/e2fsck.c
@@ -1,8 +1,12 @@
/*
* e2fsck.c - a consistency checker for the new extended file system.
*
- * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
- * redistributed under the terms of the GNU Public License.
+ * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
*/
/* Usage: e2fsck [-dfpnsvy] device
@@ -42,6 +46,7 @@
#include "et/com_err.h"
#include "uuid/uuid.h"
#include "e2fsck.h"
+#include "problem.h"
#include "../version.h"
extern int isatty(int);
@@ -60,6 +65,7 @@
int swapfs = 0;
int normalize_swapfs = 0;
int inode_buffer_blocks = 0;
+blk_t use_superblock;
blk_t superblock;
int blocksize = 0;
int verbose = 0;
@@ -236,8 +242,11 @@
{
static hint_issued = 0;
- /* Only issue the hint once */
- if (hint_issued)
+ /*
+ * Only issue the hint once, and only if we're using the
+ * primary superblocks.
+ */
+ if (hint_issued || superblock)
return;
printf("Note: if there is several inode or block bitmap blocks\n"
@@ -258,6 +267,9 @@
int i;
blk_t should_be;
errcode_t retval;
+ struct problem_context pctx;
+
+ clear_problem_context(&pctx);
/*
* Verify the super block constants...
@@ -334,55 +346,52 @@
last_block = first_block + blocks_per_group;
for (i = 0; i < fs->group_desc_count; i++) {
+ pctx.group = i;
+
if (i == fs->group_desc_count - 1)
last_block = fs->super->s_blocks_count;
if ((fs->group_desc[i].bg_block_bitmap < first_block) ||
(fs->group_desc[i].bg_block_bitmap >= last_block)) {
relocate_hint();
- printf("Block bitmap for group %d is not in group. "
- "(block %u)\n",
- i, fs->group_desc[i].bg_block_bitmap);
- preenhalt(fs);
- if (!ask("Relocate", 1)) {
- fatal_error("Block bitmap not in group");
+ pctx.blk = fs->group_desc[i].bg_block_bitmap;
+ if (fix_problem(fs, PR_0_BB_NOT_GROUP, &pctx)) {
+ fs->group_desc[i].bg_block_bitmap = 0;
+ invalid_block_bitmap[i]++;
+ invalid_bitmaps++;
}
- fs->group_desc[i].bg_block_bitmap = 0;
- invalid_block_bitmap[i]++;
- invalid_bitmaps++;
}
if ((fs->group_desc[i].bg_inode_bitmap < first_block) ||
(fs->group_desc[i].bg_inode_bitmap >= last_block)) {
relocate_hint();
- printf("Inode bitmap group %d not in group. "
- "(block %u)\n",
- i, fs->group_desc[i].bg_inode_bitmap);
- preenhalt(fs);
- if (!ask("Relocate", 1)) {
- fatal_error("Inode bitmap not in group");
+ pctx.blk = fs->group_desc[i].bg_inode_bitmap;
+ if (fix_problem(fs, PR_0_IB_NOT_GROUP, &pctx)) {
+ fs->group_desc[i].bg_inode_bitmap = 0;
+ invalid_inode_bitmap[i]++;
+ invalid_bitmaps++;
}
- fs->group_desc[i].bg_inode_bitmap = 0;
- invalid_inode_bitmap[i]++;
- invalid_bitmaps++;
}
if ((fs->group_desc[i].bg_inode_table < first_block) ||
((fs->group_desc[i].bg_inode_table +
fs->inode_blocks_per_group - 1) >= last_block)) {
relocate_hint();
- printf("Inode table for group %d not in group. "
- "(block %u)\n",
- i, fs->group_desc[i].bg_inode_table);
- printf("WARNING: SEVERE DATA LOSS POSSIBLE.\n");
- preenhalt(fs);
- if (!ask("Relocate", 1)) {
- fatal_error("Inode table not in group");
+ pctx.blk = fs->group_desc[i].bg_inode_table;
+ if (fix_problem(fs, PR_0_ITABLE_NOT_GROUP, &pctx)) {
+ fs->group_desc[i].bg_inode_table = 0;
+ invalid_inode_table[i]++;
+ invalid_bitmaps++;
}
- fs->group_desc[i].bg_inode_table = 0;
- invalid_inode_table[i]++;
- invalid_bitmaps++;
}
first_block += fs->super->s_blocks_per_group;
last_block += fs->super->s_blocks_per_group;
}
+ /*
+ * If we have invalid bitmaps, set the error state of the
+ * filesystem.
+ */
+ if (invalid_bitmaps && rwflag) {
+ fs->super->s_state &= ~EXT2_VALID_FS;
+ ext2fs_mark_super_dirty(fs);
+ }
/*
* If the UUID field isn't assigned, assign it.
@@ -492,7 +501,7 @@
/* What we do by default, anyway! */
break;
case 'b':
- superblock = atoi(optarg);
+ use_superblock = atoi(optarg);
break;
case 'B':
blocksize = atoi(optarg);
@@ -588,7 +597,9 @@
errcode_t retval = 0;
int exit_value = FSCK_OK;
int i;
- ext2_filsys fs;
+ ext2_filsys fs = 0;
+ io_manager io_ptr;
+ struct ext2fs_sb *s;
#ifdef MTRACE
mtrace();
@@ -601,7 +612,7 @@
PRS(argc, argv);
- if (!preen)
+ if (!preen || show_version_only)
fprintf (stderr, "e2fsck %s, %s for EXT2 FS %s, %s\n",
E2FSPROGS_VERSION, E2FSPROGS_DATE,
EXT2FS_VERSION, EXT2FS_DATE);
@@ -618,27 +629,46 @@
if (!isatty (0) || !isatty (1))
die ("need terminal for interactive repairs");
}
+ superblock = use_superblock;
restart:
+#if 1
+ io_ptr = unix_io_manager;
+#else
+ io_ptr = test_io_manager;
+ test_io_backing_manager = unix_io_manager;
+#endif
sync_disks();
if (superblock && blocksize) {
retval = ext2fs_open(filesystem_name,
rwflag ? EXT2_FLAG_RW : 0,
- superblock, blocksize, unix_io_manager,
- &fs);
+ superblock, blocksize, io_ptr, &fs);
} else if (superblock) {
for (i=0; possible_block_sizes[i]; i++) {
retval = ext2fs_open(filesystem_name,
rwflag ? EXT2_FLAG_RW : 0,
superblock,
possible_block_sizes[i],
- unix_io_manager, &fs);
+ io_ptr, &fs);
if (!retval)
break;
}
} else
retval = ext2fs_open(filesystem_name,
rwflag ? EXT2_FLAG_RW : 0,
- 0, 0, unix_io_manager, &fs);
+ 0, 0, io_ptr, &fs);
+ if (!superblock && !preen &&
+ ((retval == EXT2_ET_BAD_MAGIC) ||
+ ((retval == 0) && ext2fs_check_desc(fs)))) {
+ if (!fs || (fs->group_desc_count > 1)) {
+ printf("%s trying backup blocks...\n",
+ retval ? "Couldn't find ext2 superblock," :
+ "Group descriptors look bad...");
+ superblock = 8193;
+ if (fs)
+ ext2fs_close(fs);
+ goto restart;
+ }
+ }
if (retval) {
com_err(program_name, retval, "while trying to open %s",
filesystem_name);
@@ -656,16 +686,28 @@
printf(corrupt_msg);
fatal_error(0);
}
-
#ifdef EXT2_CURRENT_REV
if (fs->super->s_rev_level > E2FSCK_CURRENT_REV) {
com_err(program_name, EXT2_ET_REV_TOO_HIGH,
"while trying to open %s",
filesystem_name);
+ goto get_newer;
+ }
+#endif
+ /*
+ * Check for compatibility with the feature sets. We have to
+ * check because we need to be more stringent than ext2fs_open
+ */
+ s = (struct ext2fs_sb *) fs->super;
+ if (s->s_feature_compat || s->s_feature_incompat ||
+ s->s_feature_ro_compat) {
+ com_err(program_name, EXT2_ET_UNSUPP_FEATURE,
+ " (%s)", filesystem_name);
+ get_newer:
printf ("Get a newer version of e2fsck!\n");
fatal_error(0);
}
-#endif
+
/*
* If the user specified a specific superblock, presumably the
* master superblock has been trashed. So we mark the
@@ -715,6 +757,14 @@
*/
ext2fs_mark_valid(fs);
+ retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
+ if (retval) {
+ com_err(program_name, retval,
+ "while reading bad blocks inode");
+ preenhalt(fs);
+ printf("This doesn't bode well, but we'll try to go on...\n");
+ }
+
pass1(fs);
free(invalid_inode_bitmap);
free(invalid_block_bitmap);
@@ -723,6 +773,7 @@
ext2fs_close(fs);
printf("Restarting e2fsck from the beginning...\n");
restart_e2fsck = 0;
+ superblock = use_superblock;
goto restart;
}
pass2(fs);