badblocks.c revision 3839e65723771b85975f4263102dd3ceec4523c
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 133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ostatic void invalid_block(ext2_filsys fs, blk_t blk) 143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf("Bad block %lu out of range; ignored.\n", blk); 163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return; 173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid read_bad_blocks_file(ext2_filsys fs, const char *bad_blocks_file, 203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int replace_bad_blocks) 213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o badblocks_list bb_list = 0; 243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o FILE *f; 253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o read_bitmaps(fs); 273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * If we're appending to the bad blocks inode, read in the 303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * current bad blocks. 313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!replace_bad_blocks) { 333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_read_bb_inode(fs, &bb_list); 343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_read_bb_inode", retval, 363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while reading the bad blocks inode"); 373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 403839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 413839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 423839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Now read in the bad blocks from the file. 433839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 443839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o f = fopen(bad_blocks_file, "r"); 453839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!f) { 463839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("read_bad_blocks_file", errno, 473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while trying to open %s", bad_blocks_file); 483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); 513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fclose (f); 523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_read_bb_FILE", retval, 543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while reading in list of bad blocks from file"); 553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 563839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 573839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 593839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Finally, update the bad blocks from the bad_block_map 603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_update_bb_inode(fs, bb_list); 623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_update_bb_inode", retval, 643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while updating bad block inode"); 653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 663839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 673839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o badblocks_list_free(bb_list); 693839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return; 703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'ovoid test_disk(ext2_filsys fs) 733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 753839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o badblocks_list bb_list = 0; 763839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o FILE *f; 773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char buf[1024]; 783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o read_bitmaps(fs); 803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Always read in the current list of bad blocks. 833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_read_bb_inode(fs, &bb_list); 853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_read_bb_inode", retval, 873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while reading the bad blocks inode"); 883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Now run the bad blocks program 933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o sprintf(buf, "badblocks %s%s %ld", preen ? "" : "-s ", 953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fs->device_name, 963839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fs->super->s_blocks_count); 973839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (verbose) 983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o printf("Running command: %s\n", buf); 993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o f = popen(buf, "r"); 1003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (!f) { 1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("popen", errno, 1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while trying to run %s", buf); 1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); 1063839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fclose (f); 1073839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 1083839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_read_bb_FILE", retval, 1093839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while processing list of bad blocks from program"); 1103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 1113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 1143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Finally, update the bad blocks from the bad_block_map 1153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 1163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_update_bb_inode(fs, bb_list); 1173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) { 1183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o com_err("ext2fs_update_bb_inode", retval, 1193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o "while updating bad block inode"); 1203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fatal_error(0); 1213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 1233839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o badblocks_list_free(bb_list); 1243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return; 1253839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 1263839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 127