blob: f0613d9dc764ae3f1d2c981ea542d69414a5bb08 [file] [log] [blame]
Theodore Ts'o3839e651997-04-26 13:21:57 +00001/*
2 * badblocks.c --- replace/append bad blocks to the bad block inode
3 *
4 * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
5 * redistributed under the terms of the GNU Public License.
6 */
7
8#include <time.h>
Theodore Ts'o50e1e101997-04-26 13:58:21 +00009#ifdef HAVE_ERRNO_H
10#include <errno.h>
11#endif
Theodore Ts'o3839e651997-04-26 13:21:57 +000012
13#include <et/com_err.h>
14#include "e2fsck.h"
15
Theodore Ts'of3db3561997-04-26 13:34:30 +000016static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
17 void *private);
18
19
Theodore Ts'o3839e651997-04-26 13:21:57 +000020static void invalid_block(ext2_filsys fs, blk_t blk)
21{
Theodore Ts'o50e1e101997-04-26 13:58:21 +000022 printf("Bad block %u out of range; ignored.\n", blk);
Theodore Ts'o3839e651997-04-26 13:21:57 +000023 return;
24}
25
26void read_bad_blocks_file(ext2_filsys fs, const char *bad_blocks_file,
27 int replace_bad_blocks)
28{
29 errcode_t retval;
30 badblocks_list bb_list = 0;
31 FILE *f;
32
33 read_bitmaps(fs);
Theodore Ts'of3db3561997-04-26 13:34:30 +000034
35 /*
36 * Make sure the bad block inode is sane. If there are any
37 * illegal blocks, clear them.
38 */
39 retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
40 check_bb_inode_blocks, 0);
41 if (retval) {
42 com_err("ext2fs_block_iterate", retval,
43 "while sanity checking the bad blocks inode");
44 fatal_error(0);
45 }
46
Theodore Ts'o3839e651997-04-26 13:21:57 +000047
48 /*
49 * If we're appending to the bad blocks inode, read in the
50 * current bad blocks.
51 */
52 if (!replace_bad_blocks) {
53 retval = ext2fs_read_bb_inode(fs, &bb_list);
54 if (retval) {
55 com_err("ext2fs_read_bb_inode", retval,
56 "while reading the bad blocks inode");
57 fatal_error(0);
58 }
59 }
60
61 /*
62 * Now read in the bad blocks from the file.
63 */
64 f = fopen(bad_blocks_file, "r");
65 if (!f) {
66 com_err("read_bad_blocks_file", errno,
67 "while trying to open %s", bad_blocks_file);
68 fatal_error(0);
69 }
70 retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
71 fclose (f);
72 if (retval) {
73 com_err("ext2fs_read_bb_FILE", retval,
74 "while reading in list of bad blocks from file");
75 fatal_error(0);
76 }
77
78 /*
79 * Finally, update the bad blocks from the bad_block_map
80 */
81 retval = ext2fs_update_bb_inode(fs, bb_list);
82 if (retval) {
83 com_err("ext2fs_update_bb_inode", retval,
84 "while updating bad block inode");
85 fatal_error(0);
86 }
87
88 badblocks_list_free(bb_list);
89 return;
90}
91
Theodore Ts'of3db3561997-04-26 13:34:30 +000092static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
93 void *private)
94{
95 if (!*block_nr)
96 return 0;
97
98 /*
99 * If the block number is outrageous, clear it and ignore it.
100 */
101 if (*block_nr >= fs->super->s_blocks_count ||
102 *block_nr < fs->super->s_first_data_block) {
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000103 printf("Warning illegal block %u found in bad block inode. Cleared.\n", *block_nr);
Theodore Ts'of3db3561997-04-26 13:34:30 +0000104 *block_nr = 0;
105 return BLOCK_CHANGED;
106 }
107
108 return 0;
109}
110
Theodore Ts'o3839e651997-04-26 13:21:57 +0000111void test_disk(ext2_filsys fs)
112{
113 errcode_t retval;
114 badblocks_list bb_list = 0;
115 FILE *f;
116 char buf[1024];
117
118 read_bitmaps(fs);
119
120 /*
121 * Always read in the current list of bad blocks.
122 */
123 retval = ext2fs_read_bb_inode(fs, &bb_list);
124 if (retval) {
125 com_err("ext2fs_read_bb_inode", retval,
126 "while reading the bad blocks inode");
127 fatal_error(0);
128 }
129
130 /*
131 * Now run the bad blocks program
132 */
Theodore Ts'o50e1e101997-04-26 13:58:21 +0000133 sprintf(buf, "badblocks %s%s %d", preen ? "" : "-s ",
Theodore Ts'o3839e651997-04-26 13:21:57 +0000134 fs->device_name,
135 fs->super->s_blocks_count);
136 if (verbose)
137 printf("Running command: %s\n", buf);
138 f = popen(buf, "r");
139 if (!f) {
140 com_err("popen", errno,
141 "while trying to run %s", buf);
142 fatal_error(0);
143 }
144 retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
145 fclose (f);
146 if (retval) {
147 com_err("ext2fs_read_bb_FILE", retval,
148 "while processing list of bad blocks from program");
149 fatal_error(0);
150 }
151
152 /*
153 * Finally, update the bad blocks from the bad_block_map
154 */
155 retval = ext2fs_update_bb_inode(fs, bb_list);
156 if (retval) {
157 com_err("ext2fs_update_bb_inode", retval,
158 "while updating bad block inode");
159 fatal_error(0);
160 }
161
162 badblocks_list_free(bb_list);
163 return;
164}
165