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