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