Whamcloud - gitweb
util.c:
[tools/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, 1995, 1996, 1997 Theodore Ts'o.
5  *
6  * %Begin-Header%
7  * This file may be redistributed under the terms of the GNU Public
8  * License.
9  * %End-Header%
10  * 
11  * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
12  * and applies the following tests to each inode:
13  *
14  *      - The mode field of the inode must be legal.
15  *      - The size and block count fields of the inode are correct.
16  *      - A data block must not be used by another inode
17  *
18  * Pass 1 also gathers the collects the following information:
19  *
20  *      - A bitmap of which inodes are in use.          (inode_used_map)
21  *      - A bitmap of which inodes are directories.     (inode_dir_map)
22  *      - A bitmap of which inodes are regular files.   (inode_reg_map)
23  *      - A bitmap of which inodes have bad fields.     (inode_bad_map)
24  *      - A bitmap of which inodes are in bad blocks.   (inode_bb_map)
25  *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
26  *      - A bitmap of which blocks are in use.          (block_found_map)
27  *      - A bitmap of which blocks are in use by two inodes     (block_dup_map)
28  *      - The data blocks of the directory inodes.      (dir_map)
29  *
30  * Pass 1 is designed to stash away enough information so that the
31  * other passes should not need to read in the inode information
32  * during the normal course of a filesystem check.  (Althogh if an
33  * inconsistency is detected, other passes may need to read in an
34  * inode to fix it.)
35  *
36  * Note that pass 1B will be invoked if there are any duplicate blocks
37  * found.
38  */
39
40 #include <time.h>
41 #ifdef HAVE_ERRNO_H
42 #include <errno.h>
43 #endif
44
45 #include "e2fsck.h"
46 #include "problem.h"
47
48 #ifdef NO_INLINE_FUNCS
49 #define _INLINE_
50 #else
51 #define _INLINE_ inline
52 #endif
53
54 static int process_block(ext2_filsys fs, blk_t  *blocknr,
55                          e2_blkcnt_t blockcnt, blk_t ref_blk, 
56                          int ref_offset, void *priv_data);
57 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
58                              e2_blkcnt_t blockcnt, blk_t ref_blk,
59                              int ref_offset, void *priv_data);
60 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
61                          char *block_buf);
62 static void mark_table_blocks(e2fsck_t ctx);
63 static void alloc_bad_map(e2fsck_t ctx);
64 static void alloc_bb_map(e2fsck_t ctx);
65 static void alloc_imagic_map(e2fsck_t ctx);
66 static void handle_fs_bad_blocks(e2fsck_t ctx);
67 static void process_inodes(e2fsck_t ctx, char *block_buf);
68 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
69 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
70                                   dgrp_t group, void * priv_data);
71 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
72
73 struct process_block_struct {
74         ino_t           ino;
75         int             is_dir:1, clear:1, suppress:1, fragmented:1;
76         blk_t           num_blocks;
77         e2_blkcnt_t     last_block;
78         int             num_illegal_blocks;
79         blk_t           previous_block;
80         struct ext2_inode *inode;
81         struct problem_context *pctx;
82         e2fsck_t        ctx;
83 };
84
85 struct process_inode_block {
86         ino_t   ino;
87         struct ext2_inode inode;
88 };
89
90 struct scan_callback_struct {
91         e2fsck_t        ctx;
92         char            *block_buf;
93 };
94
95 /*
96  * For the inodes to process list.
97  */
98 static struct process_inode_block *inodes_to_process;
99 static int process_inode_count;
100
101 static __u64 ext2_max_sizes[4];
102
103 /*
104  * Free all memory allocated by pass1 in preparation for restarting
105  * things.
106  */
107 static void unwind_pass1(ext2_filsys fs)
108 {
109         ext2fs_free_mem((void **) &inodes_to_process);
110         inodes_to_process = 0;
111 }
112
113 /*
114  * Check to make sure a device inode is real.  Returns 1 if the device
115  * checks out, 0 if not.
116  *
117  * Note: this routine is now also used to check FIFO's and Sockets,
118  * since they have the same requirement; the i_block fields should be
119  * zero. 
120  */
121 int e2fsck_pass1_check_device_inode(struct ext2_inode *inode)
122 {
123         int     i;
124
125         /*
126          * We should be able to do the test below all the time, but
127          * because the kernel doesn't forcibly clear the device
128          * inode's additional i_block fields, there are some rare
129          * occasions when a legitimate device inode will have non-zero
130          * additional i_block fields.  So for now, we only complain
131          * when the immutable flag is set, which should never happen
132          * for devices.  (And that's when the problem is caused, since
133          * you can't set or clear immutable flags for devices.)  Once
134          * the kernel has been fixed we can change this...
135          */
136         if (inode->i_flags & EXT2_IMMUTABLE_FL) {
137                 for (i=4; i < EXT2_N_BLOCKS; i++) 
138                         if (inode->i_block[i])
139                                 return 0;
140         }
141         return 1;
142 }
143
144 void e2fsck_pass1(e2fsck_t ctx)
145 {
146         int     i;
147         __u64   max_sizes;
148         ext2_filsys fs = ctx->fs;
149         ino_t   ino;
150         struct ext2_inode inode;
151         ext2_inode_scan scan;
152         char            *block_buf;
153 #ifdef RESOURCE_TRACK
154         struct resource_track   rtrack;
155 #endif
156         unsigned char   frag, fsize;
157         struct          problem_context pctx;
158         struct          scan_callback_struct scan_struct;
159         struct ext2fs_sb *sb;
160         
161 #ifdef RESOURCE_TRACK
162         init_resource_track(&rtrack);
163 #endif
164         clear_problem_context(&pctx);
165
166         if (!(ctx->options & E2F_OPT_PREEN))
167                 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
168
169 #ifdef MTRACE
170         mtrace_print("Pass 1");
171 #endif
172
173 #define EXT2_BPP(bits) (1UL << ((bits) - 2))
174
175         for (i=0; i < 4; i++) {
176                 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(10+i);
177                 max_sizes = max_sizes + EXT2_BPP(10+i) * EXT2_BPP(10+i);
178                 max_sizes = (max_sizes +
179                              (__u64) EXT2_BPP(10+i) * EXT2_BPP(10+i) *
180                              EXT2_BPP(10+i));
181                 max_sizes = (max_sizes * (1UL << (10+i))) - 1;
182                 ext2_max_sizes[i] = max_sizes;
183         }
184 #undef EXT2_BPP
185         
186         /*
187          * Allocate bitmaps structures
188          */
189         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, "in-use inode map",
190                                               &ctx->inode_used_map);
191         if (pctx.errcode) {
192                 pctx.num = 1;
193                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
194                 ctx->flags |= E2F_FLAG_ABORT;
195                 return;
196         }
197         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, "directory inode map",
198                                               &ctx->inode_dir_map);
199         if (pctx.errcode) {
200                 pctx.num = 2;
201                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
202                 ctx->flags |= E2F_FLAG_ABORT;
203                 return;
204         }
205         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
206                                                     "regular file inode map",
207                                               &ctx->inode_reg_map);
208         if (pctx.errcode) {
209                 pctx.num = 6;
210                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
211                 ctx->flags |= E2F_FLAG_ABORT;
212                 return;
213         }
214         pctx.errcode = ext2fs_allocate_block_bitmap(fs, "in-use block map",
215                                               &ctx->block_found_map);
216         if (pctx.errcode) {
217                 pctx.num = 1;
218                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
219                 ctx->flags |= E2F_FLAG_ABORT;
220                 return;
221         }
222         pctx.errcode = ext2fs_allocate_block_bitmap(fs, "illegal block map",
223                                               &ctx->block_illegal_map);
224         if (pctx.errcode) {
225                 pctx.num = 2;
226                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
227                 ctx->flags |= E2F_FLAG_ABORT;
228                 return;
229         }
230         pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
231                                              &ctx->inode_link_info);
232         if (pctx.errcode) {
233                 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
234                 ctx->flags |= E2F_FLAG_ABORT;
235                 return;
236         }
237         inodes_to_process = (struct process_inode_block *)
238                 e2fsck_allocate_memory(ctx,
239                                        (ctx->process_inode_size *
240                                         sizeof(struct process_inode_block)),
241                                        "array of inodes to process");
242         process_inode_count = 0;
243
244         pctx.errcode = ext2fs_init_dblist(fs, 0);
245         if (pctx.errcode) {
246                 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
247                 ctx->flags |= E2F_FLAG_ABORT;
248                 return;
249         }
250
251         mark_table_blocks(ctx);
252         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
253                                                     "block interate buffer");
254         e2fsck_use_inode_shortcuts(ctx, 1);
255         ehandler_operation("doing inode scan");
256         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks, 
257                                               &scan);
258         if (pctx.errcode) {
259                 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
260                 ctx->flags |= E2F_FLAG_ABORT;
261                 return;
262         }
263         ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
264         pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
265         if (pctx.errcode) {
266                 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
267                 ctx->flags |= E2F_FLAG_ABORT;
268                 return;
269         }
270         ctx->stashed_inode = &inode;
271         scan_struct.ctx = ctx;
272         scan_struct.block_buf = block_buf;
273         ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
274         if (ctx->progress)
275                 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
276                         return;
277         while (ino) {
278                 pctx.ino = ino;
279                 pctx.inode = &inode;
280                 ctx->stashed_ino = ino;
281                 if (inode.i_links_count) {
282                         pctx.errcode = ext2fs_icount_store(ctx->inode_link_info, 
283                                            ino, inode.i_links_count);
284                         if (pctx.errcode) {
285                                 pctx.num = inode.i_links_count;
286                                 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
287                                 ctx->flags |= E2F_FLAG_ABORT;
288                                 return;
289                         }
290                 }
291                 if (ino == EXT2_BAD_INO) {
292                         struct process_block_struct pb;
293                         
294                         pb.ino = EXT2_BAD_INO;
295                         pb.num_blocks = pb.last_block = 0;
296                         pb.num_illegal_blocks = 0;
297                         pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
298                         pb.fragmented = 0;
299                         pb.inode = &inode;
300                         pb.pctx = &pctx;
301                         pb.ctx = ctx;
302                         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, 
303                                      block_buf, process_bad_block, &pb);
304                         if (pctx.errcode) {
305                                 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
306                                 ctx->flags |= E2F_FLAG_ABORT;
307                                 return;
308                         }
309                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
310                         clear_problem_context(&pctx);
311                         goto next;
312                 }
313                 if (ino == EXT2_ROOT_INO) {
314                         /*
315                          * Make sure the root inode is a directory; if
316                          * not, offer to clear it.  It will be
317                          * regnerated in pass #3.
318                          */
319                         if (!LINUX_S_ISDIR(inode.i_mode)) {
320                                 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
321                                         inode.i_dtime = time(0);
322                                         inode.i_links_count = 0;
323                                         ext2fs_icount_store(ctx->inode_link_info,
324                                                             ino, 0);
325                                         e2fsck_write_inode(ctx, ino, &inode,
326                                                            "pass1");
327                                 }
328                         }
329                         /*
330                          * If dtime is set, offer to clear it.  mke2fs
331                          * version 0.2b created filesystems with the
332                          * dtime field set for the root and lost+found
333                          * directories.  We won't worry about
334                          * /lost+found, since that can be regenerated
335                          * easily.  But we will fix the root directory
336                          * as a special case.
337                          */
338                         if (inode.i_dtime && inode.i_links_count) {
339                                 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
340                                         inode.i_dtime = 0;
341                                         e2fsck_write_inode(ctx, ino, &inode,
342                                                            "pass1");
343                                 }
344                         }
345                 }
346                 if ((ino != EXT2_ROOT_INO) &&
347                     (ino < EXT2_FIRST_INODE(fs->super))) {
348                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
349                         if (((ino == EXT2_BOOT_LOADER_INO) &&
350                              LINUX_S_ISDIR(inode.i_mode)) ||
351                             ((ino != EXT2_BOOT_LOADER_INO) &&
352                              (inode.i_mode != 0))) {
353                                 if (fix_problem(ctx,
354                                             PR_1_RESERVED_BAD_MODE, &pctx)) {
355                                         inode.i_mode = 0;
356                                         e2fsck_write_inode(ctx, ino, &inode,
357                                                            "pass1");
358                                 }
359                         }
360                         check_blocks(ctx, &pctx, block_buf);
361                         goto next;
362                 }
363                 /*
364                  * This code assumes that deleted inodes have
365                  * i_links_count set to 0.  
366                  */
367                 if (!inode.i_links_count) {
368                         if (!inode.i_dtime && inode.i_mode) {
369                                 if (fix_problem(ctx,
370                                             PR_1_ZERO_DTIME, &pctx)) {
371                                         inode.i_dtime = time(0);
372                                         e2fsck_write_inode(ctx, ino, &inode,
373                                                            "pass1");
374                                 }
375                         }
376                         goto next;
377                 }
378                 /*
379                  * n.b.  0.3c ext2fs code didn't clear i_links_count for
380                  * deleted files.  Oops.
381                  *
382                  * Since all new ext2 implementations get this right,
383                  * we now assume that the case of non-zero
384                  * i_links_count and non-zero dtime means that we
385                  * should keep the file, not delete it.
386                  * 
387                  */
388                 if (inode.i_dtime) {
389                         if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
390                                 inode.i_dtime = 0;
391                                 e2fsck_write_inode(ctx, ino, &inode, "pass1");
392                         }
393                 }
394                 
395                 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
396                 switch (fs->super->s_creator_os) {
397                     case EXT2_OS_LINUX:
398                         frag = inode.osd2.linux2.l_i_frag;
399                         fsize = inode.osd2.linux2.l_i_fsize;
400                         break;
401                     case EXT2_OS_HURD:
402                         frag = inode.osd2.hurd2.h_i_frag;
403                         fsize = inode.osd2.hurd2.h_i_fsize;
404                         break;
405                     case EXT2_OS_MASIX:
406                         frag = inode.osd2.masix2.m_i_frag;
407                         fsize = inode.osd2.masix2.m_i_fsize;
408                         break;
409                     default:
410                         frag = fsize = 0;
411                 }
412                 
413                 if (inode.i_faddr || frag || fsize
414                     || inode.i_file_acl ||
415                     (LINUX_S_ISDIR(inode.i_mode) && inode.i_dir_acl)) {
416                         if (!ctx->inode_bad_map)
417                                 alloc_bad_map(ctx);
418                         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
419                 }
420                 if (inode.i_flags & EXT2_IMAGIC_FL) {
421                         if (!ctx->inode_imagic_map)
422                                 alloc_imagic_map(ctx);
423                         ext2fs_mark_inode_bitmap(ctx->inode_imagic_map, ino);
424                 }
425                 
426                 if (LINUX_S_ISDIR(inode.i_mode)) {
427                         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
428                         e2fsck_add_dir_info(ctx, ino, 0);
429                         ctx->fs_directory_count++;
430                 } else if (LINUX_S_ISREG (inode.i_mode)) {
431                         ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
432                         ctx->fs_regular_count++;
433                 } else if (LINUX_S_ISCHR (inode.i_mode) &&
434                          e2fsck_pass1_check_device_inode(&inode))
435                         ctx->fs_chardev_count++;
436                 else if (LINUX_S_ISBLK (inode.i_mode) &&
437                          e2fsck_pass1_check_device_inode(&inode))
438                         ctx->fs_blockdev_count++;
439                 else if (LINUX_S_ISLNK (inode.i_mode)) {
440                         ctx->fs_symlinks_count++;
441                         if (!inode.i_blocks) {
442                                 ctx->fs_fast_symlinks_count++;
443                                 goto next;
444                         }
445                 }
446                 else if (LINUX_S_ISFIFO (inode.i_mode) &&
447                           e2fsck_pass1_check_device_inode(&inode))
448                         ctx->fs_fifo_count++;
449                 else if ((LINUX_S_ISSOCK (inode.i_mode)) &&
450                          e2fsck_pass1_check_device_inode(&inode))
451                         ctx->fs_sockets_count++;
452                 else {
453                         if (!ctx->inode_bad_map)
454                                 alloc_bad_map(ctx);
455                         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
456                 }
457                 if (inode.i_block[EXT2_IND_BLOCK])
458                         ctx->fs_ind_count++;
459                 if (inode.i_block[EXT2_DIND_BLOCK])
460                         ctx->fs_dind_count++;
461                 if (inode.i_block[EXT2_TIND_BLOCK])
462                         ctx->fs_tind_count++;
463                 if (inode.i_block[EXT2_IND_BLOCK] ||
464                     inode.i_block[EXT2_DIND_BLOCK] ||
465                     inode.i_block[EXT2_TIND_BLOCK]) {
466                         inodes_to_process[process_inode_count].ino = ino;
467                         inodes_to_process[process_inode_count].inode = inode;
468                         process_inode_count++;
469                 } else
470                         check_blocks(ctx, &pctx, block_buf);
471
472                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
473                         return;
474
475                 if (process_inode_count >= ctx->process_inode_size) {
476                         process_inodes(ctx, block_buf);
477
478                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
479                                 return;
480                 }
481         next:
482                 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
483                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
484                         return;
485                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
486                         if (!ctx->inode_bb_map)
487                                 alloc_bb_map(ctx);
488                         ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
489                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
490                         goto next;
491                 }
492                 if (pctx.errcode) {
493                         fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
494                         ctx->flags |= E2F_FLAG_ABORT;
495                         return;
496                 }
497         }
498         process_inodes(ctx, block_buf);
499         ext2fs_close_inode_scan(scan);
500         ehandler_operation(0);
501
502         if (ctx->invalid_bitmaps)
503                 handle_fs_bad_blocks(ctx);
504
505         if (ctx->flags & E2F_FLAG_RESTART) {
506                 /*
507                  * Only the master copy of the superblock and block
508                  * group descriptors are going to be written during a
509                  * restart, so set the superblock to be used to be the
510                  * master superblock.
511                  */
512                 ctx->use_superblock = 0;
513                 unwind_pass1(fs);
514                 goto endit;
515         }
516
517         if (ctx->block_dup_map) {
518                 if (ctx->options & E2F_OPT_PREEN) {
519                         clear_problem_context(&pctx);
520                         fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
521                 }
522                 e2fsck_pass1_dupblocks(ctx, block_buf);
523         }
524         ext2fs_free_mem((void **) &inodes_to_process);
525 endit:
526         e2fsck_use_inode_shortcuts(ctx, 0);
527         
528         ext2fs_free_mem((void **) &block_buf);
529         ext2fs_free_block_bitmap(ctx->block_illegal_map);
530         ctx->block_illegal_map = 0;
531
532         sb = (struct ext2fs_sb *) fs->super;
533         if (ctx->large_files && 
534             !(sb->s_feature_ro_compat & 
535               EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
536                 if (fix_problem(ctx, PR_1_FEATURE_LARGE_FILES, &pctx)) {
537                         sb->s_feature_ro_compat |= 
538                                 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
539                         ext2fs_mark_super_dirty(fs);
540                 }
541         } else if (!ctx->large_files &&
542             (sb->s_feature_ro_compat &
543               EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
544                 if (fs->flags & EXT2_FLAG_RW) {
545                         sb->s_feature_ro_compat &= 
546                                 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
547                         ext2fs_mark_super_dirty(fs);
548                 }
549         }
550         
551 #ifdef RESOURCE_TRACK
552         if (ctx->options & E2F_OPT_TIME2) {
553                 e2fsck_clear_progbar(ctx);
554                 print_resource_track("Pass 1", &rtrack);
555         }
556 #endif
557 }
558
559 /*
560  * When the inode_scan routines call this callback at the end of the
561  * glock group, call process_inodes.
562  */
563 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
564                                dgrp_t group, void * priv_data)
565 {
566         struct scan_callback_struct *scan_struct;
567         e2fsck_t ctx;
568
569         scan_struct = (struct scan_callback_struct *) priv_data;
570         ctx = scan_struct->ctx;
571         
572         process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
573
574         if (ctx->progress)
575                 if ((ctx->progress)(ctx, 1, group+1,
576                                     ctx->fs->group_desc_count))
577                         return EXT2_ET_CANCEL_REQUESTED;
578
579         return 0;
580 }
581
582 /*
583  * Process the inodes in the "inodes to process" list.
584  */
585 static void process_inodes(e2fsck_t ctx, char *block_buf)
586 {
587         int                     i;
588         struct ext2_inode       *old_stashed_inode;
589         ino_t                   old_stashed_ino;
590         const char              *old_operation;
591         char                    buf[80];
592         struct problem_context  pctx;
593         
594 #if 0
595         printf("begin process_inodes: ");
596 #endif
597         old_operation = ehandler_operation(0);
598         old_stashed_inode = ctx->stashed_inode;
599         old_stashed_ino = ctx->stashed_ino;
600         qsort(inodes_to_process, process_inode_count,
601                       sizeof(struct process_inode_block), process_inode_cmp);
602         clear_problem_context(&pctx);
603         for (i=0; i < process_inode_count; i++) {
604                 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
605                 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
606                 
607 #if 0
608                 printf("%u ", pctx.ino);
609 #endif
610                 sprintf(buf, "reading indirect blocks of inode %lu", pctx.ino);
611                 ehandler_operation(buf);
612                 check_blocks(ctx, &pctx, block_buf);
613                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
614                         break;
615         }
616         ctx->stashed_inode = old_stashed_inode;
617         ctx->stashed_ino = old_stashed_ino;
618         process_inode_count = 0;
619 #if 0
620         printf("end process inodes\n");
621 #endif
622         ehandler_operation(old_operation);
623 }
624
625 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
626 {
627         const struct process_inode_block *ib_a =
628                 (const struct process_inode_block *) a;
629         const struct process_inode_block *ib_b =
630                 (const struct process_inode_block *) b;
631
632         return (ib_a->inode.i_block[EXT2_IND_BLOCK] -
633                 ib_b->inode.i_block[EXT2_IND_BLOCK]);
634 }
635
636 /*
637  * This procedure will allocate the inode bad map table
638  */
639 static void alloc_bad_map(e2fsck_t ctx)
640 {
641         struct          problem_context pctx;
642         
643         clear_problem_context(&pctx);
644         
645         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, "bad inode map",
646                                               &ctx->inode_bad_map);
647         if (pctx.errcode) {
648                 pctx.num = 3;
649                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
650                 /* Should never get here */
651                 ctx->flags |= E2F_FLAG_ABORT;
652                 return;
653         }
654 }
655
656 /*
657  * This procedure will allocate the inode "bb" (badblock) map table
658  */
659 static void alloc_bb_map(e2fsck_t ctx)
660 {
661         struct          problem_context pctx;
662         
663         clear_problem_context(&pctx);
664         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
665                                               "inode in bad block map",
666                                               &ctx->inode_bb_map);
667         if (pctx.errcode) {
668                 pctx.num = 4;
669                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
670                 /* Should never get here */
671                 ctx->flags |= E2F_FLAG_ABORT;
672                 return;
673         }
674 }
675
676 /*
677  * This procedure will allocate the inode imagic table
678  */
679 static void alloc_imagic_map(e2fsck_t ctx)
680 {
681         struct          problem_context pctx;
682         
683         clear_problem_context(&pctx);
684         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
685                                               "imagic inode map",
686                                               &ctx->inode_imagic_map);
687         if (pctx.errcode) {
688                 pctx.num = 5;
689                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
690                 /* Should never get here */
691                 ctx->flags |= E2F_FLAG_ABORT;
692                 return;
693         }
694 }
695
696 /*
697  * Marks a block as in use, setting the dup_map if it's been set
698  * already.  Called by process_block and process_bad_block.
699  *
700  * WARNING: Assumes checks have already been done to make sure block
701  * is valid.  This is true in both process_block and process_bad_block.
702  */
703 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
704 {
705         struct          problem_context pctx;
706         
707         clear_problem_context(&pctx);
708         
709         if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
710                 if (!ctx->block_dup_map) {
711                         pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
712                               "multiply claimed block map",
713                               &ctx->block_dup_map);
714                         if (pctx.errcode) {
715                                 pctx.num = 3;
716                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, 
717                                             &pctx);
718                                 /* Should never get here */
719                                 ctx->flags |= E2F_FLAG_ABORT;
720                                 return;
721                         }
722                 }
723                 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
724         } else {
725                 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
726         }
727 }
728
729 /*
730  * This subroutine is called on each inode to account for all of the
731  * blocks used by that inode.
732  */
733 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
734                          char *block_buf)
735 {
736         ext2_filsys fs = ctx->fs;
737         struct process_block_struct pb;
738         ino_t           ino = pctx->ino;
739         struct ext2_inode *inode = pctx->inode;
740         int             bad_size = 0;
741         __u64           size;
742         struct ext2fs_sb        *sb;
743         
744         if (!ext2fs_inode_has_valid_blocks(pctx->inode))
745                 return;
746         
747         pb.ino = ino;
748         pb.num_blocks = pb.last_block = 0;
749         pb.num_illegal_blocks = 0;
750         pb.suppress = 0; pb.clear = 0;
751         pb.fragmented = 0;
752         pb.previous_block = 0;
753         pb.is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
754         pb.inode = inode;
755         pb.pctx = pctx;
756         pb.ctx = ctx;
757         pctx->ino = ino;
758         pctx->errcode = ext2fs_block_iterate2(fs, ino,
759                                        pb.is_dir ? BLOCK_FLAG_HOLE : 0,
760                                        block_buf, process_block, &pb);
761         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
762                 return;
763         end_problem_latch(ctx, PR_LATCH_BLOCK);
764         if (pctx->errcode)
765                 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
766
767         if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
768                 ctx->fs_fragmented++;
769
770         if (pb.clear) {
771                 e2fsck_read_inode(ctx, ino, inode, "check_blocks");
772                 inode->i_links_count = 0;
773                 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
774                 inode->i_dtime = time(0);
775                 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
776                 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
777                 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
778                 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
779                 /*
780                  * The inode was probably partially accounted for
781                  * before processing was aborted, so we need to
782                  * restart the pass 1 scan.
783                  */
784                 ctx->flags |= E2F_FLAG_RESTART;
785                 return;
786         }
787
788         pb.num_blocks *= (fs->blocksize / 512);
789 #if 0
790         printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
791                ino, inode->i_size, pb.last_block, inode->i_blocks,
792                pb.num_blocks);
793 #endif
794         if (!pb.num_blocks && pb.is_dir) {
795                 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
796                         inode->i_links_count = 0;
797                         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
798                         inode->i_dtime = time(0);
799                         e2fsck_write_inode(ctx, ino, inode, "check_blocks");
800                         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
801                         ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
802                         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
803                         ctx->fs_directory_count--;
804                         pb.is_dir = 0;
805                 }
806         }
807         if (pb.is_dir) {
808                 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
809                 if ((nblock > (pb.last_block + 1)) ||
810                     ((inode->i_size & (fs->blocksize-1)) != 0))
811                         bad_size = 1;
812                 else if (nblock < (pb.last_block + 1)) {
813                         sb = (struct ext2fs_sb *) fs->super;
814                         if (((pb.last_block + 1) - nblock) >
815                             sb->s_prealloc_dir_blocks)
816                                 bad_size = 2;
817                 }
818         } else {
819                 size = inode->i_size + ((__u64) inode->i_size_high << 32);
820                 if ((size < pb.last_block * fs->blocksize))
821                         bad_size = 3;
822                 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
823                         bad_size = 4;
824         }
825         if (bad_size) {
826                 pctx->num = (pb.last_block+1) * fs->blocksize;
827                 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
828                         inode->i_size = pctx->num;
829                         if (!pb.is_dir)
830                                 inode->i_size_high = pctx->num >> 32;
831                         e2fsck_write_inode(ctx, ino, inode, "check_blocks");
832                 }
833                 pctx->num = 0;
834         }
835         if (!pb.is_dir && inode->i_size_high)
836                 ctx->large_files++;
837         if (pb.num_blocks != inode->i_blocks) {
838                 pctx->num = pb.num_blocks;
839                 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
840                         inode->i_blocks = pb.num_blocks;
841                         e2fsck_write_inode(ctx, ino, inode, "check_blocks");
842                 }
843                 pctx->num = 0;
844         }
845 }
846
847 #if 0
848 /*
849  * Helper function called by process block when an illegal block is
850  * found.  It returns a description about why the block is illegal
851  */
852 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
853 {
854         blk_t   super;
855         int     i;
856         static char     problem[80];
857
858         super = fs->super->s_first_data_block;
859         strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
860         if (block < super) {
861                 sprintf(problem, "< FIRSTBLOCK (%u)", super);
862                 return(problem);
863         } else if (block >= fs->super->s_blocks_count) {
864                 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
865                 return(problem);
866         }
867         for (i = 0; i < fs->group_desc_count; i++) {
868                 if (block == super) {
869                         sprintf(problem, "is the superblock in group %d", i);
870                         break;
871                 }
872                 if (block > super &&
873                     block <= (super + fs->desc_blocks)) {
874                         sprintf(problem, "is in the group descriptors "
875                                 "of group %d", i);
876                         break;
877                 }
878                 if (block == fs->group_desc[i].bg_block_bitmap) {
879                         sprintf(problem, "is the block bitmap of group %d", i);
880                         break;
881                 }
882                 if (block == fs->group_desc[i].bg_inode_bitmap) {
883                         sprintf(problem, "is the inode bitmap of group %d", i);
884                         break;
885                 }
886                 if (block >= fs->group_desc[i].bg_inode_table &&
887                     (block < fs->group_desc[i].bg_inode_table
888                      + fs->inode_blocks_per_group)) {
889                         sprintf(problem, "is in the inode table of group %d",
890                                 i);
891                         break;
892                 }
893                 super += fs->super->s_blocks_per_group;
894         }
895         return(problem);
896 }
897 #endif
898
899 /*
900  * This is a helper function for check_blocks().
901  */
902 int process_block(ext2_filsys fs,
903                   blk_t *block_nr,
904                   e2_blkcnt_t blockcnt,
905                   blk_t ref_block,
906                   int ref_offset, 
907                   void *priv_data)
908 {
909         struct process_block_struct *p;
910         struct problem_context *pctx;
911         blk_t   blk = *block_nr;
912         int     ret_code = 0;
913         int     problem = 0;
914         e2fsck_t        ctx;
915
916         p = (struct process_block_struct *) priv_data;
917         pctx = p->pctx;
918         ctx = p->ctx;
919
920         if (blk == 0) {
921                 if (p->is_dir == 0) {
922                         /*
923                          * Should never happen, since only directories
924                          * get called with BLOCK_FLAG_HOLE
925                          */
926 #if DEBUG_E2FSCK
927                         printf("process_block() called with blk == 0, "
928                                "blockcnt=%d, inode %lu???\n",
929                                blockcnt, p->ino);
930 #endif
931                         return 0;
932                 }
933                 if (blockcnt < 0)
934                         return 0;
935                 if (blockcnt * fs->blocksize < p->inode->i_size) {
936 #if 0
937                         printf("Missing block (#%d) in directory inode %lu!\n",
938                                blockcnt, p->ino);
939 #endif
940                         goto mark_dir;
941                 }
942                 return 0;
943         }
944
945 #if 0
946         printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
947                blockcnt);
948 #endif
949         
950         /*
951          * Simplistic fragmentation check.  We merely require that the
952          * file be contiguous.  (Which can never be true for really
953          * big files that are greater than a block group.)
954          */
955         if (p->previous_block) {
956                 if (p->previous_block+1 != blk)
957                         p->fragmented = 1;
958         }
959         p->previous_block = blk;
960         
961         if (blk < fs->super->s_first_data_block ||
962             blk >= fs->super->s_blocks_count)
963                 problem = PR_1_ILLEGAL_BLOCK_NUM;
964 #if 0
965         else
966                 if (ext2fs_test_block_bitmap(block_illegal_map, blk))
967                         problem = PR_1_BLOCK_OVERLAPS_METADATA;
968 #endif
969
970         if (problem) {
971                 p->num_illegal_blocks++;
972                 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
973                         if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
974                                 p->clear = 1;
975                                 return BLOCK_ABORT;
976                         }
977                         if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
978                                 p->suppress = 1;
979                                 set_latch_flags(PR_LATCH_BLOCK,
980                                                 PRL_SUPPRESS, 0);
981                         }
982                 }
983                 pctx->blk = blk;
984                 pctx->blkcount = blockcnt;
985                 if (fix_problem(ctx, problem, pctx)) {
986                         blk = *block_nr = 0;
987                         ret_code = BLOCK_CHANGED;
988                         goto mark_dir;
989                 } else
990                         return 0;
991                 pctx->blk = 0;
992                 pctx->blkcount = -1;
993         }
994
995         mark_block_used(ctx, blk);
996         p->num_blocks++;
997         if (blockcnt >= 0)
998                 p->last_block = blockcnt;
999 mark_dir:
1000         if (p->is_dir && (blockcnt >= 0)) {
1001                 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
1002                                                     blk, blockcnt);
1003                 if (pctx->errcode) {
1004                         pctx->blk = blk;
1005                         pctx->num = blockcnt;
1006                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
1007                         /* Should never get here */
1008                         ctx->flags |= E2F_FLAG_ABORT;
1009                         return BLOCK_ABORT;
1010                 }
1011         }
1012         return ret_code;
1013 }
1014
1015 static void bad_block_indirect(e2fsck_t ctx, blk_t blk)
1016 {
1017         struct problem_context pctx;
1018
1019         clear_problem_context(&pctx);
1020         /*
1021          * Prompt to see if we should continue or not.
1022          */
1023         if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, &pctx))
1024                 ctx->flags |= E2F_FLAG_ABORT;
1025 }
1026
1027 int process_bad_block(ext2_filsys fs,
1028                       blk_t *block_nr,
1029                       e2_blkcnt_t blockcnt,
1030                       blk_t ref_block,
1031                       int ref_offset,
1032                       void *priv_data)
1033 {
1034         struct process_block_struct *p;
1035         blk_t           blk = *block_nr;
1036         int             first_block;
1037         int             i;
1038         struct problem_context *pctx;
1039         e2fsck_t        ctx;
1040
1041         if (!blk)
1042                 return 0;
1043         
1044         p = (struct process_block_struct *) priv_data;
1045         ctx = p->ctx;
1046         pctx = p->pctx;
1047         
1048         pctx->ino = EXT2_BAD_INO;
1049         pctx->blk = blk;
1050         pctx->blkcount = blockcnt;
1051
1052         if ((blk < fs->super->s_first_data_block) ||
1053             (blk >= fs->super->s_blocks_count)) {
1054                 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
1055                         *block_nr = 0;
1056                         return BLOCK_CHANGED;
1057                 } else
1058                         return 0;
1059         }
1060
1061         if (blockcnt < 0) {
1062                 if (ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
1063                         bad_block_indirect(ctx, blk);
1064                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1065                                 return BLOCK_ABORT;
1066                 } else
1067                         mark_block_used(ctx, blk);
1068                 return 0;
1069         }
1070 #if 0 
1071         printf ("DEBUG: Marking %u as bad.\n", blk);
1072 #endif
1073         ctx->fs_badblocks_count++;
1074         /*
1075          * If the block is not used, then mark it as used and return.
1076          * If it is already marked as found, this must mean that
1077          * there's an overlap between the filesystem table blocks
1078          * (bitmaps and inode table) and the bad block list.
1079          */
1080         if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
1081                 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
1082                 return 0;
1083         }
1084         /*
1085          * Try to find the where the filesystem block was used...
1086          */
1087         first_block = fs->super->s_first_data_block;
1088         
1089         for (i = 0; i < fs->group_desc_count; i++ ) {
1090                 pctx->group = i;
1091                 pctx->blk = blk;
1092                 if (!ext2fs_bg_has_super(fs, i))
1093                         goto skip_super;
1094                 if (blk == first_block) {
1095                         if (i == 0) {
1096                                 if (fix_problem(ctx,
1097                                                 PR_1_BAD_PRIMARY_SUPERBLOCK,
1098                                                 pctx)) {
1099                                         *block_nr = 0;
1100                                         return BLOCK_CHANGED;
1101                                 }
1102                                 return 0;
1103                         }
1104                         fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
1105                         return 0;
1106                 }
1107                 if ((blk > first_block) &&
1108                     (blk <= first_block + fs->desc_blocks)) {
1109                         if (i == 0) {
1110                                 pctx->blk = *block_nr;
1111                                 if (fix_problem(ctx,
1112                         PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
1113                                         *block_nr = 0;
1114                                         return BLOCK_CHANGED;
1115                                 }
1116                                 return 0;
1117                         }
1118                         fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
1119                         return 0;
1120                 }
1121         skip_super:
1122                 if (blk == fs->group_desc[i].bg_block_bitmap) {
1123                         if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
1124                                 ctx->invalid_block_bitmap_flag[i]++;
1125                                 ctx->invalid_bitmaps++;
1126                         }
1127                         return 0;
1128                 }
1129                 if (blk == fs->group_desc[i].bg_inode_bitmap) {
1130                         if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
1131                                 ctx->invalid_inode_bitmap_flag[i]++;
1132                                 ctx->invalid_bitmaps++;
1133                         }
1134                         return 0;
1135                 }
1136                 if ((blk >= fs->group_desc[i].bg_inode_table) &&
1137                     (blk < (fs->group_desc[i].bg_inode_table +
1138                             fs->inode_blocks_per_group))) {
1139                         /*
1140                          * If there are bad blocks in the inode table,
1141                          * the inode scan code will try to do
1142                          * something reasonable automatically.
1143                          */
1144                         return 0;
1145                 }
1146                 first_block += fs->super->s_blocks_per_group;
1147         }
1148         /*
1149          * If we've gotten to this point, then the only
1150          * possibility is that the bad block inode meta data
1151          * is using a bad block.
1152          */
1153         if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
1154             p->inode->i_block[EXT2_DIND_BLOCK]) {
1155                 bad_block_indirect(ctx, blk);
1156                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1157                         return BLOCK_ABORT;
1158                 return 0;
1159         }
1160
1161         pctx->group = -1;
1162
1163         /* Warn user that the block wasn't claimed */
1164         fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
1165
1166         return 0;
1167 }
1168
1169 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group, 
1170                             const char *name, int num, blk_t *new_block)
1171 {
1172         ext2_filsys fs = ctx->fs;
1173         blk_t           old_block = *new_block;
1174         int             i;
1175         char            *buf;
1176         struct problem_context  pctx;
1177
1178         clear_problem_context(&pctx);
1179
1180         pctx.group = group;
1181         pctx.blk = old_block;
1182         pctx.str = name;
1183
1184         pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
1185                         first_block + fs->super->s_blocks_per_group,
1186                                         num, ctx->block_found_map, new_block);
1187         if (pctx.errcode) {
1188                 pctx.num = num;
1189                 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
1190                 ext2fs_unmark_valid(fs);
1191                 return;
1192         }
1193         pctx.errcode = ext2fs_get_mem(fs->blocksize, (void **) &buf);
1194         if (pctx.errcode) {
1195                 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
1196                 ext2fs_unmark_valid(fs);
1197                 return;
1198         }
1199         ext2fs_mark_super_dirty(fs);
1200         pctx.blk2 = *new_block;
1201         fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
1202                           PR_1_RELOC_TO), &pctx);
1203         pctx.blk2 = 0;
1204         for (i = 0; i < num; i++) {
1205                 pctx.blk = i;
1206                 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
1207                 if (old_block) {
1208                         pctx.errcode = io_channel_read_blk(fs->io,
1209                                    old_block + i, 1, buf);
1210                         if (pctx.errcode)
1211                                 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
1212                 } else
1213                         memset(buf, 0, fs->blocksize);
1214
1215                 pctx.blk = (*new_block) + i;
1216                 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
1217                                               1, buf);
1218                 if (pctx.errcode)
1219                         fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
1220         }
1221         ext2fs_free_mem((void **) &buf);
1222 }
1223
1224 /*
1225  * This routine gets called at the end of pass 1 if bad blocks are
1226  * detected in the superblock, group descriptors, inode_bitmaps, or
1227  * block bitmaps.  At this point, all of the blocks have been mapped
1228  * out, so we can try to allocate new block(s) to replace the bad
1229  * blocks.
1230  */
1231 static void handle_fs_bad_blocks(e2fsck_t ctx)
1232 {
1233         ext2_filsys fs = ctx->fs;
1234         int             i;
1235         int             first_block = fs->super->s_first_data_block;
1236
1237         for (i = 0; i < fs->group_desc_count; i++) {
1238                 if (ctx->invalid_block_bitmap_flag[i]) {
1239                         new_table_block(ctx, first_block, i, "block bitmap", 
1240                                         1, &fs->group_desc[i].bg_block_bitmap);
1241                 }
1242                 if (ctx->invalid_inode_bitmap_flag[i]) {
1243                         new_table_block(ctx, first_block, i, "inode bitmap", 
1244                                         1, &fs->group_desc[i].bg_inode_bitmap);
1245                 }
1246                 if (ctx->invalid_inode_table_flag[i]) {
1247                         new_table_block(ctx, first_block, i, "inode table",
1248                                         fs->inode_blocks_per_group, 
1249                                         &fs->group_desc[i].bg_inode_table);
1250                         ctx->flags |= E2F_FLAG_RESTART;
1251                 }
1252                 first_block += fs->super->s_blocks_per_group;
1253         }
1254         ctx->invalid_bitmaps = 0;
1255 }
1256
1257 /*
1258  * This routine marks all blocks which are used by the superblock,
1259  * group descriptors, inode bitmaps, and block bitmaps.
1260  */
1261 static void mark_table_blocks(e2fsck_t ctx)
1262 {
1263         ext2_filsys fs = ctx->fs;
1264         blk_t   block, b;
1265         int     i,j;
1266         struct problem_context pctx;
1267         
1268         clear_problem_context(&pctx);
1269         
1270         block = fs->super->s_first_data_block;
1271         for (i = 0; i < fs->group_desc_count; i++) {
1272                 pctx.group = i;
1273
1274                 if (ext2fs_bg_has_super(fs, i)) {
1275                         /*
1276                          * Mark this group's copy of the superblock
1277                          */
1278                         ext2fs_mark_block_bitmap(ctx->block_found_map, block);
1279                         ext2fs_mark_block_bitmap(ctx->block_illegal_map,
1280                                                  block);
1281                 
1282                         /*
1283                          * Mark this group's copy of the descriptors
1284                          */
1285                         for (j = 0; j < fs->desc_blocks; j++) {
1286                                 ext2fs_mark_block_bitmap(ctx->block_found_map,
1287                                                          block + j + 1);
1288                                 ext2fs_mark_block_bitmap(ctx->block_illegal_map,
1289                                                          block + j + 1);
1290                         }
1291                 }
1292                 
1293                 /*
1294                  * Mark the blocks used for the inode table
1295                  */
1296                 if (fs->group_desc[i].bg_inode_table) {
1297                         for (j = 0, b = fs->group_desc[i].bg_inode_table;
1298                              j < fs->inode_blocks_per_group;
1299                              j++, b++) {
1300                                 if (ext2fs_test_block_bitmap(ctx->block_found_map,
1301                                                              b)) {
1302                                         pctx.blk = b;
1303                                         if (fix_problem(ctx,
1304                                                 PR_1_ITABLE_CONFLICT, &pctx)) {
1305                                                 ctx->invalid_inode_table_flag[i]++;
1306                                                 ctx->invalid_bitmaps++;
1307                                         }
1308                                 } else {
1309                                     ext2fs_mark_block_bitmap(ctx->block_found_map,
1310                                                              b);
1311                                     ext2fs_mark_block_bitmap(ctx->block_illegal_map,
1312                                                              b);
1313                                 }
1314                         }
1315                 }
1316                             
1317                 /*
1318                  * Mark block used for the block bitmap 
1319                  */
1320                 if (fs->group_desc[i].bg_block_bitmap) {
1321                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
1322                                      fs->group_desc[i].bg_block_bitmap)) {
1323                                 pctx.blk = fs->group_desc[i].bg_block_bitmap;
1324                                 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
1325                                         ctx->invalid_block_bitmap_flag[i]++;
1326                                         ctx->invalid_bitmaps++;
1327                                 }
1328                         } else {
1329                             ext2fs_mark_block_bitmap(ctx->block_found_map,
1330                                      fs->group_desc[i].bg_block_bitmap);
1331                             ext2fs_mark_block_bitmap(ctx->block_illegal_map,
1332                                      fs->group_desc[i].bg_block_bitmap);
1333                     }
1334                         
1335                 }
1336                 /*
1337                  * Mark block used for the inode bitmap 
1338                  */
1339                 if (fs->group_desc[i].bg_inode_bitmap) {
1340                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
1341                                      fs->group_desc[i].bg_inode_bitmap)) {
1342                                 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
1343                                 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
1344                                         ctx->invalid_inode_bitmap_flag[i]++;
1345                                         ctx->invalid_bitmaps++;
1346                                 } 
1347                         } else {
1348                             ext2fs_mark_block_bitmap(ctx->block_found_map,
1349                                      fs->group_desc[i].bg_inode_bitmap);
1350                             ext2fs_mark_block_bitmap(ctx->block_illegal_map,
1351                                      fs->group_desc[i].bg_inode_bitmap);
1352                         }
1353                 }
1354                 block += fs->super->s_blocks_per_group;
1355         }
1356 }
1357         
1358 /*
1359  * Thes subroutines short circuits ext2fs_get_blocks and
1360  * ext2fs_check_directory; we use them since we already have the inode
1361  * structure, so there's no point in letting the ext2fs library read
1362  * the inode again.
1363  */
1364 static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
1365 {
1366         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1367         int     i;
1368         
1369         if (ino != ctx->stashed_ino)
1370                 return EXT2_ET_CALLBACK_NOTHANDLED;
1371
1372         for (i=0; i < EXT2_N_BLOCKS; i++)
1373                 blocks[i] = ctx->stashed_inode->i_block[i];
1374         return 0;
1375 }
1376
1377 static errcode_t pass1_read_inode(ext2_filsys fs, ino_t ino,
1378                                   struct ext2_inode *inode)
1379 {
1380         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1381
1382         if (ino != ctx->stashed_ino)
1383                 return EXT2_ET_CALLBACK_NOTHANDLED;
1384         *inode = *ctx->stashed_inode;
1385         return 0;
1386 }
1387
1388 static errcode_t pass1_write_inode(ext2_filsys fs, ino_t ino,
1389                             struct ext2_inode *inode)
1390 {
1391         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1392
1393         if (ino == ctx->stashed_ino)
1394                 *ctx->stashed_inode = *inode;
1395         return EXT2_ET_CALLBACK_NOTHANDLED;
1396 }
1397
1398 static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
1399 {
1400         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1401
1402         if (ino != ctx->stashed_ino)
1403                 return EXT2_ET_CALLBACK_NOTHANDLED;
1404
1405         if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
1406                 return EXT2_ET_NO_DIRECTORY;
1407         return 0;
1408 }
1409
1410 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
1411 {
1412         ext2_filsys fs = ctx->fs;
1413
1414         if (bool) {
1415                 fs->get_blocks = pass1_get_blocks;
1416                 fs->check_directory = pass1_check_directory;
1417                 fs->read_inode = pass1_read_inode;
1418                 fs->write_inode = pass1_write_inode;
1419                 ctx->stashed_ino = 0;
1420         } else {
1421                 fs->get_blocks = 0;
1422                 fs->check_directory = 0;
1423                 fs->read_inode = 0;
1424                 fs->write_inode = 0;
1425         }
1426 }
1427
1428