Whamcloud - gitweb
e2fsck: fix spurious complaints about i_size caused by preallocated blocks
[tools/e2fsprogs.git] / e2fsck / pass1.c
1 /*
2  * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
3  * 
4  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
5  *
6  * %Begin-Header%
7  * This file may be redistributed under the terms of the GNU Public
8  * License.
9  * %End-Header%
10  * 
11  * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
12  * and applies the following tests to each inode:
13  *
14  *      - The mode field of the inode must be legal.
15  *      - The size and block count fields of the inode are correct.
16  *      - A data block must not be used by another inode
17  *
18  * Pass 1 also gathers the collects the following information:
19  *
20  *      - A bitmap of which inodes are in use.          (inode_used_map)
21  *      - A bitmap of which inodes are directories.     (inode_dir_map)
22  *      - A bitmap of which inodes are regular files.   (inode_reg_map)
23  *      - A bitmap of which inodes have bad fields.     (inode_bad_map)
24  *      - A bitmap of which inodes are in bad blocks.   (inode_bb_map)
25  *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
26  *      - A bitmap of which blocks are in use.          (block_found_map)
27  *      - A bitmap of which blocks are in use by two inodes     (block_dup_map)
28  *      - The data blocks of the directory inodes.      (dir_map)
29  *
30  * Pass 1 is designed to stash away enough information so that the
31  * other passes should not need to read in the inode information
32  * during the normal course of a filesystem check.  (Althogh if an
33  * inconsistency is detected, other passes may need to read in an
34  * inode to fix it.)
35  *
36  * Note that pass 1B will be invoked if there are any duplicate blocks
37  * found.
38  */
39
40 #define _GNU_SOURCE 1 /* get strnlen() */
41 #include <string.h>
42 #include <time.h>
43 #ifdef HAVE_ERRNO_H
44 #include <errno.h>
45 #endif
46
47 #include "e2fsck.h"
48 #include <ext2fs/ext2_ext_attr.h>
49
50 #include "problem.h"
51
52 #ifdef NO_INLINE_FUNCS
53 #define _INLINE_
54 #else
55 #define _INLINE_ inline
56 #endif
57
58 static int process_block(ext2_filsys fs, blk_t  *blocknr,
59                          e2_blkcnt_t blockcnt, blk_t ref_blk, 
60                          int ref_offset, void *priv_data);
61 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
62                              e2_blkcnt_t blockcnt, blk_t ref_blk,
63                              int ref_offset, void *priv_data);
64 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
65                          char *block_buf);
66 static void mark_table_blocks(e2fsck_t ctx);
67 static void alloc_bb_map(e2fsck_t ctx);
68 static void alloc_imagic_map(e2fsck_t ctx);
69 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
70 static void handle_fs_bad_blocks(e2fsck_t ctx);
71 static void process_inodes(e2fsck_t ctx, char *block_buf);
72 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
73 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
74                                   dgrp_t group, void * priv_data);
75 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount, 
76                                     char *block_buf, int adjust_sign);
77 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
78
79 struct process_block_struct {
80         ext2_ino_t      ino;
81         unsigned        is_dir:1, is_reg:1, clear:1, suppress:1,
82                                 fragmented:1, compressed:1, bbcheck:1;
83         blk_t           num_blocks;
84         blk_t           max_blocks;
85         e2_blkcnt_t     last_block;
86         int             num_illegal_blocks;
87         blk_t           previous_block;
88         struct ext2_inode *inode;
89         struct problem_context *pctx;
90         ext2fs_block_bitmap fs_meta_blocks;
91         e2fsck_t        ctx;
92 };
93
94 struct process_inode_block {
95         ext2_ino_t ino;
96         struct ext2_inode inode;
97 };
98
99 struct scan_callback_struct {
100         e2fsck_t        ctx;
101         char            *block_buf;
102 };
103
104 /*
105  * For the inodes to process list.
106  */
107 static struct process_inode_block *inodes_to_process;
108 static int process_inode_count;
109
110 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
111                             EXT2_MIN_BLOCK_LOG_SIZE + 1];
112
113 /*
114  * Free all memory allocated by pass1 in preparation for restarting
115  * things.
116  */
117 static void unwind_pass1(ext2_filsys fs EXT2FS_ATTR((unused)))
118 {
119         ext2fs_free_mem(&inodes_to_process);
120         inodes_to_process = 0;
121 }
122
123 /*
124  * Check to make sure a device inode is real.  Returns 1 if the device
125  * checks out, 0 if not.
126  *
127  * Note: this routine is now also used to check FIFO's and Sockets,
128  * since they have the same requirement; the i_block fields should be
129  * zero. 
130  */
131 int e2fsck_pass1_check_device_inode(ext2_filsys fs EXT2FS_ATTR((unused)), 
132                                     struct ext2_inode *inode)
133 {
134         int     i;
135
136         /*
137          * If the index flag is set, then this is a bogus
138          * device/fifo/socket
139          */
140         if (inode->i_flags & EXT2_INDEX_FL)
141                 return 0;
142
143         /*
144          * We should be able to do the test below all the time, but
145          * because the kernel doesn't forcibly clear the device
146          * inode's additional i_block fields, there are some rare
147          * occasions when a legitimate device inode will have non-zero
148          * additional i_block fields.  So for now, we only complain
149          * when the immutable flag is set, which should never happen
150          * for devices.  (And that's when the problem is caused, since
151          * you can't set or clear immutable flags for devices.)  Once
152          * the kernel has been fixed we can change this...
153          */
154         if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
155                 for (i=4; i < EXT2_N_BLOCKS; i++) 
156                         if (inode->i_block[i])
157                                 return 0;
158         }
159         return 1;
160 }
161
162 /*
163  * Check to make sure a symlink inode is real.  Returns 1 if the symlink
164  * checks out, 0 if not.
165  */
166 int e2fsck_pass1_check_symlink(ext2_filsys fs, 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_flags & EXT4_EXTENTS_FL)) {
1010                         if (inode->i_block[EXT2_IND_BLOCK])
1011                                 ctx->fs_ind_count++;
1012                         if (inode->i_block[EXT2_DIND_BLOCK])
1013                                 ctx->fs_dind_count++;
1014                         if (inode->i_block[EXT2_TIND_BLOCK])
1015                                 ctx->fs_tind_count++;
1016                 }
1017                 if (!(inode->i_flags & EXT4_EXTENTS_FL) &&
1018                     (inode->i_block[EXT2_IND_BLOCK] ||
1019                      inode->i_block[EXT2_DIND_BLOCK] ||
1020                      inode->i_block[EXT2_TIND_BLOCK] ||
1021                      inode->i_file_acl)) {
1022                         inodes_to_process[process_inode_count].ino = ino;
1023                         inodes_to_process[process_inode_count].inode = *inode;
1024                         process_inode_count++;
1025                 } else
1026                         check_blocks(ctx, &pctx, block_buf);
1027
1028                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1029                         return;
1030
1031                 if (process_inode_count >= ctx->process_inode_size) {
1032                         process_inodes(ctx, block_buf);
1033
1034                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1035                                 return;
1036                 }
1037         }
1038         process_inodes(ctx, block_buf);
1039         ext2fs_close_inode_scan(scan);
1040
1041         /*
1042          * If any extended attribute blocks' reference counts need to
1043          * be adjusted, either up (ctx->refcount_extra), or down
1044          * (ctx->refcount), then fix them.
1045          */
1046         if (ctx->refcount) {
1047                 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
1048                 ea_refcount_free(ctx->refcount);
1049                 ctx->refcount = 0;
1050         }
1051         if (ctx->refcount_extra) {
1052                 adjust_extattr_refcount(ctx, ctx->refcount_extra,
1053                                         block_buf, +1);
1054                 ea_refcount_free(ctx->refcount_extra);
1055                 ctx->refcount_extra = 0;
1056         }
1057                 
1058         if (ctx->invalid_bitmaps)
1059                 handle_fs_bad_blocks(ctx);
1060
1061         /* We don't need the block_ea_map any more */
1062         if (ctx->block_ea_map) {
1063                 ext2fs_free_block_bitmap(ctx->block_ea_map);
1064                 ctx->block_ea_map = 0;
1065         }
1066
1067         if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
1068                 ext2fs_block_bitmap save_bmap;
1069
1070                 save_bmap = fs->block_map;
1071                 fs->block_map = ctx->block_found_map;
1072                 clear_problem_context(&pctx);
1073                 pctx.errcode = ext2fs_create_resize_inode(fs);
1074                 if (pctx.errcode) {
1075                         fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
1076                         /* Should never get here */
1077                         ctx->flags |= E2F_FLAG_ABORT;
1078                         return;
1079                 }
1080                 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
1081                                   "recreate inode");
1082                 inode->i_mtime = ctx->now;
1083                 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode, 
1084                                    "recreate inode");
1085                 fs->block_map = save_bmap;
1086                 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
1087         }
1088                        
1089         if (ctx->flags & E2F_FLAG_RESTART) {
1090                 /*
1091                  * Only the master copy of the superblock and block
1092                  * group descriptors are going to be written during a
1093                  * restart, so set the superblock to be used to be the
1094                  * master superblock.
1095                  */
1096                 ctx->use_superblock = 0;
1097                 unwind_pass1(fs);
1098                 goto endit;
1099         }
1100
1101         if (ctx->block_dup_map) {
1102                 if (ctx->options & E2F_OPT_PREEN) {
1103                         clear_problem_context(&pctx);
1104                         fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
1105                 }
1106                 e2fsck_pass1_dupblocks(ctx, block_buf);
1107         }
1108         ext2fs_free_mem(&inodes_to_process);
1109 endit:
1110         e2fsck_use_inode_shortcuts(ctx, 0);
1111         
1112         ext2fs_free_mem(&block_buf);
1113         ext2fs_free_mem(&inode);
1114
1115 #ifdef RESOURCE_TRACK
1116         if (ctx->options & E2F_OPT_TIME2) {
1117                 e2fsck_clear_progbar(ctx);
1118                 print_resource_track(_("Pass 1"), &rtrack, ctx->fs->io);
1119         }
1120 #endif
1121 }
1122
1123 /*
1124  * When the inode_scan routines call this callback at the end of the
1125  * glock group, call process_inodes.
1126  */
1127 static errcode_t scan_callback(ext2_filsys fs, 
1128                                ext2_inode_scan scan EXT2FS_ATTR((unused)),
1129                                dgrp_t group, void * priv_data)
1130 {
1131         struct scan_callback_struct *scan_struct;
1132         e2fsck_t ctx;
1133
1134         scan_struct = (struct scan_callback_struct *) priv_data;
1135         ctx = scan_struct->ctx;
1136         
1137         process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
1138
1139         if (ctx->progress)
1140                 if ((ctx->progress)(ctx, 1, group+1,
1141                                     ctx->fs->group_desc_count))
1142                         return EXT2_ET_CANCEL_REQUESTED;
1143
1144         return 0;
1145 }
1146
1147 /*
1148  * Process the inodes in the "inodes to process" list.
1149  */
1150 static void process_inodes(e2fsck_t ctx, char *block_buf)
1151 {
1152         int                     i;
1153         struct ext2_inode       *old_stashed_inode;
1154         ext2_ino_t              old_stashed_ino;
1155         const char              *old_operation;
1156         char                    buf[80];
1157         struct problem_context  pctx;
1158         
1159 #if 0
1160         printf("begin process_inodes: ");
1161 #endif
1162         if (process_inode_count == 0)
1163                 return;
1164         old_operation = ehandler_operation(0);
1165         old_stashed_inode = ctx->stashed_inode;
1166         old_stashed_ino = ctx->stashed_ino;
1167         qsort(inodes_to_process, process_inode_count,
1168                       sizeof(struct process_inode_block), process_inode_cmp);
1169         clear_problem_context(&pctx);
1170         for (i=0; i < process_inode_count; i++) {
1171                 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
1172                 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
1173                 
1174 #if 0
1175                 printf("%u ", pctx.ino);
1176 #endif
1177                 sprintf(buf, _("reading indirect blocks of inode %u"),
1178                         pctx.ino);
1179                 ehandler_operation(buf);
1180                 check_blocks(ctx, &pctx, block_buf);
1181                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1182                         break;
1183         }
1184         ctx->stashed_inode = old_stashed_inode;
1185         ctx->stashed_ino = old_stashed_ino;
1186         process_inode_count = 0;
1187 #if 0
1188         printf("end process inodes\n");
1189 #endif
1190         ehandler_operation(old_operation);
1191 }
1192
1193 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
1194 {
1195         const struct process_inode_block *ib_a =
1196                 (const struct process_inode_block *) a;
1197         const struct process_inode_block *ib_b =
1198                 (const struct process_inode_block *) b;
1199         int     ret;
1200         
1201         ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
1202                ib_b->inode.i_block[EXT2_IND_BLOCK]);
1203         if (ret == 0)
1204                 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
1205         return ret;
1206 }
1207
1208 /*
1209  * Mark an inode as being bad in some what
1210  */
1211 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
1212 {
1213         struct          problem_context pctx;
1214
1215         if (!ctx->inode_bad_map) {
1216                 clear_problem_context(&pctx);
1217         
1218                 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
1219                             _("bad inode map"), &ctx->inode_bad_map);
1220                 if (pctx.errcode) {
1221                         pctx.num = 3;
1222                         fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1223                         /* Should never get here */
1224                         ctx->flags |= E2F_FLAG_ABORT;
1225                         return;
1226                 }
1227         }
1228         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
1229 }
1230
1231
1232 /*
1233  * This procedure will allocate the inode "bb" (badblock) map table
1234  */
1235 static void alloc_bb_map(e2fsck_t ctx)
1236 {
1237         struct          problem_context pctx;
1238         
1239         clear_problem_context(&pctx);
1240         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
1241                                               _("inode in bad block map"),
1242                                               &ctx->inode_bb_map);
1243         if (pctx.errcode) {
1244                 pctx.num = 4;
1245                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1246                 /* Should never get here */
1247                 ctx->flags |= E2F_FLAG_ABORT;
1248                 return;
1249         }
1250 }
1251
1252 /*
1253  * This procedure will allocate the inode imagic table
1254  */
1255 static void alloc_imagic_map(e2fsck_t ctx)
1256 {
1257         struct          problem_context pctx;
1258         
1259         clear_problem_context(&pctx);
1260         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
1261                                               _("imagic inode map"),
1262                                               &ctx->inode_imagic_map);
1263         if (pctx.errcode) {
1264                 pctx.num = 5;
1265                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
1266                 /* Should never get here */
1267                 ctx->flags |= E2F_FLAG_ABORT;
1268                 return;
1269         }
1270 }
1271
1272 /*
1273  * Marks a block as in use, setting the dup_map if it's been set
1274  * already.  Called by process_block and process_bad_block.
1275  *
1276  * WARNING: Assumes checks have already been done to make sure block
1277  * is valid.  This is true in both process_block and process_bad_block.
1278  */
1279 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
1280 {
1281         struct          problem_context pctx;
1282         
1283         clear_problem_context(&pctx);
1284         
1285         if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
1286                 if (!ctx->block_dup_map) {
1287                         pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
1288                               _("multiply claimed block map"),
1289                               &ctx->block_dup_map);
1290                         if (pctx.errcode) {
1291                                 pctx.num = 3;
1292                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, 
1293                                             &pctx);
1294                                 /* Should never get here */
1295                                 ctx->flags |= E2F_FLAG_ABORT;
1296                                 return;
1297                         }
1298                 }
1299                 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
1300         } else {
1301                 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
1302         }
1303 }
1304
1305 /*
1306  * Adjust the extended attribute block's reference counts at the end
1307  * of pass 1, either by subtracting out references for EA blocks that
1308  * are still referenced in ctx->refcount, or by adding references for
1309  * EA blocks that had extra references as accounted for in
1310  * ctx->refcount_extra.
1311  */
1312 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount, 
1313                                     char *block_buf, int adjust_sign)
1314 {
1315         struct ext2_ext_attr_header     *header;
1316         struct problem_context          pctx;
1317         ext2_filsys                     fs = ctx->fs;
1318         blk_t                           blk;
1319         __u32                           should_be;
1320         int                             count;
1321
1322         clear_problem_context(&pctx);
1323         
1324         ea_refcount_intr_begin(refcount);
1325         while (1) {
1326                 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
1327                         break;
1328                 pctx.blk = blk;
1329                 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
1330                 if (pctx.errcode) {
1331                         fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
1332                         return;
1333                 }
1334                 header = (struct ext2_ext_attr_header *) block_buf;
1335                 pctx.blkcount = header->h_refcount;
1336                 should_be = header->h_refcount + adjust_sign * count;
1337                 pctx.num = should_be;
1338                 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
1339                         header->h_refcount = should_be;
1340                         pctx.errcode = ext2fs_write_ext_attr(fs, blk,
1341                                                              block_buf);
1342                         if (pctx.errcode) {
1343                                 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
1344                                 continue;
1345                         }
1346                 }
1347         }
1348 }
1349
1350 /*
1351  * Handle processing the extended attribute blocks
1352  */
1353 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
1354                            char *block_buf)
1355 {
1356         ext2_filsys fs = ctx->fs;
1357         ext2_ino_t      ino = pctx->ino;
1358         struct ext2_inode *inode = pctx->inode;
1359         blk_t           blk;
1360         char *          end;
1361         struct ext2_ext_attr_header *header;
1362         struct ext2_ext_attr_entry *entry;
1363         int             count;
1364         region_t        region = 0;
1365
1366         blk = inode->i_file_acl;
1367         if (blk == 0)
1368                 return 0;
1369
1370         /*
1371          * If the Extended attribute flag isn't set, then a non-zero
1372          * file acl means that the inode is corrupted.
1373          *
1374          * Or if the extended attribute block is an invalid block,
1375          * then the inode is also corrupted.
1376          */
1377         if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
1378             (blk < fs->super->s_first_data_block) ||
1379             (blk >= fs->super->s_blocks_count)) {
1380                 mark_inode_bad(ctx, ino);
1381                 return 0;
1382         }
1383
1384         /* If ea bitmap hasn't been allocated, create it */
1385         if (!ctx->block_ea_map) {
1386                 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
1387                                                       _("ext attr block map"),
1388                                                       &ctx->block_ea_map);
1389                 if (pctx->errcode) {
1390                         pctx->num = 2;
1391                         fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
1392                         ctx->flags |= E2F_FLAG_ABORT;
1393                         return 0;
1394                 }
1395         }
1396
1397         /* Create the EA refcount structure if necessary */
1398         if (!ctx->refcount) {
1399                 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
1400                 if (pctx->errcode) {
1401                         pctx->num = 1;
1402                         fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
1403                         ctx->flags |= E2F_FLAG_ABORT;
1404                         return 0;
1405                 }
1406         }
1407
1408 #if 0
1409         /* Debugging text */
1410         printf("Inode %u has EA block %u\n", ino, blk);
1411 #endif
1412
1413         /* Have we seen this EA block before? */
1414         if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
1415                 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
1416                         return 1;
1417                 /* Ooops, this EA was referenced more than it stated */
1418                 if (!ctx->refcount_extra) {
1419                         pctx->errcode = ea_refcount_create(0,
1420                                            &ctx->refcount_extra);
1421                         if (pctx->errcode) {
1422                                 pctx->num = 2;
1423                                 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
1424                                 ctx->flags |= E2F_FLAG_ABORT;
1425                                 return 0;
1426                         }
1427                 }
1428                 ea_refcount_increment(ctx->refcount_extra, blk, 0);
1429                 return 1;
1430         }
1431
1432         /*
1433          * OK, we haven't seen this EA block yet.  So we need to
1434          * validate it
1435          */
1436         pctx->blk = blk;
1437         pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
1438         if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
1439                 goto clear_extattr;
1440         header = (struct ext2_ext_attr_header *) block_buf;
1441         pctx->blk = inode->i_file_acl;
1442         if (((ctx->ext_attr_ver == 1) &&
1443              (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
1444             ((ctx->ext_attr_ver == 2) &&
1445              (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
1446                 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
1447                         goto clear_extattr;
1448         }
1449
1450         if (header->h_blocks != 1) {
1451                 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
1452                         goto clear_extattr;
1453         }
1454
1455         region = region_create(0, fs->blocksize);
1456         if (!region) {
1457                 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
1458                 ctx->flags |= E2F_FLAG_ABORT;
1459                 return 0;
1460         }
1461         if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
1462                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1463                         goto clear_extattr;
1464         }
1465
1466         entry = (struct ext2_ext_attr_entry *)(header+1);
1467         end = block_buf + fs->blocksize;
1468         while ((char *)entry < end && *(__u32 *)entry) {
1469                 __u32 hash;
1470
1471                 if (region_allocate(region, (char *)entry - (char *)header,
1472                                    EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
1473                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1474                                 goto clear_extattr;
1475                         break;
1476                 }
1477                 if ((ctx->ext_attr_ver == 1 &&
1478                      (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
1479                     (ctx->ext_attr_ver == 2 &&
1480                      entry->e_name_index == 0)) {
1481                         if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
1482                                 goto clear_extattr;
1483                         break;
1484                 }
1485                 if (entry->e_value_block != 0) {
1486                         if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
1487                                 goto clear_extattr;
1488                 }
1489                 if (entry->e_value_offs + entry->e_value_size > fs->blocksize) {
1490                         if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
1491                                 goto clear_extattr;
1492                         break;
1493                 }
1494                 if (entry->e_value_size &&
1495                     region_allocate(region, entry->e_value_offs,
1496                                     EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
1497                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1498                                 goto clear_extattr;
1499                 }
1500
1501                 hash = ext2fs_ext_attr_hash_entry(entry, block_buf +
1502                                                          entry->e_value_offs);
1503
1504                 if (entry->e_hash != hash) {
1505                         pctx->num = entry->e_hash;
1506                         if (fix_problem(ctx, PR_1_ATTR_HASH, pctx))
1507                                 goto clear_extattr;
1508                         entry->e_hash = hash;
1509                 }
1510
1511                 entry = EXT2_EXT_ATTR_NEXT(entry);
1512         }
1513         if (region_allocate(region, (char *)entry - (char *)header, 4)) {
1514                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
1515                         goto clear_extattr;
1516         }
1517         region_free(region);
1518
1519         count = header->h_refcount - 1;
1520         if (count)
1521                 ea_refcount_store(ctx->refcount, blk, count);
1522         mark_block_used(ctx, blk);
1523         ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
1524         return 1;
1525
1526 clear_extattr:
1527         if (region)
1528                 region_free(region);
1529         inode->i_file_acl = 0;
1530         e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
1531         return 0;
1532 }
1533
1534 /* Returns 1 if bad htree, 0 if OK */
1535 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
1536                         ext2_ino_t ino, struct ext2_inode *inode,
1537                         char *block_buf)
1538 {
1539         struct ext2_dx_root_info        *root;
1540         ext2_filsys                     fs = ctx->fs;
1541         errcode_t                       retval;
1542         blk_t                           blk;
1543
1544         if ((!LINUX_S_ISDIR(inode->i_mode) &&
1545              fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
1546             (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
1547              fix_problem(ctx, PR_1_HTREE_SET, pctx)))
1548                 return 1;
1549
1550         pctx->errcode = ext2fs_bmap(fs, ino, inode, 0, 0, 0, &blk);
1551
1552         if ((pctx->errcode) ||
1553             (blk == 0) ||
1554             (blk < fs->super->s_first_data_block) ||
1555             (blk >= fs->super->s_blocks_count)) {
1556                 if (fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1557                         return 1;
1558                 else
1559                         return 0;
1560         }
1561
1562         retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
1563         if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1564                 return 1;
1565         
1566         /* XXX should check that beginning matches a directory */
1567         root = (struct ext2_dx_root_info *) (block_buf + 24);
1568
1569         if ((root->reserved_zero || root->info_length < 8) &&
1570             fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
1571                 return 1;
1572
1573         pctx->num = root->hash_version;
1574         if ((root->hash_version != EXT2_HASH_LEGACY) &&
1575             (root->hash_version != EXT2_HASH_HALF_MD4) &&
1576             (root->hash_version != EXT2_HASH_TEA) &&
1577             fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
1578                 return 1;
1579                 
1580         if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
1581             fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
1582                 return 1;
1583
1584         pctx->num = root->indirect_levels;
1585         if ((root->indirect_levels > 1) &&
1586             fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
1587                 return 1;
1588         
1589         return 0;
1590 }
1591
1592 void e2fsck_clear_inode(e2fsck_t ctx, ext2_ino_t ino,
1593                         struct ext2_inode *inode, int restart_flag,
1594                         const char *source)
1595 {
1596         inode->i_flags = 0;
1597         inode->i_links_count = 0;
1598         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
1599         inode->i_dtime = ctx->now;
1600
1601         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
1602         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
1603         if (ctx->inode_reg_map)
1604                 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
1605         if (ctx->inode_bad_map)
1606                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
1607
1608         /*
1609          * If the inode was partially accounted for before processing
1610          * was aborted, we need to restart the pass 1 scan.
1611          */
1612         ctx->flags |= restart_flag;
1613
1614         e2fsck_write_inode(ctx, ino, inode, source);
1615 }
1616
1617 static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
1618                              struct process_block_struct *pb,
1619                              blk64_t start_block,
1620                              ext2_extent_handle_t ehandle)
1621 {
1622         struct ext2fs_extent    extent;
1623         blk_t                   blk;
1624         e2_blkcnt_t             blockcnt;
1625         unsigned int            i;
1626         int                     is_dir, is_leaf;
1627         errcode_t               problem;
1628         struct ext2_extent_info info;
1629
1630         pctx->errcode = ext2fs_extent_get_info(ehandle, &info);
1631         if (pctx->errcode)
1632                 return;
1633
1634         pctx->errcode = ext2fs_extent_get(ehandle, EXT2_EXTENT_FIRST_SIB,
1635                                           &extent);
1636         while (!pctx->errcode && info.num_entries-- > 0) {
1637                 is_leaf = extent.e_flags & EXT2_EXTENT_FLAGS_LEAF;
1638                 is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
1639
1640                 problem = 0;
1641                 if (extent.e_pblk < ctx->fs->super->s_first_data_block ||
1642                     extent.e_pblk >= ctx->fs->super->s_blocks_count)
1643                         problem = PR_1_EXTENT_BAD_START_BLK;
1644                 else if (extent.e_lblk < start_block)
1645                         problem = PR_1_OUT_OF_ORDER_EXTENTS;
1646                 else if (is_leaf &&
1647                          (extent.e_pblk + extent.e_len) >
1648                          ctx->fs->super->s_blocks_count)
1649                         problem = PR_1_EXTENT_ENDS_BEYOND;
1650
1651                 if (problem) {
1652                         pctx->blk = extent.e_pblk;
1653                         pctx->blk2 = extent.e_lblk;
1654                         pctx->num = extent.e_len;
1655                         if (fix_problem(ctx, problem, pctx)) {
1656                                 pctx->errcode =
1657                                         ext2fs_extent_delete(ehandle, 0);
1658                                 if (pctx->errcode) {
1659                                         fix_problem(ctx,
1660                                                     PR_1_EXTENT_DELETE_FAIL,
1661                                                     pctx);
1662                                         /* Should never get here */
1663                                         ctx->flags |= E2F_FLAG_ABORT;
1664                                         return;
1665                                 }
1666                                 pctx->errcode = ext2fs_extent_get(ehandle,
1667                                                                   EXT2_EXTENT_CURRENT,
1668                                                                   &extent);
1669                                 if (pctx->errcode == EXT2_ET_NO_CURRENT_NODE) {
1670                                         pctx->errcode = 0;
1671                                         break;
1672                                 }
1673                                 continue;
1674                         }
1675                         goto next;
1676                 }
1677
1678                 if (!is_leaf) {
1679                         mark_block_used(ctx, extent.e_pblk);
1680                         pb->num_blocks++;
1681                         pctx->errcode = ext2fs_extent_get(ehandle,
1682                                                   EXT2_EXTENT_DOWN, &extent);
1683                         if (pctx->errcode) {
1684                                 printf("Error1: %s on inode %u\n",
1685                                         error_message(pctx->errcode), pctx->ino);
1686                                 abort();
1687                         }
1688                         scan_extent_node(ctx, pctx, pb, extent.e_lblk, ehandle);
1689                         pctx->errcode = ext2fs_extent_get(ehandle,
1690                                                   EXT2_EXTENT_UP, &extent);
1691                         if (pctx->errcode) {
1692                                 printf("Error1: %s on inode %u\n",
1693                                         error_message(pctx->errcode), pctx->ino);
1694                                 abort();
1695                         }
1696                         goto next;
1697                 }
1698
1699                 if ((pb->previous_block != 0) &&
1700                     (pb->previous_block+1 != extent.e_pblk)) {
1701                         if (ctx->options & E2F_OPT_FRAGCHECK)
1702                                 printf(("%6lu: expecting %6lu actual extent "
1703                                         "phys %6lu log %lu len %lu\n"),
1704                                        (unsigned long) pctx->ino,
1705                                        (unsigned long) pb->previous_block+1,
1706                                        (unsigned long) extent.e_pblk,
1707                                        (unsigned long) extent.e_lblk,
1708                                        (unsigned long) extent.e_len);
1709                         pb->fragmented = 1;
1710                 }
1711                 for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
1712                      i < extent.e_len;
1713                      blk++, blockcnt++, i++) {
1714                         mark_block_used(ctx, blk);
1715
1716                         if (is_dir) {
1717                                 pctx->errcode = ext2fs_add_dir_block(ctx->fs->dblist, pctx->ino, blk, blockcnt);
1718                                 if (pctx->errcode) {
1719                                         pctx->blk = blk;
1720                                         pctx->num = blockcnt;
1721                                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
1722                                         /* Should never get here */
1723                                         ctx->flags |= E2F_FLAG_ABORT;
1724                                         return;
1725                                 }
1726                         }
1727                 }
1728                 pb->num_blocks += extent.e_len;
1729                 pb->previous_block = extent.e_pblk + extent.e_len - 1;
1730                 start_block = extent.e_lblk + extent.e_len - 1;
1731                 if (!(extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT))
1732                         pb->last_block = start_block;
1733         next:
1734                 pctx->errcode = ext2fs_extent_get(ehandle,
1735                                                   EXT2_EXTENT_NEXT_SIB,
1736                                                   &extent);
1737         }
1738         if (pctx->errcode == EXT2_ET_EXTENT_NO_NEXT)
1739                 pctx->errcode = 0;
1740 }
1741
1742 static void check_blocks_extents(e2fsck_t ctx, struct problem_context *pctx,
1743                                  struct process_block_struct *pb)
1744 {
1745         struct ext2_extent_info info;
1746         struct ext2_inode       *inode = pctx->inode;
1747         ext2_extent_handle_t    ehandle;
1748         ext2_filsys             fs = ctx->fs;
1749         ext2_ino_t              ino = pctx->ino;
1750         errcode_t               retval;
1751
1752         pctx->errcode = ext2fs_extent_open(fs, ino, &ehandle);
1753         if (pctx->errcode &&
1754             fix_problem(ctx, PR_1_READ_EXTENT, pctx)) {
1755                 e2fsck_clear_inode(ctx, ino, inode, 0, "check_blocks_extents");
1756                 pctx->errcode = 0;
1757                 return;
1758         }
1759
1760         retval = ext2fs_extent_get_info(ehandle, &info);
1761         if (retval == 0) {
1762                 if (info.max_depth >= MAX_EXTENT_DEPTH_COUNT)
1763                         info.max_depth = MAX_EXTENT_DEPTH_COUNT-1;
1764                 ctx->extent_depth_count[info.max_depth]++;
1765         }
1766
1767         scan_extent_node(ctx, pctx, pb, 0, ehandle);
1768
1769         if (pb->fragmented && pb->num_blocks < fs->super->s_blocks_per_group)
1770                 ctx->fs_fragmented++;
1771
1772         ext2fs_extent_free(ehandle);
1773 }
1774
1775 /*
1776  * This subroutine is called on each inode to account for all of the
1777  * blocks used by that inode.
1778  */
1779 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
1780                          char *block_buf)
1781 {
1782         ext2_filsys fs = ctx->fs;
1783         struct process_block_struct pb;
1784         ext2_ino_t      ino = pctx->ino;
1785         struct ext2_inode *inode = pctx->inode;
1786         int             bad_size = 0;
1787         int             dirty_inode = 0;
1788         int             extent_fs;
1789         __u64           size;
1790         
1791         pb.ino = ino;
1792         pb.num_blocks = 0;
1793         pb.last_block = -1;
1794         pb.num_illegal_blocks = 0;
1795         pb.suppress = 0; pb.clear = 0;
1796         pb.fragmented = 0;
1797         pb.compressed = 0;
1798         pb.previous_block = 0;
1799         pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
1800         pb.is_reg = LINUX_S_ISREG(inode->i_mode);
1801         pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
1802         pb.inode = inode;
1803         pb.pctx = pctx;
1804         pb.ctx = ctx;
1805         pctx->ino = ino;
1806         pctx->errcode = 0;
1807
1808         extent_fs = (ctx->fs->super->s_feature_incompat &
1809                      EXT3_FEATURE_INCOMPAT_EXTENTS);
1810
1811         if (inode->i_flags & EXT2_COMPRBLK_FL) {
1812                 if (fs->super->s_feature_incompat &
1813                     EXT2_FEATURE_INCOMPAT_COMPRESSION)
1814                         pb.compressed = 1;
1815                 else {
1816                         if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
1817                                 inode->i_flags &= ~EXT2_COMPRBLK_FL;
1818                                 dirty_inode++;
1819                         }
1820                 }
1821         }
1822
1823         if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf)) {
1824                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1825                         goto out;
1826                 pb.num_blocks++;
1827         }
1828
1829         if (ext2fs_inode_has_valid_blocks(inode)) {
1830                 if (extent_fs && (inode->i_flags & EXT4_EXTENTS_FL))
1831                         check_blocks_extents(ctx, pctx, &pb);
1832                 else
1833                         pctx->errcode = ext2fs_block_iterate2(fs, ino,
1834                                                 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
1835                                                 block_buf, process_block, &pb);
1836         }
1837         end_problem_latch(ctx, PR_LATCH_BLOCK);
1838         end_problem_latch(ctx, PR_LATCH_TOOBIG);
1839         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1840                 goto out;
1841         if (pctx->errcode)
1842                 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
1843
1844         if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
1845                 ctx->fs_fragmented++;
1846
1847         if (pb.clear) {
1848                 e2fsck_clear_inode(ctx, ino, inode, E2F_FLAG_RESTART,
1849                                    "check_blocks");
1850                 return;
1851         }
1852         
1853         if (pb.is_dir) {
1854                 while (1) {
1855                         struct ext2_db_entry *entry;
1856
1857                         if (ext2fs_dblist_get_last(fs->dblist, &entry) ||
1858                             (entry->ino != ino) ||
1859                             (entry->blk != 0) ||
1860                             (entry->blockcnt == 0))
1861                                 break;
1862                         /* printf("Dropping ino %lu blk %lu blockcnt %d\n", 
1863                                   entry->ino, entry->blk, entry->blockcnt); */
1864                         ext2fs_dblist_drop_last(fs->dblist);
1865                         if (ext2fs_dblist_get_last(fs->dblist, &entry) ||
1866                             (entry->ino != ino))
1867                                 pb.last_block--;
1868                         else
1869                                 pb.last_block = entry->blockcnt;
1870                 }
1871         }
1872
1873         if (inode->i_flags & EXT2_INDEX_FL) {
1874                 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
1875                         inode->i_flags &= ~EXT2_INDEX_FL;
1876                         dirty_inode++;
1877                 } else {
1878 #ifdef ENABLE_HTREE
1879                         e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
1880 #endif
1881                 }
1882         }
1883         if (ctx->dirs_to_hash && pb.is_dir &&
1884             !(inode->i_flags & EXT2_INDEX_FL) &&
1885             ((inode->i_size / fs->blocksize) >= 3))
1886                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
1887                 
1888         if (!pb.num_blocks && pb.is_dir) {
1889                 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
1890                         e2fsck_clear_inode(ctx, ino, inode, 0, "check_blocks");
1891                         ctx->fs_directory_count--;
1892                         return;
1893                 }
1894         }
1895
1896         if (!(fs->super->s_feature_ro_compat &
1897               EXT4_FEATURE_RO_COMPAT_HUGE_FILE) ||
1898             !(inode->i_flags & EXT4_HUGE_FILE_FL))
1899                 pb.num_blocks *= (fs->blocksize / 512);
1900 #if 0
1901         printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
1902                ino, inode->i_size, pb.last_block, inode->i_blocks,
1903                pb.num_blocks);
1904 #endif
1905         if (pb.is_dir) {
1906                 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
1907                 if (inode->i_size & (fs->blocksize - 1)) 
1908                         bad_size = 5;
1909                 else if (nblock > (pb.last_block + 1))
1910                         bad_size = 1;
1911                 else if (nblock < (pb.last_block + 1)) {
1912                         if (((pb.last_block + 1) - nblock) >
1913                             fs->super->s_prealloc_dir_blocks)
1914                                 bad_size = 2;
1915                 }
1916         } else {
1917                 e2_blkcnt_t blkpg = ctx->blocks_per_page;
1918
1919                 size = EXT2_I_SIZE(inode);
1920                 if ((pb.last_block >= 0) &&
1921                     /* allow allocated blocks to end of PAGE_SIZE */
1922                     (size < (__u64)pb.last_block * fs->blocksize) &&
1923                     (pb.last_block / blkpg * blkpg != pb.last_block ||
1924                      size < (__u64)(pb.last_block & ~(blkpg-1)) *fs->blocksize))
1925                         bad_size = 3;
1926                 else if (!(extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) &&
1927                          size > ext2_max_sizes[fs->super->s_log_block_size])
1928                         /* too big for a direct/indirect-mapped file */
1929                         bad_size = 4;
1930                 else if ((extent_fs && (inode->i_flags & EXT4_EXTENTS_FL)) &&
1931                          size >
1932                          ((1LL << (32 + EXT2_BLOCK_SIZE_BITS(fs->super))) - 1))
1933                         /* too big for an extent-based file - 32bit ee_block */
1934                         bad_size = 6;
1935         }
1936         /* i_size for symlinks is checked elsewhere */
1937         if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
1938                 pctx->num = (pb.last_block+1) * fs->blocksize;
1939                 pctx->group = bad_size;
1940                 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
1941                         inode->i_size = pctx->num;
1942                         if (!LINUX_S_ISDIR(inode->i_mode))
1943                                 inode->i_size_high = pctx->num >> 32;
1944                         dirty_inode++;
1945                 }
1946                 pctx->num = 0;
1947         }
1948         if (LINUX_S_ISREG(inode->i_mode) &&
1949             (inode->i_size_high || inode->i_size & 0x80000000UL))
1950                 ctx->large_files++;
1951         if ((pb.num_blocks != inode->i_blocks) ||
1952             ((fs->super->s_feature_ro_compat &
1953               EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
1954              (inode->i_flags & EXT4_HUGE_FILE_FL) &&
1955              (inode->osd2.linux2.l_i_blocks_hi != 0))) {
1956                 pctx->num = pb.num_blocks;
1957                 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
1958                         inode->i_blocks = pb.num_blocks;
1959                         inode->osd2.linux2.l_i_blocks_hi = 0;
1960                         dirty_inode++;
1961                 }
1962                 pctx->num = 0;
1963         }
1964 out:
1965         if (dirty_inode)
1966                 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
1967 }
1968
1969 #if 0
1970 /*
1971  * Helper function called by process block when an illegal block is
1972  * found.  It returns a description about why the block is illegal
1973  */
1974 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
1975 {
1976         blk_t   super;
1977         int     i;
1978         static char     problem[80];
1979
1980         super = fs->super->s_first_data_block;
1981         strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
1982         if (block < super) {
1983                 sprintf(problem, "< FIRSTBLOCK (%u)", super);
1984                 return(problem);
1985         } else if (block >= fs->super->s_blocks_count) {
1986                 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
1987                 return(problem);
1988         }
1989         for (i = 0; i < fs->group_desc_count; i++) {
1990                 if (block == super) {
1991                         sprintf(problem, "is the superblock in group %d", i);
1992                         break;
1993                 }
1994                 if (block > super &&
1995                     block <= (super + fs->desc_blocks)) {
1996                         sprintf(problem, "is in the group descriptors "
1997                                 "of group %d", i);
1998                         break;
1999                 }
2000                 if (block == fs->group_desc[i].bg_block_bitmap) {
2001                         sprintf(problem, "is the block bitmap of group %d", i);
2002                         break;
2003                 }
2004                 if (block == fs->group_desc[i].bg_inode_bitmap) {
2005                         sprintf(problem, "is the inode bitmap of group %d", i);
2006                         break;
2007                 }
2008                 if (block >= fs->group_desc[i].bg_inode_table &&
2009                     (block < fs->group_desc[i].bg_inode_table
2010                      + fs->inode_blocks_per_group)) {
2011                         sprintf(problem, "is in the inode table of group %d",
2012                                 i);
2013                         break;
2014                 }
2015                 super += fs->super->s_blocks_per_group;
2016         }
2017         return(problem);
2018 }
2019 #endif
2020
2021 /*
2022  * This is a helper function for check_blocks().
2023  */
2024 static int process_block(ext2_filsys fs,
2025                   blk_t *block_nr,
2026                   e2_blkcnt_t blockcnt,
2027                   blk_t ref_block EXT2FS_ATTR((unused)),
2028                   int ref_offset EXT2FS_ATTR((unused)),
2029                   void *priv_data)
2030 {
2031         struct process_block_struct *p;
2032         struct problem_context *pctx;
2033         blk_t   blk = *block_nr;
2034         int     ret_code = 0;
2035         int     problem = 0;
2036         e2fsck_t        ctx;
2037
2038         p = (struct process_block_struct *) priv_data;
2039         pctx = p->pctx;
2040         ctx = p->ctx;
2041
2042         if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
2043                 /* todo: Check that the comprblk_fl is high, that the
2044                    blkaddr pattern looks right (all non-holes up to
2045                    first EXT2FS_COMPRESSED_BLKADDR, then all
2046                    EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
2047                    that the feature_incompat bit is high, and that the
2048                    inode is a regular file.  If we're doing a "full
2049                    check" (a concept introduced to e2fsck by e2compr,
2050                    meaning that we look at data blocks as well as
2051                    metadata) then call some library routine that
2052                    checks the compressed data.  I'll have to think
2053                    about this, because one particularly important
2054                    problem to be able to fix is to recalculate the
2055                    cluster size if necessary.  I think that perhaps
2056                    we'd better do most/all e2compr-specific checks
2057                    separately, after the non-e2compr checks.  If not
2058                    doing a full check, it may be useful to test that
2059                    the personality is linux; e.g. if it isn't then
2060                    perhaps this really is just an illegal block. */
2061                 return 0;
2062         }
2063
2064         if (blk == 0) {
2065                 if (p->is_dir == 0) {
2066                         /*
2067                          * Should never happen, since only directories
2068                          * get called with BLOCK_FLAG_HOLE
2069                          */
2070 #if DEBUG_E2FSCK
2071                         printf("process_block() called with blk == 0, "
2072                                "blockcnt=%d, inode %lu???\n",
2073                                blockcnt, p->ino);
2074 #endif
2075                         return 0;
2076                 }
2077                 if (blockcnt < 0)
2078                         return 0;
2079                 if (blockcnt * fs->blocksize < p->inode->i_size) {
2080 #if 0
2081                         printf("Missing block (#%d) in directory inode %lu!\n",
2082                                blockcnt, p->ino);
2083 #endif
2084                         p->last_block = blockcnt;
2085                         goto mark_dir;
2086                 }
2087                 return 0;
2088         }
2089
2090 #if 0
2091         printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
2092                blockcnt);
2093 #endif
2094         
2095         /*
2096          * Simplistic fragmentation check.  We merely require that the
2097          * file be contiguous.  (Which can never be true for really
2098          * big files that are greater than a block group.)
2099          */
2100         if (!HOLE_BLKADDR(p->previous_block) && p->ino != EXT2_RESIZE_INO) {
2101                 if (p->previous_block+1 != blk) {
2102                         if (ctx->options & E2F_OPT_FRAGCHECK)
2103                                 printf(_("%6lu: expecting %6lu got phys %6lu (blkcnt %lld)\n"),
2104                                        (unsigned long) pctx->ino,
2105                                        (unsigned long) p->previous_block+1,
2106                                        (unsigned long) blk,
2107                                        blockcnt);
2108                         p->fragmented = 1;
2109                 }
2110         }
2111         p->previous_block = blk;
2112
2113         if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
2114                 problem = PR_1_TOOBIG_DIR;
2115         if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
2116                 problem = PR_1_TOOBIG_REG;
2117         if (!p->is_dir && !p->is_reg && blockcnt > 0)
2118                 problem = PR_1_TOOBIG_SYMLINK;
2119             
2120         if (blk < fs->super->s_first_data_block ||
2121             blk >= fs->super->s_blocks_count)
2122                 problem = PR_1_ILLEGAL_BLOCK_NUM;
2123
2124         if (problem) {
2125                 p->num_illegal_blocks++;
2126                 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
2127                         if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
2128                                 p->clear = 1;
2129                                 return BLOCK_ABORT;
2130                         }
2131                         if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
2132                                 p->suppress = 1;
2133                                 set_latch_flags(PR_LATCH_BLOCK,
2134                                                 PRL_SUPPRESS, 0);
2135                         }
2136                 }
2137                 pctx->blk = blk;
2138                 pctx->blkcount = blockcnt;
2139                 if (fix_problem(ctx, problem, pctx)) {
2140                         blk = *block_nr = 0;
2141                         ret_code = BLOCK_CHANGED;
2142                         goto mark_dir;
2143                 } else
2144                         return 0;
2145         }
2146
2147         if (p->ino == EXT2_RESIZE_INO) {
2148                 /* 
2149                  * The resize inode has already be sanity checked
2150                  * during pass #0 (the superblock checks).  All we
2151                  * have to do is mark the double indirect block as
2152                  * being in use; all of the other blocks are handled
2153                  * by mark_table_blocks()).
2154                  */
2155                 if (blockcnt == BLOCK_COUNT_DIND)
2156                         mark_block_used(ctx, blk);
2157         } else
2158                 mark_block_used(ctx, blk);
2159         p->num_blocks++;
2160         if (blockcnt >= 0)
2161                 p->last_block = blockcnt;
2162 mark_dir:
2163         if (p->is_dir && (blockcnt >= 0)) {
2164                 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
2165                                                     blk, blockcnt);
2166                 if (pctx->errcode) {
2167                         pctx->blk = blk;
2168                         pctx->num = blockcnt;
2169                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
2170                         /* Should never get here */
2171                         ctx->flags |= E2F_FLAG_ABORT;
2172                         return BLOCK_ABORT;
2173                 }
2174         }
2175         return ret_code;
2176 }
2177
2178 static int process_bad_block(ext2_filsys fs,
2179                       blk_t *block_nr,
2180                       e2_blkcnt_t blockcnt,
2181                       blk_t ref_block EXT2FS_ATTR((unused)),
2182                       int ref_offset EXT2FS_ATTR((unused)),
2183                       void *priv_data)
2184 {
2185         struct process_block_struct *p;
2186         blk_t           blk = *block_nr;
2187         blk_t           first_block;
2188         dgrp_t          i;
2189         struct problem_context *pctx;
2190         e2fsck_t        ctx;
2191
2192         /*
2193          * Note: This function processes blocks for the bad blocks
2194          * inode, which is never compressed.  So we don't use HOLE_BLKADDR().
2195          */
2196
2197         if (!blk)
2198                 return 0;
2199         
2200         p = (struct process_block_struct *) priv_data;
2201         ctx = p->ctx;
2202         pctx = p->pctx;
2203         
2204         pctx->ino = EXT2_BAD_INO;
2205         pctx->blk = blk;
2206         pctx->blkcount = blockcnt;
2207
2208         if ((blk < fs->super->s_first_data_block) ||
2209             (blk >= fs->super->s_blocks_count)) {
2210                 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
2211                         *block_nr = 0;
2212                         return BLOCK_CHANGED;
2213                 } else
2214                         return 0;
2215         }
2216
2217         if (blockcnt < 0) {
2218                 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
2219                         p->bbcheck = 1;
2220                         if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
2221                                 *block_nr = 0;
2222                                 return BLOCK_CHANGED;
2223                         }
2224                 } else if (ext2fs_test_block_bitmap(ctx->block_found_map, 
2225                                                     blk)) {
2226                         p->bbcheck = 1;
2227                         if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, 
2228                                         pctx)) {
2229                                 *block_nr = 0;
2230                                 return BLOCK_CHANGED;
2231                         }
2232                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2233                                 return BLOCK_ABORT;
2234                 } else
2235                         mark_block_used(ctx, blk);
2236                 return 0;
2237         }
2238 #if 0 
2239         printf ("DEBUG: Marking %u as bad.\n", blk);
2240 #endif
2241         ctx->fs_badblocks_count++;
2242         /*
2243          * If the block is not used, then mark it as used and return.
2244          * If it is already marked as found, this must mean that
2245          * there's an overlap between the filesystem table blocks
2246          * (bitmaps and inode table) and the bad block list.
2247          */
2248         if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
2249                 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
2250                 return 0;
2251         }
2252         /*
2253          * Try to find the where the filesystem block was used...
2254          */
2255         first_block = fs->super->s_first_data_block;
2256         
2257         for (i = 0; i < fs->group_desc_count; i++ ) {
2258                 pctx->group = i;
2259                 pctx->blk = blk;
2260                 if (!ext2fs_bg_has_super(fs, i))
2261                         goto skip_super;
2262                 if (blk == first_block) {
2263                         if (i == 0) {
2264                                 if (fix_problem(ctx,
2265                                                 PR_1_BAD_PRIMARY_SUPERBLOCK,
2266                                                 pctx)) {
2267                                         *block_nr = 0;
2268                                         return BLOCK_CHANGED;
2269                                 }
2270                                 return 0;
2271                         }
2272                         fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
2273                         return 0;
2274                 }
2275                 if ((blk > first_block) &&
2276                     (blk <= first_block + fs->desc_blocks)) {
2277                         if (i == 0) {
2278                                 pctx->blk = *block_nr;
2279                                 if (fix_problem(ctx,
2280                         PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
2281                                         *block_nr = 0;
2282                                         return BLOCK_CHANGED;
2283                                 }
2284                                 return 0;
2285                         }
2286                         fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
2287                         return 0;
2288                 }
2289         skip_super:
2290                 if (blk == fs->group_desc[i].bg_block_bitmap) {
2291                         if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
2292                                 ctx->invalid_block_bitmap_flag[i]++;
2293                                 ctx->invalid_bitmaps++;
2294                         }
2295                         return 0;
2296                 }
2297                 if (blk == fs->group_desc[i].bg_inode_bitmap) {
2298                         if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
2299                                 ctx->invalid_inode_bitmap_flag[i]++;
2300                                 ctx->invalid_bitmaps++;
2301                         }
2302                         return 0;
2303                 }
2304                 if ((blk >= fs->group_desc[i].bg_inode_table) &&
2305                     (blk < (fs->group_desc[i].bg_inode_table +
2306                             fs->inode_blocks_per_group))) {
2307                         /*
2308                          * If there are bad blocks in the inode table,
2309                          * the inode scan code will try to do
2310                          * something reasonable automatically.
2311                          */
2312                         return 0;
2313                 }
2314                 first_block += fs->super->s_blocks_per_group;
2315         }
2316         /*
2317          * If we've gotten to this point, then the only
2318          * possibility is that the bad block inode meta data
2319          * is using a bad block.
2320          */
2321         if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
2322             (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
2323             (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
2324                 p->bbcheck = 1;
2325                 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
2326                         *block_nr = 0;
2327                         return BLOCK_CHANGED;
2328                 }
2329                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
2330                         return BLOCK_ABORT;
2331                 return 0;
2332         }
2333
2334         pctx->group = -1;
2335
2336         /* Warn user that the block wasn't claimed */
2337         fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
2338
2339         return 0;
2340 }
2341
2342 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group, 
2343                             const char *name, int num, blk_t *new_block)
2344 {
2345         ext2_filsys fs = ctx->fs;
2346         blk_t           old_block = *new_block;
2347         blk_t           last_block;
2348         int             i;
2349         char            *buf;
2350         struct problem_context  pctx;
2351
2352         clear_problem_context(&pctx);
2353
2354         pctx.group = group;
2355         pctx.blk = old_block;
2356         pctx.str = name;
2357
2358         last_block = ext2fs_group_last_block(fs, group);
2359         pctx.errcode = ext2fs_get_free_blocks(fs, first_block, last_block,
2360                                         num, ctx->block_found_map, new_block);
2361         if (pctx.errcode) {
2362                 pctx.num = num;
2363                 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
2364                 ext2fs_unmark_valid(fs);
2365                 return;
2366         }
2367         pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
2368         if (pctx.errcode) {
2369                 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
2370                 ext2fs_unmark_valid(fs);
2371                 return;
2372         }
2373         ext2fs_mark_super_dirty(fs);
2374         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2375         pctx.blk2 = *new_block;
2376         fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
2377                           PR_1_RELOC_TO), &pctx);
2378         pctx.blk2 = 0;
2379         for (i = 0; i < num; i++) {
2380                 pctx.blk = i;
2381                 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
2382                 if (old_block) {
2383                         pctx.errcode = io_channel_read_blk(fs->io,
2384                                    old_block + i, 1, buf);
2385                         if (pctx.errcode)
2386                                 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
2387                 } else
2388                         memset(buf, 0, fs->blocksize);
2389
2390                 pctx.blk = (*new_block) + i;
2391                 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
2392                                               1, buf);
2393                 if (pctx.errcode)
2394                         fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
2395         }
2396         ext2fs_free_mem(&buf);
2397 }
2398
2399 /*
2400  * This routine gets called at the end of pass 1 if bad blocks are
2401  * detected in the superblock, group descriptors, inode_bitmaps, or
2402  * block bitmaps.  At this point, all of the blocks have been mapped
2403  * out, so we can try to allocate new block(s) to replace the bad
2404  * blocks.
2405  */
2406 static void handle_fs_bad_blocks(e2fsck_t ctx)
2407 {
2408         ext2_filsys fs = ctx->fs;
2409         dgrp_t          i;
2410         blk_t           first_block;
2411
2412         for (i = 0; i < fs->group_desc_count; i++) {
2413                 first_block = ext2fs_group_first_block(fs, i);
2414
2415                 if (ctx->invalid_block_bitmap_flag[i]) {
2416                         new_table_block(ctx, first_block, i, _("block bitmap"),
2417                                         1, &fs->group_desc[i].bg_block_bitmap);
2418                 }
2419                 if (ctx->invalid_inode_bitmap_flag[i]) {
2420                         new_table_block(ctx, first_block, i, _("inode bitmap"),
2421                                         1, &fs->group_desc[i].bg_inode_bitmap);
2422                 }
2423                 if (ctx->invalid_inode_table_flag[i]) {
2424                         new_table_block(ctx, first_block, i, _("inode table"),
2425                                         fs->inode_blocks_per_group, 
2426                                         &fs->group_desc[i].bg_inode_table);
2427                         ctx->flags |= E2F_FLAG_RESTART;
2428                 }
2429         }
2430         ctx->invalid_bitmaps = 0;
2431 }
2432
2433 /*
2434  * This routine marks all blocks which are used by the superblock,
2435  * group descriptors, inode bitmaps, and block bitmaps.
2436  */
2437 static void mark_table_blocks(e2fsck_t ctx)
2438 {
2439         ext2_filsys fs = ctx->fs;
2440         blk_t   b;
2441         dgrp_t  i;
2442         int     j;
2443         struct problem_context pctx;
2444         
2445         clear_problem_context(&pctx);
2446         
2447         for (i = 0; i < fs->group_desc_count; i++) {
2448                 pctx.group = i;
2449
2450                 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
2451
2452                 /*
2453                  * Mark the blocks used for the inode table
2454                  */
2455                 if (fs->group_desc[i].bg_inode_table) {
2456                         for (j = 0, b = fs->group_desc[i].bg_inode_table;
2457                              j < fs->inode_blocks_per_group;
2458                              j++, b++) {
2459                                 if (ext2fs_test_block_bitmap(ctx->block_found_map,
2460                                                              b)) {
2461                                         pctx.blk = b;
2462                                         if (fix_problem(ctx,
2463                                                 PR_1_ITABLE_CONFLICT, &pctx)) {
2464                                                 ctx->invalid_inode_table_flag[i]++;
2465                                                 ctx->invalid_bitmaps++;
2466                                         }
2467                                 } else {
2468                                     ext2fs_mark_block_bitmap(ctx->block_found_map,
2469                                                              b);
2470                                 }
2471                         }
2472                 }
2473                             
2474                 /*
2475                  * Mark block used for the block bitmap 
2476                  */
2477                 if (fs->group_desc[i].bg_block_bitmap) {
2478                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
2479                                      fs->group_desc[i].bg_block_bitmap)) {
2480                                 pctx.blk = fs->group_desc[i].bg_block_bitmap;
2481                                 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
2482                                         ctx->invalid_block_bitmap_flag[i]++;
2483                                         ctx->invalid_bitmaps++;
2484                                 }
2485                         } else {
2486                             ext2fs_mark_block_bitmap(ctx->block_found_map,
2487                                      fs->group_desc[i].bg_block_bitmap);
2488                     }
2489                         
2490                 }
2491                 /*
2492                  * Mark block used for the inode bitmap 
2493                  */
2494                 if (fs->group_desc[i].bg_inode_bitmap) {
2495                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
2496                                      fs->group_desc[i].bg_inode_bitmap)) {
2497                                 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
2498                                 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
2499                                         ctx->invalid_inode_bitmap_flag[i]++;
2500                                         ctx->invalid_bitmaps++;
2501                                 } 
2502                         } else {
2503                             ext2fs_mark_block_bitmap(ctx->block_found_map,
2504                                      fs->group_desc[i].bg_inode_bitmap);
2505                         }
2506                 }
2507         }
2508 }
2509         
2510 /*
2511  * Thes subroutines short circuits ext2fs_get_blocks and
2512  * ext2fs_check_directory; we use them since we already have the inode
2513  * structure, so there's no point in letting the ext2fs library read
2514  * the inode again.
2515  */
2516 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
2517                                   blk_t *blocks)
2518 {
2519         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2520         int     i;
2521         
2522         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
2523                 return EXT2_ET_CALLBACK_NOTHANDLED;
2524
2525         for (i=0; i < EXT2_N_BLOCKS; i++)
2526                 blocks[i] = ctx->stashed_inode->i_block[i];
2527         return 0;
2528 }
2529
2530 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
2531                                   struct ext2_inode *inode)
2532 {
2533         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2534
2535         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
2536                 return EXT2_ET_CALLBACK_NOTHANDLED;
2537         *inode = *ctx->stashed_inode;
2538         return 0;
2539 }
2540
2541 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
2542                             struct ext2_inode *inode)
2543 {
2544         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2545
2546         if ((ino == ctx->stashed_ino) && ctx->stashed_inode &&
2547                 (inode != ctx->stashed_inode))
2548                 *ctx->stashed_inode = *inode;
2549         return EXT2_ET_CALLBACK_NOTHANDLED;
2550 }
2551
2552 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
2553 {
2554         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2555
2556         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
2557                 return EXT2_ET_CALLBACK_NOTHANDLED;
2558
2559         if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
2560                 return EXT2_ET_NO_DIRECTORY;
2561         return 0;
2562 }
2563
2564 static errcode_t e2fsck_get_alloc_block(ext2_filsys fs, blk64_t goal,
2565                                         blk64_t *ret)
2566 {
2567         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2568         errcode_t       retval;
2569         blk_t           new_block;
2570
2571         if (ctx->block_found_map) {
2572                 retval = ext2fs_new_block(fs, (blk_t) goal, 
2573                                           ctx->block_found_map, &new_block);
2574                 if (retval)
2575                         return retval;
2576         } else {
2577                 if (!fs->block_map) {
2578                         retval = ext2fs_read_block_bitmap(fs);
2579                         if (retval)
2580                                 return retval;
2581                 }
2582
2583                 retval = ext2fs_new_block(fs, (blk_t) goal, 0, &new_block);
2584                 if (retval)
2585                         return retval;
2586         }
2587                 
2588         *ret = new_block;
2589         return (0);
2590 }
2591
2592 static void e2fsck_block_alloc_stats(ext2_filsys fs, blk64_t blk, int inuse)
2593 {
2594         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
2595
2596         if (ctx->block_found_map) {
2597                 if (inuse > 0)
2598                         ext2fs_mark_block_bitmap(ctx->block_found_map, 
2599                                                  (blk_t) blk);
2600                 else
2601                         ext2fs_unmark_block_bitmap(ctx->block_found_map, 
2602                                                    (blk_t) blk);
2603         }
2604 }
2605
2606 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
2607 {
2608         ext2_filsys fs = ctx->fs;
2609
2610         if (bool) {
2611                 fs->get_blocks = pass1_get_blocks;
2612                 fs->check_directory = pass1_check_directory;
2613                 fs->read_inode = pass1_read_inode;
2614                 fs->write_inode = pass1_write_inode;
2615                 ctx->stashed_ino = 0;
2616                 ext2fs_set_alloc_block_callback(fs, e2fsck_get_alloc_block,
2617                                                 0);
2618                 ext2fs_set_block_alloc_stats_callback(fs,
2619                                                       e2fsck_block_alloc_stats,
2620                                                       0);
2621         } else {
2622                 fs->get_blocks = 0;
2623                 fs->check_directory = 0;
2624                 fs->read_inode = 0;
2625                 fs->write_inode = 0;
2626         }
2627 }