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