]>
Commit | Line | Data |
---|---|---|
3839e657 TT |
1 | /* |
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> | |
50e1e10f TT |
9 | #ifdef HAVE_ERRNO_H |
10 | #include <errno.h> | |
11 | #endif | |
3839e657 TT |
12 | |
13 | #include <et/com_err.h> | |
14 | #include "e2fsck.h" | |
15 | ||
f3db3566 TT |
16 | static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt, |
17 | void *private); | |
18 | ||
19 | ||
3839e657 TT |
20 | static void invalid_block(ext2_filsys fs, blk_t blk) |
21 | { | |
50e1e10f | 22 | printf("Bad block %u out of range; ignored.\n", blk); |
3839e657 TT |
23 | return; |
24 | } | |
25 | ||
26 | void 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; | |
74becf3c | 32 | char buf[1024]; |
3839e657 TT |
33 | |
34 | read_bitmaps(fs); | |
f3db3566 TT |
35 | |
36 | /* | |
37 | * Make sure the bad block inode is sane. If there are any | |
38 | * illegal blocks, clear them. | |
39 | */ | |
40 | retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0, | |
41 | check_bb_inode_blocks, 0); | |
42 | if (retval) { | |
43 | com_err("ext2fs_block_iterate", retval, | |
44 | "while sanity checking the bad blocks inode"); | |
45 | fatal_error(0); | |
46 | } | |
47 | ||
3839e657 TT |
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 | /* | |
74becf3c TT |
62 | * Now read in the bad blocks from the file; if |
63 | * bad_blocks_file is null, then try to run the badblocks | |
64 | * command. | |
3839e657 | 65 | */ |
74becf3c TT |
66 | if (bad_blocks_file) { |
67 | f = fopen(bad_blocks_file, "r"); | |
68 | if (!f) { | |
69 | com_err("read_bad_blocks_file", errno, | |
70 | "while trying to open %s", bad_blocks_file); | |
71 | fatal_error(0); | |
72 | } | |
73 | } else { | |
f635d7f6 TT |
74 | sprintf(buf, "badblocks -b %d %s%s %d", fs->blocksize, |
75 | preen ? "" : "-s ", fs->device_name, | |
74becf3c TT |
76 | fs->super->s_blocks_count); |
77 | f = popen(buf, "r"); | |
78 | if (!f) { | |
79 | com_err("read_bad_blocks_file", errno, | |
80 | "while trying popen '%s'", buf); | |
81 | fatal_error(0); | |
82 | } | |
3839e657 TT |
83 | } |
84 | retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); | |
74becf3c TT |
85 | if (bad_blocks_file) |
86 | fclose(f); | |
87 | else | |
88 | pclose(f); | |
3839e657 TT |
89 | if (retval) { |
90 | com_err("ext2fs_read_bb_FILE", retval, | |
91 | "while reading in list of bad blocks from file"); | |
92 | fatal_error(0); | |
93 | } | |
94 | ||
95 | /* | |
96 | * Finally, update the bad blocks from the bad_block_map | |
97 | */ | |
98 | retval = ext2fs_update_bb_inode(fs, bb_list); | |
99 | if (retval) { | |
100 | com_err("ext2fs_update_bb_inode", retval, | |
101 | "while updating bad block inode"); | |
102 | fatal_error(0); | |
103 | } | |
104 | ||
105 | badblocks_list_free(bb_list); | |
106 | return; | |
107 | } | |
108 | ||
74becf3c TT |
109 | void test_disk(ext2_filsys fs) |
110 | { | |
111 | read_bad_blocks_file(fs, 0, 1); | |
112 | } | |
113 | ||
f3db3566 TT |
114 | static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt, |
115 | void *private) | |
116 | { | |
117 | if (!*block_nr) | |
118 | return 0; | |
119 | ||
120 | /* | |
121 | * If the block number is outrageous, clear it and ignore it. | |
122 | */ | |
123 | if (*block_nr >= fs->super->s_blocks_count || | |
124 | *block_nr < fs->super->s_first_data_block) { | |
50e1e10f | 125 | printf("Warning illegal block %u found in bad block inode. Cleared.\n", *block_nr); |
f3db3566 TT |
126 | *block_nr = 0; |
127 | return BLOCK_CHANGED; | |
128 | } | |
129 | ||
130 | return 0; | |
131 | } | |
132 |