badblocks.c revision f3db3566b5e1342e49dffc5ec3f418a838584194
13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * badblocks.c --- replace/append bad blocks to the bad block inode 33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 43839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be 53839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * redistributed under the terms of the GNU Public License. 63839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 73839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 83839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h> 93839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <et/com_err.h> 113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "e2fsck.h" 123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 13f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ostatic int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt, 14f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o void *private); 15f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 16f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void invalid_block(ext2_filsys fs, blk_t blk) 183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf("Bad block %lu out of range; ignored.\n", blk); 203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return; 213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid read_bad_blocks_file(ext2_filsys fs, const char *bad_blocks_file, 243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int replace_bad_blocks) 253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o badblocks_list bb_list = 0; 283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o FILE *f; 293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o read_bitmaps(fs); 31f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 32f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o /* 33f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * Make sure the bad block inode is sane. If there are any 34f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * illegal blocks, clear them. 35f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o */ 36f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0, 37f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o check_bb_inode_blocks, 0); 38f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (retval) { 39f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o com_err("ext2fs_block_iterate", retval, 40f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o "while sanity checking the bad blocks inode"); 41f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o fatal_error(0); 42f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 43f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * If we're appending to the bad blocks inode, read in the 473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * current bad blocks. 483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!replace_bad_blocks) { 503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_read_bb_inode(fs, &bb_list); 513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_read_bb_inode", retval, 533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while reading the bad blocks inode"); 543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Now read in the bad blocks from the file. 603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o f = fopen(bad_blocks_file, "r"); 623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!f) { 633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("read_bad_blocks_file", errno, 643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while trying to open %s", bad_blocks_file); 653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); 683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fclose (f); 693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_read_bb_FILE", retval, 713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while reading in list of bad blocks from file"); 723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Finally, update the bad blocks from the bad_block_map 773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_update_bb_inode(fs, bb_list); 793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_update_bb_inode", retval, 813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while updating bad block inode"); 823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o badblocks_list_free(bb_list); 863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return; 873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 89f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'ostatic int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt, 90f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o void *private) 91f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o{ 92f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (!*block_nr) 93f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return 0; 94f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 95f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o /* 96f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * If the block number is outrageous, clear it and ignore it. 97f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o */ 98f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (*block_nr >= fs->super->s_blocks_count || 99f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o *block_nr < fs->super->s_first_data_block) { 100f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o printf("Warning illegal block %lu found in bad block inode. Cleared.\n", *block_nr); 101f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o *block_nr = 0; 102f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return BLOCK_CHANGED; 103f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 104f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 105f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o return 0; 106f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o} 107f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid test_disk(ext2_filsys fs) 1093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 1103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 1113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o badblocks_list bb_list = 0; 1123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o FILE *f; 1133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char buf[1024]; 1143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o read_bitmaps(fs); 1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 1183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Always read in the current list of bad blocks. 1193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_read_bb_inode(fs, &bb_list); 1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_read_bb_inode", retval, 1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while reading the bad blocks inode"); 1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 1283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Now run the bad blocks program 1293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 1303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o sprintf(buf, "badblocks %s%s %ld", preen ? "" : "-s ", 1313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fs->device_name, 1323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fs->super->s_blocks_count); 1333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (verbose) 1343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf("Running command: %s\n", buf); 1353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o f = popen(buf, "r"); 1363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!f) { 1373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("popen", errno, 1383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while trying to run %s", buf); 1393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 1403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); 1423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fclose (f); 1433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 1443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_read_bb_FILE", retval, 1453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while processing list of bad blocks from program"); 1463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 1473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 1503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Finally, update the bad blocks from the bad_block_map 1513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 1523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_update_bb_inode(fs, bb_list); 1533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 1543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_update_bb_inode", retval, 1553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while updating bad block inode"); 1563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 1573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o badblocks_list_free(bb_list); 1603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return; 1613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 1623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 163