1997-04-26 21:21:57 +08:00
|
|
|
/*
|
|
|
|
* badblocks.c --- replace/append bad blocks to the bad block inode
|
|
|
|
*
|
|
|
|
* Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
|
|
|
|
* redistributed under the terms of the GNU Public License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <time.h>
|
1997-04-26 21:58:21 +08:00
|
|
|
#ifdef HAVE_ERRNO_H
|
|
|
|
#include <errno.h>
|
|
|
|
#endif
|
1997-04-26 21:21:57 +08:00
|
|
|
|
|
|
|
#include <et/com_err.h>
|
|
|
|
#include "e2fsck.h"
|
|
|
|
|
1997-04-26 21:34:30 +08:00
|
|
|
static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
|
|
|
|
void *private);
|
|
|
|
|
|
|
|
|
1997-04-26 21:21:57 +08:00
|
|
|
static void invalid_block(ext2_filsys fs, blk_t blk)
|
|
|
|
{
|
1997-04-26 21:58:21 +08:00
|
|
|
printf("Bad block %u out of range; ignored.\n", blk);
|
1997-04-26 21:21:57 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
|
1997-04-26 21:21:57 +08:00
|
|
|
int replace_bad_blocks)
|
|
|
|
{
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
ext2_filsys fs = ctx->fs;
|
1997-04-26 21:21:57 +08:00
|
|
|
errcode_t retval;
|
|
|
|
badblocks_list bb_list = 0;
|
|
|
|
FILE *f;
|
1997-04-26 22:37:06 +08:00
|
|
|
char buf[1024];
|
1997-04-26 21:21:57 +08:00
|
|
|
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
read_bitmaps(ctx);
|
1997-04-26 21:34:30 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Make sure the bad block inode is sane. If there are any
|
|
|
|
* illegal blocks, clear them.
|
|
|
|
*/
|
|
|
|
retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
|
|
|
|
check_bb_inode_blocks, 0);
|
|
|
|
if (retval) {
|
|
|
|
com_err("ext2fs_block_iterate", retval,
|
|
|
|
"while sanity checking the bad blocks inode");
|
|
|
|
fatal_error(0);
|
|
|
|
}
|
|
|
|
|
1997-04-26 21:21:57 +08:00
|
|
|
/*
|
|
|
|
* If we're appending to the bad blocks inode, read in the
|
|
|
|
* current bad blocks.
|
|
|
|
*/
|
|
|
|
if (!replace_bad_blocks) {
|
|
|
|
retval = ext2fs_read_bb_inode(fs, &bb_list);
|
|
|
|
if (retval) {
|
|
|
|
com_err("ext2fs_read_bb_inode", retval,
|
|
|
|
"while reading the bad blocks inode");
|
|
|
|
fatal_error(0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
1997-04-26 22:37:06 +08:00
|
|
|
* Now read in the bad blocks from the file; if
|
|
|
|
* bad_blocks_file is null, then try to run the badblocks
|
|
|
|
* command.
|
1997-04-26 21:21:57 +08:00
|
|
|
*/
|
1997-04-26 22:37:06 +08:00
|
|
|
if (bad_blocks_file) {
|
|
|
|
f = fopen(bad_blocks_file, "r");
|
|
|
|
if (!f) {
|
|
|
|
com_err("read_bad_blocks_file", errno,
|
|
|
|
"while trying to open %s", bad_blocks_file);
|
|
|
|
fatal_error(0);
|
|
|
|
}
|
|
|
|
} else {
|
1997-05-09 10:50:16 +08:00
|
|
|
sprintf(buf, "badblocks -b %d %s%s %d", fs->blocksize,
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
(ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
|
|
|
|
fs->device_name, fs->super->s_blocks_count);
|
1997-04-26 22:37:06 +08:00
|
|
|
f = popen(buf, "r");
|
|
|
|
if (!f) {
|
|
|
|
com_err("read_bad_blocks_file", errno,
|
|
|
|
"while trying popen '%s'", buf);
|
|
|
|
fatal_error(0);
|
|
|
|
}
|
1997-04-26 21:21:57 +08:00
|
|
|
}
|
|
|
|
retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
|
1997-04-26 22:37:06 +08:00
|
|
|
if (bad_blocks_file)
|
|
|
|
fclose(f);
|
|
|
|
else
|
|
|
|
pclose(f);
|
1997-04-26 21:21:57 +08:00
|
|
|
if (retval) {
|
|
|
|
com_err("ext2fs_read_bb_FILE", retval,
|
|
|
|
"while reading in list of bad blocks from file");
|
|
|
|
fatal_error(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Finally, update the bad blocks from the bad_block_map
|
|
|
|
*/
|
|
|
|
retval = ext2fs_update_bb_inode(fs, bb_list);
|
|
|
|
if (retval) {
|
|
|
|
com_err("ext2fs_update_bb_inode", retval,
|
|
|
|
"while updating bad block inode");
|
|
|
|
fatal_error(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
badblocks_list_free(bb_list);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
void test_disk(e2fsck_t ctx)
|
1997-04-26 22:37:06 +08:00
|
|
|
{
|
Many files:
pass*.c, super.c: Massive changes to avoid using printf and com_err
routines. All diagnostic messages are now routed through the
fix_problem interface.
pass2.c (check_dir_block): Check for duplicate '.' and '..' entries.
problem.c, problem.h: Add new problem codes PR_2_DUP_DOT and
PR_2_DUP_DOT_DOT.
problem.c: Added new problem codes for some of the superblock
corruption checks, and for the pass header messages. ("Pass
1: xxxxx")
util.c (print_resource_track): Now takes a description argument.
super.c, unix.c, e2fsck.c: New files to separate out the
operating-specific operations out from e2fsck.c. e2fsck.c now
contains the global e2fsck context management routines, and
super.c contains the "pass 0" initial validation of the
superblock and global block group descriptors.
pass1.c, pass2.c, pass3.c, pass4.c, pass5.c, util.c: Eliminate
(nearly) all global variables and moved them to the e2fsck
context structure.
problem.c, problem.h: Added new problem codes PR_0_SB_CORRUPT,
PR_0_FS_SIZE_WRONG, PR_0_NO_FRAGMENTS, PR_0_BLOCKS_PER_GROUP,
PR_0_FIRST_DATA_BLOCK
expect.1, expect.2:
Updated tests to align with e2fsck problem.c changes.
1997-10-04 01:48:10 +08:00
|
|
|
read_bad_blocks_file(ctx, 0, 1);
|
1997-04-26 22:37:06 +08:00
|
|
|
}
|
|
|
|
|
1997-04-26 21:34:30 +08:00
|
|
|
static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
|
|
|
|
void *private)
|
|
|
|
{
|
|
|
|
if (!*block_nr)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If the block number is outrageous, clear it and ignore it.
|
|
|
|
*/
|
|
|
|
if (*block_nr >= fs->super->s_blocks_count ||
|
|
|
|
*block_nr < fs->super->s_first_data_block) {
|
1997-04-26 21:58:21 +08:00
|
|
|
printf("Warning illegal block %u found in bad block inode. Cleared.\n", *block_nr);
|
1997-04-26 21:34:30 +08:00
|
|
|
*block_nr = 0;
|
|
|
|
return BLOCK_CHANGED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|