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