X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=e2fsck%2Fbadblocks.c;h=fec5f10dcec3d7856bd216690c9d24e389434bac;hb=fab7345a0e9c20068872839aaeac42f8586ed349;hp=6dff23d95cf04185d14f55f04ab27e371043867c;hpb=3839e65723771b85975f4263102dd3ceec4523c0;p=tools%2Fe2fsprogs.git diff --git a/e2fsck/badblocks.c b/e2fsck/badblocks.c index 6dff23d..fec5f10 100644 --- a/e2fsck/badblocks.c +++ b/e2fsck/badblocks.c @@ -1,30 +1,52 @@ /* * 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 "config.h" #include +#ifdef HAVE_ERRNO_H +#include +#endif #include #include "e2fsck.h" -static void invalid_block(ext2_filsys fs, blk_t blk) +static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt, + void *priv_data); + + +static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk) { - printf("Bad block %lu out of range; ignored.\n", blk); + printf(_("Bad block %u out of range; ignored.\n"), blk); return; } -void read_bad_blocks_file(ext2_filsys fs, const char *bad_blocks_file, +void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, int replace_bad_blocks) { + ext2_filsys fs = ctx->fs; errcode_t retval; badblocks_list bb_list = 0; FILE *f; + char buf[1024]; + + e2fsck_read_bitmaps(ctx); + + /* + * 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, "%s", + _("while sanity checking the bad blocks inode")); + goto fatal; + } - read_bitmaps(fs); - /* * If we're appending to the bad blocks inode, read in the * current bad blocks. @@ -32,95 +54,89 @@ void read_bad_blocks_file(ext2_filsys fs, const char *bad_blocks_file, 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); + com_err("ext2fs_read_bb_inode", retval, "%s", + _("while reading the bad blocks inode")); + goto fatal; } } - + /* - * Now read in the bad blocks from the file. + * Now read in the bad blocks from the file; if + * bad_blocks_file is null, then try to run the badblocks + * command. */ - 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); + 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); + goto fatal; + } + } else { + sprintf(buf, "badblocks -b %d -X %s%s%s %llu", fs->blocksize, + (ctx->options & E2F_OPT_PREEN) ? "" : "-s ", + (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "", + fs->device_name, + (unsigned long long) ext2fs_blocks_count(fs->super)-1); + f = popen(buf, "r"); + if (!f) { + com_err("read_bad_blocks_file", errno, + _("while trying popen '%s'"), buf); + goto fatal; + } } retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); - fclose (f); + if (bad_blocks_file) + fclose(f); + else + pclose(f); if (retval) { - com_err("ext2fs_read_bb_FILE", retval, - "while reading in list of bad blocks from file"); - fatal_error(0); + com_err("ext2fs_read_bb_FILE", retval, "%s", + _("while reading in list of bad blocks from file")); + goto fatal; } - + /* * Finally, update the bad blocks from the bad_block_map */ + printf("%s: Updating bad block inode.\n", ctx->device_name); 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); + com_err("ext2fs_update_bb_inode", retval, "%s", + _("while updating bad block inode")); + goto fatal; } - badblocks_list_free(bb_list); + ext2fs_badblocks_list_free(bb_list); return; + +fatal: + ctx->flags |= E2F_FLAG_ABORT; + if (bb_list) + ext2fs_badblocks_list_free(bb_list); + return; + } -void test_disk(ext2_filsys fs) +static int check_bb_inode_blocks(ext2_filsys fs, + blk_t *block_nr, + int blockcnt EXT2FS_ATTR((unused)), + void *priv_data EXT2FS_ATTR((unused))) { - errcode_t retval; - badblocks_list bb_list = 0; - FILE *f; - char buf[1024]; + if (!*block_nr) + return 0; - read_bitmaps(fs); - /* - * Always read in the current list of bad blocks. + * If the block number is outrageous, clear it and ignore it. */ - 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); - } - - /* - * Now run the bad blocks program - */ - sprintf(buf, "badblocks %s%s %ld", preen ? "" : "-s ", - fs->device_name, - fs->super->s_blocks_count); - if (verbose) - printf("Running command: %s\n", buf); - f = popen(buf, "r"); - if (!f) { - com_err("popen", errno, - "while trying to run %s", buf); - fatal_error(0); - } - retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); - fclose (f); - if (retval) { - com_err("ext2fs_read_bb_FILE", retval, - "while processing list of bad blocks from program"); - 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); + if (*block_nr >= ext2fs_blocks_count(fs->super) || + *block_nr < fs->super->s_first_data_block) { + printf(_("Warning: illegal block %u found in bad block inode. " + "Cleared.\n"), *block_nr); + *block_nr = 0; + return BLOCK_CHANGED; } - badblocks_list_free(bb_list); - return; + return 0; }