Whamcloud - gitweb
e2fsck: Account for index nodes in the extent tree for i_blocks
[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 #define _GNU_SOURCE 1 /* get strnlen() */
41 #include <string.h>
42 #include <time.h>
43 #ifdef HAVE_ERRNO_H
44 #include <errno.h>
45 #endif
46
47 #include "e2fsck.h"
48 #include <ext2fs/ext2_ext_attr.h>
49
50 #include "problem.h"
51
52 #ifdef NO_INLINE_FUNCS
53 #define _INLINE_
54 #else
55 #define _INLINE_ inline
56 #endif
57
58 static int process_block(ext2_filsys fs, blk_t  *blocknr,
59                          e2_blkcnt_t blockcnt, blk_t ref_blk, 
60                          int ref_offset, void *priv_data);
61 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
62                              e2_blkcnt_t blockcnt, blk_t ref_blk,
63                              int ref_offset, void *priv_data);
64 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
65                          char *block_buf);
66 static void mark_table_blocks(e2fsck_t ctx);
67 static void alloc_bb_map(e2fsck_t ctx);
68 static void alloc_imagic_map(e2fsck_t ctx);
69 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
70 static void handle_fs_bad_blocks(e2fsck_t ctx);
71 static void process_inodes(e2fsck_t ctx, char *block_buf);
72 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
73 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
74                                   dgrp_t group, void * priv_data);
75 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount, 
76                                     char *block_buf, int adjust_sign);
77 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
78
79 struct process_block_struct {
80         ext2_ino_t      ino;
81         unsigned        is_dir:1, is_reg:1, clear:1, suppress:1,
82                                 fragmented:1, compressed:1, bbcheck:1;
83         blk_t           num_blocks;
84         blk_t           max_blocks;
85         e2_blkcnt_t     last_block;
86         int             num_illegal_blocks;
87         blk_t           previous_block;
88         struct ext2_inode *inode;
89         struct problem_context *pctx;
90         ext2fs_block_bitmap fs_meta_blocks;
91         e2fsck_t        ctx;
92 };
93
94 struct process_inode_block {
95         ext2_ino_t ino;
96         struct ext2_inode inode;
97 };
98
99 struct scan_callback_struct {
100         e2fsck_t        ctx;
101         char            *block_buf;
102 };
103
104 /*
105  * For the inodes to process list.
106  */
107 static struct process_inode_block *inodes_to_process;
108 static int process_inode_count;
109
110 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
111                             EXT2_MIN_BLOCK_LOG_SIZE + 1];
112
113 /*
114  * Free all memory allocated by pass1 in preparation for restarting
115  * things.
116  */
117 static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused)))
118 {
119         ext2fs_free_mem(&inodes_to_process);
120         inodes_to_process = 0;
121 }
122
123 /*
124  * Check to make sure a device inode is real.  Returns 1 if the device
125  * checks out, 0 if not.
126  *
127  * Note: this routine is now also used to check FIFO's and Sockets,
128  * since they have the same requirement; the i_block fields should be
129  * zero. 
130  */
131 int e2fsck_pass1_check_device_inode(ext2_filsys fs EXT2FS_ATTR((unused)), 
132                                     struct ext2_inode *inode)
133 {
134         int     i;
135
136         /*
137          * If the index flag is set, then this is a bogus
138          * device/fifo/socket
139          */
140         if (inode->i_flags & EXT2_INDEX_FL)
141                 return 0;
142
143         /*
144          * We should be able to do the test below all the time, but
145          * because the kernel doesn't forcibly clear the device
146          * inode's additional i_block fields, there are some rare
147          * occasions when a legitimate device inode will have non-zero
148          * additional i_block fields.  So for now, we only complain
149          * when the immutable flag is set, which should never happen
150          * for devices.  (And that's when the problem is caused, since
151          * you can't set or clear immutable flags for devices.)  Once
152          * the kernel has been fixed we can change this...
153          */
154         if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
155                 for (i=4; i < EXT2_N_BLOCKS; i++) 
156                         if (inode->i_block[i])
157                                 return 0;
158         }
159         return 1;
160 }
161
162 /*
163  * Check to make sure a symlink inode is real.  Returns 1 if the symlink
164  * checks out, 0 if not.
165  */
166 int e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode,
167                                char *buf)
168 {
169         unsigned int len;
170         int i;
171         blk_t   blocks;
172
173         if ((inode->i_size_high || inode->i_size == 0) ||
174             (inode->i_flags & EXT2_INDEX_FL))
175                 return 0;
176
177         blocks = ext2fs_inode_data_blocks(fs, inode);
178         if (blocks) {
179                 if ((inode->i_size >= fs->blocksize) ||
180                     (blocks != fs->blocksize >> 9) ||
181                     (inode->i_block[0] < fs->super->s_first_data_block) ||
182                     (inode->i_block[0] >= fs->super->s_blocks_count))
183                         return 0;
184
185                 for (i = 1; i < EXT2_N_BLOCKS; i++)
186                         if (inode->i_block[i])
187                                 return 0;
188
189                 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
190                         return 0;
191
192                 len = strnlen(buf, fs->blocksize);
193                 if (len == fs->blocksize)
194                         return 0;
195         } else {
196                 if (inode->i_size >= sizeof(inode->i_block))
197                         return 0;
198
199                 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
200                 if (len == sizeof(inode->i_block))
201                         return 0;
202         }
203         if (len != inode->i_size)
204                 return 0;
205         return 1;
206 }
207
208 /*
209  * If the immutable (or append-only) flag is set on the inode, offer
210  * to clear it.
211  */
212 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
213 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
214 {
215         if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
216                 return;
217
218         if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
219                 return;
220
221         pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
222         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
223 }
224
225 /*
226  * If device, fifo or socket, check size is zero -- if not offer to
227  * clear it
228  */
229 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
230 {
231         struct ext2_inode *inode = pctx->inode;
232         
233         if ((inode->i_size == 0) && (inode->i_size_high == 0))
234                 return;
235         
236         if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
237                 return;
238         
239         inode->i_size = 0;
240         inode->i_size_high = 0;
241         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
242 }
243         
244 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
245 {
246         struct ext2_super_block *sb = ctx->fs->super;
247         struct ext2_inode_large *inode;
248         struct ext2_ext_attr_entry *entry;
249         char *start, *end;
250         unsigned int storage_size, remain;
251         int problem = 0;
252
253         inode = (struct ext2_inode_large *) pctx->inode;
254         storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
255                 inode->i_extra_isize;
256         start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
257                 inode->i_extra_isize + sizeof(__u32);
258         end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
259         entry = (struct ext2_ext_attr_entry *) start;
260
261         /* scan all entry's headers first */
262
263         /* take finish entry 0UL into account */
264         remain = storage_size - sizeof(__u32); 
265
266         while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
267                 __u32 hash;
268
269                 /* header eats this space */
270                 remain -= sizeof(struct ext2_ext_attr_entry);
271                 
272                 /* is attribute name valid? */
273                 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
274                         pctx->num = entry->e_name_len;
275                         problem = PR_1_ATTR_NAME_LEN;
276                         goto fix;
277                 }
278
279                 /* attribute len eats this space */
280                 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
281
282                 /* check value size */
283                 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
284                         pctx->num = entry->e_value_size;
285                         problem = PR_1_ATTR_VALUE_SIZE;
286                         goto fix;
287                 }
288
289                 /* e_value_block must be 0 in inode's ea */
290                 if (entry->e_value_block != 0) {
291                         pctx->num = entry->e_value_block;
292                         problem = PR_1_ATTR_VALUE_BLOCK;
293                         goto fix;
294                 }
295
296                 hash = ext2fs_ext_attr_hash_entry(entry,
297                                                   start + entry->e_value_offs);
298
299                 /* e_hash may be 0 in older inode's ea */
300                 if (entry->e_hash != 0 && entry->e_hash != hash) {
301                         pctx->num = entry->e_hash;
302                         problem = PR_1_ATTR_HASH;
303                         goto fix;
304                 }
305
306                 remain -= entry->e_value_size;
307
308                 entry = EXT2_EXT_ATTR_NEXT(entry);
309         }
310 fix:
311         /*
312          * it seems like a corruption. it's very unlikely we could repair
313          * EA(s) in automatic fashion -bzzz
314          */
315         if (problem == 0 || !fix_problem(ctx, problem, pctx))
316                 return;
317
318         /* simply remove all possible EA(s) */
319         *((__u32 *)start) = 0UL;
320         e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
321                                 EXT2_INODE_SIZE(sb), "pass1");
322 }
323
324 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
325 {
326         struct ext2_super_block *sb = ctx->fs->super;
327         struct ext2_inode_large *inode;
328         __u32 *eamagic;
329         int min, max;
330
331         inode = (struct ext2_inode_large *) pctx->inode;
332         if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
333                 /* this isn't large inode. so, nothing to check */
334                 return;
335         }
336
337 #if 0
338         printf("inode #%u, i_extra_size %d\n", pctx->ino,
339                         inode->i_extra_isize);
340 #endif  
341         /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
342         min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
343         max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
344         /* 
345          * For now we will allow i_extra_isize to be 0, but really
346          * implementations should never allow i_extra_isize to be 0
347          */
348         if (inode->i_extra_isize &&
349             (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
350                 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
351                         return;
352                 inode->i_extra_isize = min;
353                 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
354                                         EXT2_INODE_SIZE(sb), "pass1");
355                 return;
356         }
357
358         eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
359                         inode->i_extra_isize);
360         if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
361                 /* it seems inode has an extended attribute(s) in body */
362                 check_ea_in_inode(ctx, pctx);
363         }
364 }
365
366 /* 
367  * Check to see if the inode might really be a directory, despite i_mode
368  *
369  * This is a lot of complexity for something for which I'm not really
370  * convinced happens frequently in the wild.  If for any reason this
371  * causes any problems, take this code out.
372  * [tytso:20070331.0827EDT]
373  */
374 static void check_is_really_dir(e2fsck_t ctx, struct problem_context *pctx,
375                                 char *buf)
376 {
377         struct ext2_inode *inode = pctx->inode;
378         struct ext2_dir_entry   *dirent;
379         const char              *old_op;
380         errcode_t               retval;
381         blk_t                   blk;
382         int                     i, not_device = 0;
383
384         if (LINUX_S_ISDIR(inode->i_mode) || LINUX_S_ISREG(inode->i_mode) ||
385             LINUX_S_ISLNK(inode->i_mode) || inode->i_block[0] == 0)
386                 return;
387
388         for (i=0; i < EXT2_N_BLOCKS; i++) {
389                 blk = inode->i_block[i];
390                 if (!blk)
391                         continue;
392                 if (i >= 4)
393                         not_device++;
394
395                 if (blk < ctx->fs->super->s_first_data_block ||
396                     blk >= ctx->fs->super->s_blocks_count ||
397                     ext2fs_fast_test_block_bitmap(ctx->block_found_map, blk))
398                         return; /* Invalid block, can't be dir */
399         }
400
401         if ((LINUX_S_ISCHR(inode->i_mode) || LINUX_S_ISBLK(inode->i_mode)) && 
402             (inode->i_links_count == 1) && !not_device)
403                 return;
404
405         old_op = ehandler_operation(_("reading directory block"));
406         retval = ext2fs_read_dir_block(ctx->fs, inode->i_block[0], buf);
407         ehandler_operation(0);
408         if (retval)
409                 return;
410
411         dirent = (struct ext2_dir_entry *) buf;
412         if (((dirent->name_len & 0xFF) != 1) ||
413             (dirent->name[0] != '.') ||
414             (dirent->inode != pctx->ino) ||
415             (dirent->rec_len < 12) ||
416             (dirent->rec_len % 4) ||
417             (dirent->rec_len >= ctx->fs->blocksize - 12))
418                 return;
419
420         dirent = (struct ext2_dir_entry *) (buf + dirent->rec_len);
421         if (((dirent->name_len & 0xFF) != 2) ||
422             (dirent->name[0] != '.') ||
423             (dirent->name[1] != '.') ||
424             (dirent->rec_len < 12) ||
425             (dirent->rec_len % 4))
426                 return;
427
428         if (fix_problem(ctx, PR_1_TREAT_AS_DIRECTORY, pctx)) {
429                 inode->i_mode = (inode->i_mode & 07777) | LINUX_S_IFDIR;
430                 e2fsck_write_inode_full(ctx, pctx->ino, inode, 
431                                         EXT2_INODE_SIZE(ctx->fs->super), 
432                                         "check_is_really_dir");
433         }
434 }
435
436 extern void e2fsck_setup_tdb_icount(e2fsck_t ctx, int flags, 
437                                     ext2_icount_t *ret)
438 {
439         unsigned int            threshold;
440         ext2_ino_t              num_dirs;
441         errcode_t               retval;
442         char                    *tdb_dir;
443         int                     enable;
444
445         *ret = 0;
446
447         profile_get_string(ctx->profile, "scratch_files", "directory", 0, 0,
448                            &tdb_dir);
449         profile_get_uint(ctx->profile, "scratch_files",
450                          "numdirs_threshold", 0, 0, &threshold);
451         profile_get_boolean(ctx->profile, "scratch_files",
452                             "icount", 0, 1, &enable);
453
454         retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
455         if (retval)
456                 num_dirs = 1024;        /* Guess */
457
458         if (!enable || !tdb_dir || access(tdb_dir, W_OK) ||
459             (threshold && num_dirs <= threshold))
460                 return;
461
462         retval = ext2fs_create_icount_tdb(ctx->fs, tdb_dir, flags, ret);
463         if (retval)
464                 *ret = 0;
465 }
466
467 void e2fsck_pass1(e2fsck_t ctx)
468 {
469         int     i;
470         __u64   max_sizes;
471         ext2_filsys fs = ctx->fs;
472         ext2_ino_t      ino;
473         struct ext2_inode *inode;
474         ext2_inode_scan scan;
475         char            *block_buf;
476 #ifdef RESOURCE_TRACK
477         struct resource_track   rtrack;
478 #endif
479         unsigned char   frag, fsize;
480         struct          problem_context pctx;
481         struct          scan_callback_struct scan_struct;
482         struct ext2_super_block *sb = ctx->fs->super;
483         const char      *old_op;
484         int             imagic_fs, extent_fs;
485         int             busted_fs_time = 0;
486         int             inode_size;
487         
488 #ifdef RESOURCE_TRACK
489         init_resource_track(&rtrack, ctx->fs->io);
490 #endif
491         clear_problem_context(&pctx);
492
493         if (!(ctx->options & E2F_OPT_PREEN))
494                 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
495
496         if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
497             !(ctx->options & E2F_OPT_NO)) {
498                 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
499                         ctx->dirs_to_hash = 0;
500         }
501
502 #ifdef MTRACE
503         mtrace_print("Pass 1");
504 #endif
505
506 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
507
508         for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
509                 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
510                 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
511                 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
512                 max_sizes = (max_sizes * (1UL << i)) - 1;
513                 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
514         }
515 #undef EXT2_BPP
516
517         imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
518         extent_fs = (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS);
519
520         /*
521          * Allocate bitmaps structures
522          */
523         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
524                                               &ctx->inode_used_map);
525         if (pctx.errcode) {
526                 pctx.num = 1;
527                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
528                 ctx->flags |= E2F_FLAG_ABORT;
529                 return;
530         }
531         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
532                                 _("directory inode map"), &ctx->inode_dir_map);
533         if (pctx.errcode) {
534                 pctx.num = 2;
535                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
536                 ctx->flags |= E2F_FLAG_ABORT;
537                 return;
538         }
539         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
540                         _("regular file inode map"), &ctx->inode_reg_map);
541         if (pctx.errcode) {
542                 pctx.num = 6;
543                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
544                 ctx->flags |= E2F_FLAG_ABORT;
545                 return;
546         }
547         pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
548                                               &ctx->block_found_map);
549         if (pctx.errcode) {
550                 pctx.num = 1;
551                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
552                 ctx->flags |= E2F_FLAG_ABORT;
553                 return;
554         }
555         e2fsck_setup_tdb_icount(ctx, 0, &ctx->inode_link_info);
556         if (!ctx->inode_link_info)
557                 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
558                                                      &ctx->inode_link_info);
559         if (pctx.errcode) {
560                 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
561                 ctx->flags |= E2F_FLAG_ABORT;
562                 return;
563         }
564         inode_size = EXT2_INODE_SIZE(fs->super);
565         inode = (struct ext2_inode *)
566                 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
567
568         inodes_to_process = (struct process_inode_block *)
569                 e2fsck_allocate_memory(ctx,
570                                        (ctx->process_inode_size *
571                                         sizeof(struct process_inode_block)),
572                                        "array of inodes to process");
573         process_inode_count = 0;
574
575         pctx.errcode = ext2fs_init_dblist(fs, 0);
576         if (pctx.errcode) {
577                 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
578                 ctx->flags |= E2F_FLAG_ABORT;
579                 ext2fs_free_mem(&inode);
580                 return;
581         }
582
583         /*
584          * If the last orphan field is set, clear it, since the pass1
585          * processing will automatically find and clear the orphans.
586          * In the future, we may want to try using the last_orphan
587          * linked list ourselves, but for now, we clear it so that the
588          * ext3 mount code won't get confused.
589          */
590         if (!(ctx->options & E2F_OPT_READONLY)) {
591                 if (fs->super->s_last_orphan) {
592                         fs->super->s_last_orphan = 0;
593                         ext2fs_mark_super_dirty(fs);
594                 }
595         }
596
597         mark_table_blocks(ctx);
598         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
599                                                     "block interate buffer");
600         e2fsck_use_inode_shortcuts(ctx, 1);
601         old_op = ehandler_operation(_("opening inode scan"));
602         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks, 
603                                               &scan);
604         ehandler_operation(old_op);
605         if (pctx.errcode) {
606                 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
607                 ctx->flags |= E2F_FLAG_ABORT;
608                 ext2fs_free_mem(&block_buf);
609                 ext2fs_free_mem(&inode);
610                 return;
611         }
612         ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
613         ctx->stashed_inode = inode;
614         scan_struct.ctx = ctx;
615         scan_struct.block_buf = block_buf;
616         ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
617         if (ctx->progress)
618                 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
619                         return;
620         if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
621             (fs->super->s_mtime < fs->super->s_inodes_count))
622                 busted_fs_time = 1;
623
624         while (1) {
625                 old_op = ehandler_operation(_("getting next inode from scan"));
626                 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino, 
627                                                           inode, inode_size);
628                 ehandler_operation(old_op);
629                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
630                         return;
631                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
632                         if (!ctx->inode_bb_map)
633                                 alloc_bb_map(ctx);
634                         ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
635                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
636                         continue;
637                 }
638                 if (pctx.errcode) {
639                         fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
640                         ctx->flags |= E2F_FLAG_ABORT;
641                         return;
642                 }
643                 if (!ino)
644                         break;
645                 pctx.ino = ino;
646                 pctx.inode = inode;
647                 ctx->stashed_ino = ino;
648                 if (inode->i_links_count) {
649                         pctx.errcode = ext2fs_icount_store(ctx->inode_link_info, 
650                                            ino, inode->i_links_count);
651                         if (pctx.errcode) {
652                                 pctx.num = inode->i_links_count;
653                                 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
654                                 ctx->flags |= E2F_FLAG_ABORT;
655                                 return;
656                         }
657                 }
658                 
659                 if ((inode->i_flags & EXT4_EXTENTS_FL) && !extent_fs && 
660                     (inode->i_links_count || (ino == EXT2_BAD_INO) ||
661                      (ino == EXT2_ROOT_INO) || (ino == EXT2_JOURNAL_INO))) {
662                         if ((ext2fs_extent_header_verify(inode->i_block, 
663                                                  sizeof(inode->i_block)) == 0) &&
664                             fix_problem(ctx, PR_1_EXTENT_FEATURE, &pctx)) {
665                                 sb->s_feature_incompat |= EXT3_FEATURE_INCOMPAT_EXTENTS;
666                                 ext2fs_mark_super_dirty(fs);
667                                 extent_fs = 1;
668                         } else if (fix_problem(ctx, PR_1_EXTENTS_SET, &pctx)) {
669                         clear_inode:
670                                 e2fsck_clear_inode(ctx, ino, inode, 0, "pass1");
671                                 if (ino == EXT2_BAD_INO)
672                                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, 
673                                                                  ino);
674                                 continue;
675                         }
676                 }
677
678                 if (extent_fs && !(inode->i_flags & EXT4_EXTENTS_FL) &&
679                     (inode->i_links_count || (ino == EXT2_BAD_INO) ||
680                      (ino == EXT2_ROOT_INO) || (ino == EXT2_JOURNAL_INO)) &&
681                     (LINUX_S_ISREG(inode->i_mode) ||
682                      LINUX_S_ISDIR(inode->i_mode)) &&
683                     (ext2fs_extent_header_verify(inode->i_block, 
684                                                  sizeof(inode->i_block)) == 0)) {
685                         if (fix_problem(ctx, PR_1_UNSET_EXTENT_FL, &pctx)) {
686                                 inode->i_flags |= EXT4_EXTENTS_FL;
687                                 e2fsck_write_inode(ctx, ino, inode, "pass1");
688                         }
689                 }
690
691                 if (ino == EXT2_BAD_INO) {
692                         struct process_block_struct pb;
693                         
694                         pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
695                                                           &pb.fs_meta_blocks);
696                         if (pctx.errcode) {
697                                 pctx.num = 4;
698                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
699                                 ctx->flags |= E2F_FLAG_ABORT;
700                                 return;
701                         }
702                         pb.ino = EXT2_BAD_INO;
703                         pb.num_blocks = pb.last_block = 0;
704                         pb.num_illegal_blocks = 0;
705                         pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
706                         pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
707                         pb.inode = inode;
708                         pb.pctx = &pctx;
709                         pb.ctx = ctx;
710                         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, 
711                                      block_buf, process_bad_block, &pb);
712                         ext2fs_free_block_bitmap(pb.fs_meta_blocks);
713                         if (pctx.errcode) {
714                                 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
715                                 ctx->flags |= E2F_FLAG_ABORT;
716                                 return;
717                         }
718                         if (pb.bbcheck)
719                                 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
720                                 ctx->flags |= E2F_FLAG_ABORT;
721                                 return;
722                         }
723                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
724                         clear_problem_context(&pctx);
725                         continue;
726                 } else if (ino == EXT2_ROOT_INO) {
727                         /*
728                          * Make sure the root inode is a directory; if
729                          * not, offer to clear it.  It will be
730                          * regnerated in pass #3.
731                          */
732                         if (!LINUX_S_ISDIR(inode->i_mode)) {
733                                 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx))
734                                         goto clear_inode;
735                         }
736                         /*
737                          * If dtime is set, offer to clear it.  mke2fs
738                          * version 0.2b created filesystems with the
739                          * dtime field set for the root and lost+found
740                          * directories.  We won't worry about
741                          * /lost+found, since that can be regenerated
742                          * easily.  But we will fix the root directory
743                          * as a special case.
744                          */
745                         if (inode->i_dtime && inode->i_links_count) {
746                                 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
747                                         inode->i_dtime = 0;
748                                         e2fsck_write_inode(ctx, ino, inode,
749                                                            "pass1");
750                                 }
751                         }
752                 } else if (ino == EXT2_JOURNAL_INO) {
753                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
754                         if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
755                                 if (!LINUX_S_ISREG(inode->i_mode) &&
756                                     fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
757                                                 &pctx)) {
758                                         inode->i_mode = LINUX_S_IFREG;
759                                         e2fsck_write_inode(ctx, ino, inode,
760                                                            "pass1");
761                                 }
762                                 check_blocks(ctx, &pctx, block_buf);
763                                 continue;
764                         }
765                         if ((inode->i_links_count || inode->i_blocks ||
766                              inode->i_blocks || inode->i_block[0]) &&
767                             fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR, 
768                                         &pctx)) {
769                                 memset(inode, 0, inode_size);
770                                 ext2fs_icount_store(ctx->inode_link_info,
771                                                     ino, 0);
772                                 e2fsck_write_inode_full(ctx, ino, inode, 
773                                                         inode_size, "pass1");
774                         }
775                 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
776                         int     problem = 0;
777                         
778                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
779                         if (ino == EXT2_BOOT_LOADER_INO) {
780                                 if (LINUX_S_ISDIR(inode->i_mode))
781                                         problem = PR_1_RESERVED_BAD_MODE;
782                         } else if (ino == EXT2_RESIZE_INO) {
783                                 if (inode->i_mode &&
784                                     !LINUX_S_ISREG(inode->i_mode))
785                                         problem = PR_1_RESERVED_BAD_MODE;
786                         } else {
787                                 if (inode->i_mode != 0)
788                                         problem = PR_1_RESERVED_BAD_MODE;
789                         }
790                         if (problem) {
791                                 if (fix_problem(ctx, problem, &pctx)) {
792                                         inode->i_mode = 0;
793                                         e2fsck_write_inode(ctx, ino, inode,
794                                                            "pass1");
795                                 }
796                         }
797                         check_blocks(ctx, &pctx, block_buf);
798                         continue;
799                 }
800                 /*
801                  * Check for inodes who might have been part of the
802                  * orphaned list linked list.  They should have gotten
803                  * dealt with by now, unless the list had somehow been
804                  * corrupted.
805                  * 
806                  * FIXME: In the future, inodes which are still in use
807                  * (and which are therefore) pending truncation should
808                  * be handled specially.  Right now we just clear the
809                  * dtime field, and the normal e2fsck handling of
810                  * inodes where i_size and the inode blocks are
811                  * inconsistent is to fix i_size, instead of releasing
812                  * the extra blocks.  This won't catch the inodes that
813                  * was at the end of the orphan list, but it's better
814                  * than nothing.  The right answer is that there
815                  * shouldn't be any bugs in the orphan list handling.  :-)
816                  */
817                 if (inode->i_dtime && !busted_fs_time &&
818                     inode->i_dtime < ctx->fs->super->s_inodes_count) {
819                         if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
820                                 inode->i_dtime = inode->i_links_count ?
821                                         0 : ctx->now;
822                                 e2fsck_write_inode(ctx, ino, inode,
823                                                    "pass1");
824                         }
825                 }
826                 
827                 /*
828                  * This code assumes that deleted inodes have
829                  * i_links_count set to 0.  
830                  */
831                 if (!inode->i_links_count) {
832                         if (!inode->i_dtime && inode->i_mode) {
833                                 if (fix_problem(ctx,
834                                             PR_1_ZERO_DTIME, &pctx)) {
835                                         inode->i_dtime = ctx->now;
836                                         e2fsck_write_inode(ctx, ino, inode,
837                                                            "pass1");
838                                 }
839                         }
840                         continue;
841                 }
842                 /*
843                  * n.b.  0.3c ext2fs code didn't clear i_links_count for
844                  * deleted files.  Oops.
845                  *
846                  * Since all new ext2 implementations get this right,
847                  * we now assume that the case of non-zero
848                  * i_links_count and non-zero dtime means that we
849                  * should keep the file, not delete it.
850                  * 
851                  */
852                 if (inode->i_dtime) {
853                         if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
854                                 inode->i_dtime = 0;
855                                 e2fsck_write_inode(ctx, ino, inode, "pass1");
856                         }
857                 }
858                 
859                 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
860                 switch (fs->super->s_creator_os) {
861                     case EXT2_OS_HURD:
862                         frag = inode->osd2.hurd2.h_i_frag;
863                         fsize = inode->osd2.hurd2.h_i_fsize;
864                         break;
865                     default:
866                         frag = fsize = 0;
867                 }
868                 
869                 if (inode->i_faddr || frag || fsize ||
870                     (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
871                         mark_inode_bad(ctx, ino);
872                 if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
873                     !(fs->super->s_feature_ro_compat & 
874                       EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
875                     (inode->osd2.linux2.l_i_blocks_hi != 0))
876                         mark_inode_bad(ctx, ino);
877                 if (inode->i_flags & EXT2_IMAGIC_FL) {
878                         if (imagic_fs) {
879                                 if (!ctx->inode_imagic_map)
880                                         alloc_imagic_map(ctx);
881                                 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
882                                                          ino);
883                         } else {
884                                 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
885                                         inode->i_flags &= ~EXT2_IMAGIC_FL;
886                                         e2fsck_write_inode(ctx, ino,
887                                                            inode, "pass1");
888                                 }
889                         }
890                 }
891
892                 check_inode_extra_space(ctx, &pctx);
893                 check_is_really_dir(ctx, &pctx, block_buf);
894
895                 if (LINUX_S_ISDIR(inode->i_mode)) {
896                         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
897                         e2fsck_add_dir_info(ctx, ino, 0);
898                         ctx->fs_directory_count++;
899                 } else if (LINUX_S_ISREG (inode->i_mode)) {
900                         ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
901                         ctx->fs_regular_count++;
902                 } else if (LINUX_S_ISCHR (inode->i_mode) &&
903                            e2fsck_pass1_check_device_inode(fs, inode)) {
904                         check_immutable(ctx, &pctx);
905                         check_size(ctx, &pctx);
906                         ctx->fs_chardev_count++;
907                 } else if (LINUX_S_ISBLK (inode->i_mode) &&
908                            e2fsck_pass1_check_device_inode(fs, inode)) {
909                         check_immutable(ctx, &pctx);
910                         check_size(ctx, &pctx);
911                         ctx->fs_blockdev_count++;
912                 } else if (LINUX_S_ISLNK (inode->i_mode) &&
913                            e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
914                         check_immutable(ctx, &pctx);
915                         ctx->fs_symlinks_count++;
916                         if (ext2fs_inode_data_blocks(fs, inode) == 0) {
917                                 ctx->fs_fast_symlinks_count++;
918                                 check_blocks(ctx, &pctx, block_buf);
919                                 continue;
920                         }
921                 }
922                 else if (LINUX_S_ISFIFO (inode->i_mode) &&
923                          e2fsck_pass1_check_device_inode(fs, inode)) {
924                         check_immutable(ctx, &pctx);
925                         check_size(ctx, &pctx);
926                         ctx->fs_fifo_count++;
927                 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
928                            e2fsck_pass1_check_device_inode(fs, inode)) {
929                         check_immutable(ctx, &pctx);
930                         check_size(ctx, &pctx);
931                         ctx->fs_sockets_count++;
932                 } else
933                         mark_inode_bad(ctx, ino);
934                 if (inode->i_block[EXT2_IND_BLOCK])
935                         ctx->fs_ind_count++;
936                 if (inode->i_block[EXT2_DIND_BLOCK])
937                         ctx->fs_dind_count++;
938                 if (inode->i_block[EXT2_TIND_BLOCK])
939                         ctx->fs_tind_count++;
940                 if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
941                     (inode->i_block[EXT2_IND_BLOCK] ||
942                      inode->i_block[EXT2_DIND_BLOCK] ||
943                      inode->i_block[EXT2_TIND_BLOCK] ||
944                      inode->i_file_acl)) {
945                         inodes_to_process[process_inode_count].ino = ino;
946                         inodes_to_process[process_inode_count].inode = *inode;
947                         process_inode_count++;
948                 } else
949                         check_blocks(ctx, &pctx, block_buf);
950
951                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
952                         return;
953
954                 if (process_inode_count >= ctx->process_inode_size) {
955                         process_inodes(ctx, block_buf);
956
957                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
958                                 return;
959                 }
960         }
961         process_inodes(ctx, block_buf);
962         ext2fs_close_inode_scan(scan);
963
964         /*
965          * If any extended attribute blocks' reference counts need to
966          * be adjusted, either up (ctx->refcount_extra), or down
967          * (ctx->refcount), then fix them.
968          */
969         if (ctx->refcount) {
970                 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
971                 ea_refcount_free(ctx->refcount);
972                 ctx->refcount = 0;
973         }
974         if (ctx->refcount_extra) {
975                 adjust_extattr_refcount(ctx, ctx->refcount_extra,
976                                         block_buf, +1);
977                 ea_refcount_free(ctx->refcount_extra);
978                 ctx->refcount_extra = 0;
979         }
980                 
981         if (ctx->invalid_bitmaps)
982                 handle_fs_bad_blocks(ctx);
983
984         /* We don't need the block_ea_map any more */
985         if (ctx->block_ea_map) {
986                 ext2fs_free_block_bitmap(ctx->block_ea_map);
987                 ctx->block_ea_map = 0;
988         }
989
990         if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
991                 ext2fs_block_bitmap save_bmap;
992
993                 save_bmap = fs->block_map;
994                 fs->block_map = ctx->block_found_map;
995                 clear_problem_context(&pctx);
996                 pctx.errcode = ext2fs_create_resize_inode(fs);
997                 if (pctx.errcode) {
998                         fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
999                         /* Should never get here */
1000                         ctx->flags |= E2F_FLAG_ABORT;
1001                         return;
1002                 }
1003                 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
1004                                   "recreate inode");
1005                 inode->i_mtime = ctx->now;
1006                 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode, 
1007                                    "recreate inode");
1008                 fs->block_map = save_bmap;
1009                 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
1010         }
1011                        
1012         if (ctx->flags & E2F_FLAG_RESTART) {
1013                 /*
1014                  * Only the master copy of the superblock and block
1015                  * group descriptors are going to be written during a
1016                  * restart, so set the superblock to be used to be the
1017                  * master superblock.
1018                  */
1019                 ctx->use_superblock = 0;
1020                 unwind_pass1(fs);
1021                 goto endit;
1022         }
1023
1024         if (ctx->block_dup_map) {
1025                 if (ctx->options & E2F_OPT_PREEN) {
1026                         clear_problem_context(&pctx);
1027                         fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
1028                 }
1029                 e2fsck_pass1_dupblocks(ctx, block_buf);
1030         }
1031         ext2fs_free_mem(&inodes_to_process);
1032 endit:
1033         e2fsck_use_inode_shortcuts(ctx, 0);
1034         
1035         ext2fs_free_mem(&block_buf);
1036         ext2fs_free_mem(&inode);
1037
1038 #ifdef RESOURCE_TRACK
1039         if (ctx->options & E2F_OPT_TIME2) {
1040                 e2fsck_clear_progbar(ctx);
1041                 print_resource_track(_("Pass 1"), &rtrack, ctx->fs->io);
1042         }
1043 #endif
1044 }
1045
1046 /*
1047  * When the inode_scan routines call this callback at the end of the
1048  * glock group, call process_inodes.
1049  */
1050 static errcode_t scan_callback(ext2_filsys fs, 
1051                                ext2_inode_scan scan EXT2FS_ATTR((unused)),
1052                                dgrp_t group, void * priv_data)
1053 {
1054         struct scan_callback_struct *scan_struct;
1055         e2fsck_t ctx;
1056
1057         scan_struct = (struct scan_callback_struct *) priv_data;
1058         ctx = scan_struct->ctx;
1059         
1060         process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
1061
1062         if (ctx->progress)
1063                 if ((ctx->progress)(ctx, 1, group+1,
1064                                     ctx->fs->group_desc_count))
1065                         return EXT2_ET_CANCEL_REQUESTED;
1066
1067         return 0;
1068 }
1069
1070 /*
1071  * Process the inodes in the "inodes to process" list.
1072  */
1073 static void process_inodes(e2fsck_t ctx, char *block_buf)
1074 {
1075         int                     i;
1076         struct ext2_inode       *old_stashed_inode;
1077         ext2_ino_t              old_stashed_ino;
1078         const char              *old_operation;
1079         char                    buf[80];
1080         struct problem_context  pctx;
1081         
1082 #if 0
1083         printf("begin process_inodes: ");
1084 #endif
1085         if (process_inode_count == 0)
1086                 return;
1087         old_operation = ehandler_operation(0);
1088         old_stashed_inode = ctx->stashed_inode;
1089         old_stashed_ino = ctx->stashed_ino;
1090         qsort(inodes_to_process, process_inode_count,
1091                       sizeof(struct process_inode_block), process_inode_cmp);
1092         clear_problem_context(&pctx);
1093         for (i=0; i < process_inode_count; i++) {
1094                 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
1095                 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
1096                 
1097 #if 0
1098                 printf("%u ", pctx.ino);
1099 #endif
1100                 sprintf(buf, _("reading indirect blocks of inode %u"),
1101                         pctx.ino);
1102                 ehandler_operation(buf);
1103                 check_blocks(ctx, &pctx, block_buf);
1104                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1105                         break;
1106         }
1107         ctx->stashed_inode = old_stashed_inode;
1108         ctx->stashed_ino = old_stashed_ino;
1109         process_inode_count = 0;
1110 #if 0
1111         printf("end process inodes\n");
1112 #endif
1113         ehandler_operation(old_operation);
1114 }
1115
1116 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
1117 {
1118         const struct process_inode_block *ib_a =
1119                 (const struct process_inode_block *) a;
1120         const struct process_inode_block *ib_b =
1121                 (const struct process_inode_block *) b;
1122         int     ret;
1123         
1124         ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
1125                ib_b->inode.i_block[EXT2_IND_BLOCK]);
1126         if (ret == 0)
1127                 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
1128         return ret;
1129 }
1130
1131 /*
1132  * Mark an inode as being bad in some what
1133  */
1134 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
1135 {
1136         struct          problem_context pctx;
1137
1138         if (!ctx->inode_bad_map) {
1139                 clear_problem_context(&pctx);
1140         
1141                 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
1142                             _("bad inode map"), &ctx->inode_bad_map);
1143                 if (pctx.errcode) {
1144                         pctx.num = 3;
1145                         fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1146                         /* Should never get here */
1147                         ctx->flags |= E2F_FLAG_ABORT;
1148                         return;
1149                 }
1150         }
1151         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
1152 }
1153
1154
1155 /*
1156  * This procedure will allocate the inode "bb" (badblock) map table
1157  */
1158 static void alloc_bb_map(e2fsck_t ctx)
1159 {
1160         struct          problem_context pctx;
1161         
1162         clear_problem_context(&pctx);
1163         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
1164                                               _("inode in bad block map"),
1165                                               &ctx->inode_bb_map);
1166         if (pctx.errcode) {
1167                 pctx.num = 4;
1168                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1169                 /* Should never get here */
1170                 ctx->flags |= E2F_FLAG_ABORT;
1171                 return;
1172         }
1173 }
1174
1175 /*
1176  * This procedure will allocate the inode imagic table
1177  */
1178 static void alloc_imagic_map(e2fsck_t ctx)
1179 {
1180         struct          problem_context pctx;
1181         
1182         clear_problem_context(&pctx);
1183         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
1184                                               _("imagic inode map"),
1185                                               &ctx->inode_imagic_map);
1186         if (pctx.errcode) {
1187                 pctx.num = 5;
1188                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1189                 /* Should never get here */
1190                 ctx->flags |= E2F_FLAG_ABORT;
1191                 return;
1192         }
1193 }
1194
1195 /*
1196  * Marks a block as in use, setting the dup_map if it's been set
1197  * already.  Called by process_block and process_bad_block.
1198  *
1199  * WARNING: Assumes checks have already been done to make sure block
1200  * is valid.  This is true in both process_block and process_bad_block.
1201  */
1202 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
1203 {
1204         struct          problem_context pctx;
1205         
1206         clear_problem_context(&pctx);
1207         
1208         if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
1209                 if (!ctx->block_dup_map) {
1210                         pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
1211                               _("multiply claimed block map"),
1212                               &ctx->block_dup_map);
1213                         if (pctx.errcode) {
1214                                 pctx.num = 3;
1215                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, 
1216                                             &pctx);
1217                                 /* Should never get here */
1218                                 ctx->flags |= E2F_FLAG_ABORT;
1219                                 return;
1220                         }
1221                 }
1222                 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
1223         } else {
1224                 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
1225         }
1226 }
1227
1228 /*
1229  * Adjust the extended attribute block's reference counts at the end
1230  * of pass 1, either by subtracting out references for EA blocks that
1231  * are still referenced in ctx->refcount, or by adding references for
1232  * EA blocks that had extra references as accounted for in
1233  * ctx->refcount_extra.
1234  */
1235 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount, 
1236                                     char *block_buf, int adjust_sign)
1237 {
1238         struct ext2_ext_attr_header     *header;
1239         struct problem_context          pctx;
1240         ext2_filsys                     fs = ctx->fs;
1241         blk_t                           blk;
1242         __u32                           should_be;
1243         int                             count;
1244
1245         clear_problem_context(&pctx);
1246         
1247         ea_refcount_intr_begin(refcount);
1248         while (1) {
1249                 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
1250                         break;
1251                 pctx.blk = blk;
1252                 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
1253                 if (pctx.errcode) {
1254                         fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
1255                         return;
1256                 }
1257                 header = (struct ext2_ext_attr_header *) block_buf;
1258                 pctx.blkcount = header->h_refcount;
1259                 should_be = header->h_refcount + adjust_sign * count;
1260                 pctx.num = should_be;
1261                 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
1262                         header->h_refcount = should_be;
1263                         pctx.errcode = ext2fs_write_ext_attr(fs, blk,
1264                                                              block_buf);
1265                         if (pctx.errcode) {
1266                                 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
1267                                 continue;
1268                         }
1269                 }
1270         }
1271 }
1272
1273 /*
1274  * Handle processing the extended attribute blocks
1275  */
1276 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
1277                            char *block_buf)
1278 {
1279         ext2_filsys fs = ctx->fs;
1280         ext2_ino_t      ino = pctx->ino;
1281         struct ext2_inode *inode = pctx->inode;
1282         blk_t           blk;
1283         char *          end;
1284         struct ext2_ext_attr_header *header;
1285         struct ext2_ext_attr_entry *entry;
1286         int             count;
1287         region_t        region = 0;
1288
1289         blk = inode->i_file_acl;
1290         if (blk == 0)
1291                 return 0;
1292
1293         /*
1294          * If the Extended attribute flag isn't set, then a non-zero
1295          * file acl means that the inode is corrupted.
1296          *
1297          * Or if the extended attribute block is an invalid block,
1298          * then the inode is also corrupted.
1299          */
1300         if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
1301             (blk < fs->super->s_first_data_block) ||
1302             (blk >= fs->super->s_blocks_count)) {
1303                 mark_inode_bad(ctx, ino);
1304                 return 0;
1305         }
1306
1307         /* If ea bitmap hasn't been allocated, create it */
1308         if (!ctx->block_ea_map) {
1309                 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
1310                                                       _("ext attr block map"),
1311                                                       &ctx->block_ea_map);
1312                 if (pctx->errcode) {
1313                         pctx->num = 2;
1314                         fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
1315                         ctx->flags |= E2F_FLAG_ABORT;
1316                         return 0;
1317                 }
1318         }
1319
1320         /* Create the EA refcount structure if necessary */
1321         if (!ctx->refcount) {
1322                 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
1323                 if (pctx->errcode) {
1324                         pctx->num = 1;
1325                         fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
1326                         ctx->flags |= E2F_FLAG_ABORT;
1327                         return 0;
1328                 }
1329         }
1330
1331 #if 0
1332         /* Debugging text */
1333         printf("Inode %u has EA block %u\n", ino, blk);
1334 #endif
1335
1336         /* Have we seen this EA block before? */
1337         if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
1338                 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
1339                         return 1;
1340                 /* Ooops, this EA was referenced more than it stated */
1341                 if (!ctx->refcount_extra) {
1342                         pctx->errcode = ea_refcount_create(0,
1343                                            &ctx->refcount_extra);
1344                         if (pctx->errcode) {
1345                                 pctx->num = 2;
1346                                 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
1347                                 ctx->flags |= E2F_FLAG_ABORT;
1348                                 return 0;
1349                         }
1350                 }
1351                 ea_refcount_increment(ctx->refcount_extra, blk, 0);
1352                 return 1;
1353         }
1354
1355         /*
1356          * OK, we haven't seen this EA block yet.  So we need to
1357          * validate it
1358          */
1359         pctx->blk = blk;
1360         pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
1361         if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
1362                 goto clear_extattr;
1363         header = (struct ext2_ext_attr_header *) block_buf;
1364         pctx->blk = inode->i_file_acl;
1365         if (((ctx->ext_attr_ver == 1) &&
1366              (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
1367             ((ctx->ext_attr_ver == 2) &&
1368              (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
1369                 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
1370                         goto clear_extattr;
1371         }
1372
1373         if (header->h_blocks != 1) {
1374                 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
1375                         goto clear_extattr;
1376         }
1377
1378         region = region_create(0, fs->blocksize);
1379         if (!region) {
1380                 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
1381                 ctx->flags |= E2F_FLAG_ABORT;
1382                 return 0;
1383         }
1384         if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
1385                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1386                         goto clear_extattr;
1387         }
1388
1389         entry = (struct ext2_ext_attr_entry *)(header+1);
1390         end = block_buf + fs->blocksize;
1391         while ((char *)entry < end && *(__u32 *)entry) {
1392                 __u32 hash;
1393
1394                 if (region_allocate(region, (char *)entry - (char *)header,
1395                                    EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
1396                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1397                                 goto clear_extattr;
1398                         break;
1399                 }
1400                 if ((ctx->ext_attr_ver == 1 &&
1401                      (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
1402                     (ctx->ext_attr_ver == 2 &&
1403                      entry->e_name_index == 0)) {
1404                         if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
1405                                 goto clear_extattr;
1406                         break;
1407                 }
1408                 if (entry->e_value_block != 0) {
1409                         if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
1410                                 goto clear_extattr;
1411                 }
1412                 if (entry->e_value_offs + entry->e_value_size > fs->blocksize) {
1413                         if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
1414                                 goto clear_extattr;
1415                         break;
1416                 }
1417                 if (entry->e_value_size &&
1418                     region_allocate(region, entry->e_value_offs,
1419                                     EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
1420                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1421                                 goto clear_extattr;
1422                 }
1423
1424                 hash = ext2fs_ext_attr_hash_entry(entry, block_buf +
1425                                                          entry->e_value_offs);
1426
1427                 if (entry->e_hash != hash) {
1428                         pctx->num = entry->e_hash;
1429                         if (fix_problem(ctx, PR_1_ATTR_HASH, pctx))
1430                                 goto clear_extattr;
1431                         entry->e_hash = hash;
1432                 }
1433
1434                 entry = EXT2_EXT_ATTR_NEXT(entry);
1435         }
1436         if (region_allocate(region, (char *)entry - (char *)header, 4)) {
1437                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1438                         goto clear_extattr;
1439         }
1440         region_free(region);
1441
1442         count = header->h_refcount - 1;
1443         if (count)
1444                 ea_refcount_store(ctx->refcount, blk, count);
1445         mark_block_used(ctx, blk);
1446         ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
1447         return 1;
1448
1449 clear_extattr:
1450         if (region)
1451                 region_free(region);
1452         inode->i_file_acl = 0;
1453         e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
1454         return 0;
1455 }
1456
1457 /* Returns 1 if bad htree, 0 if OK */
1458 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
1459                         ext2_ino_t ino, struct ext2_inode *inode,
1460                         char *block_buf)
1461 {
1462         struct ext2_dx_root_info        *root;
1463         ext2_filsys                     fs = ctx->fs;
1464         errcode_t                       retval;
1465         blk_t                           blk;
1466
1467         if ((!LINUX_S_ISDIR(inode->i_mode) &&
1468              fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
1469             (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
1470              fix_problem(ctx, PR_1_HTREE_SET, pctx)))
1471                 return 1;
1472
1473         pctx->errcode = ext2fs_bmap(fs, ino, inode, 0, 0, 0, &blk);
1474
1475         if ((pctx->errcode) ||
1476             (blk == 0) ||
1477             (blk < fs->super->s_first_data_block) ||
1478             (blk >= fs->super->s_blocks_count)) {
1479                 if (fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1480                         return 1;
1481                 else
1482                         return 0;
1483         }
1484
1485         retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
1486         if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1487                 return 1;
1488         
1489         /* XXX should check that beginning matches a directory */
1490         root = (struct ext2_dx_root_info *) (block_buf + 24);
1491
1492         if ((root->reserved_zero || root->info_length < 8) &&
1493             fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1494                 return 1;
1495
1496         pctx->num = root->hash_version;
1497         if ((root->hash_version != EXT2_HASH_LEGACY) &&
1498             (root->hash_version != EXT2_HASH_HALF_MD4) &&
1499             (root->hash_version != EXT2_HASH_TEA) &&
1500             fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
1501                 return 1;
1502                 
1503         if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
1504             fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
1505                 return 1;
1506
1507         pctx->num = root->indirect_levels;
1508         if ((root->indirect_levels > 1) &&
1509             fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
1510                 return 1;
1511         
1512         return 0;
1513 }
1514
1515 void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
1516                         struct ext2_inode *inode, int restart_flag,
1517                         const char *source)
1518 {
1519         inode->i_flags = 0;
1520         inode->i_links_count = 0;
1521         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
1522         inode->i_dtime = ctx->now;
1523
1524         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
1525         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
1526         if (ctx->inode_reg_map)
1527                 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
1528         if (ctx->inode_bad_map)
1529                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
1530
1531         /*
1532          * If the inode was partially accounted for before processing
1533          * was aborted, we need to restart the pass 1 scan.
1534          */
1535         ctx->flags |= restart_flag;
1536
1537         e2fsck_write_inode(ctx, ino, inode, source);
1538 }
1539
1540 static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
1541                              struct process_block_struct *pb, 
1542                              ext2_extent_handle_t ehandle)
1543 {
1544         struct ext2fs_extent    extent;
1545         blk_t                   blk;
1546         e2_blkcnt_t             blockcnt;
1547         int                     i;
1548         int                     is_dir, is_leaf;
1549         errcode_t               problem;
1550
1551
1552         pctx->errcode = ext2fs_extent_get(ehandle, EXT2_EXTENT_FIRST_SIB,
1553                                           &extent);
1554         while (!pctx->errcode) {
1555                 is_leaf = extent.e_flags & EXT2_EXTENT_FLAGS_LEAF;
1556                 is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
1557
1558                 problem = 0;
1559                 if (extent.e_pblk < ctx->fs->super->s_first_data_block ||
1560                     extent.e_pblk >= ctx->fs->super->s_blocks_count)
1561                         problem = PR_1_EXTENT_BAD_START_BLK;
1562                 else if ((extent.e_pblk + extent.e_len) >
1563                          ctx->fs->super->s_blocks_count)
1564                         problem = PR_1_EXTENT_ENDS_BEYOND;
1565
1566                 if (problem) {
1567                         pctx->blk = extent.e_pblk;
1568                         pctx->blk2 = extent.e_lblk;
1569                         pctx->num = extent.e_len;
1570                         if (fix_problem(ctx, problem, pctx)) {
1571                                 pctx->errcode =
1572                                         ext2fs_extent_delete(ehandle, 0);
1573                                 if (pctx->errcode) {
1574                                         fix_problem(ctx,
1575                                                     PR_1_EXTENT_DELETE_FAIL,
1576                                                     pctx);
1577                                         /* Should never get here */
1578                                         ctx->flags |= E2F_FLAG_ABORT;
1579                                         return;
1580                                 }
1581                         }
1582                         goto next;
1583                 }
1584
1585                 if (!is_leaf) {
1586                         mark_block_used(ctx, extent.e_pblk);
1587                         pb->num_blocks++;
1588                         pctx->errcode = ext2fs_extent_get(ehandle,
1589                                                   EXT2_EXTENT_DOWN, &extent);
1590                         if (pctx->errcode) {
1591                                 printf("Error1: %s\n", error_message(pctx->errcode));
1592                                 abort();
1593                         }
1594                         scan_extent_node(ctx, pctx, pb, ehandle);
1595                         pctx->errcode = ext2fs_extent_get(ehandle,
1596                                                   EXT2_EXTENT_UP, &extent);
1597                         if (pctx->errcode) {
1598                                 printf("Error1: %s\n", error_message(pctx->errcode));
1599                                 abort();
1600                         }
1601                         goto next;
1602                 }
1603
1604                 for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
1605                      i < extent.e_len;
1606                      blk++, blockcnt++, i++) {
1607                         mark_block_used(ctx, blk);
1608
1609                         if (is_dir) {
1610                                 pctx->errcode = ext2fs_add_dir_block(ctx->fs->dblist, pctx->ino, blk, blockcnt);
1611                                 if (pctx->errcode) {
1612                                         pctx->blk = blk;
1613                                         pctx->num = blockcnt;
1614                                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
1615                                         /* Should never get here */
1616                                         ctx->flags |= E2F_FLAG_ABORT;
1617                                         return;
1618                                 }
1619                         }
1620                 }
1621                 pb->num_blocks += extent.e_len;
1622                 pb->last_block = extent.e_lblk + extent.e_len - 1;
1623         next:
1624                 pctx->errcode = ext2fs_extent_get(ehandle,
1625                                                   EXT2_EXTENT_NEXT_SIB,
1626                                                   &extent);
1627         }
1628         if (pctx->errcode == EXT2_ET_EXTENT_NO_NEXT)
1629                 pctx->errcode = 0;
1630 }
1631
1632 static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
1633                                  struct process_block_struct *pb, 
1634                                  char *block_buf)
1635 {
1636         struct ext2_inode       *inode = pctx->inode;
1637         ext2_extent_handle_t    ehandle;
1638         ext2_filsys             fs = ctx->fs;
1639         ext2_ino_t              ino = pctx->ino;
1640
1641         pctx->errcode = ext2fs_extent_open(fs, ino, &ehandle);
1642         if (pctx->errcode &&
1643             fix_problem(ctx, PR_1_READ_EXTENT, pctx)) {
1644                 e2fsck_clear_inode(ctx, ino, inode, 0, "check_blocks_extents");
1645                 pctx->errcode = 0;
1646                 return;
1647         }
1648
1649         scan_extent_node(ctx, pctx, pb, ehandle);
1650
1651         ext2fs_extent_free(ehandle);
1652 }
1653
1654 /*
1655  * This subroutine is called on each inode to account for all of the
1656  * blocks used by that inode.
1657  */
1658 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
1659                          char *block_buf)
1660 {
1661         ext2_filsys fs = ctx->fs;
1662         struct process_block_struct pb;
1663         ext2_ino_t      ino = pctx->ino;
1664         struct ext2_inode *inode = pctx->inode;
1665         int             bad_size = 0;
1666         int             dirty_inode = 0;
1667         __u64           size;
1668         
1669         pb.ino = ino;
1670         pb.num_blocks = 0;
1671         pb.last_block = -1;
1672         pb.num_illegal_blocks = 0;
1673         pb.suppress = 0; pb.clear = 0;
1674         pb.fragmented = 0;
1675         pb.compressed = 0;
1676         pb.previous_block = 0;
1677         pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
1678         pb.is_reg = LINUX_S_ISREG(inode->i_mode);
1679         pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
1680         pb.inode = inode;
1681         pb.pctx = pctx;
1682         pb.ctx = ctx;
1683         pctx->ino = ino;
1684         pctx->errcode = 0;
1685
1686         if (inode->i_flags & EXT2_COMPRBLK_FL) {
1687                 if (fs->super->s_feature_incompat &
1688                     EXT2_FEATURE_INCOMPAT_COMPRESSION)
1689                         pb.compressed = 1;
1690                 else {
1691                         if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
1692                                 inode->i_flags &= ~EXT2_COMPRBLK_FL;
1693                                 dirty_inode++;
1694                         }
1695                 }
1696         }
1697
1698         if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf)) {
1699                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1700                         goto out;
1701                 pb.num_blocks++;
1702         }
1703
1704         if (ext2fs_inode_has_valid_blocks(inode)) {
1705                 if ((ctx->fs->super->s_feature_incompat &
1706                      EXT3_FEATURE_INCOMPAT_EXTENTS) &&
1707                     (inode->i_flags & EXT4_EXTENTS_FL))
1708                         check_blocks_extents(ctx, pctx, &pb, block_buf);
1709                 else
1710                         pctx->errcode = ext2fs_block_iterate2(fs, ino,
1711                                                 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
1712                                                 block_buf, process_block, &pb);
1713         }
1714         end_problem_latch(ctx, PR_LATCH_BLOCK);
1715         end_problem_latch(ctx, PR_LATCH_TOOBIG);
1716         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1717                 goto out;
1718         if (pctx->errcode)
1719                 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
1720
1721         if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
1722                 ctx->fs_fragmented++;
1723
1724         if (pb.clear) {
1725                 e2fsck_clear_inode(ctx, ino, inode, E2F_FLAG_RESTART,
1726                                    "check_blocks");
1727                 return;
1728         }
1729         
1730         if (inode->i_flags & EXT2_INDEX_FL) {
1731                 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
1732                         inode->i_flags &= ~EXT2_INDEX_FL;
1733                         dirty_inode++;
1734                 } else {
1735 #ifdef ENABLE_HTREE
1736                         e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
1737 #endif
1738                 }
1739         }
1740         if (ctx->dirs_to_hash && pb.is_dir &&
1741             !(inode->i_flags & EXT2_INDEX_FL) &&
1742             ((inode->i_size / fs->blocksize) >= 3))
1743                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
1744                 
1745         if (!pb.num_blocks && pb.is_dir) {
1746                 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
1747                         e2fsck_clear_inode(ctx, ino, inode, 0, "check_blocks");
1748                         ctx->fs_directory_count--;
1749                         return;
1750                 }
1751         }
1752
1753         pb.num_blocks *= (fs->blocksize / 512);
1754 #if 0
1755         printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
1756                ino, inode->i_size, pb.last_block, inode->i_blocks,
1757                pb.num_blocks);
1758 #endif
1759         if (pb.is_dir) {
1760                 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
1761                 if (nblock > (pb.last_block + 1))
1762                         bad_size = 1;
1763                 else if (nblock < (pb.last_block + 1)) {
1764                         if (((pb.last_block + 1) - nblock) >
1765                             fs->super->s_prealloc_dir_blocks)
1766                                 bad_size = 2;
1767                 }
1768         } else {
1769                 e2_blkcnt_t blkpg = ctx->blocks_per_page;
1770
1771                 size = EXT2_I_SIZE(inode);
1772                 if ((pb.last_block >= 0) &&
1773                     /* allow allocated blocks to end of PAGE_SIZE */
1774                     (size < (__u64)pb.last_block * fs->blocksize) &&
1775                     (pb.last_block / blkpg * blkpg != pb.last_block ||
1776                      size < (__u64)(pb.last_block & ~(blkpg-1)) *fs->blocksize))
1777                         bad_size = 3;
1778                 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
1779                         bad_size = 4;
1780         }
1781         /* i_size for symlinks is checked elsewhere */
1782         if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
1783                 pctx->num = (pb.last_block+1) * fs->blocksize;
1784                 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
1785                         inode->i_size = pctx->num;
1786                         if (!LINUX_S_ISDIR(inode->i_mode))
1787                                 inode->i_size_high = pctx->num >> 32;
1788                         dirty_inode++;
1789                 }
1790                 pctx->num = 0;
1791         }
1792         if (LINUX_S_ISREG(inode->i_mode) &&
1793             (inode->i_size_high || inode->i_size & 0x80000000UL))
1794                 ctx->large_files++;
1795         if (pb.num_blocks != inode->i_blocks) {
1796                 pctx->num = pb.num_blocks;
1797                 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
1798                         inode->i_blocks = pb.num_blocks;
1799                         dirty_inode++;
1800                 }
1801                 pctx->num = 0;
1802         }
1803 out:
1804         if (dirty_inode)
1805                 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
1806 }
1807
1808 #if 0
1809 /*
1810  * Helper function called by process block when an illegal block is
1811  * found.  It returns a description about why the block is illegal
1812  */
1813 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
1814 {
1815         blk_t   super;
1816         int     i;
1817         static char     problem[80];
1818
1819         super = fs->super->s_first_data_block;
1820         strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
1821         if (block < super) {
1822                 sprintf(problem, "< FIRSTBLOCK (%u)", super);
1823                 return(problem);
1824         } else if (block >= fs->super->s_blocks_count) {
1825                 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
1826                 return(problem);
1827         }
1828         for (i = 0; i < fs->group_desc_count; i++) {
1829                 if (block == super) {
1830                         sprintf(problem, "is the superblock in group %d", i);
1831                         break;
1832                 }
1833                 if (block > super &&
1834                     block <= (super + fs->desc_blocks)) {
1835                         sprintf(problem, "is in the group descriptors "
1836                                 "of group %d", i);
1837                         break;
1838                 }
1839                 if (block == fs->group_desc[i].bg_block_bitmap) {
1840                         sprintf(problem, "is the block bitmap of group %d", i);
1841                         break;
1842                 }
1843                 if (block == fs->group_desc[i].bg_inode_bitmap) {
1844                         sprintf(problem, "is the inode bitmap of group %d", i);
1845                         break;
1846                 }
1847                 if (block >= fs->group_desc[i].bg_inode_table &&
1848                     (block < fs->group_desc[i].bg_inode_table
1849                      + fs->inode_blocks_per_group)) {
1850                         sprintf(problem, "is in the inode table of group %d",
1851                                 i);
1852                         break;
1853                 }
1854                 super += fs->super->s_blocks_per_group;
1855         }
1856         return(problem);
1857 }
1858 #endif
1859
1860 /*
1861  * This is a helper function for check_blocks().
1862  */
1863 static int process_block(ext2_filsys fs,
1864                   blk_t *block_nr,
1865                   e2_blkcnt_t blockcnt,
1866                   blk_t ref_block EXT2FS_ATTR((unused)),
1867                   int ref_offset EXT2FS_ATTR((unused)),
1868                   void *priv_data)
1869 {
1870         struct process_block_struct *p;
1871         struct problem_context *pctx;
1872         blk_t   blk = *block_nr;
1873         int     ret_code = 0;
1874         int     problem = 0;
1875         e2fsck_t        ctx;
1876
1877         p = (struct process_block_struct *) priv_data;
1878         pctx = p->pctx;
1879         ctx = p->ctx;
1880
1881         if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
1882                 /* todo: Check that the comprblk_fl is high, that the
1883                    blkaddr pattern looks right (all non-holes up to
1884                    first EXT2FS_COMPRESSED_BLKADDR, then all
1885                    EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
1886                    that the feature_incompat bit is high, and that the
1887                    inode is a regular file.  If we're doing a "full
1888                    check" (a concept introduced to e2fsck by e2compr,
1889                    meaning that we look at data blocks as well as
1890                    metadata) then call some library routine that
1891                    checks the compressed data.  I'll have to think
1892                    about this, because one particularly important
1893                    problem to be able to fix is to recalculate the
1894                    cluster size if necessary.  I think that perhaps
1895                    we'd better do most/all e2compr-specific checks
1896                    separately, after the non-e2compr checks.  If not
1897                    doing a full check, it may be useful to test that
1898                    the personality is linux; e.g. if it isn't then
1899                    perhaps this really is just an illegal block. */
1900                 return 0;
1901         }
1902
1903         if (blk == 0) {
1904                 if (p->is_dir == 0) {
1905                         /*
1906                          * Should never happen, since only directories
1907                          * get called with BLOCK_FLAG_HOLE
1908                          */
1909 #if DEBUG_E2FSCK
1910                         printf("process_block() called with blk == 0, "
1911                                "blockcnt=%d, inode %lu???\n",
1912                                blockcnt, p->ino);
1913 #endif
1914                         return 0;
1915                 }
1916                 if (blockcnt < 0)
1917                         return 0;
1918                 if (blockcnt * fs->blocksize < p->inode->i_size) {
1919 #if 0
1920                         printf("Missing block (#%d) in directory inode %lu!\n",
1921                                blockcnt, p->ino);
1922 #endif
1923                         goto mark_dir;
1924                 }
1925                 return 0;
1926         }
1927
1928 #if 0
1929         printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
1930                blockcnt);
1931 #endif
1932         
1933         /*
1934          * Simplistic fragmentation check.  We merely require that the
1935          * file be contiguous.  (Which can never be true for really
1936          * big files that are greater than a block group.)
1937          */
1938         if (!HOLE_BLKADDR(p->previous_block)) {
1939                 if (p->previous_block+1 != blk)
1940                         p->fragmented = 1;
1941         }
1942         p->previous_block = blk;
1943
1944         if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
1945                 problem = PR_1_TOOBIG_DIR;
1946         if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
1947                 problem = PR_1_TOOBIG_REG;
1948         if (!p->is_dir && !p->is_reg && blockcnt > 0)
1949                 problem = PR_1_TOOBIG_SYMLINK;
1950             
1951         if (blk < fs->super->s_first_data_block ||
1952             blk >= fs->super->s_blocks_count)
1953                 problem = PR_1_ILLEGAL_BLOCK_NUM;
1954
1955         if (problem) {
1956                 p->num_illegal_blocks++;
1957                 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
1958                         if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
1959                                 p->clear = 1;
1960                                 return BLOCK_ABORT;
1961                         }
1962                         if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
1963                                 p->suppress = 1;
1964                                 set_latch_flags(PR_LATCH_BLOCK,
1965                                                 PRL_SUPPRESS, 0);
1966                         }
1967                 }
1968                 pctx->blk = blk;
1969                 pctx->blkcount = blockcnt;
1970                 if (fix_problem(ctx, problem, pctx)) {
1971                         blk = *block_nr = 0;
1972                         ret_code = BLOCK_CHANGED;
1973                         goto mark_dir;
1974                 } else
1975                         return 0;
1976         }
1977
1978         if (p->ino == EXT2_RESIZE_INO) {
1979                 /* 
1980                  * The resize inode has already be sanity checked
1981                  * during pass #0 (the superblock checks).  All we
1982                  * have to do is mark the double indirect block as
1983                  * being in use; all of the other blocks are handled
1984                  * by mark_table_blocks()).
1985                  */
1986                 if (blockcnt == BLOCK_COUNT_DIND)
1987                         mark_block_used(ctx, blk);
1988         } else
1989                 mark_block_used(ctx, blk);
1990         p->num_blocks++;
1991         if (blockcnt >= 0)
1992                 p->last_block = blockcnt;
1993 mark_dir:
1994         if (p->is_dir && (blockcnt >= 0)) {
1995                 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
1996                                                     blk, blockcnt);
1997                 if (pctx->errcode) {
1998                         pctx->blk = blk;
1999                         pctx->num = blockcnt;
2000                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
2001                         /* Should never get here */
2002                         ctx->flags |= E2F_FLAG_ABORT;
2003                         return BLOCK_ABORT;
2004                 }
2005         }
2006         return ret_code;
2007 }
2008
2009 static int process_bad_block(ext2_filsys fs,
2010                       blk_t *block_nr,
2011                       e2_blkcnt_t blockcnt,
2012                       blk_t ref_block EXT2FS_ATTR((unused)),
2013                       int ref_offset EXT2FS_ATTR((unused)),
2014                       void *priv_data)
2015 {
2016         struct process_block_struct *p;
2017         blk_t           blk = *block_nr;
2018         blk_t           first_block;
2019         dgrp_t          i;
2020         struct problem_context *pctx;
2021         e2fsck_t        ctx;
2022
2023         /*
2024          * Note: This function processes blocks for the bad blocks
2025          * inode, which is never compressed.  So we don't use HOLE_BLKADDR().
2026          */
2027
2028         if (!blk)
2029                 return 0;
2030         
2031         p = (struct process_block_struct *) priv_data;
2032         ctx = p->ctx;
2033         pctx = p->pctx;
2034         
2035         pctx->ino = EXT2_BAD_INO;
2036         pctx->blk = blk;
2037         pctx->blkcount = blockcnt;
2038
2039         if ((blk < fs->super->s_first_data_block) ||
2040             (blk >= fs->super->s_blocks_count)) {
2041                 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
2042                         *block_nr = 0;
2043                         return BLOCK_CHANGED;
2044                 } else
2045                         return 0;
2046         }
2047
2048         if (blockcnt < 0) {
2049                 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
2050                         p->bbcheck = 1;
2051                         if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
2052                                 *block_nr = 0;
2053                                 return BLOCK_CHANGED;
2054                         }
2055                 } else if (ext2fs_test_block_bitmap(ctx->block_found_map, 
2056                                                     blk)) {
2057                         p->bbcheck = 1;
2058                         if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, 
2059                                         pctx)) {
2060                                 *block_nr = 0;
2061                                 return BLOCK_CHANGED;
2062                         }
2063                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2064                                 return BLOCK_ABORT;
2065                 } else
2066                         mark_block_used(ctx, blk);
2067                 return 0;
2068         }
2069 #if 0 
2070         printf ("DEBUG: Marking %u as bad.\n", blk);
2071 #endif
2072         ctx->fs_badblocks_count++;
2073         /*
2074          * If the block is not used, then mark it as used and return.
2075          * If it is already marked as found, this must mean that
2076          * there's an overlap between the filesystem table blocks
2077          * (bitmaps and inode table) and the bad block list.
2078          */
2079         if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
2080                 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
2081                 return 0;
2082         }
2083         /*
2084          * Try to find the where the filesystem block was used...
2085          */
2086         first_block = fs->super->s_first_data_block;
2087         
2088         for (i = 0; i < fs->group_desc_count; i++ ) {
2089                 pctx->group = i;
2090                 pctx->blk = blk;
2091                 if (!ext2fs_bg_has_super(fs, i))
2092                         goto skip_super;
2093                 if (blk == first_block) {
2094                         if (i == 0) {
2095                                 if (fix_problem(ctx,
2096                                                 PR_1_BAD_PRIMARY_SUPERBLOCK,
2097                                                 pctx)) {
2098                                         *block_nr = 0;
2099                                         return BLOCK_CHANGED;
2100                                 }
2101                                 return 0;
2102                         }
2103                         fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
2104                         return 0;
2105                 }
2106                 if ((blk > first_block) &&
2107                     (blk <= first_block + fs->desc_blocks)) {
2108                         if (i == 0) {
2109                                 pctx->blk = *block_nr;
2110                                 if (fix_problem(ctx,
2111                         PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
2112                                         *block_nr = 0;
2113                                         return BLOCK_CHANGED;
2114                                 }
2115                                 return 0;
2116                         }
2117                         fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
2118                         return 0;
2119                 }
2120         skip_super:
2121                 if (blk == fs->group_desc[i].bg_block_bitmap) {
2122                         if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
2123                                 ctx->invalid_block_bitmap_flag[i]++;
2124                                 ctx->invalid_bitmaps++;
2125                         }
2126                         return 0;
2127                 }
2128                 if (blk == fs->group_desc[i].bg_inode_bitmap) {
2129                         if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
2130                                 ctx->invalid_inode_bitmap_flag[i]++;
2131                                 ctx->invalid_bitmaps++;
2132                         }
2133                         return 0;
2134                 }
2135                 if ((blk >= fs->group_desc[i].bg_inode_table) &&
2136                     (blk < (fs->group_desc[i].bg_inode_table +
2137                             fs->inode_blocks_per_group))) {
2138                         /*
2139                          * If there are bad blocks in the inode table,
2140                          * the inode scan code will try to do
2141                          * something reasonable automatically.
2142                          */
2143                         return 0;
2144                 }
2145                 first_block += fs->super->s_blocks_per_group;
2146         }
2147         /*
2148          * If we've gotten to this point, then the only
2149          * possibility is that the bad block inode meta data
2150          * is using a bad block.
2151          */
2152         if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
2153             (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
2154             (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
2155                 p->bbcheck = 1;
2156                 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
2157                         *block_nr = 0;
2158                         return BLOCK_CHANGED;
2159                 }
2160                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2161                         return BLOCK_ABORT;
2162                 return 0;
2163         }
2164
2165         pctx->group = -1;
2166
2167         /* Warn user that the block wasn't claimed */
2168         fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
2169
2170         return 0;
2171 }
2172
2173 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group, 
2174                             const char *name, int num, blk_t *new_block)
2175 {
2176         ext2_filsys fs = ctx->fs;
2177         blk_t           old_block = *new_block;
2178         blk_t           last_block;
2179         int             i;
2180         char            *buf;
2181         struct problem_context  pctx;
2182
2183         clear_problem_context(&pctx);
2184
2185         pctx.group = group;
2186         pctx.blk = old_block;
2187         pctx.str = name;
2188
2189         last_block = ext2fs_group_last_block(fs, group);
2190         pctx.errcode = ext2fs_get_free_blocks(fs, first_block, last_block,
2191                                         num, ctx->block_found_map, new_block);
2192         if (pctx.errcode) {
2193                 pctx.num = num;
2194                 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
2195                 ext2fs_unmark_valid(fs);
2196                 return;
2197         }
2198         pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
2199         if (pctx.errcode) {
2200                 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
2201                 ext2fs_unmark_valid(fs);
2202                 return;
2203         }
2204         ext2fs_mark_super_dirty(fs);
2205         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2206         pctx.blk2 = *new_block;
2207         fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
2208                           PR_1_RELOC_TO), &pctx);
2209         pctx.blk2 = 0;
2210         for (i = 0; i < num; i++) {
2211                 pctx.blk = i;
2212                 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
2213                 if (old_block) {
2214                         pctx.errcode = io_channel_read_blk(fs->io,
2215                                    old_block + i, 1, buf);
2216                         if (pctx.errcode)
2217                                 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
2218                 } else
2219                         memset(buf, 0, fs->blocksize);
2220
2221                 pctx.blk = (*new_block) + i;
2222                 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
2223                                               1, buf);
2224                 if (pctx.errcode)
2225                         fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
2226         }
2227         ext2fs_free_mem(&buf);
2228 }
2229
2230 /*
2231  * This routine gets called at the end of pass 1 if bad blocks are
2232  * detected in the superblock, group descriptors, inode_bitmaps, or
2233  * block bitmaps.  At this point, all of the blocks have been mapped
2234  * out, so we can try to allocate new block(s) to replace the bad
2235  * blocks.
2236  */
2237 static void handle_fs_bad_blocks(e2fsck_t ctx)
2238 {
2239         ext2_filsys fs = ctx->fs;
2240         dgrp_t          i;
2241         blk_t           first_block;
2242
2243         for (i = 0; i < fs->group_desc_count; i++) {
2244                 first_block = ext2fs_group_first_block(fs, i);
2245
2246                 if (ctx->invalid_block_bitmap_flag[i]) {
2247                         new_table_block(ctx, first_block, i, _("block bitmap"),
2248                                         1, &fs->group_desc[i].bg_block_bitmap);
2249                 }
2250                 if (ctx->invalid_inode_bitmap_flag[i]) {
2251                         new_table_block(ctx, first_block, i, _("inode bitmap"),
2252                                         1, &fs->group_desc[i].bg_inode_bitmap);
2253                 }
2254                 if (ctx->invalid_inode_table_flag[i]) {
2255                         new_table_block(ctx, first_block, i, _("inode table"),
2256                                         fs->inode_blocks_per_group, 
2257                                         &fs->group_desc[i].bg_inode_table);
2258                         ctx->flags |= E2F_FLAG_RESTART;
2259                 }
2260         }
2261         ctx->invalid_bitmaps = 0;
2262 }
2263
2264 /*
2265  * This routine marks all blocks which are used by the superblock,
2266  * group descriptors, inode bitmaps, and block bitmaps.
2267  */
2268 static void mark_table_blocks(e2fsck_t ctx)
2269 {
2270         ext2_filsys fs = ctx->fs;
2271         blk_t   b;
2272         dgrp_t  i;
2273         int     j;
2274         struct problem_context pctx;
2275         
2276         clear_problem_context(&pctx);
2277         
2278         for (i = 0; i < fs->group_desc_count; i++) {
2279                 pctx.group = i;
2280
2281                 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
2282
2283                 /*
2284                  * Mark the blocks used for the inode table
2285                  */
2286                 if (fs->group_desc[i].bg_inode_table) {
2287                         for (j = 0, b = fs->group_desc[i].bg_inode_table;
2288                              j < fs->inode_blocks_per_group;
2289                              j++, b++) {
2290                                 if (ext2fs_test_block_bitmap(ctx->block_found_map,
2291                                                              b)) {
2292                                         pctx.blk = b;
2293                                         if (fix_problem(ctx,
2294                                                 PR_1_ITABLE_CONFLICT, &pctx)) {
2295                                                 ctx->invalid_inode_table_flag[i]++;
2296                                                 ctx->invalid_bitmaps++;
2297                                         }
2298                                 } else {
2299                                     ext2fs_mark_block_bitmap(ctx->block_found_map,
2300                                                              b);
2301                                 }
2302                         }
2303                 }
2304                             
2305                 /*
2306                  * Mark block used for the block bitmap 
2307                  */
2308                 if (fs->group_desc[i].bg_block_bitmap) {
2309                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
2310                                      fs->group_desc[i].bg_block_bitmap)) {
2311                                 pctx.blk = fs->group_desc[i].bg_block_bitmap;
2312                                 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
2313                                         ctx->invalid_block_bitmap_flag[i]++;
2314                                         ctx->invalid_bitmaps++;
2315                                 }
2316                         } else {
2317                             ext2fs_mark_block_bitmap(ctx->block_found_map,
2318                                      fs->group_desc[i].bg_block_bitmap);
2319                     }
2320                         
2321                 }
2322                 /*
2323                  * Mark block used for the inode bitmap 
2324                  */
2325                 if (fs->group_desc[i].bg_inode_bitmap) {
2326                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
2327                                      fs->group_desc[i].bg_inode_bitmap)) {
2328                                 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
2329                                 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
2330                                         ctx->invalid_inode_bitmap_flag[i]++;
2331                                         ctx->invalid_bitmaps++;
2332                                 } 
2333                         } else {
2334                             ext2fs_mark_block_bitmap(ctx->block_found_map,
2335                                      fs->group_desc[i].bg_inode_bitmap);
2336                         }
2337                 }
2338         }
2339 }
2340         
2341 /*
2342  * Thes subroutines short circuits ext2fs_get_blocks and
2343  * ext2fs_check_directory; we use them since we already have the inode
2344  * structure, so there's no point in letting the ext2fs library read
2345  * the inode again.
2346  */
2347 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
2348                                   blk_t *blocks)
2349 {
2350         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2351         int     i;
2352         
2353         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
2354                 return EXT2_ET_CALLBACK_NOTHANDLED;
2355
2356         for (i=0; i < EXT2_N_BLOCKS; i++)
2357                 blocks[i] = ctx->stashed_inode->i_block[i];
2358         return 0;
2359 }
2360
2361 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
2362                                   struct ext2_inode *inode)
2363 {
2364         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2365
2366         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
2367                 return EXT2_ET_CALLBACK_NOTHANDLED;
2368         *inode = *ctx->stashed_inode;
2369         return 0;
2370 }
2371
2372 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
2373                             struct ext2_inode *inode)
2374 {
2375         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2376
2377         if ((ino == ctx->stashed_ino) && ctx->stashed_inode &&
2378                 (inode != ctx->stashed_inode))
2379                 *ctx->stashed_inode = *inode;
2380         return EXT2_ET_CALLBACK_NOTHANDLED;
2381 }
2382
2383 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
2384 {
2385         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2386
2387         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
2388                 return EXT2_ET_CALLBACK_NOTHANDLED;
2389
2390         if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
2391                 return EXT2_ET_NO_DIRECTORY;
2392         return 0;
2393 }
2394
2395 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
2396 {
2397         ext2_filsys fs = ctx->fs;
2398
2399         if (bool) {
2400                 fs->get_blocks = pass1_get_blocks;
2401                 fs->check_directory = pass1_check_directory;
2402                 fs->read_inode = pass1_read_inode;
2403                 fs->write_inode = pass1_write_inode;
2404                 ctx->stashed_ino = 0;
2405         } else {
2406                 fs->get_blocks = 0;
2407                 fs->check_directory = 0;
2408                 fs->read_inode = 0;
2409                 fs->write_inode = 0;
2410         }
2411 }