Whamcloud - gitweb
ChangeLog, e2fsck.h, pass1.c, pass1b.c:
[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 <time.h>
41 #ifdef HAVE_ERRNO_H
42 #include <errno.h>
43 #endif
44
45 #include "e2fsck.h"
46 #include "problem.h"
47
48 #ifdef NO_INLINE_FUNCS
49 #define _INLINE_
50 #else
51 #define _INLINE_ inline
52 #endif
53
54 static int process_block(ext2_filsys fs, blk_t  *blocknr,
55                          e2_blkcnt_t blockcnt, blk_t ref_blk, 
56                          int ref_offset, void *priv_data);
57 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
58                              e2_blkcnt_t blockcnt, blk_t ref_blk,
59                              int ref_offset, void *priv_data);
60 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
61                          char *block_buf);
62 static void mark_table_blocks(e2fsck_t ctx);
63 static void alloc_bad_map(e2fsck_t ctx);
64 static void alloc_bb_map(e2fsck_t ctx);
65 static void alloc_imagic_map(e2fsck_t ctx);
66 static void handle_fs_bad_blocks(e2fsck_t ctx);
67 static void process_inodes(e2fsck_t ctx, char *block_buf);
68 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
69 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
70                                   dgrp_t group, void * priv_data);
71 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
72
73 struct process_block_struct {
74         ino_t           ino;
75         int             is_dir:1, clear:1, suppress:1, fragmented:1;
76         blk_t           num_blocks;
77         e2_blkcnt_t     last_block;
78         int             num_illegal_blocks;
79         blk_t           previous_block;
80         struct ext2_inode *inode;
81         struct problem_context *pctx;
82         e2fsck_t        ctx;
83 };
84
85 struct process_inode_block {
86         ino_t   ino;
87         struct ext2_inode inode;
88 };
89
90 struct scan_callback_struct {
91         e2fsck_t        ctx;
92         char            *block_buf;
93 };
94
95 /*
96  * For the inodes to process list.
97  */
98 static struct process_inode_block *inodes_to_process;
99 static int process_inode_count;
100
101 static __u64 ext2_max_sizes[4];
102
103 /*
104  * Free all memory allocated by pass1 in preparation for restarting
105  * things.
106  */
107 static void unwind_pass1(ext2_filsys fs)
108 {
109         ext2fs_free_mem((void **) &inodes_to_process);
110         inodes_to_process = 0;
111 }
112
113 /*
114  * Check to make sure a device inode is real.  Returns 1 if the device
115  * checks out, 0 if not.
116  *
117  * Note: this routine is now also used to check FIFO's and Sockets,
118  * since they have the same requirement; the i_block fields should be
119  * zero. 
120  */
121 int e2fsck_pass1_check_device_inode(struct ext2_inode *inode)
122 {
123         int     i;
124
125         /*
126          * We should be able to do the test below all the time, but
127          * because the kernel doesn't forcibly clear the device
128          * inode's additional i_block fields, there are some rare
129          * occasions when a legitimate device inode will have non-zero
130          * additional i_block fields.  So for now, we only complain
131          * when the immutable flag is set, which should never happen
132          * for devices.  (And that's when the problem is caused, since
133          * you can't set or clear immutable flags for devices.)  Once
134          * the kernel has been fixed we can change this...
135          */
136         if (inode->i_flags & EXT2_IMMUTABLE_FL) {
137                 for (i=4; i < EXT2_N_BLOCKS; i++) 
138                         if (inode->i_block[i])
139                                 return 0;
140         }
141         return 1;
142 }
143
144 /*
145  * If the immutable flag is set on the inode, offer to clear it.
146  */
147 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
148 {
149         if (!(pctx->inode->i_flags & EXT2_IMMUTABLE_FL))
150                 return;
151
152         if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
153                 return;
154
155         pctx->inode->i_flags &= ~EXT2_IMMUTABLE_FL;
156         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
157 }
158
159
160 void e2fsck_pass1(e2fsck_t ctx)
161 {
162         int     i;
163         __u64   max_sizes;
164         ext2_filsys fs = ctx->fs;
165         ino_t   ino;
166         struct ext2_inode inode;
167         ext2_inode_scan scan;
168         char            *block_buf;
169 #ifdef RESOURCE_TRACK
170         struct resource_track   rtrack;
171 #endif
172         unsigned char   frag, fsize;
173         struct          problem_context pctx;
174         struct          scan_callback_struct scan_struct;
175         struct ext2fs_sb *sb;
176         int             imagic_fs;
177         
178 #ifdef RESOURCE_TRACK
179         init_resource_track(&rtrack);
180 #endif
181         clear_problem_context(&pctx);
182
183         if (!(ctx->options & E2F_OPT_PREEN))
184                 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
185
186 #ifdef MTRACE
187         mtrace_print("Pass 1");
188 #endif
189
190 #define EXT2_BPP(bits) (1UL << ((bits) - 2))
191
192         for (i=0; i < 4; i++) {
193                 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(10+i);
194                 max_sizes = max_sizes + EXT2_BPP(10+i) * EXT2_BPP(10+i);
195                 max_sizes = (max_sizes +
196                              (__u64) EXT2_BPP(10+i) * EXT2_BPP(10+i) *
197                              EXT2_BPP(10+i));
198                 max_sizes = (max_sizes * (1UL << (10+i))) - 1;
199                 ext2_max_sizes[i] = max_sizes;
200         }
201 #undef EXT2_BPP
202
203         sb = (struct ext2fs_sb *) fs->super;
204         imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
205
206         /*
207          * Allocate bitmaps structures
208          */
209         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
210                                               &ctx->inode_used_map);
211         if (pctx.errcode) {
212                 pctx.num = 1;
213                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
214                 ctx->flags |= E2F_FLAG_ABORT;
215                 return;
216         }
217         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
218                                 _("directory inode map"), &ctx->inode_dir_map);
219         if (pctx.errcode) {
220                 pctx.num = 2;
221                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
222                 ctx->flags |= E2F_FLAG_ABORT;
223                 return;
224         }
225         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
226                         _("regular file inode map"), &ctx->inode_reg_map);
227         if (pctx.errcode) {
228                 pctx.num = 6;
229                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
230                 ctx->flags |= E2F_FLAG_ABORT;
231                 return;
232         }
233         pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
234                                               &ctx->block_found_map);
235         if (pctx.errcode) {
236                 pctx.num = 1;
237                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
238                 ctx->flags |= E2F_FLAG_ABORT;
239                 return;
240         }
241         pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
242                                              &ctx->inode_link_info);
243         if (pctx.errcode) {
244                 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
245                 ctx->flags |= E2F_FLAG_ABORT;
246                 return;
247         }
248         inodes_to_process = (struct process_inode_block *)
249                 e2fsck_allocate_memory(ctx,
250                                        (ctx->process_inode_size *
251                                         sizeof(struct process_inode_block)),
252                                        "array of inodes to process");
253         process_inode_count = 0;
254
255         pctx.errcode = ext2fs_init_dblist(fs, 0);
256         if (pctx.errcode) {
257                 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
258                 ctx->flags |= E2F_FLAG_ABORT;
259                 return;
260         }
261
262         mark_table_blocks(ctx);
263         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
264                                                     "block interate buffer");
265         e2fsck_use_inode_shortcuts(ctx, 1);
266         ehandler_operation(_("doing inode scan"));
267         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks, 
268                                               &scan);
269         if (pctx.errcode) {
270                 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
271                 ctx->flags |= E2F_FLAG_ABORT;
272                 return;
273         }
274         ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
275         pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
276         if (pctx.errcode) {
277                 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
278                 ctx->flags |= E2F_FLAG_ABORT;
279                 return;
280         }
281         ctx->stashed_inode = &inode;
282         scan_struct.ctx = ctx;
283         scan_struct.block_buf = block_buf;
284         ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
285         if (ctx->progress)
286                 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
287                         return;
288         while (ino) {
289                 pctx.ino = ino;
290                 pctx.inode = &inode;
291                 ctx->stashed_ino = ino;
292                 if (inode.i_links_count) {
293                         pctx.errcode = ext2fs_icount_store(ctx->inode_link_info, 
294                                            ino, inode.i_links_count);
295                         if (pctx.errcode) {
296                                 pctx.num = inode.i_links_count;
297                                 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
298                                 ctx->flags |= E2F_FLAG_ABORT;
299                                 return;
300                         }
301                 }
302                 if (ino == EXT2_BAD_INO) {
303                         struct process_block_struct pb;
304                         
305                         pb.ino = EXT2_BAD_INO;
306                         pb.num_blocks = pb.last_block = 0;
307                         pb.num_illegal_blocks = 0;
308                         pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
309                         pb.fragmented = 0;
310                         pb.inode = &inode;
311                         pb.pctx = &pctx;
312                         pb.ctx = ctx;
313                         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, 
314                                      block_buf, process_bad_block, &pb);
315                         if (pctx.errcode) {
316                                 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
317                                 ctx->flags |= E2F_FLAG_ABORT;
318                                 return;
319                         }
320                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
321                         clear_problem_context(&pctx);
322                         goto next;
323                 }
324                 if (ino == EXT2_ROOT_INO) {
325                         /*
326                          * Make sure the root inode is a directory; if
327                          * not, offer to clear it.  It will be
328                          * regnerated in pass #3.
329                          */
330                         if (!LINUX_S_ISDIR(inode.i_mode)) {
331                                 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
332                                         inode.i_dtime = time(0);
333                                         inode.i_links_count = 0;
334                                         ext2fs_icount_store(ctx->inode_link_info,
335                                                             ino, 0);
336                                         e2fsck_write_inode(ctx, ino, &inode,
337                                                            "pass1");
338                                 }
339                         }
340                         /*
341                          * If dtime is set, offer to clear it.  mke2fs
342                          * version 0.2b created filesystems with the
343                          * dtime field set for the root and lost+found
344                          * directories.  We won't worry about
345                          * /lost+found, since that can be regenerated
346                          * easily.  But we will fix the root directory
347                          * as a special case.
348                          */
349                         if (inode.i_dtime && inode.i_links_count) {
350                                 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
351                                         inode.i_dtime = 0;
352                                         e2fsck_write_inode(ctx, ino, &inode,
353                                                            "pass1");
354                                 }
355                         }
356                 }
357                 if ((ino != EXT2_ROOT_INO) &&
358                     (ino < EXT2_FIRST_INODE(fs->super))) {
359                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
360                         if (((ino == EXT2_BOOT_LOADER_INO) &&
361                              LINUX_S_ISDIR(inode.i_mode)) ||
362                             ((ino != EXT2_BOOT_LOADER_INO) &&
363                              (inode.i_mode != 0))) {
364                                 if (fix_problem(ctx,
365                                             PR_1_RESERVED_BAD_MODE, &pctx)) {
366                                         inode.i_mode = 0;
367                                         e2fsck_write_inode(ctx, ino, &inode,
368                                                            "pass1");
369                                 }
370                         }
371                         check_blocks(ctx, &pctx, block_buf);
372                         goto next;
373                 }
374                 /*
375                  * This code assumes that deleted inodes have
376                  * i_links_count set to 0.  
377                  */
378                 if (!inode.i_links_count) {
379                         if (!inode.i_dtime && inode.i_mode) {
380                                 if (fix_problem(ctx,
381                                             PR_1_ZERO_DTIME, &pctx)) {
382                                         inode.i_dtime = time(0);
383                                         e2fsck_write_inode(ctx, ino, &inode,
384                                                            "pass1");
385                                 }
386                         }
387                         goto next;
388                 }
389                 /*
390                  * n.b.  0.3c ext2fs code didn't clear i_links_count for
391                  * deleted files.  Oops.
392                  *
393                  * Since all new ext2 implementations get this right,
394                  * we now assume that the case of non-zero
395                  * i_links_count and non-zero dtime means that we
396                  * should keep the file, not delete it.
397                  * 
398                  */
399                 if (inode.i_dtime) {
400                         if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
401                                 inode.i_dtime = 0;
402                                 e2fsck_write_inode(ctx, ino, &inode, "pass1");
403                         }
404                 }
405                 
406                 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
407                 switch (fs->super->s_creator_os) {
408                     case EXT2_OS_LINUX:
409                         frag = inode.osd2.linux2.l_i_frag;
410                         fsize = inode.osd2.linux2.l_i_fsize;
411                         break;
412                     case EXT2_OS_HURD:
413                         frag = inode.osd2.hurd2.h_i_frag;
414                         fsize = inode.osd2.hurd2.h_i_fsize;
415                         break;
416                     case EXT2_OS_MASIX:
417                         frag = inode.osd2.masix2.m_i_frag;
418                         fsize = inode.osd2.masix2.m_i_fsize;
419                         break;
420                     default:
421                         frag = fsize = 0;
422                 }
423                 
424                 if (inode.i_faddr || frag || fsize
425                     || inode.i_file_acl ||
426                     (LINUX_S_ISDIR(inode.i_mode) && inode.i_dir_acl)) {
427                         if (!ctx->inode_bad_map)
428                                 alloc_bad_map(ctx);
429                         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
430                 }
431                 if (inode.i_flags & EXT2_IMAGIC_FL) {
432                         if (imagic_fs) {
433                                 if (!ctx->inode_imagic_map)
434                                         alloc_imagic_map(ctx);
435                                 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
436                                                          ino);
437                         } else {
438                                 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
439                                         inode.i_flags &= ~EXT2_IMAGIC_FL;
440                                         e2fsck_write_inode(ctx, ino,
441                                                            &inode, "pass1");
442                                 }
443                         }
444                 }
445                 
446                 if (LINUX_S_ISDIR(inode.i_mode)) {
447                         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
448                         e2fsck_add_dir_info(ctx, ino, 0);
449                         ctx->fs_directory_count++;
450                 } else if (LINUX_S_ISREG (inode.i_mode)) {
451                         ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
452                         ctx->fs_regular_count++;
453                 } else if (LINUX_S_ISCHR (inode.i_mode) &&
454                            e2fsck_pass1_check_device_inode(&inode)) {
455                         check_immutable(ctx, &pctx);
456                         ctx->fs_chardev_count++;
457                 } else if (LINUX_S_ISBLK (inode.i_mode) &&
458                            e2fsck_pass1_check_device_inode(&inode)) {
459                         check_immutable(ctx, &pctx);
460                         ctx->fs_blockdev_count++;
461                 } else if (LINUX_S_ISLNK (inode.i_mode)) {
462                         ctx->fs_symlinks_count++;
463                         if (!inode.i_blocks) {
464                                 ctx->fs_fast_symlinks_count++;
465                                 goto next;
466                         }
467                 }
468                 else if (LINUX_S_ISFIFO (inode.i_mode) &&
469                          e2fsck_pass1_check_device_inode(&inode)) {
470                         check_immutable(ctx, &pctx);
471                         ctx->fs_fifo_count++;
472                 } else if ((LINUX_S_ISSOCK (inode.i_mode)) &&
473                            e2fsck_pass1_check_device_inode(&inode)) {
474                         check_immutable(ctx, &pctx);
475                         ctx->fs_sockets_count++;
476                 } else {
477                         if (!ctx->inode_bad_map)
478                                 alloc_bad_map(ctx);
479                         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
480                 }
481                 if (inode.i_block[EXT2_IND_BLOCK])
482                         ctx->fs_ind_count++;
483                 if (inode.i_block[EXT2_DIND_BLOCK])
484                         ctx->fs_dind_count++;
485                 if (inode.i_block[EXT2_TIND_BLOCK])
486                         ctx->fs_tind_count++;
487                 if (inode.i_block[EXT2_IND_BLOCK] ||
488                     inode.i_block[EXT2_DIND_BLOCK] ||
489                     inode.i_block[EXT2_TIND_BLOCK]) {
490                         inodes_to_process[process_inode_count].ino = ino;
491                         inodes_to_process[process_inode_count].inode = inode;
492                         process_inode_count++;
493                 } else
494                         check_blocks(ctx, &pctx, block_buf);
495
496                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
497                         return;
498
499                 if (process_inode_count >= ctx->process_inode_size) {
500                         process_inodes(ctx, block_buf);
501
502                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
503                                 return;
504                 }
505         next:
506                 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
507                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
508                         return;
509                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
510                         if (!ctx->inode_bb_map)
511                                 alloc_bb_map(ctx);
512                         ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
513                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
514                         goto next;
515                 }
516                 if (pctx.errcode) {
517                         fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
518                         ctx->flags |= E2F_FLAG_ABORT;
519                         return;
520                 }
521         }
522         process_inodes(ctx, block_buf);
523         ext2fs_close_inode_scan(scan);
524         ehandler_operation(0);
525
526         if (ctx->invalid_bitmaps)
527                 handle_fs_bad_blocks(ctx);
528
529         if (ctx->flags & E2F_FLAG_RESTART) {
530                 /*
531                  * Only the master copy of the superblock and block
532                  * group descriptors are going to be written during a
533                  * restart, so set the superblock to be used to be the
534                  * master superblock.
535                  */
536                 ctx->use_superblock = 0;
537                 unwind_pass1(fs);
538                 goto endit;
539         }
540
541         if (ctx->block_dup_map) {
542                 if (ctx->options & E2F_OPT_PREEN) {
543                         clear_problem_context(&pctx);
544                         fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
545                 }
546                 e2fsck_pass1_dupblocks(ctx, block_buf);
547         }
548         ext2fs_free_mem((void **) &inodes_to_process);
549 endit:
550         e2fsck_use_inode_shortcuts(ctx, 0);
551         
552         ext2fs_free_mem((void **) &block_buf);
553
554         if (ctx->large_files && 
555             !(sb->s_feature_ro_compat & 
556               EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
557                 if (fix_problem(ctx, PR_1_FEATURE_LARGE_FILES, &pctx)) {
558                         sb->s_feature_ro_compat |= 
559                                 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
560                         ext2fs_mark_super_dirty(fs);
561                 }
562         } else if (!ctx->large_files &&
563             (sb->s_feature_ro_compat &
564               EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
565                 if (fs->flags & EXT2_FLAG_RW) {
566                         sb->s_feature_ro_compat &= 
567                                 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
568                         ext2fs_mark_super_dirty(fs);
569                 }
570         }
571         
572 #ifdef RESOURCE_TRACK
573         if (ctx->options & E2F_OPT_TIME2) {
574                 e2fsck_clear_progbar(ctx);
575                 print_resource_track(_("Pass 1"), &rtrack);
576         }
577 #endif
578 }
579
580 /*
581  * When the inode_scan routines call this callback at the end of the
582  * glock group, call process_inodes.
583  */
584 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
585                                dgrp_t group, void * priv_data)
586 {
587         struct scan_callback_struct *scan_struct;
588         e2fsck_t ctx;
589
590         scan_struct = (struct scan_callback_struct *) priv_data;
591         ctx = scan_struct->ctx;
592         
593         process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
594
595         if (ctx->progress)
596                 if ((ctx->progress)(ctx, 1, group+1,
597                                     ctx->fs->group_desc_count))
598                         return EXT2_ET_CANCEL_REQUESTED;
599
600         return 0;
601 }
602
603 /*
604  * Process the inodes in the "inodes to process" list.
605  */
606 static void process_inodes(e2fsck_t ctx, char *block_buf)
607 {
608         int                     i;
609         struct ext2_inode       *old_stashed_inode;
610         ino_t                   old_stashed_ino;
611         const char              *old_operation;
612         char                    buf[80];
613         struct problem_context  pctx;
614         
615 #if 0
616         printf("begin process_inodes: ");
617 #endif
618         if (process_inode_count == 0)
619                 return;
620         old_operation = ehandler_operation(0);
621         old_stashed_inode = ctx->stashed_inode;
622         old_stashed_ino = ctx->stashed_ino;
623         qsort(inodes_to_process, process_inode_count,
624                       sizeof(struct process_inode_block), process_inode_cmp);
625         clear_problem_context(&pctx);
626         for (i=0; i < process_inode_count; i++) {
627                 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
628                 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
629                 
630 #if 0
631                 printf("%u ", pctx.ino);
632 #endif
633                 sprintf(buf, _("reading indirect blocks of inode %lu"),
634                         pctx.ino);
635                 ehandler_operation(buf);
636                 check_blocks(ctx, &pctx, block_buf);
637                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
638                         break;
639         }
640         ctx->stashed_inode = old_stashed_inode;
641         ctx->stashed_ino = old_stashed_ino;
642         process_inode_count = 0;
643 #if 0
644         printf("end process inodes\n");
645 #endif
646         ehandler_operation(old_operation);
647 }
648
649 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
650 {
651         const struct process_inode_block *ib_a =
652                 (const struct process_inode_block *) a;
653         const struct process_inode_block *ib_b =
654                 (const struct process_inode_block *) b;
655
656         return (ib_a->inode.i_block[EXT2_IND_BLOCK] -
657                 ib_b->inode.i_block[EXT2_IND_BLOCK]);
658 }
659
660 /*
661  * This procedure will allocate the inode bad map table
662  */
663 static void alloc_bad_map(e2fsck_t ctx)
664 {
665         struct          problem_context pctx;
666         
667         clear_problem_context(&pctx);
668         
669         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, _("bad inode map"),
670                                               &ctx->inode_bad_map);
671         if (pctx.errcode) {
672                 pctx.num = 3;
673                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
674                 /* Should never get here */
675                 ctx->flags |= E2F_FLAG_ABORT;
676                 return;
677         }
678 }
679
680 /*
681  * This procedure will allocate the inode "bb" (badblock) map table
682  */
683 static void alloc_bb_map(e2fsck_t ctx)
684 {
685         struct          problem_context pctx;
686         
687         clear_problem_context(&pctx);
688         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
689                                               _("inode in bad block map"),
690                                               &ctx->inode_bb_map);
691         if (pctx.errcode) {
692                 pctx.num = 4;
693                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
694                 /* Should never get here */
695                 ctx->flags |= E2F_FLAG_ABORT;
696                 return;
697         }
698 }
699
700 /*
701  * This procedure will allocate the inode imagic table
702  */
703 static void alloc_imagic_map(e2fsck_t ctx)
704 {
705         struct          problem_context pctx;
706         
707         clear_problem_context(&pctx);
708         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
709                                               _("imagic inode map"),
710                                               &ctx->inode_imagic_map);
711         if (pctx.errcode) {
712                 pctx.num = 5;
713                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
714                 /* Should never get here */
715                 ctx->flags |= E2F_FLAG_ABORT;
716                 return;
717         }
718 }
719
720 /*
721  * Marks a block as in use, setting the dup_map if it's been set
722  * already.  Called by process_block and process_bad_block.
723  *
724  * WARNING: Assumes checks have already been done to make sure block
725  * is valid.  This is true in both process_block and process_bad_block.
726  */
727 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
728 {
729         struct          problem_context pctx;
730         
731         clear_problem_context(&pctx);
732         
733         if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
734                 if (!ctx->block_dup_map) {
735                         pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
736                               _("multiply claimed block map"),
737                               &ctx->block_dup_map);
738                         if (pctx.errcode) {
739                                 pctx.num = 3;
740                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, 
741                                             &pctx);
742                                 /* Should never get here */
743                                 ctx->flags |= E2F_FLAG_ABORT;
744                                 return;
745                         }
746                 }
747                 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
748         } else {
749                 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
750         }
751 }
752
753 /*
754  * This subroutine is called on each inode to account for all of the
755  * blocks used by that inode.
756  */
757 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
758                          char *block_buf)
759 {
760         ext2_filsys fs = ctx->fs;
761         struct process_block_struct pb;
762         ino_t           ino = pctx->ino;
763         struct ext2_inode *inode = pctx->inode;
764         int             bad_size = 0;
765         __u64           size;
766         struct ext2fs_sb        *sb;
767         
768         if (!ext2fs_inode_has_valid_blocks(pctx->inode))
769                 return;
770         
771         pb.ino = ino;
772         pb.num_blocks = pb.last_block = 0;
773         pb.num_illegal_blocks = 0;
774         pb.suppress = 0; pb.clear = 0;
775         pb.fragmented = 0;
776         pb.previous_block = 0;
777         pb.is_dir = LINUX_S_ISDIR(pctx->inode->i_mode);
778         pb.inode = inode;
779         pb.pctx = pctx;
780         pb.ctx = ctx;
781         pctx->ino = ino;
782         pctx->errcode = ext2fs_block_iterate2(fs, ino,
783                                        pb.is_dir ? BLOCK_FLAG_HOLE : 0,
784                                        block_buf, process_block, &pb);
785         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
786                 return;
787         end_problem_latch(ctx, PR_LATCH_BLOCK);
788         if (pctx->errcode)
789                 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
790
791         if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
792                 ctx->fs_fragmented++;
793
794         if (pb.clear) {
795                 e2fsck_read_inode(ctx, ino, inode, "check_blocks");
796                 inode->i_links_count = 0;
797                 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
798                 inode->i_dtime = time(0);
799                 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
800                 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
801                 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
802                 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
803                 /*
804                  * The inode was probably partially accounted for
805                  * before processing was aborted, so we need to
806                  * restart the pass 1 scan.
807                  */
808                 ctx->flags |= E2F_FLAG_RESTART;
809                 return;
810         }
811
812         pb.num_blocks *= (fs->blocksize / 512);
813 #if 0
814         printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
815                ino, inode->i_size, pb.last_block, inode->i_blocks,
816                pb.num_blocks);
817 #endif
818         if (!pb.num_blocks && pb.is_dir) {
819                 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
820                         inode->i_links_count = 0;
821                         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
822                         inode->i_dtime = time(0);
823                         e2fsck_write_inode(ctx, ino, inode, "check_blocks");
824                         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
825                         ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
826                         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
827                         ctx->fs_directory_count--;
828                         pb.is_dir = 0;
829                 }
830         }
831         if (pb.is_dir) {
832                 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
833                 if ((nblock > (pb.last_block + 1)) ||
834                     ((inode->i_size & (fs->blocksize-1)) != 0))
835                         bad_size = 1;
836                 else if (nblock < (pb.last_block + 1)) {
837                         sb = (struct ext2fs_sb *) fs->super;
838                         if (((pb.last_block + 1) - nblock) >
839                             sb->s_prealloc_dir_blocks)
840                                 bad_size = 2;
841                 }
842         } else {
843                 size = inode->i_size + ((__u64) inode->i_size_high << 32);
844                 if ((size < pb.last_block * fs->blocksize))
845                         bad_size = 3;
846                 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
847                         bad_size = 4;
848         }
849         if (bad_size) {
850                 pctx->num = (pb.last_block+1) * fs->blocksize;
851                 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
852                         inode->i_size = pctx->num;
853                         if (!pb.is_dir)
854                                 inode->i_size_high = pctx->num >> 32;
855                         e2fsck_write_inode(ctx, ino, inode, "check_blocks");
856                 }
857                 pctx->num = 0;
858         }
859         if (!pb.is_dir && inode->i_size_high)
860                 ctx->large_files++;
861         if (pb.num_blocks != inode->i_blocks) {
862                 pctx->num = pb.num_blocks;
863                 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
864                         inode->i_blocks = pb.num_blocks;
865                         e2fsck_write_inode(ctx, ino, inode, "check_blocks");
866                 }
867                 pctx->num = 0;
868         }
869 }
870
871 #if 0
872 /*
873  * Helper function called by process block when an illegal block is
874  * found.  It returns a description about why the block is illegal
875  */
876 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
877 {
878         blk_t   super;
879         int     i;
880         static char     problem[80];
881
882         super = fs->super->s_first_data_block;
883         strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
884         if (block < super) {
885                 sprintf(problem, "< FIRSTBLOCK (%u)", super);
886                 return(problem);
887         } else if (block >= fs->super->s_blocks_count) {
888                 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
889                 return(problem);
890         }
891         for (i = 0; i < fs->group_desc_count; i++) {
892                 if (block == super) {
893                         sprintf(problem, "is the superblock in group %d", i);
894                         break;
895                 }
896                 if (block > super &&
897                     block <= (super + fs->desc_blocks)) {
898                         sprintf(problem, "is in the group descriptors "
899                                 "of group %d", i);
900                         break;
901                 }
902                 if (block == fs->group_desc[i].bg_block_bitmap) {
903                         sprintf(problem, "is the block bitmap of group %d", i);
904                         break;
905                 }
906                 if (block == fs->group_desc[i].bg_inode_bitmap) {
907                         sprintf(problem, "is the inode bitmap of group %d", i);
908                         break;
909                 }
910                 if (block >= fs->group_desc[i].bg_inode_table &&
911                     (block < fs->group_desc[i].bg_inode_table
912                      + fs->inode_blocks_per_group)) {
913                         sprintf(problem, "is in the inode table of group %d",
914                                 i);
915                         break;
916                 }
917                 super += fs->super->s_blocks_per_group;
918         }
919         return(problem);
920 }
921 #endif
922
923 /*
924  * This is a helper function for check_blocks().
925  */
926 int process_block(ext2_filsys fs,
927                   blk_t *block_nr,
928                   e2_blkcnt_t blockcnt,
929                   blk_t ref_block,
930                   int ref_offset, 
931                   void *priv_data)
932 {
933         struct process_block_struct *p;
934         struct problem_context *pctx;
935         blk_t   blk = *block_nr;
936         int     ret_code = 0;
937         int     problem = 0;
938         e2fsck_t        ctx;
939
940         p = (struct process_block_struct *) priv_data;
941         pctx = p->pctx;
942         ctx = p->ctx;
943
944         if (blk == 0) {
945                 if (p->is_dir == 0) {
946                         /*
947                          * Should never happen, since only directories
948                          * get called with BLOCK_FLAG_HOLE
949                          */
950 #if DEBUG_E2FSCK
951                         printf("process_block() called with blk == 0, "
952                                "blockcnt=%d, inode %lu???\n",
953                                blockcnt, p->ino);
954 #endif
955                         return 0;
956                 }
957                 if (blockcnt < 0)
958                         return 0;
959                 if (blockcnt * fs->blocksize < p->inode->i_size) {
960 #if 0
961                         printf("Missing block (#%d) in directory inode %lu!\n",
962                                blockcnt, p->ino);
963 #endif
964                         goto mark_dir;
965                 }
966                 return 0;
967         }
968
969 #if 0
970         printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
971                blockcnt);
972 #endif
973         
974         /*
975          * Simplistic fragmentation check.  We merely require that the
976          * file be contiguous.  (Which can never be true for really
977          * big files that are greater than a block group.)
978          */
979         if (p->previous_block) {
980                 if (p->previous_block+1 != blk)
981                         p->fragmented = 1;
982         }
983         p->previous_block = blk;
984         
985         if (blk < fs->super->s_first_data_block ||
986             blk >= fs->super->s_blocks_count)
987                 problem = PR_1_ILLEGAL_BLOCK_NUM;
988
989         if (problem) {
990                 p->num_illegal_blocks++;
991                 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
992                         if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
993                                 p->clear = 1;
994                                 return BLOCK_ABORT;
995                         }
996                         if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
997                                 p->suppress = 1;
998                                 set_latch_flags(PR_LATCH_BLOCK,
999                                                 PRL_SUPPRESS, 0);
1000                         }
1001                 }
1002                 pctx->blk = blk;
1003                 pctx->blkcount = blockcnt;
1004                 if (fix_problem(ctx, problem, pctx)) {
1005                         blk = *block_nr = 0;
1006                         ret_code = BLOCK_CHANGED;
1007                         goto mark_dir;
1008                 } else
1009                         return 0;
1010                 pctx->blk = 0;
1011                 pctx->blkcount = -1;
1012         }
1013
1014         mark_block_used(ctx, blk);
1015         p->num_blocks++;
1016         if (blockcnt >= 0)
1017                 p->last_block = blockcnt;
1018 mark_dir:
1019         if (p->is_dir && (blockcnt >= 0)) {
1020                 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
1021                                                     blk, blockcnt);
1022                 if (pctx->errcode) {
1023                         pctx->blk = blk;
1024                         pctx->num = blockcnt;
1025                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
1026                         /* Should never get here */
1027                         ctx->flags |= E2F_FLAG_ABORT;
1028                         return BLOCK_ABORT;
1029                 }
1030         }
1031         return ret_code;
1032 }
1033
1034 static void bad_block_indirect(e2fsck_t ctx, blk_t blk)
1035 {
1036         struct problem_context pctx;
1037
1038         clear_problem_context(&pctx);
1039         /*
1040          * Prompt to see if we should continue or not.
1041          */
1042         if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, &pctx))
1043                 ctx->flags |= E2F_FLAG_ABORT;
1044 }
1045
1046 int process_bad_block(ext2_filsys fs,
1047                       blk_t *block_nr,
1048                       e2_blkcnt_t blockcnt,
1049                       blk_t ref_block,
1050                       int ref_offset,
1051                       void *priv_data)
1052 {
1053         struct process_block_struct *p;
1054         blk_t           blk = *block_nr;
1055         int             first_block;
1056         int             i;
1057         struct problem_context *pctx;
1058         e2fsck_t        ctx;
1059
1060         if (!blk)
1061                 return 0;
1062         
1063         p = (struct process_block_struct *) priv_data;
1064         ctx = p->ctx;
1065         pctx = p->pctx;
1066         
1067         pctx->ino = EXT2_BAD_INO;
1068         pctx->blk = blk;
1069         pctx->blkcount = blockcnt;
1070
1071         if ((blk < fs->super->s_first_data_block) ||
1072             (blk >= fs->super->s_blocks_count)) {
1073                 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
1074                         *block_nr = 0;
1075                         return BLOCK_CHANGED;
1076                 } else
1077                         return 0;
1078         }
1079
1080         if (blockcnt < 0) {
1081                 if (ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
1082                         bad_block_indirect(ctx, blk);
1083                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1084                                 return BLOCK_ABORT;
1085                 } else
1086                         mark_block_used(ctx, blk);
1087                 return 0;
1088         }
1089 #if 0 
1090         printf ("DEBUG: Marking %u as bad.\n", blk);
1091 #endif
1092         ctx->fs_badblocks_count++;
1093         /*
1094          * If the block is not used, then mark it as used and return.
1095          * If it is already marked as found, this must mean that
1096          * there's an overlap between the filesystem table blocks
1097          * (bitmaps and inode table) and the bad block list.
1098          */
1099         if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
1100                 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
1101                 return 0;
1102         }
1103         /*
1104          * Try to find the where the filesystem block was used...
1105          */
1106         first_block = fs->super->s_first_data_block;
1107         
1108         for (i = 0; i < fs->group_desc_count; i++ ) {
1109                 pctx->group = i;
1110                 pctx->blk = blk;
1111                 if (!ext2fs_bg_has_super(fs, i))
1112                         goto skip_super;
1113                 if (blk == first_block) {
1114                         if (i == 0) {
1115                                 if (fix_problem(ctx,
1116                                                 PR_1_BAD_PRIMARY_SUPERBLOCK,
1117                                                 pctx)) {
1118                                         *block_nr = 0;
1119                                         return BLOCK_CHANGED;
1120                                 }
1121                                 return 0;
1122                         }
1123                         fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
1124                         return 0;
1125                 }
1126                 if ((blk > first_block) &&
1127                     (blk <= first_block + fs->desc_blocks)) {
1128                         if (i == 0) {
1129                                 pctx->blk = *block_nr;
1130                                 if (fix_problem(ctx,
1131                         PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
1132                                         *block_nr = 0;
1133                                         return BLOCK_CHANGED;
1134                                 }
1135                                 return 0;
1136                         }
1137                         fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
1138                         return 0;
1139                 }
1140         skip_super:
1141                 if (blk == fs->group_desc[i].bg_block_bitmap) {
1142                         if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
1143                                 ctx->invalid_block_bitmap_flag[i]++;
1144                                 ctx->invalid_bitmaps++;
1145                         }
1146                         return 0;
1147                 }
1148                 if (blk == fs->group_desc[i].bg_inode_bitmap) {
1149                         if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
1150                                 ctx->invalid_inode_bitmap_flag[i]++;
1151                                 ctx->invalid_bitmaps++;
1152                         }
1153                         return 0;
1154                 }
1155                 if ((blk >= fs->group_desc[i].bg_inode_table) &&
1156                     (blk < (fs->group_desc[i].bg_inode_table +
1157                             fs->inode_blocks_per_group))) {
1158                         /*
1159                          * If there are bad blocks in the inode table,
1160                          * the inode scan code will try to do
1161                          * something reasonable automatically.
1162                          */
1163                         return 0;
1164                 }
1165                 first_block += fs->super->s_blocks_per_group;
1166         }
1167         /*
1168          * If we've gotten to this point, then the only
1169          * possibility is that the bad block inode meta data
1170          * is using a bad block.
1171          */
1172         if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
1173             p->inode->i_block[EXT2_DIND_BLOCK]) {
1174                 bad_block_indirect(ctx, blk);
1175                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
1176                         return BLOCK_ABORT;
1177                 return 0;
1178         }
1179
1180         pctx->group = -1;
1181
1182         /* Warn user that the block wasn't claimed */
1183         fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
1184
1185         return 0;
1186 }
1187
1188 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group, 
1189                             const char *name, int num, blk_t *new_block)
1190 {
1191         ext2_filsys fs = ctx->fs;
1192         blk_t           old_block = *new_block;
1193         int             i;
1194         char            *buf;
1195         struct problem_context  pctx;
1196
1197         clear_problem_context(&pctx);
1198
1199         pctx.group = group;
1200         pctx.blk = old_block;
1201         pctx.str = name;
1202
1203         pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
1204                         first_block + fs->super->s_blocks_per_group,
1205                                         num, ctx->block_found_map, new_block);
1206         if (pctx.errcode) {
1207                 pctx.num = num;
1208                 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
1209                 ext2fs_unmark_valid(fs);
1210                 return;
1211         }
1212         pctx.errcode = ext2fs_get_mem(fs->blocksize, (void **) &buf);
1213         if (pctx.errcode) {
1214                 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
1215                 ext2fs_unmark_valid(fs);
1216                 return;
1217         }
1218         ext2fs_mark_super_dirty(fs);
1219         pctx.blk2 = *new_block;
1220         fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
1221                           PR_1_RELOC_TO), &pctx);
1222         pctx.blk2 = 0;
1223         for (i = 0; i < num; i++) {
1224                 pctx.blk = i;
1225                 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
1226                 if (old_block) {
1227                         pctx.errcode = io_channel_read_blk(fs->io,
1228                                    old_block + i, 1, buf);
1229                         if (pctx.errcode)
1230                                 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
1231                 } else
1232                         memset(buf, 0, fs->blocksize);
1233
1234                 pctx.blk = (*new_block) + i;
1235                 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
1236                                               1, buf);
1237                 if (pctx.errcode)
1238                         fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
1239         }
1240         ext2fs_free_mem((void **) &buf);
1241 }
1242
1243 /*
1244  * This routine gets called at the end of pass 1 if bad blocks are
1245  * detected in the superblock, group descriptors, inode_bitmaps, or
1246  * block bitmaps.  At this point, all of the blocks have been mapped
1247  * out, so we can try to allocate new block(s) to replace the bad
1248  * blocks.
1249  */
1250 static void handle_fs_bad_blocks(e2fsck_t ctx)
1251 {
1252         ext2_filsys fs = ctx->fs;
1253         int             i;
1254         int             first_block = fs->super->s_first_data_block;
1255
1256         for (i = 0; i < fs->group_desc_count; i++) {
1257                 if (ctx->invalid_block_bitmap_flag[i]) {
1258                         new_table_block(ctx, first_block, i, _("block bitmap"),
1259                                         1, &fs->group_desc[i].bg_block_bitmap);
1260                 }
1261                 if (ctx->invalid_inode_bitmap_flag[i]) {
1262                         new_table_block(ctx, first_block, i, _("inode bitmap"),
1263                                         1, &fs->group_desc[i].bg_inode_bitmap);
1264                 }
1265                 if (ctx->invalid_inode_table_flag[i]) {
1266                         new_table_block(ctx, first_block, i, _("inode table"),
1267                                         fs->inode_blocks_per_group, 
1268                                         &fs->group_desc[i].bg_inode_table);
1269                         ctx->flags |= E2F_FLAG_RESTART;
1270                 }
1271                 first_block += fs->super->s_blocks_per_group;
1272         }
1273         ctx->invalid_bitmaps = 0;
1274 }
1275
1276 /*
1277  * This routine marks all blocks which are used by the superblock,
1278  * group descriptors, inode bitmaps, and block bitmaps.
1279  */
1280 static void mark_table_blocks(e2fsck_t ctx)
1281 {
1282         ext2_filsys fs = ctx->fs;
1283         blk_t   block, b;
1284         int     i,j;
1285         struct problem_context pctx;
1286         
1287         clear_problem_context(&pctx);
1288         
1289         block = fs->super->s_first_data_block;
1290         for (i = 0; i < fs->group_desc_count; i++) {
1291                 pctx.group = i;
1292
1293                 if (ext2fs_bg_has_super(fs, i)) {
1294                         /*
1295                          * Mark this group's copy of the superblock
1296                          */
1297                         ext2fs_mark_block_bitmap(ctx->block_found_map, block);
1298                 
1299                         /*
1300                          * Mark this group's copy of the descriptors
1301                          */
1302                         for (j = 0; j < fs->desc_blocks; j++) {
1303                                 ext2fs_mark_block_bitmap(ctx->block_found_map,
1304                                                          block + j + 1);
1305                         }
1306                 }
1307                 
1308                 /*
1309                  * Mark the blocks used for the inode table
1310                  */
1311                 if (fs->group_desc[i].bg_inode_table) {
1312                         for (j = 0, b = fs->group_desc[i].bg_inode_table;
1313                              j < fs->inode_blocks_per_group;
1314                              j++, b++) {
1315                                 if (ext2fs_test_block_bitmap(ctx->block_found_map,
1316                                                              b)) {
1317                                         pctx.blk = b;
1318                                         if (fix_problem(ctx,
1319                                                 PR_1_ITABLE_CONFLICT, &pctx)) {
1320                                                 ctx->invalid_inode_table_flag[i]++;
1321                                                 ctx->invalid_bitmaps++;
1322                                         }
1323                                 } else {
1324                                     ext2fs_mark_block_bitmap(ctx->block_found_map,
1325                                                              b);
1326                                 }
1327                         }
1328                 }
1329                             
1330                 /*
1331                  * Mark block used for the block bitmap 
1332                  */
1333                 if (fs->group_desc[i].bg_block_bitmap) {
1334                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
1335                                      fs->group_desc[i].bg_block_bitmap)) {
1336                                 pctx.blk = fs->group_desc[i].bg_block_bitmap;
1337                                 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
1338                                         ctx->invalid_block_bitmap_flag[i]++;
1339                                         ctx->invalid_bitmaps++;
1340                                 }
1341                         } else {
1342                             ext2fs_mark_block_bitmap(ctx->block_found_map,
1343                                      fs->group_desc[i].bg_block_bitmap);
1344                     }
1345                         
1346                 }
1347                 /*
1348                  * Mark block used for the inode bitmap 
1349                  */
1350                 if (fs->group_desc[i].bg_inode_bitmap) {
1351                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
1352                                      fs->group_desc[i].bg_inode_bitmap)) {
1353                                 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
1354                                 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
1355                                         ctx->invalid_inode_bitmap_flag[i]++;
1356                                         ctx->invalid_bitmaps++;
1357                                 } 
1358                         } else {
1359                             ext2fs_mark_block_bitmap(ctx->block_found_map,
1360                                      fs->group_desc[i].bg_inode_bitmap);
1361                         }
1362                 }
1363                 block += fs->super->s_blocks_per_group;
1364         }
1365 }
1366         
1367 /*
1368  * Thes subroutines short circuits ext2fs_get_blocks and
1369  * ext2fs_check_directory; we use them since we already have the inode
1370  * structure, so there's no point in letting the ext2fs library read
1371  * the inode again.
1372  */
1373 static errcode_t pass1_get_blocks(ext2_filsys fs, ino_t ino, blk_t *blocks)
1374 {
1375         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1376         int     i;
1377         
1378         if (ino != ctx->stashed_ino)
1379                 return EXT2_ET_CALLBACK_NOTHANDLED;
1380
1381         for (i=0; i < EXT2_N_BLOCKS; i++)
1382                 blocks[i] = ctx->stashed_inode->i_block[i];
1383         return 0;
1384 }
1385
1386 static errcode_t pass1_read_inode(ext2_filsys fs, ino_t ino,
1387                                   struct ext2_inode *inode)
1388 {
1389         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1390
1391         if (ino != ctx->stashed_ino)
1392                 return EXT2_ET_CALLBACK_NOTHANDLED;
1393         *inode = *ctx->stashed_inode;
1394         return 0;
1395 }
1396
1397 static errcode_t pass1_write_inode(ext2_filsys fs, ino_t ino,
1398                             struct ext2_inode *inode)
1399 {
1400         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1401
1402         if (ino == ctx->stashed_ino)
1403                 *ctx->stashed_inode = *inode;
1404         return EXT2_ET_CALLBACK_NOTHANDLED;
1405 }
1406
1407 static errcode_t pass1_check_directory(ext2_filsys fs, ino_t ino)
1408 {
1409         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
1410
1411         if (ino != ctx->stashed_ino)
1412                 return EXT2_ET_CALLBACK_NOTHANDLED;
1413
1414         if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
1415                 return EXT2_ET_NO_DIRECTORY;
1416         return 0;
1417 }
1418
1419 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
1420 {
1421         ext2_filsys fs = ctx->fs;
1422
1423         if (bool) {
1424                 fs->get_blocks = pass1_get_blocks;
1425                 fs->check_directory = pass1_check_directory;
1426                 fs->read_inode = pass1_read_inode;
1427                 fs->write_inode = pass1_write_inode;
1428                 ctx->stashed_ino = 0;
1429         } else {
1430                 fs->get_blocks = 0;
1431                 fs->check_directory = 0;
1432                 fs->read_inode = 0;
1433                 fs->write_inode = 0;
1434         }
1435 }
1436
1437