2 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
4 * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be
5 * redistributed under the terms of the GNU Public License.
7 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
8 * and applies the following tests to each inode:
10 * - The mode field of the inode must be legal.
11 * - The size and block count fields of the inode are correct.
12 * - A data block must not be used by another inode
14 * Pass 1 also gathers the collects the following information:
16 * - A bitmap of which inodes are in use. (inode_used_map)
17 * - A bitmap of which inodes are directories. (inode_dir_map)
18 * - A bitmap of which inodes have bad fields. (inode_bad_map)
19 * - A bitmap of which blocks are in use. (block_found_map)
20 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
21 * - The data blocks of the directory inodes. (dir_map)
23 * Pass 1 is designed to stash away enough information so that the
24 * other passes should not need to read in the inode information
25 * during the normal course of a filesystem check. (Althogh if an
26 * inconsistency is detected, other passes may need to read in an
29 * Note that pass 1B will be invoked if there are any duplicate blocks
35 #include <et/com_err.h>
39 int fs_directory_count
= 0;
40 int fs_regular_count
= 0;
41 int fs_blockdev_count
= 0;
42 int fs_chardev_count
= 0;
43 int fs_links_count
= 0;
44 int fs_symlinks_count
= 0;
45 int fs_fast_symlinks_count
= 0;
46 int fs_fifo_count
= 0;
47 int fs_total_count
= 0;
48 int fs_badblocks_count
= 0;
49 int fs_sockets_count
= 0;
51 ext2fs_inode_bitmap inode_used_map
= 0; /* Inodes which are in use */
52 ext2fs_inode_bitmap inode_bad_map
= 0; /* Inodes which are bad in some way */
53 ext2fs_inode_bitmap inode_dir_map
= 0; /* Inodes which are directories */
55 ext2fs_block_bitmap block_found_map
= 0;
56 ext2fs_block_bitmap block_dup_map
= 0;
58 static int fix_link_count
= -1;
60 unsigned short * inode_link_info
= NULL
;
62 static int process_block(ext2_filsys fs
, blk_t
*blocknr
,
63 int blockcnt
, void *private);
64 static int process_bad_block(ext2_filsys fs
, blk_t
*block_nr
,
65 int blockcnt
, void *private);
66 static void check_blocks(ext2_filsys fs
, ino_t ino
, struct ext2_inode
*inode
,
68 static void mark_table_blocks(ext2_filsys fs
);
69 static errcode_t
pass1_check_directory(ext2_filsys fs
, ino_t ino
);
70 static errcode_t
pass1_get_blocks(ext2_filsys fs
, ino_t ino
, blk_t
*blocks
);
71 static void alloc_bad_map(ext2_filsys fs
);
72 static void handle_fs_bad_blocks(ext2_filsys fs
);
73 static void process_inodes(ext2_filsys fs
, char *block_buf
);
74 static int process_inode_cmp(const void *a
, const void *b
);
75 static int dir_block_cmp(const void *a
, const void *b
);
76 static errcode_t
scan_callback(ext2_filsys fs
, ext2_inode_scan scan
,
77 dgrp_t group
, void * private);
79 struct process_block_struct
{
81 int is_dir
:1, clear
:1, suppress
:1;
84 int num_illegal_blocks
;
86 struct ext2_inode
*inode
;
89 struct process_inode_block
{
91 struct ext2_inode inode
;
95 * For pass1_check_directory and pass1_get_blocks
98 struct ext2_inode
*stashed_inode
;
101 * For the inodes to process list.
103 static struct process_inode_block
*inodes_to_process
;
104 static int process_inode_count
;
105 int process_inode_size
= 256;
108 * For the directory blocks list.
110 struct dir_block_struct
*dir_blocks
= 0;
111 int dir_block_count
= 0;
112 int dir_block_size
= 0;
115 * Free all memory allocated by pass1 in preparation for restarting
118 static void unwind_pass1(ext2_filsys fs
)
120 ext2fs_free_inode_bitmap(inode_used_map
); inode_used_map
= 0;
121 ext2fs_free_inode_bitmap(inode_dir_map
); inode_dir_map
= 0;
122 ext2fs_free_block_bitmap(block_found_map
); block_found_map
= 0;
123 free(inode_link_info
); inode_link_info
= 0;
124 free(inodes_to_process
);inodes_to_process
= 0;
125 free(dir_blocks
); dir_blocks
= 0;
128 free(block_dup_map
); block_dup_map
= 0;
131 /* Clear statistic counters */
132 fs_directory_count
= 0;
133 fs_regular_count
= 0;
134 fs_blockdev_count
= 0;
135 fs_chardev_count
= 0;
137 fs_symlinks_count
= 0;
138 fs_fast_symlinks_count
= 0;
141 fs_badblocks_count
= 0;
142 fs_sockets_count
= 0;
145 void pass1(ext2_filsys fs
)
148 struct ext2_inode inode
;
149 ext2_inode_scan scan
;
152 struct resource_track rtrack
;
154 init_resource_track(&rtrack
);
157 printf("Pass 1: Checking inodes, blocks, and sizes\n");
160 mtrace_print("Pass 1");
164 * Allocate bitmaps structures
166 retval
= ext2fs_allocate_inode_bitmap(fs
, "in-use inode map",
169 com_err("ext2fs_allocate_inode_bitmap", retval
,
170 "while allocating inode_used_map");
173 retval
= ext2fs_allocate_inode_bitmap(fs
, "directory inode map",
176 com_err("ext2fs_allocate_inode_bitmap", retval
,
177 "while allocating inode_dir_map");
180 retval
= ext2fs_allocate_block_bitmap(fs
, "in-use block map",
183 com_err("ext2fs_allocate_block_bitmap", retval
,
184 "while allocating block_found_map");
187 inode_link_info
= allocate_memory((fs
->super
->s_inodes_count
+ 1) *
188 sizeof(unsigned short),
189 "inode link count array");
190 inodes_to_process
= allocate_memory(process_inode_size
*
191 sizeof(struct process_inode_block
),
192 "array of inodes to process");
193 process_inode_count
= 0;
195 dir_block_size
= get_num_dirs(fs
) * 4;
197 dir_blocks
= allocate_memory(sizeof(struct dir_block_struct
) *
199 "directory block information");
201 mark_table_blocks(fs
);
202 block_buf
= allocate_memory(fs
->blocksize
* 3, "block interate buffer");
203 fs
->get_blocks
= pass1_get_blocks
;
204 fs
->check_directory
= pass1_check_directory
;
205 ehandler_operation("doing inode scan");
206 retval
= ext2fs_open_inode_scan(fs
, inode_buffer_blocks
, &scan
);
208 com_err(program_name
, retval
, "while opening inode scan");
211 retval
= ext2fs_get_next_inode(scan
, &ino
, &inode
);
213 com_err(program_name
, retval
, "while starting inode scan");
216 stashed_inode
= &inode
;
217 ext2fs_set_inode_callback(scan
, scan_callback
, block_buf
);
220 inode_link_info
[ino
] = inode
.i_links_count
;
221 if (ino
== EXT2_BAD_INO
) {
222 struct process_block_struct pb
;
224 pb
.ino
= EXT2_BAD_INO
;
225 pb
.num_blocks
= pb
.last_block
= 0;
226 pb
.num_illegal_blocks
= 0;
227 pb
.suppress
= pb
.clear
= pb
.is_dir
= 0;
230 retval
= ext2fs_block_iterate(fs
, ino
, 0, block_buf
,
231 process_bad_block
, &pb
);
233 com_err(program_name
, retval
, "while calling e2fsc_block_interate in pass 1");
235 ext2fs_mark_inode_bitmap(inode_used_map
, ino
);
238 if (ino
== EXT2_ROOT_INO
) {
240 * Make sure the root inode is a directory; if
241 * not, offer to clear it. It will be
242 * regnerated in pass #3.
244 if (!S_ISDIR(inode
.i_mode
)) {
245 printf("Root inode is not a directory. ");
247 if (ask("Clear", 1)) {
248 inode
.i_dtime
= time(0);
249 inode
.i_links_count
= 0;
250 inode_link_info
[ino
] = 0;
251 e2fsck_write_inode(fs
, ino
, &inode
,
254 ext2fs_unmark_valid(fs
);
257 * If dtime is set, offer to clear it. mke2fs
258 * version 0.2b created filesystems with the
259 * dtime field set for the root and lost+found
260 * directories. We won't worry about
261 * /lost+found, since that can be regenerated
262 * easily. But we will fix the root directory
265 if (inode
.i_dtime
&& inode
.i_links_count
) {
266 if (ask("Root inode has dtime set "
267 "(probably due to old mke2fs). Fix",
270 e2fsck_write_inode(fs
, ino
, &inode
,
272 printf("Note: /lost+found will "
273 "probably be deleted as well, "
274 "due to the mke2fs bug.\n"
275 "Be sure to run mklost+found "
276 "to recreate it after e2fsck "
279 ext2fs_unmark_valid(fs
);
282 if ((ino
!= EXT2_ROOT_INO
) && (ino
< EXT2_FIRST_INO
)) {
283 ext2fs_mark_inode_bitmap(inode_used_map
, ino
);
284 check_blocks(fs
, ino
, &inode
, block_buf
);
288 * This code assumes that deleted inodes have
289 * i_links_count set to 0.
291 if (!inode
.i_links_count
) {
292 if (!inode
.i_dtime
&& inode
.i_mode
) {
293 printf("Deleted inode %lu has zero dtime.\n",
295 if (ask("Set dtime", 1)) {
296 inode
.i_dtime
= time(0);
297 e2fsck_write_inode(fs
, ino
, &inode
,
300 ext2fs_unmark_valid(fs
);
305 * 0.3c ext2fs code didn't clear i_links_count for
306 * deleted files. Oops.
308 * In the future, when the new ext2fs behavior is the
309 * norm, we may want to handle the case of a non-zero
310 * i_links_count and non-zero dtime by clearing dtime
311 * and assuming the inode is in use, instead of
312 * assuming the inode is not in use.
315 if (fix_link_count
== -1) {
316 printf("\nDeleted inode detected with non-zero link count.\n");
317 printf("This is probably due to old ext2fs kernel code. \n");
318 fix_link_count
= ask("Fix inode(s)", 1);
320 printf("Inode %lu is deleted w/ non-zero link_count. %s\n",
321 ino
, clear_msg
[fix_link_count
]);
322 if (fix_link_count
) {
323 inode
.i_links_count
= 0;
324 inode_link_info
[ino
] = 0;
325 e2fsck_write_inode(fs
, ino
, &inode
, "pass1");
327 ext2fs_unmark_valid(fs
);
331 ext2fs_mark_inode_bitmap(inode_used_map
, ino
);
332 if (inode
.i_faddr
|| inode
.i_frag
|| inode
.i_fsize
||
333 inode
.i_file_acl
|| inode
.i_dir_acl
) {
336 ext2fs_mark_inode_bitmap(inode_bad_map
, ino
);
339 if (S_ISDIR(inode
.i_mode
)) {
340 ext2fs_mark_inode_bitmap(inode_dir_map
, ino
);
341 add_dir_info(fs
, ino
, 0, &inode
);
342 fs_directory_count
++;
343 } else if (S_ISREG (inode
.i_mode
))
345 else if (S_ISCHR (inode
.i_mode
))
347 else if (S_ISBLK (inode
.i_mode
))
349 else if (S_ISLNK (inode
.i_mode
)) {
352 fs_fast_symlinks_count
++;
354 else if (S_ISFIFO (inode
.i_mode
))
356 else if (S_ISSOCK (inode
.i_mode
))
361 ext2fs_mark_inode_bitmap(inode_bad_map
, ino
);
363 if (inode
.i_block
[EXT2_IND_BLOCK
] ||
364 inode
.i_block
[EXT2_DIND_BLOCK
] ||
365 inode
.i_block
[EXT2_TIND_BLOCK
]) {
366 inodes_to_process
[process_inode_count
].ino
= ino
;
367 inodes_to_process
[process_inode_count
].inode
= inode
;
368 process_inode_count
++;
370 check_blocks(fs
, ino
, &inode
, block_buf
);
372 if (process_inode_count
>= process_inode_size
)
373 process_inodes(fs
, block_buf
);
375 retval
= ext2fs_get_next_inode(scan
, &ino
, &inode
);
377 com_err(program_name
, retval
,
378 "while doing inode scan");
382 process_inodes(fs
, block_buf
);
383 ext2fs_close_inode_scan(scan
);
384 ehandler_operation(0);
386 qsort(dir_blocks
, dir_block_count
, sizeof(struct dir_block_struct
),
390 handle_fs_bad_blocks(fs
);
392 if (restart_e2fsck
) {
399 printf("Duplicate or bad blocks in use!\n");
402 pass1_dupblocks(fs
, block_buf
);
405 fs
->check_directory
= 0;
406 free(inodes_to_process
);
411 print_resource_track(&rtrack
);
416 * When the inode_scan routines call this callback at the end of the
417 * glock group, call process_inodes.
419 static errcode_t
scan_callback(ext2_filsys fs
, ext2_inode_scan scan
,
420 dgrp_t group
, void * private)
422 process_inodes(fs
, (char *) private);
427 * Process the inodes in the "inodes to process" list.
429 static void process_inodes(ext2_filsys fs
, char *block_buf
)
432 struct ext2_inode
*old_stashed_inode
;
434 const char *old_operation
;
438 printf("begin process_inodes: ");
440 old_operation
= ehandler_operation(0);
441 old_stashed_inode
= stashed_inode
;
442 qsort(inodes_to_process
, process_inode_count
,
443 sizeof(struct process_inode_block
), process_inode_cmp
);
444 for (i
=0; i
< process_inode_count
; i
++) {
445 stashed_inode
= &inodes_to_process
[i
].inode
;
446 ino
= inodes_to_process
[i
].ino
;
451 sprintf(buf
, "reading indirect blocks of inode %lu", ino
);
452 ehandler_operation(buf
);
453 check_blocks(fs
, ino
, stashed_inode
, block_buf
);
456 stashed_inode
= old_stashed_inode
;
457 process_inode_count
= 0;
459 printf("end process inodes\n");
461 ehandler_operation(old_operation
);
464 static int process_inode_cmp(const void *a
, const void *b
)
466 const struct process_inode_block
*ib_a
=
467 (const struct process_inode_block
*) a
;
468 const struct process_inode_block
*ib_b
=
469 (const struct process_inode_block
*) b
;
471 return (ib_a
->inode
.i_block
[EXT2_IND_BLOCK
] -
472 ib_b
->inode
.i_block
[EXT2_IND_BLOCK
]);
475 static int dir_block_cmp(const void *a
, const void *b
)
477 const struct dir_block_struct
*db_a
=
478 (const struct dir_block_struct
*) a
;
479 const struct dir_block_struct
*db_b
=
480 (const struct dir_block_struct
*) b
;
482 return (db_a
->blk
- db_b
->blk
);
486 * This procedure will allocate the inode bad map table
488 static void alloc_bad_map(ext2_filsys fs
)
492 retval
= ext2fs_allocate_inode_bitmap(fs
, "bad inode map",
495 com_err("ext2fs_allocate_inode_bitmap", retval
,
496 "while allocating inode_bad_map");
502 * Marks a block as in use, setting the dup_map if it's been set
503 * already. Called by process_block and process_bad_block.
505 static void mark_block_used(ext2_filsys fs
, blk_t block
)
509 if (ext2fs_test_block_bitmap(block_found_map
, block
)) {
510 if (!block_dup_map
) {
511 retval
= ext2fs_allocate_block_bitmap(fs
,
512 "multiply claimed block map", &block_dup_map
);
514 com_err("ext2fs_allocate_block_bitmap", retval
,
515 "while allocating block_dup_map");
519 ext2fs_mark_block_bitmap(block_dup_map
, block
);
521 ext2fs_mark_block_bitmap(block_found_map
, block
);
526 * This subroutine is called on each inode to account for all of the
527 * blocks used by that inode.
529 static void check_blocks(ext2_filsys fs
, ino_t ino
, struct ext2_inode
*inode
,
532 struct process_block_struct pb
;
535 if (!inode_has_valid_blocks(inode
))
539 pb
.num_blocks
= pb
.last_block
= 0;
540 pb
.num_illegal_blocks
= 0;
541 pb
.suppress
= pb
.clear
= 0;
542 pb
.is_dir
= S_ISDIR(inode
->i_mode
);
545 retval
= ext2fs_block_iterate(fs
, ino
, 0, block_buf
,
548 com_err(program_name
, retval
,
549 "while calling ext2fs_block_iterate in check_blocks");
552 e2fsck_read_inode(fs
, ino
, inode
, "check_blocks");
554 com_err("check_blocks", retval
,
555 "while reading to be cleared inode %d", ino
);
558 inode
->i_links_count
= 0;
559 inode_link_info
[ino
] = 0;
560 inode
->i_dtime
= time(0);
561 e2fsck_write_inode(fs
, ino
, inode
, "check_blocks");
562 ext2fs_unmark_inode_bitmap(inode_dir_map
, ino
);
563 ext2fs_unmark_inode_bitmap(inode_used_map
, ino
);
565 * The inode was probably partially accounted for
566 * before processing was aborted, so we need to
567 * restart the pass 1 scan.
574 e2fsck_read_inode(fs
, ino
, inode
, "check_blocks");
576 pb
.num_blocks
*= (fs
->blocksize
/ 512);
578 printf("inode %lu, i_size = %lu, last_block = %lu, i_blocks=%lu, num_blocks = %lu\n",
579 ino
, inode
->i_size
, pb
.last_block
, inode
->i_blocks
,
582 if (!pb
.num_blocks
&& pb
.is_dir
) {
583 printf("Inode %lu is a zero length directory. ", ino
);
584 if (ask("Clear", 1)) {
585 inode
->i_links_count
= 0;
586 inode_link_info
[ino
] = 0;
587 inode
->i_dtime
= time(0);
588 e2fsck_write_inode(fs
, ino
, inode
, "check_blocks");
589 ext2fs_unmark_inode_bitmap(inode_dir_map
, ino
);
590 ext2fs_unmark_inode_bitmap(inode_used_map
, ino
);
591 fs_directory_count
--;
593 ext2fs_unmark_valid(fs
);
595 if (inode
->i_size
< pb
.last_block
* fs
->blocksize
) {
596 printf ("Inode %lu, incorrect size, %lu (counted = %u). ",
598 (pb
.last_block
+1) * fs
->blocksize
);
599 if (ask ("Set size to counted", 1)) {
600 inode
->i_size
= (pb
.last_block
+1) * fs
->blocksize
;
601 e2fsck_write_inode(fs
, ino
, inode
, "check_blocks");
603 ext2fs_unmark_valid(fs
);
605 if (pb
.num_blocks
!= inode
->i_blocks
) {
606 printf ("Inode %lu, i_blocks wrong %lu (counted=%u). ",
607 ino
, inode
->i_blocks
, pb
.num_blocks
);
608 if (ask ("Set i_blocks to counted", 1)) {
609 inode
->i_blocks
= pb
.num_blocks
;
610 e2fsck_write_inode(fs
, ino
, inode
, "check_blocks");
612 ext2fs_unmark_valid(fs
);
617 * This is a helper function for check_blocks().
619 int process_block(ext2_filsys fs
,
624 struct process_block_struct
*p
;
626 int illegal_block
= 0;
628 blk_t firstblock
, group_super
;
629 blk_t blk
= *block_nr
;
633 p
= (struct process_block_struct
*) private;
636 printf("Process_block, inode %lu, block %lu, #%d\n", p
->ino
, blk
,
640 firstblock
= fs
->super
->s_first_data_block
;
641 group
= (blk
- firstblock
) / fs
->super
->s_blocks_per_group
;
642 group_super
= ((group
* fs
->super
->s_blocks_per_group
) +
643 fs
->super
->s_first_data_block
);
644 if (blk
< firstblock
) {
645 sprintf(problem
, "< FIRSTBLOCK (%lu)", firstblock
);
647 } else if (blk
>= fs
->super
->s_blocks_count
) {
648 sprintf(problem
, "> BLOCKS (%lu)", fs
->super
->s_blocks_count
);
650 } else if (blk
== group_super
) {
651 sprintf(problem
, "is the superblock in group %d", group
);
653 } else if (blk
> group_super
&&
654 blk
<= (group_super
+ fs
->desc_blocks
)) {
655 sprintf(problem
, "is in the group descriptors in group %d",
658 } else if (blk
== fs
->group_desc
[group
].bg_block_bitmap
) {
659 sprintf(problem
, "is the block bitmap of group %d", group
);
661 } else if (blk
== fs
->group_desc
[group
].bg_inode_bitmap
) {
662 sprintf(problem
, "is the inode bitmap of group %d", group
);
664 } else if (blk
>= fs
->group_desc
[group
].bg_inode_table
&&
665 blk
< fs
->group_desc
[group
].bg_inode_table
+ fs
->inode_blocks_per_group
) {
666 sprintf(problem
, "is in the inode table of group %d", group
);
671 printf("Block %lu of inode %lu %s\n", blk
, p
->ino
,
676 printf("Remove illegal block(s) in inode %lu", p
->ino
);
679 p
->num_illegal_blocks
++;
680 if (!p
->suppress
&& (p
->num_illegal_blocks
% 20) == 0) {
681 printf("Too many illegal blocks in inode %lu.\n",
683 if (ask("Clear inode", 1)) {
687 if (ask("Supress messages", 0)) {
692 printf("Block #%d (%lu) %s. %s\n", blockcnt
, blk
,
693 problem
, clear_msg
[p
->fix
]);
696 return BLOCK_CHANGED
;
698 ext2fs_unmark_valid(fs
);
705 p
->last_block
= blockcnt
;
706 mark_block_used(fs
, blk
);
708 if (p
->is_dir
&& (blockcnt
>= 0)) {
709 if (dir_block_count
>= dir_block_size
) {
710 dir_block_size
+= 100;
711 dir_blocks
= realloc(dir_blocks
,
713 sizeof(struct dir_block_struct
));
716 dir_blocks
[dir_block_count
].blk
= blk
;
717 dir_blocks
[dir_block_count
].ino
= p
->ino
;
718 dir_blocks
[dir_block_count
].blockcnt
= blockcnt
;
723 printf("process block, inode %lu, block #%d is %lu\n",
724 p
->ino
, blockcnt
, blk
);
730 static void bad_block_indirect(blk_t blk
)
732 printf("Bad block %lu used as bad block indirect block?!?\n", blk
);
734 printf("\nThis inconsistency can not be fixed with "
735 "e2fsck; to fix it, use\n"
736 """dumpe2fs -b"" to dump out the bad block "
737 "list and ""e2fsck -L filename""\n"
738 "to read it back in again.\n");
739 if (ask("Continue", 0))
744 int process_bad_block(ext2_filsys fs
,
749 struct process_block_struct
*p
;
750 blk_t blk
= *block_nr
;
756 p
= (struct process_block_struct
*) private;
758 if ((blk
< fs
->super
->s_first_data_block
) ||
759 (blk
>= fs
->super
->s_blocks_count
)) {
761 printf("Illegal block %lu in bad block inode\n", blk
);
765 p
->fix
= ask("Remove illegal block(s) in bad block inode", 1);
766 printf("Illegal block %lu in bad block inode. %s\n", blk
,
770 return BLOCK_CHANGED
;
772 ext2fs_unmark_valid(fs
);
778 if (ext2fs_test_block_bitmap(block_found_map
, blk
))
779 bad_block_indirect(blk
);
781 mark_block_used(fs
, blk
);
785 printf ("DEBUG: Marking %lu as bad.\n", blk
);
787 fs_badblocks_count
++;
789 * If the block is not used, then mark it as used and return.
790 * If it is already marked as found, this must mean that
791 * there's an overlap between the filesystem table blocks
792 * (bitmaps and inode table) and the bad block list.
794 if (!ext2fs_test_block_bitmap(block_found_map
, blk
)) {
795 ext2fs_mark_block_bitmap(block_found_map
, blk
);
799 * Try to find the where the filesystem block was used...
801 first_block
= fs
->super
->s_first_data_block
;
803 for (i
= 0; i
< fs
->group_desc_count
; i
++ ) {
804 if (blk
== first_block
) {
806 printf("The primary superblock (%lu) is "
807 "bad. Aiiieeee....\n", blk
);
811 printf("Warning: Group %d's superblock "
812 "(%lu) is bad.\n", i
, blk
);
815 if ((blk
> first_block
) &&
816 (blk
<= first_block
+ fs
->desc_blocks
)) {
818 printf("Bad block %lu is in the primary "
819 "group descriptors. Aiiieeee....\n",
824 printf("Warning: Group %d's copy of the "
825 "group descriptors has a bad "
826 "block (%lu).\n", i
, blk
);
829 if (blk
== fs
->group_desc
[i
].bg_block_bitmap
) {
830 printf("Group %d's block bitmap (%lu) is bad. ",
832 if (ask("Relocate", 1)) {
833 invalid_block_bitmap
[i
]++;
836 ext2fs_unmark_valid(fs
);
839 if (blk
== fs
->group_desc
[i
].bg_inode_bitmap
) {
840 printf("Group %d's inode bitmap (%lu) is bad. ",
842 if (ask("Relocate", 1)) {
843 invalid_inode_bitmap
[i
]++;
846 ext2fs_unmark_valid(fs
);
849 if ((blk
>= fs
->group_desc
[i
].bg_inode_table
) &&
850 (blk
< (fs
->group_desc
[i
].bg_inode_table
+
851 fs
->inode_blocks_per_group
))) {
852 printf("WARNING: Severe data loss possible!!!!\n");
853 printf("Bad block %lu in group %d's inode table. ",
855 if (ask("Relocate", 1)) {
856 invalid_inode_table
[i
]++;
859 ext2fs_unmark_valid(fs
);
862 first_block
+= fs
->super
->s_blocks_per_group
;
865 * If we've gotten to this point, then the only
866 * possibility is that the bad block inode meta data
867 * is using a bad block.
869 if ((blk
== p
->inode
->i_block
[EXT2_IND_BLOCK
]) ||
870 p
->inode
->i_block
[EXT2_DIND_BLOCK
]) {
871 bad_block_indirect(blk
);
875 printf("Programming error? block #%lu claimed for no reason "
876 "in process_bad_block.\n", blk
);
880 static void new_table_block(ext2_filsys fs
, blk_t first_block
, int group
,
881 const char *name
, int num
, blk_t
*new_block
)
884 blk_t old_block
= *new_block
;
888 retval
= ext2fs_get_free_blocks(fs
, first_block
,
889 first_block
+ fs
->super
->s_blocks_per_group
,
890 num
, block_found_map
, new_block
);
892 printf("Could not allocate %d block(s) for %s: %s\n",
893 num
, name
, error_message(retval
));
894 ext2fs_unmark_valid(fs
);
897 buf
= malloc(fs
->blocksize
);
899 printf("Could not allocate block buffer for relocating %s\n",
901 ext2fs_unmark_valid(fs
);
904 ext2fs_mark_super_dirty(fs
);
905 printf("Relocating group %d's %s ", group
, name
);
907 printf("from %lu ", old_block
);
908 printf("to %lu...\n", *new_block
);
909 for (i
= 0; i
< num
; i
++) {
910 ext2fs_mark_block_bitmap(block_found_map
, (*new_block
)+i
);
912 retval
= io_channel_read_blk(fs
->io
, old_block
+ i
,
915 printf("Warning: could not read block %lu "
918 error_message(retval
));
920 memset(buf
, 0, fs
->blocksize
);
922 retval
= io_channel_write_blk(fs
->io
, (*new_block
) + i
,
925 printf("Warning: could not write block %lu for %s: %s\n",
926 (*new_block
) + i
, name
, error_message(retval
));
932 * This routine gets called at the end of pass 1 if bad blocks are
933 * detected in the superblock, group descriptors, inode_bitmaps, or
934 * block bitmaps. At this point, all of the blocks have been mapped
935 * out, so we can try to allocate new block(s) to replace the bad
938 static void handle_fs_bad_blocks(ext2_filsys fs
)
941 int first_block
= fs
->super
->s_first_data_block
;
943 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
944 if (invalid_block_bitmap
[i
]) {
945 new_table_block(fs
, first_block
, i
, "block bitmap", 1,
946 &fs
->group_desc
[i
].bg_block_bitmap
);
948 if (invalid_inode_bitmap
[i
]) {
949 new_table_block(fs
, first_block
, i
, "inode bitmap", 1,
950 &fs
->group_desc
[i
].bg_inode_bitmap
);
952 if (invalid_inode_table
[i
]) {
953 new_table_block(fs
, first_block
, i
, "inode table",
954 fs
->inode_blocks_per_group
,
955 &fs
->group_desc
[i
].bg_inode_table
);
958 first_block
+= fs
->super
->s_blocks_per_group
;
964 * This routine marks all blocks which are used by the superblock,
965 * group descriptors, inode bitmaps, and block bitmaps.
967 static void mark_table_blocks(ext2_filsys fs
)
972 block
= fs
->super
->s_first_data_block
;
973 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
975 * Mark block used for the block bitmap
977 if (fs
->group_desc
[i
].bg_block_bitmap
) {
978 if (ext2fs_test_block_bitmap(block_found_map
,
979 fs
->group_desc
[i
].bg_block_bitmap
)) {
980 printf("Group %i's block bitmap at %lu "
981 "conflicts with some other fs block.\n",
982 i
, fs
->group_desc
[i
].bg_block_bitmap
);
984 if (ask("Relocate", 1)) {
985 invalid_block_bitmap
[i
]++;
988 ext2fs_unmark_valid(fs
);
991 ext2fs_mark_block_bitmap(block_found_map
,
992 fs
->group_desc
[i
].bg_block_bitmap
);
995 * Mark block used for the inode bitmap
997 if (fs
->group_desc
[i
].bg_inode_bitmap
) {
998 if (ext2fs_test_block_bitmap(block_found_map
,
999 fs
->group_desc
[i
].bg_inode_bitmap
)) {
1000 printf("Group %i's inode bitmap at %lu "
1001 "conflicts with some other fs block.\n",
1002 i
, fs
->group_desc
[i
].bg_inode_bitmap
);
1004 if (ask("Relocate", 1)) {
1005 invalid_inode_bitmap
[i
]++;
1008 ext2fs_unmark_valid(fs
);
1011 ext2fs_mark_block_bitmap(block_found_map
,
1012 fs
->group_desc
[i
].bg_inode_bitmap
);
1016 * Mark the blocks used for the inode table
1018 if (fs
->group_desc
[i
].bg_inode_table
) {
1019 for (j
= 0, b
= fs
->group_desc
[i
].bg_inode_table
;
1020 j
< fs
->inode_blocks_per_group
;
1022 if (ext2fs_test_block_bitmap(block_found_map
,
1024 printf("Group %i's inode table at %lu "
1025 "conflicts with some other "
1029 if (ask("Relocate", 1)) {
1030 invalid_inode_table
[i
]++;
1033 ext2fs_unmark_valid(fs
);
1036 ext2fs_mark_block_bitmap(block_found_map
,
1042 * Mark this group's copy of the superblock
1044 ext2fs_mark_block_bitmap(block_found_map
, block
);
1047 * Mark this group's copy of the descriptors
1049 for (j
= 0; j
< fs
->desc_blocks
; j
++)
1050 ext2fs_mark_block_bitmap(block_found_map
,
1052 block
+= fs
->super
->s_blocks_per_group
;
1057 * This subroutines short circuits ext2fs_get_blocks and
1058 * ext2fs_check_directory; we use them since we already have the inode
1059 * structure, so there's no point in letting the ext2fs library read
1062 static errcode_t
pass1_get_blocks(ext2_filsys fs
, ino_t ino
, blk_t
*blocks
)
1066 if (ino
== stashed_ino
) {
1067 for (i
=0; i
< EXT2_N_BLOCKS
; i
++)
1068 blocks
[i
] = stashed_inode
->i_block
[i
];
1071 printf("INTERNAL ERROR: pass1_get_blocks: unexpected inode #%lu\n",
1073 printf("\t(was expecting %lu)\n", stashed_ino
);
1077 static errcode_t
pass1_check_directory(ext2_filsys fs
, ino_t ino
)
1079 if (ino
== stashed_ino
) {
1080 if (!S_ISDIR(stashed_inode
->i_mode
))
1084 printf("INTERNAL ERROR: pass1_check_directory: unexpected inode #%lu\n",
1086 printf("\t(was expecting %lu)\n", stashed_ino
);