]> git.ipfire.org Git - thirdparty/e2fsprogs.git/blob - e2fsck/pass1.c
Many files:
[thirdparty/e2fsprogs.git] / e2fsck / pass1.c
1 /*
2 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
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 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
8 * and applies the following tests to each inode:
9 *
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
13 *
14 * Pass 1 also gathers the collects the following information:
15 *
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)
22 *
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
27 * inode to fix it.)
28 *
29 * Note that pass 1B will be invoked if there are any duplicate blocks
30 * found.
31 */
32
33 #include <time.h>
34
35 #include <et/com_err.h>
36 #include "e2fsck.h"
37
38 /* Files counts */
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;
50
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 */
54
55 ext2fs_block_bitmap block_found_map = 0;
56 ext2fs_block_bitmap block_dup_map = 0;
57
58 static int fix_link_count = -1;
59
60 unsigned short * inode_link_info = NULL;
61
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,
67 char *block_buf);
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);
78
79 struct process_block_struct {
80 ino_t ino;
81 int is_dir:1, clear:1, suppress:1;
82 int num_blocks;
83 int last_block;
84 int num_illegal_blocks;
85 int fix;
86 struct ext2_inode *inode;
87 };
88
89 struct process_inode_block {
90 ino_t ino;
91 struct ext2_inode inode;
92 };
93
94 /*
95 * For pass1_check_directory and pass1_get_blocks
96 */
97 ino_t stashed_ino;
98 struct ext2_inode *stashed_inode;
99
100 /*
101 * For the inodes to process list.
102 */
103 static struct process_inode_block *inodes_to_process;
104 static int process_inode_count;
105 int process_inode_size = 256;
106
107 /*
108 * For the directory blocks list.
109 */
110 struct dir_block_struct *dir_blocks = 0;
111 int dir_block_count = 0;
112 int dir_block_size = 0;
113
114 /*
115 * Free all memory allocated by pass1 in preparation for restarting
116 * things.
117 */
118 static void unwind_pass1(ext2_filsys fs)
119 {
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;
126 dir_block_size = 0;
127 if (block_dup_map) {
128 free(block_dup_map); block_dup_map = 0;
129 }
130
131 /* Clear statistic counters */
132 fs_directory_count = 0;
133 fs_regular_count = 0;
134 fs_blockdev_count = 0;
135 fs_chardev_count = 0;
136 fs_links_count = 0;
137 fs_symlinks_count = 0;
138 fs_fast_symlinks_count = 0;
139 fs_fifo_count = 0;
140 fs_total_count = 0;
141 fs_badblocks_count = 0;
142 fs_sockets_count = 0;
143 }
144
145 void pass1(ext2_filsys fs)
146 {
147 ino_t ino;
148 struct ext2_inode inode;
149 ext2_inode_scan scan;
150 char *block_buf;
151 errcode_t retval;
152 struct resource_track rtrack;
153
154 init_resource_track(&rtrack);
155
156 if (!preen)
157 printf("Pass 1: Checking inodes, blocks, and sizes\n");
158
159 #ifdef MTRACE
160 mtrace_print("Pass 1");
161 #endif
162
163 /*
164 * Allocate bitmaps structures
165 */
166 retval = ext2fs_allocate_inode_bitmap(fs, "in-use inode map",
167 &inode_used_map);
168 if (retval) {
169 com_err("ext2fs_allocate_inode_bitmap", retval,
170 "while allocating inode_used_map");
171 fatal_error(0);
172 }
173 retval = ext2fs_allocate_inode_bitmap(fs, "directory inode map",
174 &inode_dir_map);
175 if (retval) {
176 com_err("ext2fs_allocate_inode_bitmap", retval,
177 "while allocating inode_dir_map");
178 fatal_error(0);
179 }
180 retval = ext2fs_allocate_block_bitmap(fs, "in-use block map",
181 &block_found_map);
182 if (retval) {
183 com_err("ext2fs_allocate_block_bitmap", retval,
184 "while allocating block_found_map");
185 fatal_error(0);
186 }
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;
194
195 dir_block_size = get_num_dirs(fs) * 4;
196 dir_block_count = 0;
197 dir_blocks = allocate_memory(sizeof(struct dir_block_struct) *
198 dir_block_size,
199 "directory block information");
200
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);
207 if (retval) {
208 com_err(program_name, retval, "while opening inode scan");
209 fatal_error(0);
210 }
211 retval = ext2fs_get_next_inode(scan, &ino, &inode);
212 if (retval) {
213 com_err(program_name, retval, "while starting inode scan");
214 fatal_error(0);
215 }
216 stashed_inode = &inode;
217 ext2fs_set_inode_callback(scan, scan_callback, block_buf);
218 while (ino) {
219 stashed_ino = ino;
220 inode_link_info[ino] = inode.i_links_count;
221 if (ino == EXT2_BAD_INO) {
222 struct process_block_struct pb;
223
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;
228 pb.fix = -1;
229 pb.inode = &inode;
230 retval = ext2fs_block_iterate(fs, ino, 0, block_buf,
231 process_bad_block, &pb);
232 if (retval)
233 com_err(program_name, retval, "while calling e2fsc_block_interate in pass 1");
234
235 ext2fs_mark_inode_bitmap(inode_used_map, ino);
236 goto next;
237 }
238 if (ino == EXT2_ROOT_INO) {
239 /*
240 * Make sure the root inode is a directory; if
241 * not, offer to clear it. It will be
242 * regnerated in pass #3.
243 */
244 if (!S_ISDIR(inode.i_mode)) {
245 printf("Root inode is not a directory. ");
246 preenhalt();
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,
252 "pass1");
253 } else
254 ext2fs_unmark_valid(fs);
255 }
256 /*
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
263 * as a special case.
264 */
265 if (inode.i_dtime && inode.i_links_count) {
266 if (ask("Root inode has dtime set "
267 "(probably due to old mke2fs). Fix",
268 1)) {
269 inode.i_dtime = 0;
270 e2fsck_write_inode(fs, ino, &inode,
271 "pass1");
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 "
277 "finishes.\n\n");
278 } else
279 ext2fs_unmark_valid(fs);
280 }
281 }
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);
285 goto next;
286 }
287 /*
288 * This code assumes that deleted inodes have
289 * i_links_count set to 0.
290 */
291 if (!inode.i_links_count) {
292 if (!inode.i_dtime && inode.i_mode) {
293 printf("Deleted inode %lu has zero dtime.\n",
294 ino);
295 if (ask("Set dtime", 1)) {
296 inode.i_dtime = time(0);
297 e2fsck_write_inode(fs, ino, &inode,
298 "pass1");
299 } else
300 ext2fs_unmark_valid(fs);
301 }
302 goto next;
303 }
304 /*
305 * 0.3c ext2fs code didn't clear i_links_count for
306 * deleted files. Oops.
307 *
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.
313 */
314 if (inode.i_dtime) {
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);
319 }
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");
326 } else
327 ext2fs_unmark_valid(fs);
328 goto next;
329 }
330
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) {
334 if (!inode_bad_map)
335 alloc_bad_map(fs);
336 ext2fs_mark_inode_bitmap(inode_bad_map, ino);
337 }
338
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))
344 fs_regular_count++;
345 else if (S_ISCHR (inode.i_mode))
346 fs_chardev_count++;
347 else if (S_ISBLK (inode.i_mode))
348 fs_blockdev_count++;
349 else if (S_ISLNK (inode.i_mode)) {
350 fs_symlinks_count++;
351 if (!inode.i_blocks)
352 fs_fast_symlinks_count++;
353 }
354 else if (S_ISFIFO (inode.i_mode))
355 fs_fifo_count++;
356 else if (S_ISSOCK (inode.i_mode))
357 fs_sockets_count++;
358 else {
359 if (!inode_bad_map)
360 alloc_bad_map(fs);
361 ext2fs_mark_inode_bitmap(inode_bad_map, ino);
362 }
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++;
369 } else
370 check_blocks(fs, ino, &inode, block_buf);
371
372 if (process_inode_count >= process_inode_size)
373 process_inodes(fs, block_buf);
374 next:
375 retval = ext2fs_get_next_inode(scan, &ino, &inode);
376 if (retval) {
377 com_err(program_name, retval,
378 "while doing inode scan");
379 fatal_error(0);
380 }
381 }
382 process_inodes(fs, block_buf);
383 ext2fs_close_inode_scan(scan);
384 ehandler_operation(0);
385
386 qsort(dir_blocks, dir_block_count, sizeof(struct dir_block_struct),
387 dir_block_cmp);
388
389 if (invalid_bitmaps)
390 handle_fs_bad_blocks(fs);
391
392 if (restart_e2fsck) {
393 unwind_pass1(fs);
394 goto endit;
395 }
396
397 if (block_dup_map) {
398 if (preen) {
399 printf("Duplicate or bad blocks in use!\n");
400 preenhalt();
401 }
402 pass1_dupblocks(fs, block_buf);
403 }
404 fs->get_blocks = 0;
405 fs->check_directory = 0;
406 free(inodes_to_process);
407 endit:
408 free(block_buf);
409 if (tflag > 1) {
410 printf("Pass 1: ");
411 print_resource_track(&rtrack);
412 }
413 }
414
415 /*
416 * When the inode_scan routines call this callback at the end of the
417 * glock group, call process_inodes.
418 */
419 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
420 dgrp_t group, void * private)
421 {
422 process_inodes(fs, (char *) private);
423 return 0;
424 }
425
426 /*
427 * Process the inodes in the "inodes to process" list.
428 */
429 static void process_inodes(ext2_filsys fs, char *block_buf)
430 {
431 int i;
432 struct ext2_inode *old_stashed_inode;
433 ino_t ino;
434 const char *old_operation;
435 char buf[80];
436
437 #if 0
438 printf("begin process_inodes: ");
439 #endif
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;
447 stashed_ino = ino;
448 #if 0
449 printf("%lu ", ino);
450 #endif
451 sprintf(buf, "reading indirect blocks of inode %lu", ino);
452 ehandler_operation(buf);
453 check_blocks(fs, ino, stashed_inode, block_buf);
454
455 }
456 stashed_inode = old_stashed_inode;
457 process_inode_count = 0;
458 #if 0
459 printf("end process inodes\n");
460 #endif
461 ehandler_operation(old_operation);
462 }
463
464 static int process_inode_cmp(const void *a, const void *b)
465 {
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;
470
471 return (ib_a->inode.i_block[EXT2_IND_BLOCK] -
472 ib_b->inode.i_block[EXT2_IND_BLOCK]);
473 }
474
475 static int dir_block_cmp(const void *a, const void *b)
476 {
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;
481
482 return (db_a->blk - db_b->blk);
483 }
484
485 /*
486 * This procedure will allocate the inode bad map table
487 */
488 static void alloc_bad_map(ext2_filsys fs)
489 {
490 errcode_t retval;
491
492 retval = ext2fs_allocate_inode_bitmap(fs, "bad inode map",
493 &inode_bad_map);
494 if (retval) {
495 com_err("ext2fs_allocate_inode_bitmap", retval,
496 "while allocating inode_bad_map");
497 fatal_error(0);
498 }
499 }
500
501 /*
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.
504 */
505 static void mark_block_used(ext2_filsys fs, blk_t block)
506 {
507 errcode_t retval;
508
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);
513 if (retval) {
514 com_err("ext2fs_allocate_block_bitmap", retval,
515 "while allocating block_dup_map");
516 fatal_error(0);
517 }
518 }
519 ext2fs_mark_block_bitmap(block_dup_map, block);
520 } else {
521 ext2fs_mark_block_bitmap(block_found_map, block);
522 }
523 }
524
525 /*
526 * This subroutine is called on each inode to account for all of the
527 * blocks used by that inode.
528 */
529 static void check_blocks(ext2_filsys fs, ino_t ino, struct ext2_inode *inode,
530 char *block_buf)
531 {
532 struct process_block_struct pb;
533 errcode_t retval;
534
535 if (!inode_has_valid_blocks(inode))
536 return;
537
538 pb.ino = ino;
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);
543 pb.fix = -1;
544 pb.inode = inode;
545 retval = ext2fs_block_iterate(fs, ino, 0, block_buf,
546 process_block, &pb);
547 if (retval)
548 com_err(program_name, retval,
549 "while calling ext2fs_block_iterate in check_blocks");
550
551 if (pb.clear) {
552 e2fsck_read_inode(fs, ino, inode, "check_blocks");
553 if (retval) {
554 com_err("check_blocks", retval,
555 "while reading to be cleared inode %d", ino);
556 fatal_error(0);
557 }
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);
564 /*
565 * The inode was probably partially accounted for
566 * before processing was aborted, so we need to
567 * restart the pass 1 scan.
568 */
569 restart_e2fsck++;
570 return;
571 }
572
573 if (pb.fix > 0)
574 e2fsck_read_inode(fs, ino, inode, "check_blocks");
575
576 pb.num_blocks *= (fs->blocksize / 512);
577 #if 0
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,
580 pb.num_blocks);
581 #endif
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--;
592 } else
593 ext2fs_unmark_valid(fs);
594 }
595 if (inode->i_size < pb.last_block * fs->blocksize) {
596 printf ("Inode %lu, incorrect size, %lu (counted = %u). ",
597 ino, inode->i_size,
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");
602 } else
603 ext2fs_unmark_valid(fs);
604 }
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");
611 } else
612 ext2fs_unmark_valid(fs);
613 }
614 }
615
616 /*
617 * This is a helper function for check_blocks().
618 */
619 int process_block(ext2_filsys fs,
620 blk_t *block_nr,
621 int blockcnt,
622 void *private)
623 {
624 struct process_block_struct *p;
625 int group;
626 int illegal_block = 0;
627 char problem[80];
628 blk_t firstblock, group_super;
629 blk_t blk = *block_nr;
630
631 if (!blk)
632 return 0;
633 p = (struct process_block_struct *) private;
634
635 #if 0
636 printf("Process_block, inode %lu, block %lu, #%d\n", p->ino, blk,
637 blockcnt);
638 #endif
639
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);
646 illegal_block++;
647 } else if (blk >= fs->super->s_blocks_count) {
648 sprintf(problem, "> BLOCKS (%lu)", fs->super->s_blocks_count);
649 illegal_block++;
650 } else if (blk == group_super) {
651 sprintf(problem, "is the superblock in group %d", group);
652 illegal_block++;
653 } else if (blk > group_super &&
654 blk <= (group_super + fs->desc_blocks)) {
655 sprintf(problem, "is in the group descriptors in group %d",
656 group);
657 illegal_block++;
658 } else if (blk == fs->group_desc[group].bg_block_bitmap) {
659 sprintf(problem, "is the block bitmap of group %d", group);
660 illegal_block++;
661 } else if (blk == fs->group_desc[group].bg_inode_bitmap) {
662 sprintf(problem, "is the inode bitmap of group %d", group);
663 illegal_block++;
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);
667 illegal_block++;
668 }
669 if (illegal_block) {
670 if (preen) {
671 printf("Block %lu of inode %lu %s\n", blk, p->ino,
672 problem);
673 preenhalt();
674 }
675 if (p->fix == -1) {
676 printf("Remove illegal block(s) in inode %lu", p->ino);
677 p->fix = ask("", 1);
678 }
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",
682 p->ino);
683 if (ask("Clear inode", 1)) {
684 p->clear = 1;
685 return BLOCK_ABORT;
686 }
687 if (ask("Supress messages", 0)) {
688 p->suppress = 1;
689 }
690 }
691 if (!p->suppress)
692 printf("Block #%d (%lu) %s. %s\n", blockcnt, blk,
693 problem, clear_msg[p->fix]);
694 if (p->fix) {
695 *block_nr = 0;
696 return BLOCK_CHANGED;
697 } else {
698 ext2fs_unmark_valid(fs);
699 return 0;
700 }
701 }
702
703 p->num_blocks++;
704 if (blockcnt > 0)
705 p->last_block = blockcnt;
706 mark_block_used(fs, blk);
707
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,
712 dir_block_size *
713 sizeof(struct dir_block_struct));
714 }
715
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;
719 dir_block_count++;
720 }
721
722 #if 0
723 printf("process block, inode %lu, block #%d is %lu\n",
724 p->ino, blockcnt, blk);
725 #endif
726
727 return 0;
728 }
729
730 static void bad_block_indirect(blk_t blk)
731 {
732 printf("Bad block %lu used as bad block indirect block?!?\n", blk);
733 preenhalt();
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))
740 return;
741 fatal_error(0);
742 }
743
744 int process_bad_block(ext2_filsys fs,
745 blk_t *block_nr,
746 int blockcnt,
747 void *private)
748 {
749 struct process_block_struct *p;
750 blk_t blk = *block_nr;
751 int first_block;
752 int i;
753
754 if (!blk)
755 return 0;
756 p = (struct process_block_struct *) private;
757
758 if ((blk < fs->super->s_first_data_block) ||
759 (blk >= fs->super->s_blocks_count)) {
760 if (preen) {
761 printf("Illegal block %lu in bad block inode\n", blk);
762 preenhalt();
763 }
764 if (p->fix == -1)
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,
767 clear_msg[p->fix]);
768 if (p->fix) {
769 *block_nr = 0;
770 return BLOCK_CHANGED;
771 } else {
772 ext2fs_unmark_valid(fs);
773 return 0;
774 }
775 }
776
777 if (blockcnt < 0) {
778 if (ext2fs_test_block_bitmap(block_found_map, blk))
779 bad_block_indirect(blk);
780 else
781 mark_block_used(fs, blk);
782 return 0;
783 }
784 #if 0
785 printf ("DEBUG: Marking %lu as bad.\n", blk);
786 #endif
787 fs_badblocks_count++;
788 /*
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.
793 */
794 if (!ext2fs_test_block_bitmap(block_found_map, blk)) {
795 ext2fs_mark_block_bitmap(block_found_map, blk);
796 return 0;
797 }
798 /*
799 * Try to find the where the filesystem block was used...
800 */
801 first_block = fs->super->s_first_data_block;
802
803 for (i = 0; i < fs->group_desc_count; i++ ) {
804 if (blk == first_block) {
805 if (i == 0) {
806 printf("The primary superblock (%lu) is "
807 "bad. Aiiieeee....\n", blk);
808 fatal_error(0);
809 }
810 if (!preen)
811 printf("Warning: Group %d's superblock "
812 "(%lu) is bad.\n", i, blk);
813 return 0;
814 }
815 if ((blk > first_block) &&
816 (blk <= first_block + fs->desc_blocks)) {
817 if (i == 0) {
818 printf("Bad block %lu is in the primary "
819 "group descriptors. Aiiieeee....\n",
820 blk);
821 fatal_error(0);
822 }
823 if (!preen)
824 printf("Warning: Group %d's copy of the "
825 "group descriptors has a bad "
826 "block (%lu).\n", i, blk);
827 return 0;
828 }
829 if (blk == fs->group_desc[i].bg_block_bitmap) {
830 printf("Group %d's block bitmap (%lu) is bad. ",
831 i, blk);
832 if (ask("Relocate", 1)) {
833 invalid_block_bitmap[i]++;
834 invalid_bitmaps++;
835 } else
836 ext2fs_unmark_valid(fs);
837 return 0;
838 }
839 if (blk == fs->group_desc[i].bg_inode_bitmap) {
840 printf("Group %d's inode bitmap (%lu) is bad. ",
841 i, blk);
842 if (ask("Relocate", 1)) {
843 invalid_inode_bitmap[i]++;
844 invalid_bitmaps++;
845 } else
846 ext2fs_unmark_valid(fs);
847 return 0;
848 }
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. ",
854 blk, i);
855 if (ask("Relocate", 1)) {
856 invalid_inode_table[i]++;
857 invalid_bitmaps++;
858 } else
859 ext2fs_unmark_valid(fs);
860 return 0;
861 }
862 first_block += fs->super->s_blocks_per_group;
863 }
864 /*
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.
868 */
869 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
870 p->inode->i_block[EXT2_DIND_BLOCK]) {
871 bad_block_indirect(blk);
872 return 0;
873 }
874
875 printf("Programming error? block #%lu claimed for no reason "
876 "in process_bad_block.\n", blk);
877 return 0;
878 }
879
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)
882 {
883 errcode_t retval;
884 blk_t old_block = *new_block;
885 int i;
886 char *buf;
887
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);
891 if (retval) {
892 printf("Could not allocate %d block(s) for %s: %s\n",
893 num, name, error_message(retval));
894 ext2fs_unmark_valid(fs);
895 return;
896 }
897 buf = malloc(fs->blocksize);
898 if (!buf) {
899 printf("Could not allocate block buffer for relocating %s\n",
900 name);
901 ext2fs_unmark_valid(fs);
902 return;
903 }
904 ext2fs_mark_super_dirty(fs);
905 printf("Relocating group %d's %s ", group, name);
906 if (old_block)
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);
911 if (old_block) {
912 retval = io_channel_read_blk(fs->io, old_block + i,
913 1, buf);
914 if (retval)
915 printf("Warning: could not read block %lu "
916 "of %s: %s\n",
917 old_block + i, name,
918 error_message(retval));
919 } else
920 memset(buf, 0, fs->blocksize);
921
922 retval = io_channel_write_blk(fs->io, (*new_block) + i,
923 1, buf);
924 if (retval)
925 printf("Warning: could not write block %lu for %s: %s\n",
926 (*new_block) + i, name, error_message(retval));
927 }
928 free(buf);
929 }
930
931 /*
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
936 * blocks.
937 */
938 static void handle_fs_bad_blocks(ext2_filsys fs)
939 {
940 int i;
941 int first_block = fs->super->s_first_data_block;
942
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);
947 }
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);
951 }
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);
956 restart_e2fsck++;
957 }
958 first_block += fs->super->s_blocks_per_group;
959 }
960 invalid_bitmaps = 0;
961 }
962
963 /*
964 * This routine marks all blocks which are used by the superblock,
965 * group descriptors, inode bitmaps, and block bitmaps.
966 */
967 static void mark_table_blocks(ext2_filsys fs)
968 {
969 blk_t block, b;
970 int i,j;
971
972 block = fs->super->s_first_data_block;
973 for (i = 0; i < fs->group_desc_count; i++) {
974 /*
975 * Mark block used for the block bitmap
976 */
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);
983 preenhalt();
984 if (ask("Relocate", 1)) {
985 invalid_block_bitmap[i]++;
986 invalid_bitmaps++;
987 } else {
988 ext2fs_unmark_valid(fs);
989 }
990 } else
991 ext2fs_mark_block_bitmap(block_found_map,
992 fs->group_desc[i].bg_block_bitmap);
993 }
994 /*
995 * Mark block used for the inode bitmap
996 */
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);
1003 preenhalt();
1004 if (ask("Relocate", 1)) {
1005 invalid_inode_bitmap[i]++;
1006 invalid_bitmaps++;
1007 } else {
1008 ext2fs_unmark_valid(fs);
1009 }
1010 } else
1011 ext2fs_mark_block_bitmap(block_found_map,
1012 fs->group_desc[i].bg_inode_bitmap);
1013 }
1014
1015 /*
1016 * Mark the blocks used for the inode table
1017 */
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;
1021 j++, b++) {
1022 if (ext2fs_test_block_bitmap(block_found_map,
1023 b)) {
1024 printf("Group %i's inode table at %lu "
1025 "conflicts with some other "
1026 "fs block.\n",
1027 i, b);
1028 preenhalt();
1029 if (ask("Relocate", 1)) {
1030 invalid_inode_table[i]++;
1031 invalid_bitmaps++;
1032 } else {
1033 ext2fs_unmark_valid(fs);
1034 }
1035 } else
1036 ext2fs_mark_block_bitmap(block_found_map,
1037 b);
1038 }
1039 }
1040
1041 /*
1042 * Mark this group's copy of the superblock
1043 */
1044 ext2fs_mark_block_bitmap(block_found_map, block);
1045
1046 /*
1047 * Mark this group's copy of the descriptors
1048 */
1049 for (j = 0; j < fs->desc_blocks; j++)
1050 ext2fs_mark_block_bitmap(block_found_map,
1051 block + j + 1);
1052 block += fs->super->s_blocks_per_group;
1053 }
1054 }
1055
1056 /*
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
1060 * the inode again.
1061 */
1062 static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
1063 {
1064 int i;
1065
1066 if (ino == stashed_ino) {
1067 for (i=0; i < EXT2_N_BLOCKS; i++)
1068 blocks[i] = stashed_inode->i_block[i];
1069 return 0;
1070 }
1071 printf("INTERNAL ERROR: pass1_get_blocks: unexpected inode #%lu\n",
1072 ino);
1073 printf("\t(was expecting %lu)\n", stashed_ino);
1074 exit(FSCK_ERROR);
1075 }
1076
1077 static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
1078 {
1079 if (ino == stashed_ino) {
1080 if (!S_ISDIR(stashed_inode->i_mode))
1081 return ENOTDIR;
1082 return 0;
1083 }
1084 printf("INTERNAL ERROR: pass1_check_directory: unexpected inode #%lu\n",
1085 ino);
1086 printf("\t(was expecting %lu)\n", stashed_ino);
1087 exit(FSCK_ERROR);
1088 }