diff options
author | Rob Landley <rob@landley.net> | 2006-05-05 17:29:09 +0000 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2006-05-05 17:29:09 +0000 |
commit | d8f6601502d8b0c124c3389a9c32b85d36f33869 (patch) | |
tree | bc84566f7142bb02dfc3a1178e5bce73ba7b62a0 /e2fsprogs | |
parent | 2c39eee805e4bc875eab737e529feb0c4c91f50e (diff) | |
download | busybox-w32-d8f6601502d8b0c124c3389a9c32b85d36f33869.tar.gz busybox-w32-d8f6601502d8b0c124c3389a9c32b85d36f33869.tar.bz2 busybox-w32-d8f6601502d8b0c124c3389a9c32b85d36f33869.zip |
Another patch from Garrett: remove bad block bitmap checking code. Everything
produced in the list ten years has some variant of internal error correction
(disks, cdrom, flash), so if it has user-visible bad blocks on it the
hardware has exhausted its remapping reserve and is dying, and you need to get
your data off pronto. (The one exception I can think of is floppies, and I
don't care.)
Diffstat (limited to 'e2fsprogs')
-rw-r--r-- | e2fsprogs/e2fsck.c | 427 | ||||
-rw-r--r-- | e2fsprogs/e2fsck.h | 2 |
2 files changed, 10 insertions, 419 deletions
diff --git a/e2fsprogs/e2fsck.c b/e2fsprogs/e2fsck.c index 7e1c82e54..eadb0f64d 100644 --- a/e2fsprogs/e2fsck.c +++ b/e2fsprogs/e2fsck.c | |||
@@ -101,7 +101,6 @@ struct problem_context { | |||
101 | }; | 101 | }; |
102 | 102 | ||
103 | 103 | ||
104 | |||
105 | /* | 104 | /* |
106 | * Function declarations | 105 | * Function declarations |
107 | */ | 106 | */ |
@@ -227,124 +226,6 @@ static void do_cache_destroy(kmem_cache_t *cache) | |||
227 | free(cache); | 226 | free(cache); |
228 | } | 227 | } |
229 | 228 | ||
230 | /* | ||
231 | * badblocks.c --- replace/append bad blocks to the bad block inode | ||
232 | */ | ||
233 | |||
234 | static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt, | ||
235 | void *priv_data); | ||
236 | |||
237 | |||
238 | static void invalid_block(ext2_filsys fs FSCK_ATTR((unused)), blk_t blk) | ||
239 | { | ||
240 | printf(_("Bad block %u out of range; ignored.\n"), blk); | ||
241 | return; | ||
242 | } | ||
243 | |||
244 | static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file, | ||
245 | int replace_bad_blocks) | ||
246 | { | ||
247 | ext2_filsys fs = ctx->fs; | ||
248 | errcode_t retval; | ||
249 | badblocks_list bb_list = 0; | ||
250 | FILE *f; | ||
251 | char buf[1024]; | ||
252 | |||
253 | e2fsck_read_bitmaps(ctx); | ||
254 | |||
255 | /* | ||
256 | * Make sure the bad block inode is sane. If there are any | ||
257 | * illegal blocks, clear them. | ||
258 | */ | ||
259 | retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0, | ||
260 | check_bb_inode_blocks, 0); | ||
261 | if (retval) { | ||
262 | bb_error_msg(_("while sanity checking the bad blocks inode")); | ||
263 | goto fatal; | ||
264 | } | ||
265 | |||
266 | /* | ||
267 | * If we're appending to the bad blocks inode, read in the | ||
268 | * current bad blocks. | ||
269 | */ | ||
270 | if (!replace_bad_blocks) { | ||
271 | retval = ext2fs_read_bb_inode(fs, &bb_list); | ||
272 | if (retval) { | ||
273 | bb_error_msg(_("while reading the bad blocks inode")); | ||
274 | goto fatal; | ||
275 | } | ||
276 | } | ||
277 | |||
278 | /* | ||
279 | * Now read in the bad blocks from the file; if | ||
280 | * bad_blocks_file is null, then try to run the badblocks | ||
281 | * command. | ||
282 | */ | ||
283 | if (bad_blocks_file) { | ||
284 | f = fopen(bad_blocks_file, "r"); | ||
285 | if (!f) { | ||
286 | bb_error_msg(_("while trying to open %s"), bad_blocks_file); | ||
287 | goto fatal; | ||
288 | } | ||
289 | } else { | ||
290 | sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize, | ||
291 | (ctx->options & E2F_OPT_PREEN) ? "" : "-s ", | ||
292 | (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "", | ||
293 | fs->device_name, fs->super->s_blocks_count); | ||
294 | f = popen(buf, "r"); | ||
295 | if (!f) { | ||
296 | bb_error_msg(_("while trying popen '%s'"), buf); | ||
297 | goto fatal; | ||
298 | } | ||
299 | } | ||
300 | retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block); | ||
301 | if (bad_blocks_file) | ||
302 | fclose(f); | ||
303 | else | ||
304 | pclose(f); | ||
305 | if (retval) { | ||
306 | bb_error_msg(_("while reading in list of bad blocks from file")); | ||
307 | goto fatal; | ||
308 | } | ||
309 | |||
310 | /* | ||
311 | * Finally, update the bad blocks from the bad_block_map | ||
312 | */ | ||
313 | retval = ext2fs_update_bb_inode(fs, bb_list); | ||
314 | if (retval) { | ||
315 | bb_error_msg(_("while updating bad block inode")); | ||
316 | goto fatal; | ||
317 | } | ||
318 | |||
319 | ext2fs_badblocks_list_free(bb_list); | ||
320 | return; | ||
321 | |||
322 | fatal: | ||
323 | ctx->flags |= E2F_FLAG_ABORT; | ||
324 | return; | ||
325 | |||
326 | } | ||
327 | |||
328 | static int check_bb_inode_blocks(ext2_filsys fs, | ||
329 | blk_t *block_nr, | ||
330 | int blockcnt FSCK_ATTR((unused)), | ||
331 | void *priv_data FSCK_ATTR((unused))) | ||
332 | { | ||
333 | if (!*block_nr) | ||
334 | return 0; | ||
335 | |||
336 | /* | ||
337 | * If the block number is outrageous, clear it and ignore it. | ||
338 | */ | ||
339 | if (*block_nr >= fs->super->s_blocks_count || | ||
340 | *block_nr < fs->super->s_first_data_block) { | ||
341 | printf(_("Warning illegal block %u found in bad block inode. Cleared.\n"), *block_nr); | ||
342 | *block_nr = 0; | ||
343 | return BLOCK_CHANGED; | ||
344 | } | ||
345 | |||
346 | return 0; | ||
347 | } | ||
348 | 229 | ||
349 | /* | 230 | /* |
350 | * Dictionary Abstract Data Type | 231 | * Dictionary Abstract Data Type |
@@ -1081,8 +962,6 @@ static errcode_t e2fsck_reset_context(e2fsck_t ctx) | |||
1081 | ctx->block_dup_map = 0; | 962 | ctx->block_dup_map = 0; |
1082 | ext2fs_free_block_bitmap(ctx->block_ea_map); | 963 | ext2fs_free_block_bitmap(ctx->block_ea_map); |
1083 | ctx->block_ea_map = 0; | 964 | ctx->block_ea_map = 0; |
1084 | ext2fs_free_inode_bitmap(ctx->inode_bb_map); | ||
1085 | ctx->inode_bb_map = 0; | ||
1086 | ext2fs_free_inode_bitmap(ctx->inode_bad_map); | 965 | ext2fs_free_inode_bitmap(ctx->inode_bad_map); |
1087 | ctx->inode_bad_map = 0; | 966 | ctx->inode_bad_map = 0; |
1088 | ext2fs_free_inode_bitmap(ctx->inode_imagic_map); | 967 | ext2fs_free_inode_bitmap(ctx->inode_imagic_map); |
@@ -1107,7 +986,6 @@ static errcode_t e2fsck_reset_context(e2fsck_t ctx) | |||
1107 | ctx->fs_fast_symlinks_count = 0; | 986 | ctx->fs_fast_symlinks_count = 0; |
1108 | ctx->fs_fifo_count = 0; | 987 | ctx->fs_fifo_count = 0; |
1109 | ctx->fs_total_count = 0; | 988 | ctx->fs_total_count = 0; |
1110 | ctx->fs_badblocks_count = 0; | ||
1111 | ctx->fs_sockets_count = 0; | 989 | ctx->fs_sockets_count = 0; |
1112 | ctx->fs_ind_count = 0; | 990 | ctx->fs_ind_count = 0; |
1113 | ctx->fs_dind_count = 0; | 991 | ctx->fs_dind_count = 0; |
@@ -2983,7 +2861,6 @@ static int region_allocate(region_t region, region_addr_t start, int n) | |||
2983 | * - A bitmap of which inodes are directories. (inode_dir_map) | 2861 | * - A bitmap of which inodes are directories. (inode_dir_map) |
2984 | * - A bitmap of which inodes are regular files. (inode_reg_map) | 2862 | * - A bitmap of which inodes are regular files. (inode_reg_map) |
2985 | * - A bitmap of which inodes have bad fields. (inode_bad_map) | 2863 | * - A bitmap of which inodes have bad fields. (inode_bad_map) |
2986 | * - A bitmap of which inodes are in bad blocks. (inode_bb_map) | ||
2987 | * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) | 2864 | * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) |
2988 | * - A bitmap of which blocks are in use. (block_found_map) | 2865 | * - A bitmap of which blocks are in use. (block_found_map) |
2989 | * - A bitmap of which blocks are in use by two inodes (block_dup_map) | 2866 | * - A bitmap of which blocks are in use by two inodes (block_dup_map) |
@@ -3009,7 +2886,6 @@ static int process_bad_block(ext2_filsys fs, blk_t *block_nr, | |||
3009 | static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, | 2886 | static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, |
3010 | char *block_buf); | 2887 | char *block_buf); |
3011 | static void mark_table_blocks(e2fsck_t ctx); | 2888 | static void mark_table_blocks(e2fsck_t ctx); |
3012 | static void alloc_bb_map(e2fsck_t ctx); | ||
3013 | static void alloc_imagic_map(e2fsck_t ctx); | 2889 | static void alloc_imagic_map(e2fsck_t ctx); |
3014 | static void mark_inode_bad(e2fsck_t ctx, ino_t ino); | 2890 | static void mark_inode_bad(e2fsck_t ctx, ino_t ino); |
3015 | static void handle_fs_bad_blocks(e2fsck_t ctx); | 2891 | static void handle_fs_bad_blocks(e2fsck_t ctx); |
@@ -3462,10 +3338,6 @@ static void e2fsck_pass1(e2fsck_t ctx) | |||
3462 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | 3338 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) |
3463 | return; | 3339 | return; |
3464 | if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { | 3340 | if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { |
3465 | if (!ctx->inode_bb_map) | ||
3466 | alloc_bb_map(ctx); | ||
3467 | ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino); | ||
3468 | ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); | ||
3469 | continue; | 3341 | continue; |
3470 | } | 3342 | } |
3471 | if (pctx.errcode) { | 3343 | if (pctx.errcode) { |
@@ -3947,26 +3819,6 @@ static void mark_inode_bad(e2fsck_t ctx, ino_t ino) | |||
3947 | 3819 | ||
3948 | 3820 | ||
3949 | /* | 3821 | /* |
3950 | * This procedure will allocate the inode "bb" (badblock) map table | ||
3951 | */ | ||
3952 | static void alloc_bb_map(e2fsck_t ctx) | ||
3953 | { | ||
3954 | struct problem_context pctx; | ||
3955 | |||
3956 | clear_problem_context(&pctx); | ||
3957 | pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, | ||
3958 | _("inode in bad block map"), | ||
3959 | &ctx->inode_bb_map); | ||
3960 | if (pctx.errcode) { | ||
3961 | pctx.num = 4; | ||
3962 | fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); | ||
3963 | /* Should never get here */ | ||
3964 | ctx->flags |= E2F_FLAG_ABORT; | ||
3965 | return; | ||
3966 | } | ||
3967 | } | ||
3968 | |||
3969 | /* | ||
3970 | * This procedure will allocate the inode imagic table | 3822 | * This procedure will allocate the inode imagic table |
3971 | */ | 3823 | */ |
3972 | static void alloc_imagic_map(e2fsck_t ctx) | 3824 | static void alloc_imagic_map(e2fsck_t ctx) |
@@ -4570,222 +4422,20 @@ mark_dir: | |||
4570 | return ret_code; | 4422 | return ret_code; |
4571 | } | 4423 | } |
4572 | 4424 | ||
4573 | static int process_bad_block(ext2_filsys fs, | 4425 | static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)), |
4574 | blk_t *block_nr, | 4426 | blk_t *block_nr, |
4575 | e2_blkcnt_t blockcnt, | 4427 | e2_blkcnt_t blockcnt, |
4576 | blk_t ref_block FSCK_ATTR((unused)), | 4428 | blk_t ref_block FSCK_ATTR((unused)), |
4577 | int ref_offset FSCK_ATTR((unused)), | 4429 | int ref_offset FSCK_ATTR((unused)), |
4578 | void *priv_data) | 4430 | void *priv_data EXT2FS_ATTR((unused))) |
4579 | { | 4431 | { |
4580 | struct process_block_struct_1 *p; | ||
4581 | blk_t blk = *block_nr; | ||
4582 | blk_t first_block; | ||
4583 | dgrp_t i; | ||
4584 | struct problem_context *pctx; | ||
4585 | e2fsck_t ctx; | ||
4586 | |||
4587 | /* | 4432 | /* |
4588 | * Note: This function processes blocks for the bad blocks | 4433 | * Note: This function processes blocks for the bad blocks |
4589 | * inode, which is never compressed. So we don't use HOLE_BLKADDR(). | 4434 | * inode, which is never compressed. So we don't use HOLE_BLKADDR(). |
4590 | */ | 4435 | */ |
4591 | 4436 | ||
4592 | if (!blk) | 4437 | printf("Unrecoverable Error: Found %lli bad blocks starting at block number: %u\n", blockcnt, *block_nr); |
4593 | return 0; | 4438 | return BLOCK_ERROR; |
4594 | |||
4595 | p = (struct process_block_struct_1 *) priv_data; | ||
4596 | ctx = p->ctx; | ||
4597 | pctx = p->pctx; | ||
4598 | |||
4599 | pctx->ino = EXT2_BAD_INO; | ||
4600 | pctx->blk = blk; | ||
4601 | pctx->blkcount = blockcnt; | ||
4602 | |||
4603 | if ((blk < fs->super->s_first_data_block) || | ||
4604 | (blk >= fs->super->s_blocks_count)) { | ||
4605 | if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) { | ||
4606 | *block_nr = 0; | ||
4607 | return BLOCK_CHANGED; | ||
4608 | } else | ||
4609 | return 0; | ||
4610 | } | ||
4611 | |||
4612 | if (blockcnt < 0) { | ||
4613 | if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) { | ||
4614 | p->bbcheck = 1; | ||
4615 | if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) { | ||
4616 | *block_nr = 0; | ||
4617 | return BLOCK_CHANGED; | ||
4618 | } | ||
4619 | } else if (ext2fs_test_block_bitmap(ctx->block_found_map, | ||
4620 | blk)) { | ||
4621 | p->bbcheck = 1; | ||
4622 | if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, | ||
4623 | pctx)) { | ||
4624 | *block_nr = 0; | ||
4625 | return BLOCK_CHANGED; | ||
4626 | } | ||
4627 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | ||
4628 | return BLOCK_ABORT; | ||
4629 | } else | ||
4630 | mark_block_used(ctx, blk); | ||
4631 | return 0; | ||
4632 | } | ||
4633 | |||
4634 | ctx->fs_badblocks_count++; | ||
4635 | /* | ||
4636 | * If the block is not used, then mark it as used and return. | ||
4637 | * If it is already marked as found, this must mean that | ||
4638 | * there's an overlap between the filesystem table blocks | ||
4639 | * (bitmaps and inode table) and the bad block list. | ||
4640 | */ | ||
4641 | if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) { | ||
4642 | ext2fs_mark_block_bitmap(ctx->block_found_map, blk); | ||
4643 | return 0; | ||
4644 | } | ||
4645 | /* | ||
4646 | * Try to find the where the filesystem block was used... | ||
4647 | */ | ||
4648 | first_block = fs->super->s_first_data_block; | ||
4649 | |||
4650 | for (i = 0; i < fs->group_desc_count; i++ ) { | ||
4651 | pctx->group = i; | ||
4652 | pctx->blk = blk; | ||
4653 | if (!ext2fs_bg_has_super(fs, i)) | ||
4654 | goto skip_super; | ||
4655 | if (blk == first_block) { | ||
4656 | if (i == 0) { | ||
4657 | if (fix_problem(ctx, | ||
4658 | PR_1_BAD_PRIMARY_SUPERBLOCK, | ||
4659 | pctx)) { | ||
4660 | *block_nr = 0; | ||
4661 | return BLOCK_CHANGED; | ||
4662 | } | ||
4663 | return 0; | ||
4664 | } | ||
4665 | fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx); | ||
4666 | return 0; | ||
4667 | } | ||
4668 | if ((blk > first_block) && | ||
4669 | (blk <= first_block + fs->desc_blocks)) { | ||
4670 | if (i == 0) { | ||
4671 | pctx->blk = *block_nr; | ||
4672 | if (fix_problem(ctx, | ||
4673 | PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) { | ||
4674 | *block_nr = 0; | ||
4675 | return BLOCK_CHANGED; | ||
4676 | } | ||
4677 | return 0; | ||
4678 | } | ||
4679 | fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx); | ||
4680 | return 0; | ||
4681 | } | ||
4682 | skip_super: | ||
4683 | if (blk == fs->group_desc[i].bg_block_bitmap) { | ||
4684 | if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) { | ||
4685 | ctx->invalid_block_bitmap_flag[i]++; | ||
4686 | ctx->invalid_bitmaps++; | ||
4687 | } | ||
4688 | return 0; | ||
4689 | } | ||
4690 | if (blk == fs->group_desc[i].bg_inode_bitmap) { | ||
4691 | if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) { | ||
4692 | ctx->invalid_inode_bitmap_flag[i]++; | ||
4693 | ctx->invalid_bitmaps++; | ||
4694 | } | ||
4695 | return 0; | ||
4696 | } | ||
4697 | if ((blk >= fs->group_desc[i].bg_inode_table) && | ||
4698 | (blk < (fs->group_desc[i].bg_inode_table + | ||
4699 | fs->inode_blocks_per_group))) { | ||
4700 | /* | ||
4701 | * If there are bad blocks in the inode table, | ||
4702 | * the inode scan code will try to do | ||
4703 | * something reasonable automatically. | ||
4704 | */ | ||
4705 | return 0; | ||
4706 | } | ||
4707 | first_block += fs->super->s_blocks_per_group; | ||
4708 | } | ||
4709 | /* | ||
4710 | * If we've gotten to this point, then the only | ||
4711 | * possibility is that the bad block inode meta data | ||
4712 | * is using a bad block. | ||
4713 | */ | ||
4714 | if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) || | ||
4715 | (blk == p->inode->i_block[EXT2_DIND_BLOCK]) || | ||
4716 | (blk == p->inode->i_block[EXT2_TIND_BLOCK])) { | ||
4717 | p->bbcheck = 1; | ||
4718 | if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) { | ||
4719 | *block_nr = 0; | ||
4720 | return BLOCK_CHANGED; | ||
4721 | } | ||
4722 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | ||
4723 | return BLOCK_ABORT; | ||
4724 | return 0; | ||
4725 | } | ||
4726 | |||
4727 | pctx->group = -1; | ||
4728 | |||
4729 | /* Warn user that the block wasn't claimed */ | ||
4730 | fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx); | ||
4731 | |||
4732 | return 0; | ||
4733 | } | ||
4734 | |||
4735 | static void new_table_block(e2fsck_t ctx, blk_t first_block, int group, | ||
4736 | const char *name, int num, blk_t *new_block) | ||
4737 | { | ||
4738 | ext2_filsys fs = ctx->fs; | ||
4739 | blk_t old_block = *new_block; | ||
4740 | int i; | ||
4741 | char *buf; | ||
4742 | struct problem_context pctx; | ||
4743 | |||
4744 | clear_problem_context(&pctx); | ||
4745 | |||
4746 | pctx.group = group; | ||
4747 | pctx.blk = old_block; | ||
4748 | pctx.str = name; | ||
4749 | |||
4750 | pctx.errcode = ext2fs_get_free_blocks(fs, first_block, | ||
4751 | first_block + fs->super->s_blocks_per_group, | ||
4752 | num, ctx->block_found_map, new_block); | ||
4753 | if (pctx.errcode) { | ||
4754 | pctx.num = num; | ||
4755 | fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx); | ||
4756 | ext2fs_unmark_valid(fs); | ||
4757 | return; | ||
4758 | } | ||
4759 | pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf); | ||
4760 | if (pctx.errcode) { | ||
4761 | fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx); | ||
4762 | ext2fs_unmark_valid(fs); | ||
4763 | return; | ||
4764 | } | ||
4765 | ext2fs_mark_super_dirty(fs); | ||
4766 | fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; | ||
4767 | pctx.blk2 = *new_block; | ||
4768 | fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO : | ||
4769 | PR_1_RELOC_TO), &pctx); | ||
4770 | pctx.blk2 = 0; | ||
4771 | for (i = 0; i < num; i++) { | ||
4772 | pctx.blk = i; | ||
4773 | ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i); | ||
4774 | if (old_block) { | ||
4775 | pctx.errcode = io_channel_read_blk(fs->io, | ||
4776 | old_block + i, 1, buf); | ||
4777 | if (pctx.errcode) | ||
4778 | fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx); | ||
4779 | } else | ||
4780 | memset(buf, 0, fs->blocksize); | ||
4781 | |||
4782 | pctx.blk = (*new_block) + i; | ||
4783 | pctx.errcode = io_channel_write_blk(fs->io, pctx.blk, | ||
4784 | 1, buf); | ||
4785 | if (pctx.errcode) | ||
4786 | fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx); | ||
4787 | } | ||
4788 | ext2fs_free_mem(&buf); | ||
4789 | } | 4439 | } |
4790 | 4440 | ||
4791 | /* | 4441 | /* |
@@ -4797,28 +4447,8 @@ static void new_table_block(e2fsck_t ctx, blk_t first_block, int group, | |||
4797 | */ | 4447 | */ |
4798 | static void handle_fs_bad_blocks(e2fsck_t ctx) | 4448 | static void handle_fs_bad_blocks(e2fsck_t ctx) |
4799 | { | 4449 | { |
4800 | ext2_filsys fs = ctx->fs; | 4450 | printf("Bad blocks detected on your filesystem\n" |
4801 | dgrp_t i; | 4451 | "You should get your data off as the device will soon die\n"); |
4802 | int first_block = fs->super->s_first_data_block; | ||
4803 | |||
4804 | for (i = 0; i < fs->group_desc_count; i++) { | ||
4805 | if (ctx->invalid_block_bitmap_flag[i]) { | ||
4806 | new_table_block(ctx, first_block, i, _("block bitmap"), | ||
4807 | 1, &fs->group_desc[i].bg_block_bitmap); | ||
4808 | } | ||
4809 | if (ctx->invalid_inode_bitmap_flag[i]) { | ||
4810 | new_table_block(ctx, first_block, i, _("inode bitmap"), | ||
4811 | 1, &fs->group_desc[i].bg_inode_bitmap); | ||
4812 | } | ||
4813 | if (ctx->invalid_inode_table_flag[i]) { | ||
4814 | new_table_block(ctx, first_block, i, _("inode table"), | ||
4815 | fs->inode_blocks_per_group, | ||
4816 | &fs->group_desc[i].bg_inode_table); | ||
4817 | ctx->flags |= E2F_FLAG_RESTART; | ||
4818 | } | ||
4819 | first_block += fs->super->s_blocks_per_group; | ||
4820 | } | ||
4821 | ctx->invalid_bitmaps = 0; | ||
4822 | } | 4452 | } |
4823 | 4453 | ||
4824 | /* | 4454 | /* |
@@ -6579,14 +6209,6 @@ static int check_dir_block(ext2_filsys fs, | |||
6579 | * If the inode is unused, offer to clear it. | 6209 | * If the inode is unused, offer to clear it. |
6580 | */ | 6210 | */ |
6581 | problem = PR_2_UNUSED_INODE; | 6211 | problem = PR_2_UNUSED_INODE; |
6582 | } else if (ctx->inode_bb_map && | ||
6583 | (ext2fs_test_inode_bitmap(ctx->inode_bb_map, | ||
6584 | dirent->inode))) { | ||
6585 | /* | ||
6586 | * If the inode is in a bad block, offer to | ||
6587 | * clear it. | ||
6588 | */ | ||
6589 | problem = PR_2_BB_INODE; | ||
6590 | } else if ((dot_state > 1) && | 6212 | } else if ((dot_state > 1) && |
6591 | ((dirent->name_len & 0xFF) == 1) && | 6213 | ((dirent->name_len & 0xFF) == 1) && |
6592 | (dirent->name[0] == '.')) { | 6214 | (dirent->name[0] == '.')) { |
@@ -7863,7 +7485,6 @@ errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir, | |||
7863 | * pass4.c -- pass #4 of e2fsck: Check reference counts | 7485 | * pass4.c -- pass #4 of e2fsck: Check reference counts |
7864 | * | 7486 | * |
7865 | * Pass 4 frees the following data structures: | 7487 | * Pass 4 frees the following data structures: |
7866 | * - A bitmap of which inodes are in bad blocks. (inode_bb_map) | ||
7867 | * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) | 7488 | * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) |
7868 | */ | 7489 | */ |
7869 | 7490 | ||
@@ -7967,9 +7588,7 @@ static void e2fsck_pass4(e2fsck_t ctx) | |||
7967 | continue; | 7588 | continue; |
7968 | if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) || | 7589 | if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) || |
7969 | (ctx->inode_imagic_map && | 7590 | (ctx->inode_imagic_map && |
7970 | ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) || | 7591 | ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i))) |
7971 | (ctx->inode_bb_map && | ||
7972 | ext2fs_test_inode_bitmap(ctx->inode_bb_map, i))) | ||
7973 | continue; | 7592 | continue; |
7974 | ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count); | 7593 | ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count); |
7975 | ext2fs_icount_fetch(ctx->inode_count, i, &link_counted); | 7594 | ext2fs_icount_fetch(ctx->inode_count, i, &link_counted); |
@@ -8004,8 +7623,6 @@ static void e2fsck_pass4(e2fsck_t ctx) | |||
8004 | } | 7623 | } |
8005 | ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0; | 7624 | ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0; |
8006 | ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0; | 7625 | ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0; |
8007 | ext2fs_free_inode_bitmap(ctx->inode_bb_map); | ||
8008 | ctx->inode_bb_map = 0; | ||
8009 | ext2fs_free_inode_bitmap(ctx->inode_imagic_map); | 7626 | ext2fs_free_inode_bitmap(ctx->inode_imagic_map); |
8010 | ctx->inode_imagic_map = 0; | 7627 | ctx->inode_imagic_map = 0; |
8011 | ext2fs_free_mem(&buf); | 7628 | ext2fs_free_mem(&buf); |
@@ -12981,10 +12598,6 @@ static int cflag; /* check disk */ | |||
12981 | static int show_version_only; | 12598 | static int show_version_only; |
12982 | static int verbose; | 12599 | static int verbose; |
12983 | 12600 | ||
12984 | static int replace_bad_blocks; | ||
12985 | static int keep_bad_blocks; | ||
12986 | static char *bad_blocks_file; | ||
12987 | |||
12988 | #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural) | 12601 | #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural) |
12989 | 12602 | ||
12990 | static void show_stats(e2fsck_t ctx) | 12603 | static void show_stats(e2fsck_t ctx) |
@@ -13024,7 +12637,6 @@ static void show_stats(e2fsck_t ctx) | |||
13024 | ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count); | 12637 | ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count); |
13025 | printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used), | 12638 | printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used), |
13026 | (int) ((long long) 100 * blocks_used / blocks)); | 12639 | (int) ((long long) 100 * blocks_used / blocks)); |
13027 | printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count)); | ||
13028 | printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files)); | 12640 | printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files)); |
13029 | printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count)); | 12641 | printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count)); |
13030 | printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count)); | 12642 | printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count)); |
@@ -13131,8 +12743,7 @@ static void check_if_skip(e2fsck_t ctx) | |||
13131 | int batt = is_on_batt(); | 12743 | int batt = is_on_batt(); |
13132 | time_t now = time(0); | 12744 | time_t now = time(0); |
13133 | 12745 | ||
13134 | if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file || | 12746 | if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs) |
13135 | cflag || swapfs) | ||
13136 | return; | 12747 | return; |
13137 | 12748 | ||
13138 | if ((fs->super->s_state & EXT2_ERROR_FS) || | 12749 | if ((fs->super->s_state & EXT2_ERROR_FS) || |
@@ -13519,11 +13130,6 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) | |||
13519 | case 'P': | 13130 | case 'P': |
13520 | ctx->process_inode_size = atoi(optarg); | 13131 | ctx->process_inode_size = atoi(optarg); |
13521 | break; | 13132 | break; |
13522 | case 'L': | ||
13523 | replace_bad_blocks++; | ||
13524 | case 'l': | ||
13525 | bad_blocks_file = string_copy(optarg, 0); | ||
13526 | break; | ||
13527 | case 'd': | 13133 | case 'd': |
13528 | ctx->options |= E2F_OPT_DEBUG; | 13134 | ctx->options |= E2F_OPT_DEBUG; |
13529 | break; | 13135 | break; |
@@ -13556,9 +13162,6 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) | |||
13556 | "of e2fsck\n")); | 13162 | "of e2fsck\n")); |
13557 | exit(1); | 13163 | exit(1); |
13558 | #endif | 13164 | #endif |
13559 | case 'k': | ||
13560 | keep_bad_blocks++; | ||
13561 | break; | ||
13562 | default: | 13165 | default: |
13563 | bb_show_usage(); | 13166 | bb_show_usage(); |
13564 | } | 13167 | } |
@@ -13566,7 +13169,7 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) | |||
13566 | return 0; | 13169 | return 0; |
13567 | if (optind != argc - 1) | 13170 | if (optind != argc - 1) |
13568 | bb_show_usage(); | 13171 | bb_show_usage(); |
13569 | if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file && | 13172 | if ((ctx->options & E2F_OPT_NO) && |
13570 | !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS)) | 13173 | !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS)) |
13571 | ctx->options |= E2F_OPT_READONLY; | 13174 | ctx->options |= E2F_OPT_READONLY; |
13572 | ctx->io_options = strchr(argv[optind], '?'); | 13175 | ctx->io_options = strchr(argv[optind], '?'); |
@@ -13595,19 +13198,13 @@ static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx) | |||
13595 | close(fd); | 13198 | close(fd); |
13596 | } | 13199 | } |
13597 | #ifdef ENABLE_SWAPFS | 13200 | #ifdef ENABLE_SWAPFS |
13598 | if (swapfs) { | 13201 | if (swapfs && cflag) { |
13599 | if (cflag || bad_blocks_file) { | ||
13600 | fprintf(stderr, _("Incompatible options not " | 13202 | fprintf(stderr, _("Incompatible options not " |
13601 | "allowed when byte-swapping.\n")); | 13203 | "allowed when byte-swapping.\n")); |
13602 | exit(EXIT_USAGE); | 13204 | exit(EXIT_USAGE); |
13603 | } | 13205 | } |
13604 | } | 13206 | } |
13605 | #endif | 13207 | #endif |
13606 | if (cflag && bad_blocks_file) { | ||
13607 | fprintf(stderr, _("The -c and the -l/-L options may " | ||
13608 | "not be both used at the same time.\n")); | ||
13609 | exit(EXIT_USAGE); | ||
13610 | } | ||
13611 | /* | 13208 | /* |
13612 | * Set up signal action | 13209 | * Set up signal action |
13613 | */ | 13210 | */ |
@@ -13873,10 +13470,6 @@ restart: | |||
13873 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | 13470 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) |
13874 | bb_error_msg_and_die(0); | 13471 | bb_error_msg_and_die(0); |
13875 | check_if_skip(ctx); | 13472 | check_if_skip(ctx); |
13876 | if (bad_blocks_file) | ||
13877 | read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks); | ||
13878 | else if (cflag) | ||
13879 | read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */ | ||
13880 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) | 13473 | if (ctx->flags & E2F_FLAG_SIGNAL_MASK) |
13881 | bb_error_msg_and_die(0); | 13474 | bb_error_msg_and_die(0); |
13882 | #ifdef ENABLE_SWAPFS | 13475 | #ifdef ENABLE_SWAPFS |
diff --git a/e2fsprogs/e2fsck.h b/e2fsprogs/e2fsck.h index 0957f20a8..43080d24e 100644 --- a/e2fsprogs/e2fsck.h +++ b/e2fsprogs/e2fsck.h | |||
@@ -518,7 +518,6 @@ struct e2fsck_struct { | |||
518 | ext2fs_inode_bitmap inode_used_map; /* Inodes which are in use */ | 518 | ext2fs_inode_bitmap inode_used_map; /* Inodes which are in use */ |
519 | ext2fs_inode_bitmap inode_bad_map; /* Inodes which are bad somehow */ | 519 | ext2fs_inode_bitmap inode_bad_map; /* Inodes which are bad somehow */ |
520 | ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */ | 520 | ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */ |
521 | ext2fs_inode_bitmap inode_bb_map; /* Inodes which are in bad blocks */ | ||
522 | ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */ | 521 | ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */ |
523 | ext2fs_inode_bitmap inode_reg_map; /* Inodes which are regular files*/ | 522 | ext2fs_inode_bitmap inode_reg_map; /* Inodes which are regular files*/ |
524 | 523 | ||
@@ -612,7 +611,6 @@ struct e2fsck_struct { | |||
612 | int fs_fast_symlinks_count; | 611 | int fs_fast_symlinks_count; |
613 | int fs_fifo_count; | 612 | int fs_fifo_count; |
614 | int fs_total_count; | 613 | int fs_total_count; |
615 | int fs_badblocks_count; | ||
616 | int fs_sockets_count; | 614 | int fs_sockets_count; |
617 | int fs_ind_count; | 615 | int fs_ind_count; |
618 | int fs_dind_count; | 616 | int fs_dind_count; |