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
38 #include <et/com_err.h>
41 #ifdef NO_INLINE_FUNCS
44 #define _INLINE_ inline
48 int fs_directory_count = 0;
49 int fs_regular_count = 0;
50 int fs_blockdev_count = 0;
51 int fs_chardev_count = 0;
52 int fs_links_count = 0;
53 int fs_symlinks_count = 0;
54 int fs_fast_symlinks_count = 0;
55 int fs_fifo_count = 0;
56 int fs_total_count = 0;
57 int fs_badblocks_count = 0;
58 int fs_sockets_count = 0;
60 int fs_dind_count = 0;
61 int fs_tind_count = 0;
62 int fs_fragmented = 0;
64 ext2fs_inode_bitmap inode_used_map = 0; /* Inodes which are in use */
65 ext2fs_inode_bitmap inode_bad_map = 0; /* Inodes which are bad in some way */
66 ext2fs_inode_bitmap inode_dir_map = 0; /* Inodes which are directories */
68 ext2fs_block_bitmap block_found_map = 0;
69 ext2fs_block_bitmap block_dup_map = 0;
70 ext2fs_block_bitmap block_illegal_map = 0;
72 static int fix_link_count = -1;
74 unsigned short * inode_link_info = NULL;
76 static int process_block(ext2_filsys fs, blk_t *blocknr,
77 int blockcnt, void *private);
78 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
79 int blockcnt, void *private);
80 static void check_blocks(ext2_filsys fs, ino_t ino, struct ext2_inode *inode,
82 static void mark_table_blocks(ext2_filsys fs);
83 static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino);
84 static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks);
85 static void alloc_bad_map(ext2_filsys fs);
86 static void handle_fs_bad_blocks(ext2_filsys fs);
87 static void process_inodes(ext2_filsys fs, char *block_buf);
88 static int process_inode_cmp(const void *a, const void *b);
89 static int dir_block_cmp(const void *a, const void *b);
90 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
91 dgrp_t group, void * private);
92 static char *describe_illegal_block(ext2_filsys fs, blk_t block);
94 struct process_block_struct {
96 int is_dir:1, clear:1, suppress:1, fragmented:1;
99 int num_illegal_blocks;
101 blk_t previous_block;
102 struct ext2_inode *inode;
105 struct process_inode_block {
107 struct ext2_inode inode;
111 * For pass1_check_directory and pass1_get_blocks
114 struct ext2_inode *stashed_inode;
117 * For the inodes to process list.
119 static struct process_inode_block *inodes_to_process;
120 static int process_inode_count;
121 int process_inode_size = 256;
124 * For the directory blocks list.
126 struct dir_block_struct *dir_blocks = 0;
127 int dir_block_count = 0;
128 int dir_block_size = 0;
131 * Free all memory allocated by pass1 in preparation for restarting
134 static void unwind_pass1(ext2_filsys fs)
136 ext2fs_free_inode_bitmap(inode_used_map); inode_used_map = 0;
137 ext2fs_free_inode_bitmap(inode_dir_map); inode_dir_map = 0;
138 ext2fs_free_block_bitmap(block_found_map); block_found_map = 0;
139 free(inode_link_info); inode_link_info = 0;
140 free(inodes_to_process);inodes_to_process = 0;
141 free(dir_blocks); dir_blocks = 0;
144 ext2fs_free_block_bitmap(block_dup_map); block_dup_map = 0;
147 /* Clear statistic counters */
148 fs_directory_count = 0;
149 fs_regular_count = 0;
150 fs_blockdev_count = 0;
151 fs_chardev_count = 0;
153 fs_symlinks_count = 0;
154 fs_fast_symlinks_count = 0;
157 fs_badblocks_count = 0;
158 fs_sockets_count = 0;
165 void pass1(ext2_filsys fs)
168 struct ext2_inode inode;
169 ext2_inode_scan scan;
172 struct resource_track rtrack;
174 init_resource_track(&rtrack);
177 printf("Pass 1: Checking inodes, blocks, and sizes\n");
180 mtrace_print("Pass 1");
184 * Allocate bitmaps structures
186 retval = ext2fs_allocate_inode_bitmap(fs, "in-use inode map",
189 com_err("ext2fs_allocate_inode_bitmap", retval,
190 "while allocating inode_used_map");
193 retval = ext2fs_allocate_inode_bitmap(fs, "directory inode map",
196 com_err("ext2fs_allocate_inode_bitmap", retval,
197 "while allocating inode_dir_map");
200 retval = ext2fs_allocate_block_bitmap(fs, "in-use block map",
203 com_err("ext2fs_allocate_block_bitmap", retval,
204 "while allocating block_found_map");
207 retval = ext2fs_allocate_block_bitmap(fs, "illegal block map",
210 com_err("ext2fs_allocate_block_bitmap", retval,
211 "while allocating block_illegal_map");
214 inode_link_info = allocate_memory((fs->super->s_inodes_count + 1) *
215 sizeof(unsigned short),
216 "inode link count array");
217 inodes_to_process = allocate_memory(process_inode_size *
218 sizeof(struct process_inode_block),
219 "array of inodes to process");
220 process_inode_count = 0;
222 dir_block_size = get_num_dirs(fs) * 4;
224 dir_blocks = allocate_memory(sizeof(struct dir_block_struct) *
226 "directory block information");
228 mark_table_blocks(fs);
229 block_buf = allocate_memory(fs->blocksize * 3, "block interate buffer");
230 fs->get_blocks = pass1_get_blocks;
231 fs->check_directory = pass1_check_directory;
232 ehandler_operation("doing inode scan");
233 retval = ext2fs_open_inode_scan(fs, inode_buffer_blocks, &scan);
235 com_err(program_name, retval, "while opening inode scan");
238 retval = ext2fs_get_next_inode(scan, &ino, &inode);
240 com_err(program_name, retval, "while starting inode scan");
243 stashed_inode = &inode;
244 ext2fs_set_inode_callback(scan, scan_callback, block_buf);
247 inode_link_info[ino] = inode.i_links_count;
248 if (ino == EXT2_BAD_INO) {
249 struct process_block_struct pb;
251 pb.ino = EXT2_BAD_INO;
252 pb.num_blocks = pb.last_block = 0;
253 pb.num_illegal_blocks = 0;
254 pb.suppress = pb.clear = pb.is_dir = 0;
258 retval = ext2fs_block_iterate(fs, ino, 0, block_buf,
259 process_bad_block, &pb);
261 com_err(program_name, retval, "while calling e2fsc_block_interate in pass 1");
263 ext2fs_mark_inode_bitmap(inode_used_map, ino);
266 if (ino == EXT2_ROOT_INO) {
268 * Make sure the root inode is a directory; if
269 * not, offer to clear it. It will be
270 * regnerated in pass #3.
272 if (!LINUX_S_ISDIR(inode.i_mode)) {
273 printf("Root inode is not a directory. ");
275 if (ask("Clear", 1)) {
276 inode.i_dtime = time(0);
277 inode.i_links_count = 0;
278 inode_link_info[ino] = 0;
279 e2fsck_write_inode(fs, ino, &inode,
282 ext2fs_unmark_valid(fs);
285 * If dtime is set, offer to clear it. mke2fs
286 * version 0.2b created filesystems with the
287 * dtime field set for the root and lost+found
288 * directories. We won't worry about
289 * /lost+found, since that can be regenerated
290 * easily. But we will fix the root directory
293 if (inode.i_dtime && inode.i_links_count) {
294 if (ask("Root inode has dtime set "
295 "(probably due to old mke2fs). Fix",
298 e2fsck_write_inode(fs, ino, &inode,
300 printf("Note: /lost+found will "
301 "probably be deleted as well, "
302 "due to the mke2fs bug.\n"
303 "Be sure to run mklost+found "
304 "to recreate it after e2fsck "
307 ext2fs_unmark_valid(fs);
310 if ((ino != EXT2_ROOT_INO) &&
311 (ino < EXT2_FIRST_INODE(fs->super))) {
312 ext2fs_mark_inode_bitmap(inode_used_map, ino);
313 if (inode.i_mode != 0) {
314 printf("Reserved inode %lu has bad mode. ", ino);
315 if (ask("Clear", 1)) {
317 e2fsck_write_inode(fs, ino, &inode,
320 ext2fs_unmark_valid(fs);
322 check_blocks(fs, ino, &inode, block_buf);
326 * This code assumes that deleted inodes have
327 * i_links_count set to 0.
329 if (!inode.i_links_count) {
330 if (!inode.i_dtime && inode.i_mode) {
331 printf("Deleted inode %lu has zero dtime.\n",
333 if (ask("Set dtime", 1)) {
334 inode.i_dtime = time(0);
335 e2fsck_write_inode(fs, ino, &inode,
338 ext2fs_unmark_valid(fs);
343 * 0.3c ext2fs code didn't clear i_links_count for
344 * deleted files. Oops.
346 * In the future, when the new ext2fs behavior is the
347 * norm, we may want to handle the case of a non-zero
348 * i_links_count and non-zero dtime by clearing dtime
349 * and assuming the inode is in use, instead of
350 * assuming the inode is not in use.
353 if (fix_link_count == -1) {
354 printf("\nDeleted inode detected with non-zero link count.\n");
355 printf("This is probably due to old ext2fs kernel code. \n");
356 fix_link_count = ask("Fix inode(s)", 1);
358 printf("Inode %lu is deleted w/ non-zero link_count. %s\n",
359 ino, clear_msg[fix_link_count]);
360 if (fix_link_count) {
361 inode.i_links_count = 0;
362 inode_link_info[ino] = 0;
363 e2fsck_write_inode(fs, ino, &inode, "pass1");
365 ext2fs_unmark_valid(fs);
369 ext2fs_mark_inode_bitmap(inode_used_map, ino);
372 || inode.i_frag || inode.i_fsize
374 || inode.i_file_acl || inode.i_dir_acl) {
377 ext2fs_mark_inode_bitmap(inode_bad_map, ino);
380 if (LINUX_S_ISDIR(inode.i_mode)) {
381 ext2fs_mark_inode_bitmap(inode_dir_map, ino);
382 add_dir_info(fs, ino, 0, &inode);
383 fs_directory_count++;
384 } else if (LINUX_S_ISREG (inode.i_mode))
386 else if (LINUX_S_ISCHR (inode.i_mode))
388 else if (LINUX_S_ISBLK (inode.i_mode))
390 else if (LINUX_S_ISLNK (inode.i_mode)) {
393 fs_fast_symlinks_count++;
395 else if (LINUX_S_ISFIFO (inode.i_mode))
397 else if (LINUX_S_ISSOCK (inode.i_mode))
402 ext2fs_mark_inode_bitmap(inode_bad_map, ino);
404 if (inode.i_block[EXT2_IND_BLOCK])
406 if (inode.i_block[EXT2_DIND_BLOCK])
408 if (inode.i_block[EXT2_TIND_BLOCK])
410 if (inode.i_block[EXT2_IND_BLOCK] ||
411 inode.i_block[EXT2_DIND_BLOCK] ||
412 inode.i_block[EXT2_TIND_BLOCK]) {
413 inodes_to_process[process_inode_count].ino = ino;
414 inodes_to_process[process_inode_count].inode = inode;
415 process_inode_count++;
417 check_blocks(fs, ino, &inode, block_buf);
419 if (process_inode_count >= process_inode_size)
420 process_inodes(fs, block_buf);
422 retval = ext2fs_get_next_inode(scan, &ino, &inode);
424 com_err(program_name, retval,
425 "while doing inode scan");
429 process_inodes(fs, block_buf);
430 ext2fs_close_inode_scan(scan);
431 ehandler_operation(0);
433 qsort(dir_blocks, dir_block_count, sizeof(struct dir_block_struct),
437 handle_fs_bad_blocks(fs);
439 if (restart_e2fsck) {
446 printf("Duplicate or bad blocks in use!\n");
449 pass1_dupblocks(fs, block_buf);
452 fs->check_directory = 0;
453 free(inodes_to_process);
456 ext2fs_free_block_bitmap(block_illegal_map);
457 block_illegal_map = 0;
461 print_resource_track(&rtrack);
466 * When the inode_scan routines call this callback at the end of the
467 * glock group, call process_inodes.
469 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
470 dgrp_t group, void * private)
472 process_inodes(fs, (char *) private);
477 * Process the inodes in the "inodes to process" list.
479 static void process_inodes(ext2_filsys fs, char *block_buf)
482 struct ext2_inode *old_stashed_inode;
484 const char *old_operation;
488 printf("begin process_inodes: ");
490 old_operation = ehandler_operation(0);
491 old_stashed_inode = stashed_inode;
492 qsort(inodes_to_process, process_inode_count,
493 sizeof(struct process_inode_block), process_inode_cmp);
494 for (i=0; i < process_inode_count; i++) {
495 stashed_inode = &inodes_to_process[i].inode;
496 ino = inodes_to_process[i].ino;
501 sprintf(buf, "reading indirect blocks of inode %lu", ino);
502 ehandler_operation(buf);
503 check_blocks(fs, ino, stashed_inode, block_buf);
506 stashed_inode = old_stashed_inode;
507 process_inode_count = 0;
509 printf("end process inodes\n");
511 ehandler_operation(old_operation);
514 static int process_inode_cmp(const void *a, const void *b)
516 const struct process_inode_block *ib_a =
517 (const struct process_inode_block *) a;
518 const struct process_inode_block *ib_b =
519 (const struct process_inode_block *) b;
521 return (ib_a->inode.i_block[EXT2_IND_BLOCK] -
522 ib_b->inode.i_block[EXT2_IND_BLOCK]);
525 static int dir_block_cmp(const void *a, const void *b)
527 const struct dir_block_struct *db_a =
528 (const struct dir_block_struct *) a;
529 const struct dir_block_struct *db_b =
530 (const struct dir_block_struct *) b;
532 if (db_a->blk != db_b->blk)
533 return (db_a->blk - db_b->blk);
535 if (db_a->ino != db_b->ino)
536 return (db_a->ino - db_b->ino);
538 return (db_a->blockcnt - db_b->blockcnt);
542 * This procedure will allocate the inode bad map table
544 static void alloc_bad_map(ext2_filsys fs)
548 retval = ext2fs_allocate_inode_bitmap(fs, "bad inode map",
551 com_err("ext2fs_allocate_inode_bitmap", retval,
552 "while allocating inode_bad_map");
558 * Marks a block as in use, setting the dup_map if it's been set
559 * already. Called by process_block and process_bad_block.
561 * WARNING: Assumes checks have already been done to make sure block
562 * is valid. This is true in both process_block and process_bad_block.
564 static _INLINE_ void mark_block_used(ext2_filsys fs, blk_t block)
568 if (ext2fs_fast_test_block_bitmap(block_found_map, block)) {
569 if (!block_dup_map) {
570 retval = ext2fs_allocate_block_bitmap(fs,
571 "multiply claimed block map", &block_dup_map);
573 com_err("ext2fs_allocate_block_bitmap", retval,
574 "while allocating block_dup_map");
578 ext2fs_fast_mark_block_bitmap(block_dup_map, block);
580 ext2fs_fast_mark_block_bitmap(block_found_map, block);
585 * This subroutine is called on each inode to account for all of the
586 * blocks used by that inode.
588 static void check_blocks(ext2_filsys fs, ino_t ino, struct ext2_inode *inode,
591 struct process_block_struct pb;
594 if (!inode_has_valid_blocks(inode))
598 pb.num_blocks = pb.last_block = 0;
599 pb.num_illegal_blocks = 0;
600 pb.suppress = pb.clear = 0;
602 pb.previous_block = 0;
603 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
606 retval = ext2fs_block_iterate(fs, ino,
607 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
608 block_buf, process_block, &pb);
610 com_err(program_name, retval,
611 "while calling ext2fs_block_iterate in check_blocks");
613 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
617 e2fsck_read_inode(fs, ino, inode, "check_blocks");
619 com_err("check_blocks", retval,
620 "while reading to be cleared inode %d", ino);
623 inode->i_links_count = 0;
624 inode_link_info[ino] = 0;
625 inode->i_dtime = time(0);
626 e2fsck_write_inode(fs, ino, inode, "check_blocks");
627 ext2fs_unmark_inode_bitmap(inode_dir_map, ino);
628 ext2fs_unmark_inode_bitmap(inode_used_map, ino);
630 * The inode was probably partially accounted for
631 * before processing was aborted, so we need to
632 * restart the pass 1 scan.
639 e2fsck_read_inode(fs, ino, inode, "check_blocks");
641 pb.num_blocks *= (fs->blocksize / 512);
643 printf("inode %u, i_size = %lu, last_block = %lu, i_blocks=%lu, num_blocks = %lu\n",
644 ino, inode->i_size, pb.last_block, inode->i_blocks,
647 if (!pb.num_blocks && pb.is_dir) {
648 printf("Inode %lu is a zero length directory. ", ino);
649 if (ask("Clear", 1)) {
650 inode->i_links_count = 0;
651 inode_link_info[ino] = 0;
652 inode->i_dtime = time(0);
653 e2fsck_write_inode(fs, ino, inode, "check_blocks");
654 ext2fs_unmark_inode_bitmap(inode_dir_map, ino);
655 ext2fs_unmark_inode_bitmap(inode_used_map, ino);
656 fs_directory_count--;
659 ext2fs_unmark_valid(fs);
661 if ((pb.is_dir && (inode->i_size != (pb.last_block + 1) * fs->blocksize)) ||
662 (inode->i_size < pb.last_block * fs->blocksize)) {
663 printf ("%s %lu, incorrect size, %u (counted = %u). ",
664 pb.is_dir ? "Directory" : "Inode", ino, inode->i_size,
665 (pb.last_block+1) * fs->blocksize);
666 if (ask ("Set size to counted", 1)) {
667 inode->i_size = (pb.last_block+1) * fs->blocksize;
668 e2fsck_write_inode(fs, ino, inode, "check_blocks");
670 ext2fs_unmark_valid(fs);
672 if (pb.num_blocks != inode->i_blocks) {
673 printf ("Inode %lu, i_blocks wrong %u (counted=%u). ",
674 ino, inode->i_blocks, pb.num_blocks);
675 if (ask ("Set i_blocks to counted", 1)) {
676 inode->i_blocks = pb.num_blocks;
677 e2fsck_write_inode(fs, ino, inode, "check_blocks");
679 ext2fs_unmark_valid(fs);
684 * Helper function called by process block when an illegal block is
685 * found. It returns a description about why the block is illegal
687 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
691 static char problem[80];
693 super = fs->super->s_first_data_block;
694 strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
696 sprintf(problem, "< FIRSTBLOCK (%u)", super);
698 } else if (block >= fs->super->s_blocks_count) {
699 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
702 for (i = 0; i < fs->group_desc_count; i++) {
703 if (block == super) {
704 sprintf(problem, "is the superblock in group %d", i);
708 block <= (super + fs->desc_blocks)) {
709 sprintf(problem, "is in the group descriptors "
713 if (block == fs->group_desc[i].bg_block_bitmap) {
714 sprintf(problem, "is the block bitmap of group %d", i);
717 if (block == fs->group_desc[i].bg_inode_bitmap) {
718 sprintf(problem, "is the inode bitmap of group %d", i);
721 if (block >= fs->group_desc[i].bg_inode_table &&
722 (block < fs->group_desc[i].bg_inode_table
723 + fs->inode_blocks_per_group)) {
724 sprintf(problem, "is in the inode table of group %d",
728 super += fs->super->s_blocks_per_group;
734 * This is a helper function for check_blocks().
736 int process_block(ext2_filsys fs,
741 struct process_block_struct *p;
743 blk_t blk = *block_nr;
746 p = (struct process_block_struct *) private;
749 if (p->is_dir == 0) {
750 printf("process_block() called with blk == 0, "
751 "inode %lu???", p->ino);
756 if (blockcnt * fs->blocksize < p->inode->i_size) {
757 printf("Hole found in directory inode %lu! "
758 "(blkcnt=%d)\n", p->ino, blockcnt);
765 printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
770 * Simplistic fragmentation check. We merely require that the
771 * file be contiguous. (Which can never be true for really
772 * big files that are greater than a block group.)
774 if (p->previous_block) {
775 if (p->previous_block+1 != blk)
778 p->previous_block = blk;
781 if (blk < fs->super->s_first_data_block ||
782 blk >= fs->super->s_blocks_count ||
783 ext2fs_test_block_bitmap(block_illegal_map, blk)) {
784 problem = describe_illegal_block(fs, blk);
786 printf("Block %u of inode %lu %s\n", blk, p->ino,
791 printf("Remove illegal block(s) in inode %lu", p->ino);
794 p->num_illegal_blocks++;
795 if (!p->suppress && (p->num_illegal_blocks % 20) == 0) {
796 printf("Too many illegal blocks in inode %lu.\n",
798 if (ask("Clear inode", 1)) {
802 if (ask("Supress messages", 0)) {
807 printf("Block #%d (%u) %s. %s\n", blockcnt, blk,
808 problem, clear_msg[p->fix]);
811 ret_code = BLOCK_CHANGED;
814 ext2fs_unmark_valid(fs);
819 mark_block_used(fs, blk);
824 p->last_block = blockcnt;
827 if (dir_block_count >= dir_block_size) {
828 dir_block_size += 100;
829 dir_blocks = realloc(dir_blocks,
831 sizeof(struct dir_block_struct));
833 fatal_error("Not enough memory to "
834 "realloc dir_blocks");
837 dir_blocks[dir_block_count].blk = blk;
838 dir_blocks[dir_block_count].ino = p->ino;
839 dir_blocks[dir_block_count].blockcnt = blockcnt;
845 static void bad_block_indirect(ext2_filsys fs, blk_t blk)
847 printf("Bad block %u used as bad block indirect block?!?\n", blk);
849 printf("\nThis inconsistency can not be fixed with "
850 "e2fsck; to fix it, use\n"
851 """dumpe2fs -b"" to dump out the bad block "
852 "list and ""e2fsck -L filename""\n"
853 "to read it back in again.\n");
854 if (ask("Continue", 0))
859 static int bad_primary_block(ext2_filsys fs, blk_t *block_nr)
861 printf("\nIf the block is really bad, the filesystem can not be "
864 printf("You can clear the this block from the bad block list\n");
865 printf("and hope that block is really OK, but there are no "
867 if (ask("Clear (and hope for the best)", 1)) {
871 ext2fs_unmark_valid(fs);
875 int process_bad_block(ext2_filsys fs,
880 struct process_block_struct *p;
881 blk_t blk = *block_nr;
887 p = (struct process_block_struct *) private;
889 if ((blk < fs->super->s_first_data_block) ||
890 (blk >= fs->super->s_blocks_count)) {
892 printf("Illegal block %u in bad block inode\n", blk);
896 p->fix = ask("Remove illegal block(s) in bad block inode", 1);
897 printf("Illegal block %u in bad block inode. %s\n", blk,
901 return BLOCK_CHANGED;
903 ext2fs_unmark_valid(fs);
909 if (ext2fs_test_block_bitmap(block_found_map, blk))
910 bad_block_indirect(fs, blk);
912 mark_block_used(fs, blk);
916 printf ("DEBUG: Marking %u as bad.\n", blk);
918 fs_badblocks_count++;
920 * If the block is not used, then mark it as used and return.
921 * If it is already marked as found, this must mean that
922 * there's an overlap between the filesystem table blocks
923 * (bitmaps and inode table) and the bad block list.
925 if (!ext2fs_test_block_bitmap(block_found_map, blk)) {
926 ext2fs_mark_block_bitmap(block_found_map, blk);
930 * Try to find the where the filesystem block was used...
932 first_block = fs->super->s_first_data_block;
934 for (i = 0; i < fs->group_desc_count; i++ ) {
935 if (blk == first_block) {
937 printf("The primary superblock (%u) is "
938 "on the bad block list.\n", blk);
939 if (bad_primary_block(fs, block_nr))
940 return BLOCK_CHANGED;
944 printf("Warning: Group %d's superblock "
945 "(%u) is bad.\n", i, blk);
948 if ((blk > first_block) &&
949 (blk <= first_block + fs->desc_blocks)) {
951 printf("Block %u in the primary group "
952 "descriptors is on the bad block "
954 if (bad_primary_block(fs, block_nr))
955 return BLOCK_CHANGED;
959 printf("Warning: Group %d's copy of the "
960 "group descriptors has a bad "
961 "block (%u).\n", i, blk);
964 if (blk == fs->group_desc[i].bg_block_bitmap) {
965 printf("Group %d's block bitmap (%u) is bad. ",
967 if (ask("Relocate", 1)) {
968 invalid_block_bitmap[i]++;
971 ext2fs_unmark_valid(fs);
974 if (blk == fs->group_desc[i].bg_inode_bitmap) {
975 printf("Group %d's inode bitmap (%u) is bad. ",
977 if (ask("Relocate", 1)) {
978 invalid_inode_bitmap[i]++;
981 ext2fs_unmark_valid(fs);
984 if ((blk >= fs->group_desc[i].bg_inode_table) &&
985 (blk < (fs->group_desc[i].bg_inode_table +
986 fs->inode_blocks_per_group))) {
987 printf("WARNING: Severe data loss possible!!!!\n");
988 printf("Bad block %u in group %d's inode table. ",
990 if (ask("Relocate", 1)) {
991 invalid_inode_table[i]++;
994 ext2fs_unmark_valid(fs);
997 first_block += fs->super->s_blocks_per_group;
1000 * If we've gotten to this point, then the only
1001 * possibility is that the bad block inode meta data
1002 * is using a bad block.
1004 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
1005 p->inode->i_block[EXT2_DIND_BLOCK]) {
1006 bad_block_indirect(fs, blk);
1010 printf("Programming error? block #%u claimed for no reason "
1011 "in process_bad_block.\n", blk);
1015 static void new_table_block(ext2_filsys fs, blk_t first_block, int group,
1016 const char *name, int num, blk_t *new_block)
1019 blk_t old_block = *new_block;
1023 retval = ext2fs_get_free_blocks(fs, first_block,
1024 first_block + fs->super->s_blocks_per_group,
1025 num, block_found_map, new_block);
1027 printf("Could not allocate %d block(s) for %s: %s\n",
1028 num, name, error_message(retval));
1029 ext2fs_unmark_valid(fs);
1032 buf = malloc(fs->blocksize);
1034 printf("Could not allocate block buffer for relocating %s\n",
1036 ext2fs_unmark_valid(fs);
1039 ext2fs_mark_super_dirty(fs);
1040 printf("Relocating group %d's %s ", group, name);
1042 printf("from %u ", old_block);
1043 printf("to %u...\n", *new_block);
1044 for (i = 0; i < num; i++) {
1045 ext2fs_mark_block_bitmap(block_found_map, (*new_block)+i);
1047 retval = io_channel_read_blk(fs->io, old_block + i,
1050 printf("Warning: could not read block %u "
1052 old_block + i, name,
1053 error_message(retval));
1055 memset(buf, 0, fs->blocksize);
1057 retval = io_channel_write_blk(fs->io, (*new_block) + i,
1060 printf("Warning: could not write block %u for %s: %s\n",
1061 (*new_block) + i, name, error_message(retval));
1067 * This routine gets called at the end of pass 1 if bad blocks are
1068 * detected in the superblock, group descriptors, inode_bitmaps, or
1069 * block bitmaps. At this point, all of the blocks have been mapped
1070 * out, so we can try to allocate new block(s) to replace the bad
1073 static void handle_fs_bad_blocks(ext2_filsys fs)
1076 int first_block = fs->super->s_first_data_block;
1078 for (i = 0; i < fs->group_desc_count; i++) {
1079 if (invalid_block_bitmap[i]) {
1080 new_table_block(fs, first_block, i, "block bitmap", 1,
1081 &fs->group_desc[i].bg_block_bitmap);
1083 if (invalid_inode_bitmap[i]) {
1084 new_table_block(fs, first_block, i, "inode bitmap", 1,
1085 &fs->group_desc[i].bg_inode_bitmap);
1087 if (invalid_inode_table[i]) {
1088 new_table_block(fs, first_block, i, "inode table",
1089 fs->inode_blocks_per_group,
1090 &fs->group_desc[i].bg_inode_table);
1093 first_block += fs->super->s_blocks_per_group;
1095 invalid_bitmaps = 0;
1099 * This routine marks all blocks which are used by the superblock,
1100 * group descriptors, inode bitmaps, and block bitmaps.
1102 static void mark_table_blocks(ext2_filsys fs)
1107 block = fs->super->s_first_data_block;
1108 for (i = 0; i < fs->group_desc_count; i++) {
1110 * Mark block used for the block bitmap
1112 if (fs->group_desc[i].bg_block_bitmap) {
1113 if (ext2fs_test_block_bitmap(block_found_map,
1114 fs->group_desc[i].bg_block_bitmap)) {
1115 printf("Group %i's block bitmap at %u "
1116 "conflicts with some other fs block.\n",
1117 i, fs->group_desc[i].bg_block_bitmap);
1119 if (ask("Relocate", 1)) {
1120 invalid_block_bitmap[i]++;
1123 ext2fs_unmark_valid(fs);
1126 ext2fs_mark_block_bitmap(block_found_map,
1127 fs->group_desc[i].bg_block_bitmap);
1128 ext2fs_mark_block_bitmap(block_illegal_map,
1129 fs->group_desc[i].bg_block_bitmap);
1134 * Mark block used for the inode bitmap
1136 if (fs->group_desc[i].bg_inode_bitmap) {
1137 if (ext2fs_test_block_bitmap(block_found_map,
1138 fs->group_desc[i].bg_inode_bitmap)) {
1139 printf("Group %i's inode bitmap at %u "
1140 "conflicts with some other fs block.\n",
1141 i, fs->group_desc[i].bg_inode_bitmap);
1143 if (ask("Relocate", 1)) {
1144 invalid_inode_bitmap[i]++;
1147 ext2fs_unmark_valid(fs);
1150 ext2fs_mark_block_bitmap(block_found_map,
1151 fs->group_desc[i].bg_inode_bitmap);
1152 ext2fs_mark_block_bitmap(block_illegal_map,
1153 fs->group_desc[i].bg_inode_bitmap);
1158 * Mark the blocks used for the inode table
1160 if (fs->group_desc[i].bg_inode_table) {
1161 for (j = 0, b = fs->group_desc[i].bg_inode_table;
1162 j < fs->inode_blocks_per_group;
1164 if (ext2fs_test_block_bitmap(block_found_map,
1166 printf("Group %i's inode table at %u "
1167 "conflicts with some other "
1171 if (ask("Relocate", 1)) {
1172 invalid_inode_table[i]++;
1175 ext2fs_unmark_valid(fs);
1178 ext2fs_mark_block_bitmap(block_found_map,
1180 ext2fs_mark_block_bitmap(block_illegal_map,
1187 * Mark this group's copy of the superblock
1189 ext2fs_mark_block_bitmap(block_found_map, block);
1190 ext2fs_mark_block_bitmap(block_illegal_map, block);
1193 * Mark this group's copy of the descriptors
1195 for (j = 0; j < fs->desc_blocks; j++) {
1196 ext2fs_mark_block_bitmap(block_found_map,
1198 ext2fs_mark_block_bitmap(block_illegal_map,
1201 block += fs->super->s_blocks_per_group;
1206 * This subroutines short circuits ext2fs_get_blocks and
1207 * ext2fs_check_directory; we use them since we already have the inode
1208 * structure, so there's no point in letting the ext2fs library read
1211 static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
1215 if (ino == stashed_ino) {
1216 for (i=0; i < EXT2_N_BLOCKS; i++)
1217 blocks[i] = stashed_inode->i_block[i];
1220 printf("INTERNAL ERROR: pass1_get_blocks: unexpected inode #%lu\n",
1222 printf("\t(was expecting %lu)\n", stashed_ino);
1226 static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
1228 if (ino == stashed_ino) {
1229 if (!LINUX_S_ISDIR(stashed_inode->i_mode))
1233 printf("INTERNAL ERROR: pass1_check_directory: unexpected inode #%lu\n",
1235 printf("\t(was expecting %lu)\n", stashed_ino);