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