7e1c82e54ce9048f0e0dab82fffe7e2f6409758f
[oweals/busybox.git] / e2fsprogs / e2fsck.c
1 /*
2  * e2fsck
3  *
4  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
5  * Copyright (C) 2006 Garrett Kajmowicz
6  * This file may be
7  * redistributed under the terms of the GNU Public License.
8  *
9  *
10  * Dictionary Abstract Data Type
11  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
12  * Free Software License:
13  * All rights are reserved by the author, with the following exceptions:
14  * Permission is granted to freely reproduce and distribute this software,
15  * possibly in exchange for a fee, provided that this copyright notice appears
16  * intact. Permission is also granted to adapt this software to produce
17  * derivative works, as long as the modified versions carry this copyright
18  * notice and additional notices stating that the work has been modified.
19  * This source code may be translated into executable form and incorporated
20  * into proprietary software; there is no requirement for such software to
21  * contain a copyright notice related to this source.
22  *
23  * linux/fs/recovery  and linux/fs/revoke
24  * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
25  *
26  * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
27  *
28  * This file is part of the Linux kernel and is made available under
29  * the terms of the GNU General Public License, version 2, or at your
30  * option, any later version, incorporated herein by reference.
31  *
32  * Journal recovery routines for the generic filesystem journaling code;
33  * part of the ext2fs journaling system.
34  */
35
36 #ifndef _GNU_SOURCE
37 #define _GNU_SOURCE 1 /* get strnlen() */
38 #endif
39
40 #include "e2fsck.h"     /*Put all of our defines here to clean things up*/
41
42 /*
43  * Procedure declarations
44  */
45
46 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
47
48 /* pass1.c */
49 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
50
51 /* pass2.c */
52 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
53                                     ext2_ino_t ino, char *buf);
54
55 /* pass3.c */
56 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
57 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
58                                          int num, int gauranteed_size);
59 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
60 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
61                                            int adj);
62
63 /* rehash.c */
64 static void e2fsck_rehash_directories(e2fsck_t ctx);
65
66 /* util.c */
67 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
68                                     const char *description);
69 static int ask(e2fsck_t ctx, const char * string, int def);
70 static void e2fsck_read_bitmaps(e2fsck_t ctx);
71 static void preenhalt(e2fsck_t ctx);
72 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
73                               struct ext2_inode * inode, const char * proc);
74 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
75                                struct ext2_inode * inode, const char * proc);
76 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
77                            const char *name, io_manager manager);
78
79 /* unix.c */
80 static void e2fsck_clear_progbar(e2fsck_t ctx);
81 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
82                                   float percent, unsigned int dpynum);
83
84
85 /*
86  * problem.h --- e2fsck problem error codes
87  */
88
89 typedef __u32 problem_t;
90
91 struct problem_context {
92         errcode_t       errcode;
93         ext2_ino_t ino, ino2, dir;
94         struct ext2_inode *inode;
95         struct ext2_dir_entry *dirent;
96         blk_t   blk, blk2;
97         e2_blkcnt_t     blkcount;
98         int             group;
99         __u64   num;
100         const char *str;
101 };
102
103
104
105 /*
106  * Function declarations
107  */
108 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
109 static int end_problem_latch(e2fsck_t ctx, int mask);
110 static int set_latch_flags(int mask, int setflags, int clearflags);
111 static void clear_problem_context(struct problem_context *ctx);
112
113 /*
114  * Dictionary Abstract Data Type
115  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
116  *
117  * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
118  * kazlib_1_20
119  */
120
121 #ifndef DICT_H
122 #define DICT_H
123
124 /*
125  * Blurb for inclusion into C++ translation units
126  */
127
128 typedef unsigned long dictcount_t;
129 #define DICTCOUNT_T_MAX ULONG_MAX
130
131 /*
132  * The dictionary is implemented as a red-black tree
133  */
134
135 typedef enum { dnode_red, dnode_black } dnode_color_t;
136
137 typedef struct dnode_t {
138     struct dnode_t *dict_left;
139     struct dnode_t *dict_right;
140     struct dnode_t *dict_parent;
141     dnode_color_t dict_color;
142     const void *dict_key;
143     void *dict_data;
144 } dnode_t;
145
146 typedef int (*dict_comp_t)(const void *, const void *);
147 typedef void (*dnode_free_t)(dnode_t *);
148
149 typedef struct dict_t {
150     dnode_t dict_nilnode;
151     dictcount_t dict_nodecount;
152     dictcount_t dict_maxcount;
153     dict_comp_t dict_compare;
154     dnode_free_t dict_freenode;
155     int dict_dupes;
156 } dict_t;
157
158 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
159
160 typedef struct dict_load_t {
161     dict_t *dict_dictptr;
162     dnode_t dict_nilnode;
163 } dict_load_t;
164
165 #define dict_count(D) ((D)->dict_nodecount)
166 #define dnode_get(N) ((N)->dict_data)
167 #define dnode_getkey(N) ((N)->dict_key)
168
169 #endif
170
171 /*
172  * Compatibility header file for e2fsck which should be included
173  * instead of linux/jfs.h
174  *
175  * Copyright (C) 2000 Stephen C. Tweedie
176  */
177
178 /*
179  * Pull in the definition of the e2fsck context structure
180  */
181
182 struct buffer_head {
183         char            b_data[8192];
184         e2fsck_t        b_ctx;
185         io_channel      b_io;
186         int             b_size;
187         blk_t           b_blocknr;
188         int             b_dirty;
189         int             b_uptodate;
190         int             b_err;
191 };
192
193
194 #define K_DEV_FS        1
195 #define K_DEV_JOURNAL   2
196
197 #define lock_buffer(bh) do {} while(0)
198 #define unlock_buffer(bh) do {} while(0)
199 #define buffer_req(bh) 1
200 #define do_readahead(journal, start) do {} while(0)
201
202 static e2fsck_t e2fsck_global_ctx;  /* Try your very best not to use this! */
203
204 typedef struct {
205         int     object_length;
206 } kmem_cache_t;
207
208 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
209
210 /*
211  * We use the standard libext2fs portability tricks for inline
212  * functions.
213  */
214
215 static kmem_cache_t * do_cache_create(int len)
216 {
217         kmem_cache_t *new_cache;
218
219         new_cache = malloc(sizeof(*new_cache));
220         if (new_cache)
221                 new_cache->object_length = len;
222         return new_cache;
223 }
224
225 static void do_cache_destroy(kmem_cache_t *cache)
226 {
227         free(cache);
228 }
229
230 /*
231  * badblocks.c --- replace/append bad blocks to the bad block inode
232  */
233
234 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
235                                  void *priv_data);
236
237
238 static void invalid_block(ext2_filsys fs FSCK_ATTR((unused)), blk_t blk)
239 {
240         printf(_("Bad block %u out of range; ignored.\n"), blk);
241         return;
242 }
243
244 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
245                           int replace_bad_blocks)
246 {
247         ext2_filsys fs = ctx->fs;
248         errcode_t       retval;
249         badblocks_list  bb_list = 0;
250         FILE            *f;
251         char            buf[1024];
252
253         e2fsck_read_bitmaps(ctx);
254
255         /*
256          * Make sure the bad block inode is sane.  If there are any
257          * illegal blocks, clear them.
258          */
259         retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
260                                       check_bb_inode_blocks, 0);
261         if (retval) {
262                 bb_error_msg(_("while sanity checking the bad blocks inode"));
263                 goto fatal;
264         }
265
266         /*
267          * If we're appending to the bad blocks inode, read in the
268          * current bad blocks.
269          */
270         if (!replace_bad_blocks) {
271                 retval = ext2fs_read_bb_inode(fs, &bb_list);
272                 if (retval) {
273                         bb_error_msg(_("while reading the bad blocks inode"));
274                         goto fatal;
275                 }
276         }
277
278         /*
279          * Now read in the bad blocks from the file; if
280          * bad_blocks_file is null, then try to run the badblocks
281          * command.
282          */
283         if (bad_blocks_file) {
284                 f = fopen(bad_blocks_file, "r");
285                 if (!f) {
286                         bb_error_msg(_("while trying to open %s"), bad_blocks_file);
287                         goto fatal;
288                 }
289         } else {
290                 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
291                         (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
292                         (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
293                         fs->device_name, fs->super->s_blocks_count);
294                 f = popen(buf, "r");
295                 if (!f) {
296                         bb_error_msg(_("while trying popen '%s'"), buf);
297                         goto fatal;
298                 }
299         }
300         retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
301         if (bad_blocks_file)
302                 fclose(f);
303         else
304                 pclose(f);
305         if (retval) {
306                 bb_error_msg(_("while reading in list of bad blocks from file"));
307                 goto fatal;
308         }
309
310         /*
311          * Finally, update the bad blocks from the bad_block_map
312          */
313         retval = ext2fs_update_bb_inode(fs, bb_list);
314         if (retval) {
315                 bb_error_msg(_("while updating bad block inode"));
316                 goto fatal;
317         }
318
319         ext2fs_badblocks_list_free(bb_list);
320         return;
321
322 fatal:
323         ctx->flags |= E2F_FLAG_ABORT;
324         return;
325
326 }
327
328 static int check_bb_inode_blocks(ext2_filsys fs,
329                                  blk_t *block_nr,
330                                  int blockcnt FSCK_ATTR((unused)),
331                                  void *priv_data FSCK_ATTR((unused)))
332 {
333         if (!*block_nr)
334                 return 0;
335
336         /*
337          * If the block number is outrageous, clear it and ignore it.
338          */
339         if (*block_nr >= fs->super->s_blocks_count ||
340             *block_nr < fs->super->s_first_data_block) {
341                 printf(_("Warning illegal block %u found in bad block inode.  Cleared.\n"), *block_nr);
342                 *block_nr = 0;
343                 return BLOCK_CHANGED;
344         }
345
346         return 0;
347 }
348
349 /*
350  * Dictionary Abstract Data Type
351  */
352
353
354 /*
355  * These macros provide short convenient names for structure members,
356  * which are embellished with dict_ prefixes so that they are
357  * properly confined to the documented namespace. It's legal for a
358  * program which uses dict to define, for instance, a macro called ``parent''.
359  * Such a macro would interfere with the dnode_t struct definition.
360  * In general, highly portable and reusable C modules which expose their
361  * structures need to confine structure member names to well-defined spaces.
362  * The resulting identifiers aren't necessarily convenient to use, nor
363  * readable, in the implementation, however!
364  */
365
366 #define left dict_left
367 #define right dict_right
368 #define parent dict_parent
369 #define color dict_color
370 #define key dict_key
371 #define data dict_data
372
373 #define nilnode dict_nilnode
374 #define maxcount dict_maxcount
375 #define compare dict_compare
376 #define dupes dict_dupes
377
378 #define dict_root(D) ((D)->nilnode.left)
379 #define dict_nil(D) (&(D)->nilnode)
380
381 static void dnode_free(dnode_t *node);
382
383 /*
384  * Perform a ``left rotation'' adjustment on the tree.  The given node P and
385  * its right child C are rearranged so that the P instead becomes the left
386  * child of C.   The left subtree of C is inherited as the new right subtree
387  * for P.  The ordering of the keys within the tree is thus preserved.
388  */
389
390 static void rotate_left(dnode_t *upper)
391 {
392     dnode_t *lower, *lowleft, *upparent;
393
394     lower = upper->right;
395     upper->right = lowleft = lower->left;
396     lowleft->parent = upper;
397
398     lower->parent = upparent = upper->parent;
399
400     /* don't need to check for root node here because root->parent is
401        the sentinel nil node, and root->parent->left points back to root */
402
403     if (upper == upparent->left) {
404         upparent->left = lower;
405     } else {
406         assert (upper == upparent->right);
407         upparent->right = lower;
408     }
409
410     lower->left = upper;
411     upper->parent = lower;
412 }
413
414 /*
415  * This operation is the ``mirror'' image of rotate_left. It is
416  * the same procedure, but with left and right interchanged.
417  */
418
419 static void rotate_right(dnode_t *upper)
420 {
421     dnode_t *lower, *lowright, *upparent;
422
423     lower = upper->left;
424     upper->left = lowright = lower->right;
425     lowright->parent = upper;
426
427     lower->parent = upparent = upper->parent;
428
429     if (upper == upparent->right) {
430         upparent->right = lower;
431     } else {
432         assert (upper == upparent->left);
433         upparent->left = lower;
434     }
435
436     lower->right = upper;
437     upper->parent = lower;
438 }
439
440 /*
441  * Do a postorder traversal of the tree rooted at the specified
442  * node and free everything under it.  Used by dict_free().
443  */
444
445 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
446 {
447     if (node == nil)
448         return;
449     free_nodes(dict, node->left, nil);
450     free_nodes(dict, node->right, nil);
451     dict->dict_freenode(node);
452 }
453
454 /*
455  * Verify that the tree contains the given node. This is done by
456  * traversing all of the nodes and comparing their pointers to the
457  * given pointer. Returns 1 if the node is found, otherwise
458  * returns zero. It is intended for debugging purposes.
459  */
460
461 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
462 {
463     if (root != nil) {
464         return root == node
465                 || verify_dict_has_node(nil, root->left, node)
466                 || verify_dict_has_node(nil, root->right, node);
467     }
468     return 0;
469 }
470
471
472 /*
473  * Select a different set of node allocator routines.
474  */
475
476 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
477 {
478     assert (dict_count(dict) == 0);
479     dict->dict_freenode = fr;
480 }
481
482 /*
483  * Free all the nodes in the dictionary by using the dictionary's
484  * installed free routine. The dictionary is emptied.
485  */
486
487 static void dict_free_nodes(dict_t *dict)
488 {
489     dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
490     free_nodes(dict, root, nil);
491     dict->dict_nodecount = 0;
492     dict->nilnode.left = &dict->nilnode;
493     dict->nilnode.right = &dict->nilnode;
494 }
495
496 /*
497  * Initialize a user-supplied dictionary object.
498  */
499
500 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
501 {
502     dict->compare = comp;
503     dict->dict_freenode = dnode_free;
504     dict->dict_nodecount = 0;
505     dict->maxcount = maxcount;
506     dict->nilnode.left = &dict->nilnode;
507     dict->nilnode.right = &dict->nilnode;
508     dict->nilnode.parent = &dict->nilnode;
509     dict->nilnode.color = dnode_black;
510     dict->dupes = 0;
511     return dict;
512 }
513
514 /*
515  * Locate a node in the dictionary having the given key.
516  * If the node is not found, a null a pointer is returned (rather than
517  * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
518  * located node is returned.
519  */
520
521 static dnode_t *dict_lookup(dict_t *dict, const void *key)
522 {
523     dnode_t *root = dict_root(dict);
524     dnode_t *nil = dict_nil(dict);
525     dnode_t *saved;
526     int result;
527
528     /* simple binary search adapted for trees that contain duplicate keys */
529
530     while (root != nil) {
531         result = dict->compare(key, root->key);
532         if (result < 0)
533             root = root->left;
534         else if (result > 0)
535             root = root->right;
536         else {
537             if (!dict->dupes) { /* no duplicates, return match          */
538                 return root;
539             } else {            /* could be dupes, find leftmost one    */
540                 do {
541                     saved = root;
542                     root = root->left;
543                     while (root != nil && dict->compare(key, root->key))
544                         root = root->right;
545                 } while (root != nil);
546                 return saved;
547             }
548         }
549     }
550
551     return NULL;
552 }
553
554 /*
555  * Insert a node into the dictionary. The node should have been
556  * initialized with a data field. All other fields are ignored.
557  * The behavior is undefined if the user attempts to insert into
558  * a dictionary that is already full (for which the dict_isfull()
559  * function returns true).
560  */
561
562 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
563 {
564     dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
565     dnode_t *parent = nil, *uncle, *grandpa;
566     int result = -1;
567
568     node->key = key;
569
570     /* basic binary tree insert */
571
572     while (where != nil) {
573         parent = where;
574         result = dict->compare(key, where->key);
575         /* trap attempts at duplicate key insertion unless it's explicitly allowed */
576         assert (dict->dupes || result != 0);
577         if (result < 0)
578             where = where->left;
579         else
580             where = where->right;
581     }
582
583     assert (where == nil);
584
585     if (result < 0)
586         parent->left = node;
587     else
588         parent->right = node;
589
590     node->parent = parent;
591     node->left = nil;
592     node->right = nil;
593
594     dict->dict_nodecount++;
595
596     /* red black adjustments */
597
598     node->color = dnode_red;
599
600     while (parent->color == dnode_red) {
601         grandpa = parent->parent;
602         if (parent == grandpa->left) {
603             uncle = grandpa->right;
604             if (uncle->color == dnode_red) {    /* red parent, red uncle */
605                 parent->color = dnode_black;
606                 uncle->color = dnode_black;
607                 grandpa->color = dnode_red;
608                 node = grandpa;
609                 parent = grandpa->parent;
610             } else {                            /* red parent, black uncle */
611                 if (node == parent->right) {
612                     rotate_left(parent);
613                     parent = node;
614                     assert (grandpa == parent->parent);
615                     /* rotation between parent and child preserves grandpa */
616                 }
617                 parent->color = dnode_black;
618                 grandpa->color = dnode_red;
619                 rotate_right(grandpa);
620                 break;
621             }
622         } else {        /* symmetric cases: parent == parent->parent->right */
623             uncle = grandpa->left;
624             if (uncle->color == dnode_red) {
625                 parent->color = dnode_black;
626                 uncle->color = dnode_black;
627                 grandpa->color = dnode_red;
628                 node = grandpa;
629                 parent = grandpa->parent;
630             } else {
631                 if (node == parent->left) {
632                     rotate_right(parent);
633                     parent = node;
634                     assert (grandpa == parent->parent);
635                 }
636                 parent->color = dnode_black;
637                 grandpa->color = dnode_red;
638                 rotate_left(grandpa);
639                 break;
640             }
641         }
642     }
643
644     dict_root(dict)->color = dnode_black;
645
646 }
647
648 /*
649  * Allocate a node using the dictionary's allocator routine, give it
650  * the data item.
651  */
652
653 static dnode_t *dnode_init(dnode_t *dnode, void *data)
654 {
655     dnode->data = data;
656     dnode->parent = NULL;
657     dnode->left = NULL;
658     dnode->right = NULL;
659     return dnode;
660 }
661
662 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
663 {
664     dnode_t *node = malloc(sizeof(dnode_t));
665
666     if (node) {
667         dnode_init(node, data);
668         dict_insert(dict, node, key);
669         return 1;
670     }
671     return 0;
672 }
673
674 /*
675  * Return the node with the lowest (leftmost) key. If the dictionary is empty
676  * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
677  */
678
679 static dnode_t *dict_first(dict_t *dict)
680 {
681     dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
682
683     if (root != nil)
684         while ((left = root->left) != nil)
685             root = left;
686
687     return (root == nil) ? NULL : root;
688 }
689
690 /*
691  * Return the given node's successor node---the node which has the
692  * next key in the the left to right ordering. If the node has
693  * no successor, a null pointer is returned rather than a pointer to
694  * the nil node.
695  */
696
697 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
698 {
699     dnode_t *nil = dict_nil(dict), *parent, *left;
700
701     if (curr->right != nil) {
702         curr = curr->right;
703         while ((left = curr->left) != nil)
704             curr = left;
705         return curr;
706     }
707
708     parent = curr->parent;
709
710     while (parent != nil && curr == parent->right) {
711         curr = parent;
712         parent = curr->parent;
713     }
714
715     return (parent == nil) ? NULL : parent;
716 }
717
718
719 static void dnode_free(dnode_t *node)
720 {
721     free(node);
722 }
723
724
725 #undef left
726 #undef right
727 #undef parent
728 #undef color
729 #undef key
730 #undef data
731
732 #undef nilnode
733 #undef maxcount
734 #undef compare
735 #undef dupes
736
737
738 /*
739  * dirinfo.c --- maintains the directory information table for e2fsck.
740  */
741
742 /*
743  * This subroutine is called during pass1 to create a directory info
744  * entry.  During pass1, the passed-in parent is 0; it will get filled
745  * in during pass2.
746  */
747 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
748 {
749         struct dir_info *dir;
750         int             i, j;
751         ext2_ino_t      num_dirs;
752         errcode_t       retval;
753         unsigned long   old_size;
754
755         if (!ctx->dir_info) {
756                 ctx->dir_info_count = 0;
757                 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
758                 if (retval)
759                         num_dirs = 1024;        /* Guess */
760                 ctx->dir_info_size = num_dirs + 10;
761                 ctx->dir_info  = (struct dir_info *)
762                         e2fsck_allocate_memory(ctx, ctx->dir_info_size
763                                                * sizeof (struct dir_info),
764                                                "directory map");
765         }
766
767         if (ctx->dir_info_count >= ctx->dir_info_size) {
768                 old_size = ctx->dir_info_size * sizeof(struct dir_info);
769                 ctx->dir_info_size += 10;
770                 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
771                                            sizeof(struct dir_info),
772                                            &ctx->dir_info);
773                 if (retval) {
774                         ctx->dir_info_size -= 10;
775                         return;
776                 }
777         }
778
779         /*
780          * Normally, add_dir_info is called with each inode in
781          * sequential order; but once in a while (like when pass 3
782          * needs to recreate the root directory or lost+found
783          * directory) it is called out of order.  In those cases, we
784          * need to move the dir_info entries down to make room, since
785          * the dir_info array needs to be sorted by inode number for
786          * get_dir_info()'s sake.
787          */
788         if (ctx->dir_info_count &&
789             ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
790                 for (i = ctx->dir_info_count-1; i > 0; i--)
791                         if (ctx->dir_info[i-1].ino < ino)
792                                 break;
793                 dir = &ctx->dir_info[i];
794                 if (dir->ino != ino)
795                         for (j = ctx->dir_info_count++; j > i; j--)
796                                 ctx->dir_info[j] = ctx->dir_info[j-1];
797         } else
798                 dir = &ctx->dir_info[ctx->dir_info_count++];
799
800         dir->ino = ino;
801         dir->dotdot = parent;
802         dir->parent = parent;
803 }
804
805 /*
806  * get_dir_info() --- given an inode number, try to find the directory
807  * information entry for it.
808  */
809 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
810 {
811         int     low, high, mid;
812
813         low = 0;
814         high = ctx->dir_info_count-1;
815         if (!ctx->dir_info)
816                 return 0;
817         if (ino == ctx->dir_info[low].ino)
818                 return &ctx->dir_info[low];
819         if  (ino == ctx->dir_info[high].ino)
820                 return &ctx->dir_info[high];
821
822         while (low < high) {
823                 mid = (low+high)/2;
824                 if (mid == low || mid == high)
825                         break;
826                 if (ino == ctx->dir_info[mid].ino)
827                         return &ctx->dir_info[mid];
828                 if (ino < ctx->dir_info[mid].ino)
829                         high = mid;
830                 else
831                         low = mid;
832         }
833         return 0;
834 }
835
836 /*
837  * Free the dir_info structure when it isn't needed any more.
838  */
839 static void e2fsck_free_dir_info(e2fsck_t ctx)
840 {
841         ext2fs_free_mem(&ctx->dir_info);
842         ctx->dir_info_size = 0;
843         ctx->dir_info_count = 0;
844 }
845
846 /*
847  * Return the count of number of directories in the dir_info structure
848  */
849 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
850 {
851         return ctx->dir_info_count;
852 }
853
854 /*
855  * A simple interator function
856  */
857 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
858 {
859         if (*control >= ctx->dir_info_count)
860                 return 0;
861
862         return(ctx->dir_info + (*control)++);
863 }
864
865 /*
866  * dirinfo.c --- maintains the directory information table for e2fsck.
867  *
868  */
869
870 #ifdef ENABLE_HTREE
871
872 /*
873  * This subroutine is called during pass1 to create a directory info
874  * entry.  During pass1, the passed-in parent is 0; it will get filled
875  * in during pass2.
876  */
877 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
878 {
879         struct dx_dir_info *dir;
880         int             i, j;
881         errcode_t       retval;
882         unsigned long   old_size;
883
884         if (!ctx->dx_dir_info) {
885                 ctx->dx_dir_info_count = 0;
886                 ctx->dx_dir_info_size = 100; /* Guess */
887                 ctx->dx_dir_info  = (struct dx_dir_info *)
888                         e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
889                                                * sizeof (struct dx_dir_info),
890                                                "directory map");
891         }
892
893         if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
894                 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
895                 ctx->dx_dir_info_size += 10;
896                 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
897                                            sizeof(struct dx_dir_info),
898                                            &ctx->dx_dir_info);
899                 if (retval) {
900                         ctx->dx_dir_info_size -= 10;
901                         return;
902                 }
903         }
904
905         /*
906          * Normally, add_dx_dir_info is called with each inode in
907          * sequential order; but once in a while (like when pass 3
908          * needs to recreate the root directory or lost+found
909          * directory) it is called out of order.  In those cases, we
910          * need to move the dx_dir_info entries down to make room, since
911          * the dx_dir_info array needs to be sorted by inode number for
912          * get_dx_dir_info()'s sake.
913          */
914         if (ctx->dx_dir_info_count &&
915             ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
916                 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
917                         if (ctx->dx_dir_info[i-1].ino < ino)
918                                 break;
919                 dir = &ctx->dx_dir_info[i];
920                 if (dir->ino != ino)
921                         for (j = ctx->dx_dir_info_count++; j > i; j--)
922                                 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
923         } else
924                 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
925
926         dir->ino = ino;
927         dir->numblocks = num_blocks;
928         dir->hashversion = 0;
929         dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
930                                        * sizeof (struct dx_dirblock_info),
931                                        "dx_block info array");
932
933 }
934
935 /*
936  * get_dx_dir_info() --- given an inode number, try to find the directory
937  * information entry for it.
938  */
939 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
940 {
941         int     low, high, mid;
942
943         low = 0;
944         high = ctx->dx_dir_info_count-1;
945         if (!ctx->dx_dir_info)
946                 return 0;
947         if (ino == ctx->dx_dir_info[low].ino)
948                 return &ctx->dx_dir_info[low];
949         if  (ino == ctx->dx_dir_info[high].ino)
950                 return &ctx->dx_dir_info[high];
951
952         while (low < high) {
953                 mid = (low+high)/2;
954                 if (mid == low || mid == high)
955                         break;
956                 if (ino == ctx->dx_dir_info[mid].ino)
957                         return &ctx->dx_dir_info[mid];
958                 if (ino < ctx->dx_dir_info[mid].ino)
959                         high = mid;
960                 else
961                         low = mid;
962         }
963         return 0;
964 }
965
966 /*
967  * Free the dx_dir_info structure when it isn't needed any more.
968  */
969 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
970 {
971         int     i;
972         struct dx_dir_info *dir;
973
974         if (ctx->dx_dir_info) {
975                 dir = ctx->dx_dir_info;
976                 for (i=0; i < ctx->dx_dir_info_count; i++) {
977                         ext2fs_free_mem(&dir->dx_block);
978                 }
979                 ext2fs_free_mem(&ctx->dx_dir_info);
980         }
981         ctx->dx_dir_info_size = 0;
982         ctx->dx_dir_info_count = 0;
983 }
984
985 /*
986  * A simple interator function
987  */
988 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
989 {
990         if (*control >= ctx->dx_dir_info_count)
991                 return 0;
992
993         return(ctx->dx_dir_info + (*control)++);
994 }
995
996 #endif /* ENABLE_HTREE */
997 /*
998  * e2fsck.c - a consistency checker for the new extended file system.
999  *
1000  */
1001
1002 /*
1003  * This function allocates an e2fsck context
1004  */
1005 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
1006 {
1007         e2fsck_t        context;
1008         errcode_t       retval;
1009
1010         retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
1011         if (retval)
1012                 return retval;
1013
1014         memset(context, 0, sizeof(struct e2fsck_struct));
1015
1016         context->process_inode_size = 256;
1017         context->ext_attr_ver = 2;
1018
1019         *ret = context;
1020         return 0;
1021 }
1022
1023 struct ea_refcount_el {
1024         blk_t   ea_blk;
1025         int     ea_count;
1026 };
1027
1028 struct ea_refcount {
1029         blk_t           count;
1030         blk_t           size;
1031         blk_t           cursor;
1032         struct ea_refcount_el   *list;
1033 };
1034
1035 static void ea_refcount_free(ext2_refcount_t refcount)
1036 {
1037         if (!refcount)
1038                 return;
1039
1040         ext2fs_free_mem(&refcount->list);
1041         ext2fs_free_mem(&refcount);
1042 }
1043
1044 /*
1045  * This function resets an e2fsck context; it is called when e2fsck
1046  * needs to be restarted.
1047  */
1048 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
1049 {
1050         ctx->flags = 0;
1051         ctx->lost_and_found = 0;
1052         ctx->bad_lost_and_found = 0;
1053         ext2fs_free_inode_bitmap(ctx->inode_used_map);
1054         ctx->inode_used_map = 0;
1055         ext2fs_free_inode_bitmap(ctx->inode_dir_map);
1056         ctx->inode_dir_map = 0;
1057         ext2fs_free_inode_bitmap(ctx->inode_reg_map);
1058         ctx->inode_reg_map = 0;
1059         ext2fs_free_block_bitmap(ctx->block_found_map);
1060         ctx->block_found_map = 0;
1061         ext2fs_free_icount(ctx->inode_link_info);
1062         ctx->inode_link_info = 0;
1063         if (ctx->journal_io) {
1064                 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1065                         io_channel_close(ctx->journal_io);
1066                 ctx->journal_io = 0;
1067         }
1068         if (ctx->fs) {
1069                 ext2fs_free_dblist(ctx->fs->dblist);
1070                 ctx->fs->dblist = 0;
1071         }
1072         e2fsck_free_dir_info(ctx);
1073 #ifdef ENABLE_HTREE
1074         e2fsck_free_dx_dir_info(ctx);
1075 #endif
1076         ea_refcount_free(ctx->refcount);
1077         ctx->refcount = 0;
1078         ea_refcount_free(ctx->refcount_extra);
1079         ctx->refcount_extra = 0;
1080         ext2fs_free_block_bitmap(ctx->block_dup_map);
1081         ctx->block_dup_map = 0;
1082         ext2fs_free_block_bitmap(ctx->block_ea_map);
1083         ctx->block_ea_map = 0;
1084         ext2fs_free_inode_bitmap(ctx->inode_bb_map);
1085         ctx->inode_bb_map = 0;
1086         ext2fs_free_inode_bitmap(ctx->inode_bad_map);
1087         ctx->inode_bad_map = 0;
1088         ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
1089         ctx->inode_imagic_map = 0;
1090         ext2fs_u32_list_free(ctx->dirs_to_hash);
1091         ctx->dirs_to_hash = 0;
1092
1093         /*
1094          * Clear the array of invalid meta-data flags
1095          */
1096         ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
1097         ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
1098         ext2fs_free_mem(&ctx->invalid_inode_table_flag);
1099
1100         /* Clear statistic counters */
1101         ctx->fs_directory_count = 0;
1102         ctx->fs_regular_count = 0;
1103         ctx->fs_blockdev_count = 0;
1104         ctx->fs_chardev_count = 0;
1105         ctx->fs_links_count = 0;
1106         ctx->fs_symlinks_count = 0;
1107         ctx->fs_fast_symlinks_count = 0;
1108         ctx->fs_fifo_count = 0;
1109         ctx->fs_total_count = 0;
1110         ctx->fs_badblocks_count = 0;
1111         ctx->fs_sockets_count = 0;
1112         ctx->fs_ind_count = 0;
1113         ctx->fs_dind_count = 0;
1114         ctx->fs_tind_count = 0;
1115         ctx->fs_fragmented = 0;
1116         ctx->large_files = 0;
1117
1118         /* Reset the superblock to the user's requested value */
1119         ctx->superblock = ctx->use_superblock;
1120
1121         return 0;
1122 }
1123
1124 static void e2fsck_free_context(e2fsck_t ctx)
1125 {
1126         if (!ctx)
1127                 return;
1128
1129         e2fsck_reset_context(ctx);
1130         if (ctx->blkid)
1131                 blkid_put_cache(ctx->blkid);
1132
1133         ext2fs_free_mem(&ctx);
1134 }
1135
1136 /*
1137  * ea_refcount.c
1138  */
1139
1140 /*
1141  * The strategy we use for keeping track of EA refcounts is as
1142  * follows.  We keep a sorted array of first EA blocks and its
1143  * reference counts.  Once the refcount has dropped to zero, it is
1144  * removed from the array to save memory space.  Once the EA block is
1145  * checked, its bit is set in the block_ea_map bitmap.
1146  */
1147
1148
1149 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1150 {
1151         ext2_refcount_t refcount;
1152         errcode_t       retval;
1153         size_t          bytes;
1154
1155         retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1156         if (retval)
1157                 return retval;
1158         memset(refcount, 0, sizeof(struct ea_refcount));
1159
1160         if (!size)
1161                 size = 500;
1162         refcount->size = size;
1163         bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1164 #ifdef DEBUG
1165         printf("Refcount allocated %d entries, %d bytes.\n",
1166                refcount->size, bytes);
1167 #endif
1168         retval = ext2fs_get_mem(bytes, &refcount->list);
1169         if (retval)
1170                 goto errout;
1171         memset(refcount->list, 0, bytes);
1172
1173         refcount->count = 0;
1174         refcount->cursor = 0;
1175
1176         *ret = refcount;
1177         return 0;
1178
1179 errout:
1180         ea_refcount_free(refcount);
1181         return(retval);
1182 }
1183
1184 /*
1185  * collapse_refcount() --- go through the refcount array, and get rid
1186  * of any count == zero entries
1187  */
1188 static void refcount_collapse(ext2_refcount_t refcount)
1189 {
1190         unsigned int    i, j;
1191         struct ea_refcount_el   *list;
1192
1193         list = refcount->list;
1194         for (i = 0, j = 0; i < refcount->count; i++) {
1195                 if (list[i].ea_count) {
1196                         if (i != j)
1197                                 list[j] = list[i];
1198                         j++;
1199                 }
1200         }
1201 #if defined(DEBUG) || defined(TEST_PROGRAM)
1202         printf("Refcount_collapse: size was %d, now %d\n",
1203                refcount->count, j);
1204 #endif
1205         refcount->count = j;
1206 }
1207
1208
1209 /*
1210  * insert_refcount_el() --- Insert a new entry into the sorted list at a
1211  *      specified position.
1212  */
1213 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1214                                                  blk_t blk, int pos)
1215 {
1216         struct ea_refcount_el   *el;
1217         errcode_t               retval;
1218         blk_t                   new_size = 0;
1219         int                     num;
1220
1221         if (refcount->count >= refcount->size) {
1222                 new_size = refcount->size + 100;
1223 #ifdef DEBUG
1224                 printf("Reallocating refcount %d entries...\n", new_size);
1225 #endif
1226                 retval = ext2fs_resize_mem((size_t) refcount->size *
1227                                            sizeof(struct ea_refcount_el),
1228                                            (size_t) new_size *
1229                                            sizeof(struct ea_refcount_el),
1230                                            &refcount->list);
1231                 if (retval)
1232                         return 0;
1233                 refcount->size = new_size;
1234         }
1235         num = (int) refcount->count - pos;
1236         if (num < 0)
1237                 return 0;       /* should never happen */
1238         if (num) {
1239                 memmove(&refcount->list[pos+1], &refcount->list[pos],
1240                         sizeof(struct ea_refcount_el) * num);
1241         }
1242         refcount->count++;
1243         el = &refcount->list[pos];
1244         el->ea_count = 0;
1245         el->ea_blk = blk;
1246         return el;
1247 }
1248
1249
1250 /*
1251  * get_refcount_el() --- given an block number, try to find refcount
1252  *      information in the sorted list.  If the create flag is set,
1253  *      and we can't find an entry, create one in the sorted list.
1254  */
1255 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1256                                               blk_t blk, int create)
1257 {
1258         float   range;
1259         int     low, high, mid;
1260         blk_t   lowval, highval;
1261
1262         if (!refcount || !refcount->list)
1263                 return 0;
1264 retry:
1265         low = 0;
1266         high = (int) refcount->count-1;
1267         if (create && ((refcount->count == 0) ||
1268                        (blk > refcount->list[high].ea_blk))) {
1269                 if (refcount->count >= refcount->size)
1270                         refcount_collapse(refcount);
1271
1272                 return insert_refcount_el(refcount, blk,
1273                                           (unsigned) refcount->count);
1274         }
1275         if (refcount->count == 0)
1276                 return 0;
1277
1278         if (refcount->cursor >= refcount->count)
1279                 refcount->cursor = 0;
1280         if (blk == refcount->list[refcount->cursor].ea_blk)
1281                 return &refcount->list[refcount->cursor++];
1282 #ifdef DEBUG
1283         printf("Non-cursor get_refcount_el: %u\n", blk);
1284 #endif
1285         while (low <= high) {
1286                 if (low == high)
1287                         mid = low;
1288                 else {
1289                         /* Interpolate for efficiency */
1290                         lowval = refcount->list[low].ea_blk;
1291                         highval = refcount->list[high].ea_blk;
1292
1293                         if (blk < lowval)
1294                                 range = 0;
1295                         else if (blk > highval)
1296                                 range = 1;
1297                         else
1298                                 range = ((float) (blk - lowval)) /
1299                                         (highval - lowval);
1300                         mid = low + ((int) (range * (high-low)));
1301                 }
1302
1303                 if (blk == refcount->list[mid].ea_blk) {
1304                         refcount->cursor = mid+1;
1305                         return &refcount->list[mid];
1306                 }
1307                 if (blk < refcount->list[mid].ea_blk)
1308                         high = mid-1;
1309                 else
1310                         low = mid+1;
1311         }
1312         /*
1313          * If we need to create a new entry, it should be right at
1314          * low (where high will be left at low-1).
1315          */
1316         if (create) {
1317                 if (refcount->count >= refcount->size) {
1318                         refcount_collapse(refcount);
1319                         if (refcount->count < refcount->size)
1320                                 goto retry;
1321                 }
1322                 return insert_refcount_el(refcount, blk, low);
1323         }
1324         return 0;
1325 }
1326
1327 static errcode_t
1328 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1329 {
1330         struct ea_refcount_el   *el;
1331
1332         el = get_refcount_el(refcount, blk, 1);
1333         if (!el)
1334                 return EXT2_ET_NO_MEMORY;
1335         el->ea_count++;
1336
1337         if (ret)
1338                 *ret = el->ea_count;
1339         return 0;
1340 }
1341
1342 static errcode_t
1343 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1344 {
1345         struct ea_refcount_el   *el;
1346
1347         el = get_refcount_el(refcount, blk, 0);
1348         if (!el || el->ea_count == 0)
1349                 return EXT2_ET_INVALID_ARGUMENT;
1350
1351         el->ea_count--;
1352
1353         if (ret)
1354                 *ret = el->ea_count;
1355         return 0;
1356 }
1357
1358 static errcode_t
1359 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1360 {
1361         struct ea_refcount_el   *el;
1362
1363         /*
1364          * Get the refcount element
1365          */
1366         el = get_refcount_el(refcount, blk, count ? 1 : 0);
1367         if (!el)
1368                 return count ? EXT2_ET_NO_MEMORY : 0;
1369         el->ea_count = count;
1370         return 0;
1371 }
1372
1373 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1374 {
1375         refcount->cursor = 0;
1376 }
1377
1378
1379 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1380 {
1381         struct ea_refcount_el   *list;
1382
1383         while (1) {
1384                 if (refcount->cursor >= refcount->count)
1385                         return 0;
1386                 list = refcount->list;
1387                 if (list[refcount->cursor].ea_count) {
1388                         if (ret)
1389                                 *ret = list[refcount->cursor].ea_count;
1390                         return list[refcount->cursor++].ea_blk;
1391                 }
1392                 refcount->cursor++;
1393         }
1394 }
1395
1396
1397 /*
1398  * ehandler.c --- handle bad block errors which come up during the
1399  *      course of an e2fsck session.
1400  */
1401
1402
1403 static const char *operation;
1404
1405 static errcode_t
1406 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1407                          void *data, size_t size FSCK_ATTR((unused)),
1408                          int actual FSCK_ATTR((unused)), errcode_t error)
1409 {
1410         int     i;
1411         char    *p;
1412         ext2_filsys fs = (ext2_filsys) channel->app_data;
1413         e2fsck_t ctx;
1414
1415         ctx = (e2fsck_t) fs->priv_data;
1416
1417         /*
1418          * If more than one block was read, try reading each block
1419          * separately.  We could use the actual bytes read to figure
1420          * out where to start, but we don't bother.
1421          */
1422         if (count > 1) {
1423                 p = (char *) data;
1424                 for (i=0; i < count; i++, p += channel->block_size, block++) {
1425                         error = io_channel_read_blk(channel, block,
1426                                                     1, p);
1427                         if (error)
1428                                 return error;
1429                 }
1430                 return 0;
1431         }
1432         if (operation)
1433                 printf(_("Error reading block %lu (%s) while %s.  "), block,
1434                        error_message(error), operation);
1435         else
1436                 printf(_("Error reading block %lu (%s).  "), block,
1437                        error_message(error));
1438         preenhalt(ctx);
1439         if (ask(ctx, _("Ignore error"), 1)) {
1440                 if (ask(ctx, _("Force rewrite"), 1))
1441                         io_channel_write_blk(channel, block, 1, data);
1442                 return 0;
1443         }
1444
1445         return error;
1446 }
1447
1448 static errcode_t
1449 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1450                         const void *data, size_t size FSCK_ATTR((unused)),
1451                         int actual FSCK_ATTR((unused)), errcode_t error)
1452 {
1453         int             i;
1454         const char      *p;
1455         ext2_filsys fs = (ext2_filsys) channel->app_data;
1456         e2fsck_t ctx;
1457
1458         ctx = (e2fsck_t) fs->priv_data;
1459
1460         /*
1461          * If more than one block was written, try writing each block
1462          * separately.  We could use the actual bytes read to figure
1463          * out where to start, but we don't bother.
1464          */
1465         if (count > 1) {
1466                 p = (const char *) data;
1467                 for (i=0; i < count; i++, p += channel->block_size, block++) {
1468                         error = io_channel_write_blk(channel, block,
1469                                                      1, p);
1470                         if (error)
1471                                 return error;
1472                 }
1473                 return 0;
1474         }
1475
1476         if (operation)
1477                 printf(_("Error writing block %lu (%s) while %s.  "), block,
1478                        error_message(error), operation);
1479         else
1480                 printf(_("Error writing block %lu (%s).  "), block,
1481                        error_message(error));
1482         preenhalt(ctx);
1483         if (ask(ctx, _("Ignore error"), 1))
1484                 return 0;
1485
1486         return error;
1487 }
1488
1489 static inline const char *ehandler_operation(const char *op)
1490 {
1491         const char *ret = operation;
1492
1493         operation = op;
1494         return ret;
1495 }
1496
1497 static void ehandler_init(io_channel channel)
1498 {
1499         channel->read_error = e2fsck_handle_read_error;
1500         channel->write_error = e2fsck_handle_write_error;
1501 }
1502
1503 /*
1504  * journal.c --- code for handling the "ext3" journal
1505  *
1506  * Copyright (C) 2000 Andreas Dilger
1507  * Copyright (C) 2000 Theodore Ts'o
1508  *
1509  * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1510  * Copyright (C) 1999 Red Hat Software
1511  *
1512  * This file may be redistributed under the terms of the
1513  * GNU General Public License version 2 or at your discretion
1514  * any later version.
1515  */
1516
1517 /*
1518  * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1519  * This creates a larger static binary, and a smaller binary using
1520  * shared libraries.  It's also probably slightly less CPU-efficient,
1521  * which is why it's not on by default.  But, it's a good way of
1522  * testing the functions in inode_io.c and fileio.c.
1523  */
1524 #undef USE_INODE_IO
1525
1526 /* Kernel compatibility functions for handling the journal.  These allow us
1527  * to use the recovery.c file virtually unchanged from the kernel, so we
1528  * don't have to do much to keep kernel and user recovery in sync.
1529  */
1530 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1531 {
1532 #ifdef USE_INODE_IO
1533         *phys = block;
1534         return 0;
1535 #else
1536         struct inode    *inode = journal->j_inode;
1537         errcode_t       retval;
1538         blk_t           pblk;
1539
1540         if (!inode) {
1541                 *phys = block;
1542                 return 0;
1543         }
1544
1545         retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1546                             &inode->i_ext2, NULL, 0, block, &pblk);
1547         *phys = pblk;
1548         return (retval);
1549 #endif
1550 }
1551
1552 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1553 {
1554         struct buffer_head *bh;
1555
1556         bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1557         if (!bh)
1558                 return NULL;
1559
1560         bh->b_ctx = kdev->k_ctx;
1561         if (kdev->k_dev == K_DEV_FS)
1562                 bh->b_io = kdev->k_ctx->fs->io;
1563         else
1564                 bh->b_io = kdev->k_ctx->journal_io;
1565         bh->b_size = blocksize;
1566         bh->b_blocknr = blocknr;
1567
1568         return bh;
1569 }
1570
1571 static void sync_blockdev(kdev_t kdev)
1572 {
1573         io_channel      io;
1574
1575         if (kdev->k_dev == K_DEV_FS)
1576                 io = kdev->k_ctx->fs->io;
1577         else
1578                 io = kdev->k_ctx->journal_io;
1579
1580         io_channel_flush(io);
1581 }
1582
1583 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1584 {
1585         int retval;
1586         struct buffer_head *bh;
1587
1588         for (; nr > 0; --nr) {
1589                 bh = *bhp++;
1590                 if (rw == READ && !bh->b_uptodate) {
1591                         retval = io_channel_read_blk(bh->b_io,
1592                                                      bh->b_blocknr,
1593                                                      1, bh->b_data);
1594                         if (retval) {
1595                                 bb_error_msg("while reading block %lu\n",
1596                                         (unsigned long) bh->b_blocknr);
1597                                 bh->b_err = retval;
1598                                 continue;
1599                         }
1600                         bh->b_uptodate = 1;
1601                 } else if (rw == WRITE && bh->b_dirty) {
1602                         retval = io_channel_write_blk(bh->b_io,
1603                                                       bh->b_blocknr,
1604                                                       1, bh->b_data);
1605                         if (retval) {
1606                                 bb_error_msg("while writing block %lu\n",
1607                                         (unsigned long) bh->b_blocknr);
1608                                 bh->b_err = retval;
1609                                 continue;
1610                         }
1611                         bh->b_dirty = 0;
1612                         bh->b_uptodate = 1;
1613                 }
1614         }
1615 }
1616
1617 static inline void mark_buffer_dirty(struct buffer_head *bh)
1618 {
1619         bh->b_dirty = 1;
1620 }
1621
1622 static inline void mark_buffer_clean(struct buffer_head * bh)
1623 {
1624         bh->b_dirty = 0;
1625 }
1626
1627 static void brelse(struct buffer_head *bh)
1628 {
1629         if (bh->b_dirty)
1630                 ll_rw_block(WRITE, 1, &bh);
1631         ext2fs_free_mem(&bh);
1632 }
1633
1634 static inline int buffer_uptodate(struct buffer_head *bh)
1635 {
1636         return bh->b_uptodate;
1637 }
1638
1639 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1640 {
1641         bh->b_uptodate = val;
1642 }
1643
1644 static void wait_on_buffer(struct buffer_head *bh)
1645 {
1646         if (!bh->b_uptodate)
1647                 ll_rw_block(READ, 1, &bh);
1648 }
1649
1650
1651 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1652 {
1653         ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1654
1655         /* if we had an error doing journal recovery, we need a full fsck */
1656         if (error)
1657                 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1658         ext2fs_mark_super_dirty(ctx->fs);
1659 }
1660
1661 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1662 {
1663         struct ext2_super_block *sb = ctx->fs->super;
1664         struct ext2_super_block jsuper;
1665         struct problem_context  pctx;
1666         struct buffer_head      *bh;
1667         struct inode            *j_inode = NULL;
1668         struct kdev_s           *dev_fs = NULL, *dev_journal;
1669         const char              *journal_name = 0;
1670         journal_t               *journal = NULL;
1671         errcode_t               retval = 0;
1672         io_manager              io_ptr = 0;
1673         unsigned long           start = 0;
1674         blk_t                   blk;
1675         int                     ext_journal = 0;
1676         int                     tried_backup_jnl = 0;
1677         int                     i;
1678
1679         clear_problem_context(&pctx);
1680
1681         journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1682         if (!journal) {
1683                 return EXT2_ET_NO_MEMORY;
1684         }
1685
1686         dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1687         if (!dev_fs) {
1688                 retval = EXT2_ET_NO_MEMORY;
1689                 goto errout;
1690         }
1691         dev_journal = dev_fs+1;
1692
1693         dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1694         dev_fs->k_dev = K_DEV_FS;
1695         dev_journal->k_dev = K_DEV_JOURNAL;
1696
1697         journal->j_dev = dev_journal;
1698         journal->j_fs_dev = dev_fs;
1699         journal->j_inode = NULL;
1700         journal->j_blocksize = ctx->fs->blocksize;
1701
1702         if (uuid_is_null(sb->s_journal_uuid)) {
1703                 if (!sb->s_journal_inum)
1704                         return EXT2_ET_BAD_INODE_NUM;
1705                 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1706                                                  "journal inode");
1707                 if (!j_inode) {
1708                         retval = EXT2_ET_NO_MEMORY;
1709                         goto errout;
1710                 }
1711
1712                 j_inode->i_ctx = ctx;
1713                 j_inode->i_ino = sb->s_journal_inum;
1714
1715                 if ((retval = ext2fs_read_inode(ctx->fs,
1716                                                 sb->s_journal_inum,
1717                                                 &j_inode->i_ext2))) {
1718                 try_backup_journal:
1719                         if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1720                             tried_backup_jnl)
1721                                 goto errout;
1722                         memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1723                         memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1724                                EXT2_N_BLOCKS*4);
1725                         j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1726                         j_inode->i_ext2.i_links_count = 1;
1727                         j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1728                         tried_backup_jnl++;
1729                 }
1730                 if (!j_inode->i_ext2.i_links_count ||
1731                     !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1732                         retval = EXT2_ET_NO_JOURNAL;
1733                         goto try_backup_journal;
1734                 }
1735                 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1736                     JFS_MIN_JOURNAL_BLOCKS) {
1737                         retval = EXT2_ET_JOURNAL_TOO_SMALL;
1738                         goto try_backup_journal;
1739                 }
1740                 for (i=0; i < EXT2_N_BLOCKS; i++) {
1741                         blk = j_inode->i_ext2.i_block[i];
1742                         if (!blk) {
1743                                 if (i < EXT2_NDIR_BLOCKS) {
1744                                         retval = EXT2_ET_JOURNAL_TOO_SMALL;
1745                                         goto try_backup_journal;
1746                                 }
1747                                 continue;
1748                         }
1749                         if (blk < sb->s_first_data_block ||
1750                             blk >= sb->s_blocks_count) {
1751                                 retval = EXT2_ET_BAD_BLOCK_NUM;
1752                                 goto try_backup_journal;
1753                         }
1754                 }
1755                 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1756
1757 #ifdef USE_INODE_IO
1758                 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1759                                                  &j_inode->i_ext2,
1760                                                  &journal_name);
1761                 if (retval)
1762                         goto errout;
1763
1764                 io_ptr = inode_io_manager;
1765 #else
1766                 journal->j_inode = j_inode;
1767                 ctx->journal_io = ctx->fs->io;
1768                 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1769                         goto errout;
1770 #endif
1771         } else {
1772                 ext_journal = 1;
1773                 if (!ctx->journal_name) {
1774                         char uuid[37];
1775
1776                         uuid_unparse(sb->s_journal_uuid, uuid);
1777                         ctx->journal_name = blkid_get_devname(ctx->blkid,
1778                                                               "UUID", uuid);
1779                         if (!ctx->journal_name)
1780                                 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1781                 }
1782                 journal_name = ctx->journal_name;
1783
1784                 if (!journal_name) {
1785                         fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1786                         return EXT2_ET_LOAD_EXT_JOURNAL;
1787                 }
1788
1789                 io_ptr = unix_io_manager;
1790         }
1791
1792 #ifndef USE_INODE_IO
1793         if (ext_journal)
1794 #endif
1795                 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1796                                       &ctx->journal_io);
1797         if (retval)
1798                 goto errout;
1799
1800         io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1801
1802         if (ext_journal) {
1803                 if (ctx->fs->blocksize == 1024)
1804                         start = 1;
1805                 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1806                 if (!bh) {
1807                         retval = EXT2_ET_NO_MEMORY;
1808                         goto errout;
1809                 }
1810                 ll_rw_block(READ, 1, &bh);
1811                 if ((retval = bh->b_err) != 0)
1812                         goto errout;
1813                 memcpy(&jsuper, start ? bh->b_data :  bh->b_data + 1024,
1814                        sizeof(jsuper));
1815                 brelse(bh);
1816 #if BB_BIG_ENDIAN
1817                 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1818                         ext2fs_swap_super(&jsuper);
1819 #endif
1820                 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1821                     !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1822                         fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1823                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
1824                         goto errout;
1825                 }
1826                 /* Make sure the journal UUID is correct */
1827                 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1828                            sizeof(jsuper.s_uuid))) {
1829                         fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1830                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
1831                         goto errout;
1832                 }
1833
1834                 journal->j_maxlen = jsuper.s_blocks_count;
1835                 start++;
1836         }
1837
1838         if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1839                 retval = EXT2_ET_NO_MEMORY;
1840                 goto errout;
1841         }
1842
1843         journal->j_sb_buffer = bh;
1844         journal->j_superblock = (journal_superblock_t *)bh->b_data;
1845
1846 #ifdef USE_INODE_IO
1847         ext2fs_free_mem(&j_inode);
1848 #endif
1849
1850         *ret_journal = journal;
1851         return 0;
1852
1853 errout:
1854         ext2fs_free_mem(&dev_fs);
1855         ext2fs_free_mem(&j_inode);
1856         ext2fs_free_mem(&journal);
1857         return retval;
1858
1859 }
1860
1861 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1862                                               struct problem_context *pctx)
1863 {
1864         struct ext2_super_block *sb = ctx->fs->super;
1865         int recover = ctx->fs->super->s_feature_incompat &
1866                 EXT3_FEATURE_INCOMPAT_RECOVER;
1867         int has_journal = ctx->fs->super->s_feature_compat &
1868                 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1869
1870         if (has_journal || sb->s_journal_inum) {
1871                 /* The journal inode is bogus, remove and force full fsck */
1872                 pctx->ino = sb->s_journal_inum;
1873                 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1874                         if (has_journal && sb->s_journal_inum)
1875                                 printf("*** ext3 journal has been deleted - "
1876                                        "filesystem is now ext2 only ***\n\n");
1877                         sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1878                         sb->s_journal_inum = 0;
1879                         ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1880                         e2fsck_clear_recover(ctx, 1);
1881                         return 0;
1882                 }
1883                 return EXT2_ET_BAD_INODE_NUM;
1884         } else if (recover) {
1885                 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1886                         e2fsck_clear_recover(ctx, 1);
1887                         return 0;
1888                 }
1889                 return EXT2_ET_UNSUPP_FEATURE;
1890         }
1891         return 0;
1892 }
1893
1894 #define V1_SB_SIZE      0x0024
1895 static void clear_v2_journal_fields(journal_t *journal)
1896 {
1897         e2fsck_t ctx = journal->j_dev->k_ctx;
1898         struct problem_context pctx;
1899
1900         clear_problem_context(&pctx);
1901
1902         if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1903                 return;
1904
1905         memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1906                ctx->fs->blocksize-V1_SB_SIZE);
1907         mark_buffer_dirty(journal->j_sb_buffer);
1908 }
1909
1910
1911 static errcode_t e2fsck_journal_load(journal_t *journal)
1912 {
1913         e2fsck_t ctx = journal->j_dev->k_ctx;
1914         journal_superblock_t *jsb;
1915         struct buffer_head *jbh = journal->j_sb_buffer;
1916         struct problem_context pctx;
1917
1918         clear_problem_context(&pctx);
1919
1920         ll_rw_block(READ, 1, &jbh);
1921         if (jbh->b_err) {
1922                 bb_error_msg(_("reading journal superblock\n"));
1923                 return jbh->b_err;
1924         }
1925
1926         jsb = journal->j_superblock;
1927         /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1928         if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1929                 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1930
1931         switch (ntohl(jsb->s_header.h_blocktype)) {
1932         case JFS_SUPERBLOCK_V1:
1933                 journal->j_format_version = 1;
1934                 if (jsb->s_feature_compat ||
1935                     jsb->s_feature_incompat ||
1936                     jsb->s_feature_ro_compat ||
1937                     jsb->s_nr_users)
1938                         clear_v2_journal_fields(journal);
1939                 break;
1940
1941         case JFS_SUPERBLOCK_V2:
1942                 journal->j_format_version = 2;
1943                 if (ntohl(jsb->s_nr_users) > 1 &&
1944                     uuid_is_null(ctx->fs->super->s_journal_uuid))
1945                         clear_v2_journal_fields(journal);
1946                 if (ntohl(jsb->s_nr_users) > 1) {
1947                         fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1948                         return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1949                 }
1950                 break;
1951
1952         /*
1953          * These should never appear in a journal super block, so if
1954          * they do, the journal is badly corrupted.
1955          */
1956         case JFS_DESCRIPTOR_BLOCK:
1957         case JFS_COMMIT_BLOCK:
1958         case JFS_REVOKE_BLOCK:
1959                 return EXT2_ET_CORRUPT_SUPERBLOCK;
1960
1961         /* If we don't understand the superblock major type, but there
1962          * is a magic number, then it is likely to be a new format we
1963          * just don't understand, so leave it alone. */
1964         default:
1965                 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1966         }
1967
1968         if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1969                 return EXT2_ET_UNSUPP_FEATURE;
1970
1971         if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1972                 return EXT2_ET_RO_UNSUPP_FEATURE;
1973
1974         /* We have now checked whether we know enough about the journal
1975          * format to be able to proceed safely, so any other checks that
1976          * fail we should attempt to recover from. */
1977         if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1978                 bb_error_msg(_("%s: no valid journal superblock found\n"),
1979                         ctx->device_name);
1980                 return EXT2_ET_CORRUPT_SUPERBLOCK;
1981         }
1982
1983         if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1984                 journal->j_maxlen = ntohl(jsb->s_maxlen);
1985         else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1986                 bb_error_msg(_("%s: journal too short\n"),
1987                         ctx->device_name);
1988                 return EXT2_ET_CORRUPT_SUPERBLOCK;
1989         }
1990
1991         journal->j_tail_sequence = ntohl(jsb->s_sequence);
1992         journal->j_transaction_sequence = journal->j_tail_sequence;
1993         journal->j_tail = ntohl(jsb->s_start);
1994         journal->j_first = ntohl(jsb->s_first);
1995         journal->j_last = ntohl(jsb->s_maxlen);
1996
1997         return 0;
1998 }
1999
2000 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
2001                                        journal_t *journal)
2002 {
2003         char *p;
2004         union {
2005                 uuid_t uuid;
2006                 __u32 val[4];
2007         } u;
2008         __u32 new_seq = 0;
2009         int i;
2010
2011         /* Leave a valid existing V1 superblock signature alone.
2012          * Anything unrecognisable we overwrite with a new V2
2013          * signature. */
2014
2015         if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
2016             jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
2017                 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
2018                 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
2019         }
2020
2021         /* Zero out everything else beyond the superblock header */
2022
2023         p = ((char *) jsb) + sizeof(journal_header_t);
2024         memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
2025
2026         jsb->s_blocksize = htonl(ctx->fs->blocksize);
2027         jsb->s_maxlen = htonl(journal->j_maxlen);
2028         jsb->s_first = htonl(1);
2029
2030         /* Initialize the journal sequence number so that there is "no"
2031          * chance we will find old "valid" transactions in the journal.
2032          * This avoids the need to zero the whole journal (slow to do,
2033          * and risky when we are just recovering the filesystem).
2034          */
2035         uuid_generate(u.uuid);
2036         for (i = 0; i < 4; i ++)
2037                 new_seq ^= u.val[i];
2038         jsb->s_sequence = htonl(new_seq);
2039
2040         mark_buffer_dirty(journal->j_sb_buffer);
2041         ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
2042 }
2043
2044 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
2045                                                   journal_t *journal,
2046                                                   struct problem_context *pctx)
2047 {
2048         struct ext2_super_block *sb = ctx->fs->super;
2049         int recover = ctx->fs->super->s_feature_incompat &
2050                 EXT3_FEATURE_INCOMPAT_RECOVER;
2051
2052         if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
2053                 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
2054                         e2fsck_journal_reset_super(ctx, journal->j_superblock,
2055                                                    journal);
2056                         journal->j_transaction_sequence = 1;
2057                         e2fsck_clear_recover(ctx, recover);
2058                         return 0;
2059                 }
2060                 return EXT2_ET_CORRUPT_SUPERBLOCK;
2061         } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
2062                 return EXT2_ET_CORRUPT_SUPERBLOCK;
2063
2064         return 0;
2065 }
2066
2067 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
2068                                    int reset, int drop)
2069 {
2070         journal_superblock_t *jsb;
2071
2072         if (drop)
2073                 mark_buffer_clean(journal->j_sb_buffer);
2074         else if (!(ctx->options & E2F_OPT_READONLY)) {
2075                 jsb = journal->j_superblock;
2076                 jsb->s_sequence = htonl(journal->j_transaction_sequence);
2077                 if (reset)
2078                         jsb->s_start = 0; /* this marks the journal as empty */
2079                 mark_buffer_dirty(journal->j_sb_buffer);
2080         }
2081         brelse(journal->j_sb_buffer);
2082
2083         if (ctx->journal_io) {
2084                 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2085                         io_channel_close(ctx->journal_io);
2086                 ctx->journal_io = 0;
2087         }
2088
2089 #ifndef USE_INODE_IO
2090         ext2fs_free_mem(&journal->j_inode);
2091 #endif
2092         ext2fs_free_mem(&journal->j_fs_dev);
2093         ext2fs_free_mem(&journal);
2094 }
2095
2096 /*
2097  * This function makes sure that the superblock fields regarding the
2098  * journal are consistent.
2099  */
2100 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
2101 {
2102         struct ext2_super_block *sb = ctx->fs->super;
2103         journal_t *journal;
2104         int recover = ctx->fs->super->s_feature_incompat &
2105                 EXT3_FEATURE_INCOMPAT_RECOVER;
2106         struct problem_context pctx;
2107         problem_t problem;
2108         int reset = 0, force_fsck = 0;
2109         int retval;
2110
2111         /* If we don't have any journal features, don't do anything more */
2112         if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
2113             !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
2114             uuid_is_null(sb->s_journal_uuid))
2115                 return 0;
2116
2117         clear_problem_context(&pctx);
2118         pctx.num = sb->s_journal_inum;
2119
2120         retval = e2fsck_get_journal(ctx, &journal);
2121         if (retval) {
2122                 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2123                     (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2124                     (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2125                     (retval == EXT2_ET_NO_JOURNAL))
2126                         return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2127                 return retval;
2128         }
2129
2130         retval = e2fsck_journal_load(journal);
2131         if (retval) {
2132                 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2133                     ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2134                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2135                                   &pctx))) ||
2136                     ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2137                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2138                                   &pctx))) ||
2139                     ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2140                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2141                         retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2142                                                                   &pctx);
2143                 e2fsck_journal_release(ctx, journal, 0, 1);
2144                 return retval;
2145         }
2146
2147         /*
2148          * We want to make the flags consistent here.  We will not leave with
2149          * needs_recovery set but has_journal clear.  We can't get in a loop
2150          * with -y, -n, or -p, only if a user isn't making up their mind.
2151          */
2152 no_has_journal:
2153         if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2154                 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2155                 pctx.str = "inode";
2156                 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2157                         if (recover &&
2158                             !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2159                                 goto no_has_journal;
2160                         /*
2161                          * Need a full fsck if we are releasing a
2162                          * journal stored on a reserved inode.
2163                          */
2164                         force_fsck = recover ||
2165                                 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2166                         /* Clear all of the journal fields */
2167                         sb->s_journal_inum = 0;
2168                         sb->s_journal_dev = 0;
2169                         memset(sb->s_journal_uuid, 0,
2170                                sizeof(sb->s_journal_uuid));
2171                         e2fsck_clear_recover(ctx, force_fsck);
2172                 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2173                         sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2174                         ext2fs_mark_super_dirty(ctx->fs);
2175                 }
2176         }
2177
2178         if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2179             !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2180             journal->j_superblock->s_start != 0) {
2181                 /* Print status information */
2182                 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2183                 if (ctx->superblock)
2184                         problem = PR_0_JOURNAL_RUN_DEFAULT;
2185                 else
2186                         problem = PR_0_JOURNAL_RUN;
2187                 if (fix_problem(ctx, problem, &pctx)) {
2188                         ctx->options |= E2F_OPT_FORCE;
2189                         sb->s_feature_incompat |=
2190                                 EXT3_FEATURE_INCOMPAT_RECOVER;
2191                         ext2fs_mark_super_dirty(ctx->fs);
2192                 } else if (fix_problem(ctx,
2193                                        PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2194                         reset = 1;
2195                         sb->s_state &= ~EXT2_VALID_FS;
2196                         ext2fs_mark_super_dirty(ctx->fs);
2197                 }
2198                 /*
2199                  * If the user answers no to the above question, we
2200                  * ignore the fact that journal apparently has data;
2201                  * accidentally replaying over valid data would be far
2202                  * worse than skipping a questionable recovery.
2203                  *
2204                  * XXX should we abort with a fatal error here?  What
2205                  * will the ext3 kernel code do if a filesystem with
2206                  * !NEEDS_RECOVERY but with a non-zero
2207                  * journal->j_superblock->s_start is mounted?
2208                  */
2209         }
2210
2211         e2fsck_journal_release(ctx, journal, reset, 0);
2212         return retval;
2213 }
2214
2215 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2216 {
2217         journal_t *journal;
2218         int retval;
2219
2220         journal_init_revoke_caches();
2221         retval = e2fsck_get_journal(ctx, &journal);
2222         if (retval)
2223                 return retval;
2224
2225         retval = e2fsck_journal_load(journal);
2226         if (retval)
2227                 goto errout;
2228
2229         retval = journal_init_revoke(journal, 1024);
2230         if (retval)
2231                 goto errout;
2232
2233         retval = -journal_recover(journal);
2234         if (retval)
2235                 goto errout;
2236
2237         if (journal->j_superblock->s_errno) {
2238                 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2239                 ext2fs_mark_super_dirty(ctx->fs);
2240                 journal->j_superblock->s_errno = 0;
2241                 mark_buffer_dirty(journal->j_sb_buffer);
2242         }
2243
2244 errout:
2245         journal_destroy_revoke(journal);
2246         journal_destroy_revoke_caches();
2247         e2fsck_journal_release(ctx, journal, 1, 0);
2248         return retval;
2249 }
2250
2251 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2252 {
2253         io_manager io_ptr = ctx->fs->io->manager;
2254         int blocksize = ctx->fs->blocksize;
2255         errcode_t       retval, recover_retval;
2256
2257         printf(_("%s: recovering journal\n"), ctx->device_name);
2258         if (ctx->options & E2F_OPT_READONLY) {
2259                 printf(_("%s: won't do journal recovery while read-only\n"),
2260                        ctx->device_name);
2261                 return EXT2_ET_FILE_RO;
2262         }
2263
2264         if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2265                 ext2fs_flush(ctx->fs);  /* Force out any modifications */
2266
2267         recover_retval = recover_ext3_journal(ctx);
2268
2269         /*
2270          * Reload the filesystem context to get up-to-date data from disk
2271          * because journal recovery will change the filesystem under us.
2272          */
2273         ext2fs_close(ctx->fs);
2274         retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2275                              ctx->superblock, blocksize, io_ptr,
2276                              &ctx->fs);
2277
2278         if (retval) {
2279                 bb_error_msg(_("while trying to re-open %s"),
2280                         ctx->device_name);
2281                 bb_error_msg_and_die(0);
2282         }
2283         ctx->fs->priv_data = ctx;
2284
2285         /* Set the superblock flags */
2286         e2fsck_clear_recover(ctx, recover_retval);
2287         return recover_retval;
2288 }
2289
2290 /*
2291  * This function will move the journal inode from a visible file in
2292  * the filesystem directory hierarchy to the reserved inode if necessary.
2293  */
2294 static const char * const journal_names[] = {
2295         ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2296
2297 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2298 {
2299         struct ext2_super_block *sb = ctx->fs->super;
2300         struct problem_context  pctx;
2301         struct ext2_inode       inode;
2302         ext2_filsys             fs = ctx->fs;
2303         ext2_ino_t              ino;
2304         errcode_t               retval;
2305         const char * const *    cpp;
2306         int                     group, mount_flags;
2307
2308         clear_problem_context(&pctx);
2309
2310         /*
2311          * If the filesystem is opened read-only, or there is no
2312          * journal, then do nothing.
2313          */
2314         if ((ctx->options & E2F_OPT_READONLY) ||
2315             (sb->s_journal_inum == 0) ||
2316             !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2317                 return;
2318
2319         /*
2320          * Read in the journal inode
2321          */
2322         if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2323                 return;
2324
2325         /*
2326          * If it's necessary to backup the journal inode, do so.
2327          */
2328         if ((sb->s_jnl_backup_type == 0) ||
2329             ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2330              memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2331                 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2332                         memcpy(sb->s_jnl_blocks, inode.i_block,
2333                                EXT2_N_BLOCKS*4);
2334                         sb->s_jnl_blocks[16] = inode.i_size;
2335                         sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2336                         ext2fs_mark_super_dirty(fs);
2337                         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2338                 }
2339         }
2340
2341         /*
2342          * If the journal is already the hidden inode, then do nothing
2343          */
2344         if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2345                 return;
2346
2347         /*
2348          * The journal inode had better have only one link and not be readable.
2349          */
2350         if (inode.i_links_count != 1)
2351                 return;
2352
2353         /*
2354          * If the filesystem is mounted, or we can't tell whether
2355          * or not it's mounted, do nothing.
2356          */
2357         retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2358         if (retval || (mount_flags & EXT2_MF_MOUNTED))
2359                 return;
2360
2361         /*
2362          * If we can't find the name of the journal inode, then do
2363          * nothing.
2364          */
2365         for (cpp = journal_names; *cpp; cpp++) {
2366                 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2367                                        strlen(*cpp), 0, &ino);
2368                 if ((retval == 0) && (ino == sb->s_journal_inum))
2369                         break;
2370         }
2371         if (*cpp == 0)
2372                 return;
2373
2374         /* We need the inode bitmap to be loaded */
2375         retval = ext2fs_read_bitmaps(fs);
2376         if (retval)
2377                 return;
2378
2379         pctx.str = *cpp;
2380         if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2381                 return;
2382
2383         /*
2384          * OK, we've done all the checks, let's actually move the
2385          * journal inode.  Errors at this point mean we need to force
2386          * an ext2 filesystem check.
2387          */
2388         if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2389                 goto err_out;
2390         if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2391                 goto err_out;
2392         sb->s_journal_inum = EXT2_JOURNAL_INO;
2393         ext2fs_mark_super_dirty(fs);
2394         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2395         inode.i_links_count = 0;
2396         inode.i_dtime = time(0);
2397         if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2398                 goto err_out;
2399
2400         group = ext2fs_group_of_ino(fs, ino);
2401         ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2402         ext2fs_mark_ib_dirty(fs);
2403         fs->group_desc[group].bg_free_inodes_count++;
2404         fs->super->s_free_inodes_count++;
2405         return;
2406
2407 err_out:
2408         pctx.errcode = retval;
2409         fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2410         fs->super->s_state &= ~EXT2_VALID_FS;
2411         ext2fs_mark_super_dirty(fs);
2412         return;
2413 }
2414
2415 /*
2416  * message.c --- print e2fsck messages (with compression)
2417  *
2418  * print_e2fsck_message() prints a message to the user, using
2419  * compression techniques and expansions of abbreviations.
2420  *
2421  * The following % expansions are supported:
2422  *
2423  *      %b      <blk>                   block number
2424  *      %B      <blkcount>              integer
2425  *      %c      <blk2>                  block number
2426  *      %Di     <dirent>->ino           inode number
2427  *      %Dn     <dirent>->name          string
2428  *      %Dr     <dirent>->rec_len
2429  *      %Dl     <dirent>->name_len
2430  *      %Dt     <dirent>->filetype
2431  *      %d      <dir>                   inode number
2432  *      %g      <group>                 integer
2433  *      %i      <ino>                   inode number
2434  *      %Is     <inode> -> i_size
2435  *      %IS     <inode> -> i_extra_isize
2436  *      %Ib     <inode> -> i_blocks
2437  *      %Il     <inode> -> i_links_count
2438  *      %Im     <inode> -> i_mode
2439  *      %IM     <inode> -> i_mtime
2440  *      %IF     <inode> -> i_faddr
2441  *      %If     <inode> -> i_file_acl
2442  *      %Id     <inode> -> i_dir_acl
2443  *      %Iu     <inode> -> i_uid
2444  *      %Ig     <inode> -> i_gid
2445  *      %j      <ino2>                  inode number
2446  *      %m      <com_err error message>
2447  *      %N      <num>
2448  *      %p      ext2fs_get_pathname of directory <ino>
2449  *      %P      ext2fs_get_pathname of <dirent>->ino with <ino2> as
2450  *                      the containing directory.  (If dirent is NULL
2451  *                      then return the pathname of directory <ino2>)
2452  *      %q      ext2fs_get_pathname of directory <dir>
2453  *      %Q      ext2fs_get_pathname of directory <ino> with <dir> as
2454  *                      the containing directory.
2455  *      %s      <str>                   miscellaneous string
2456  *      %S      backup superblock
2457  *      %X      <num> hexadecimal format
2458  *
2459  * The following '@' expansions are supported:
2460  *
2461  *      @a      extended attribute
2462  *      @A      error allocating
2463  *      @b      block
2464  *      @B      bitmap
2465  *      @c      compress
2466  *      @C      conflicts with some other fs block
2467  *      @D      deleted
2468  *      @d      directory
2469  *      @e      entry
2470  *      @E      Entry '%Dn' in %p (%i)
2471  *      @f      filesystem
2472  *      @F      for @i %i (%Q) is
2473  *      @g      group
2474  *      @h      HTREE directory inode
2475  *      @i      inode
2476  *      @I      illegal
2477  *      @j      journal
2478  *      @l      lost+found
2479  *      @L      is a link
2480  *      @m      multiply-claimed
2481  *      @n      invalid
2482  *      @o      orphaned
2483  *      @p      problem in
2484  *      @r      root inode
2485  *      @s      should be
2486  *      @S      superblock
2487  *      @u      unattached
2488  *      @v      device
2489  *      @z      zero-length
2490  */
2491
2492
2493 /*
2494  * This structure defines the abbreviations used by the text strings
2495  * below.  The first character in the string is the index letter.  An
2496  * abbreviation of the form '@<i>' is expanded by looking up the index
2497  * letter <i> in the table below.
2498  */
2499 static const char * const abbrevs[] = {
2500         N_("aextended attribute"),
2501         N_("Aerror allocating"),
2502         N_("bblock"),
2503         N_("Bbitmap"),
2504         N_("ccompress"),
2505         N_("Cconflicts with some other fs @b"),
2506         N_("iinode"),
2507         N_("Iillegal"),
2508         N_("jjournal"),
2509         N_("Ddeleted"),
2510         N_("ddirectory"),
2511         N_("eentry"),
2512         N_("E@e '%Dn' in %p (%i)"),
2513         N_("ffilesystem"),
2514         N_("Ffor @i %i (%Q) is"),
2515         N_("ggroup"),
2516         N_("hHTREE @d @i"),
2517         N_("llost+found"),
2518         N_("Lis a link"),
2519     N_("mmultiply-claimed"),
2520     N_("ninvalid"),
2521         N_("oorphaned"),
2522         N_("pproblem in"),
2523         N_("rroot @i"),
2524         N_("sshould be"),
2525         N_("Ssuper@b"),
2526         N_("uunattached"),
2527         N_("vdevice"),
2528         N_("zzero-length"),
2529         "@@",
2530         0
2531         };
2532
2533 /*
2534  * Give more user friendly names to the "special" inodes.
2535  */
2536 #define num_special_inodes      11
2537 static const char * const special_inode_name[] =
2538 {
2539         N_("<The NULL inode>"),                 /* 0 */
2540         N_("<The bad blocks inode>"),           /* 1 */
2541         "/",                                    /* 2 */
2542         N_("<The ACL index inode>"),            /* 3 */
2543         N_("<The ACL data inode>"),             /* 4 */
2544         N_("<The boot loader inode>"),          /* 5 */
2545         N_("<The undelete directory inode>"),   /* 6 */
2546         N_("<The group descriptor inode>"),     /* 7 */
2547         N_("<The journal inode>"),              /* 8 */
2548         N_("<Reserved inode 9>"),               /* 9 */
2549         N_("<Reserved inode 10>"),              /* 10 */
2550 };
2551
2552 /*
2553  * This function does "safe" printing.  It will convert non-printable
2554  * ASCII characters using '^' and M- notation.
2555  */
2556 static void safe_print(const char *cp, int len)
2557 {
2558         unsigned char   ch;
2559
2560         if (len < 0)
2561                 len = strlen(cp);
2562
2563         while (len--) {
2564                 ch = *cp++;
2565                 if (ch > 128) {
2566                         fputs("M-", stdout);
2567                         ch -= 128;
2568                 }
2569                 if ((ch < 32) || (ch == 0x7f)) {
2570                         fputc('^', stdout);
2571                         ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2572                 }
2573                 fputc(ch, stdout);
2574         }
2575 }
2576
2577
2578 /*
2579  * This function prints a pathname, using the ext2fs_get_pathname
2580  * function
2581  */
2582 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2583 {
2584         errcode_t       retval;
2585         char            *path;
2586
2587         if (!dir && (ino < num_special_inodes)) {
2588                 fputs(_(special_inode_name[ino]), stdout);
2589                 return;
2590         }
2591
2592         retval = ext2fs_get_pathname(fs, dir, ino, &path);
2593         if (retval)
2594                 fputs("???", stdout);
2595         else {
2596                 safe_print(path, -1);
2597                 ext2fs_free_mem(&path);
2598         }
2599 }
2600
2601 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2602                           struct problem_context *pctx, int first);
2603 /*
2604  * This function handles the '@' expansion.  We allow recursive
2605  * expansion; an @ expression can contain further '@' and '%'
2606  * expressions.
2607  */
2608 static void expand_at_expression(e2fsck_t ctx, char ch,
2609                                           struct problem_context *pctx,
2610                                           int *first)
2611 {
2612         const char * const *cpp;
2613         const char *str;
2614
2615         /* Search for the abbreviation */
2616         for (cpp = abbrevs; *cpp; cpp++) {
2617                 if (ch == *cpp[0])
2618                         break;
2619         }
2620         if (*cpp) {
2621                 str = _(*cpp) + 1;
2622                 if (*first && islower(*str)) {
2623                         *first = 0;
2624                         fputc(toupper(*str++), stdout);
2625                 }
2626                 print_e2fsck_message(ctx, str, pctx, *first);
2627         } else
2628                 printf("@%c", ch);
2629 }
2630
2631 /*
2632  * This function expands '%IX' expressions
2633  */
2634 static void expand_inode_expression(char ch,
2635                                              struct problem_context *ctx)
2636 {
2637         struct ext2_inode       *inode;
2638         struct ext2_inode_large *large_inode;
2639         char *                  time_str;
2640         time_t                  t;
2641         int                     do_gmt = -1;
2642
2643         if (!ctx || !ctx->inode)
2644                 goto no_inode;
2645
2646         inode = ctx->inode;
2647         large_inode = (struct ext2_inode_large *) inode;
2648
2649         switch (ch) {
2650         case 's':
2651                 if (LINUX_S_ISDIR(inode->i_mode))
2652                         printf("%u", inode->i_size);
2653                 else {
2654 #ifdef EXT2_NO_64_TYPE
2655                         if (inode->i_size_high)
2656                                 printf("0x%x%08x", inode->i_size_high,
2657                                        inode->i_size);
2658                         else
2659                                 printf("%u", inode->i_size);
2660 #else
2661                         printf("%llu", (inode->i_size |
2662                                         ((__u64) inode->i_size_high << 32)));
2663 #endif
2664                 }
2665                 break;
2666         case 'S':
2667                 printf("%u", large_inode->i_extra_isize);
2668                 break;
2669         case 'b':
2670                 printf("%u", inode->i_blocks);
2671                 break;
2672         case 'l':
2673                 printf("%d", inode->i_links_count);
2674                 break;
2675         case 'm':
2676                 printf("0%o", inode->i_mode);
2677                 break;
2678         case 'M':
2679                 /* The diet libc doesn't respect the TZ environemnt variable */
2680                 if (do_gmt == -1) {
2681                         time_str = getenv("TZ");
2682                         if (!time_str)
2683                                 time_str = "";
2684                         do_gmt = !strcmp(time_str, "GMT");
2685                 }
2686                 t = inode->i_mtime;
2687                 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2688                 printf("%.24s", time_str);
2689                 break;
2690         case 'F':
2691                 printf("%u", inode->i_faddr);
2692                 break;
2693         case 'f':
2694                 printf("%u", inode->i_file_acl);
2695                 break;
2696         case 'd':
2697                 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2698                               inode->i_dir_acl : 0));
2699                 break;
2700         case 'u':
2701                 printf("%d", (inode->i_uid |
2702                               (inode->osd2.linux2.l_i_uid_high << 16)));
2703                 break;
2704         case 'g':
2705                 printf("%d", (inode->i_gid |
2706                               (inode->osd2.linux2.l_i_gid_high << 16)));
2707                 break;
2708         default:
2709         no_inode:
2710                 printf("%%I%c", ch);
2711                 break;
2712         }
2713 }
2714
2715 /*
2716  * This function expands '%dX' expressions
2717  */
2718 static void expand_dirent_expression(char ch,
2719                                               struct problem_context *ctx)
2720 {
2721         struct ext2_dir_entry   *dirent;
2722         int     len;
2723
2724         if (!ctx || !ctx->dirent)
2725                 goto no_dirent;
2726
2727         dirent = ctx->dirent;
2728
2729         switch (ch) {
2730         case 'i':
2731                 printf("%u", dirent->inode);
2732                 break;
2733         case 'n':
2734                 len = dirent->name_len & 0xFF;
2735                 if (len > EXT2_NAME_LEN)
2736                         len = EXT2_NAME_LEN;
2737                 if (len > dirent->rec_len)
2738                         len = dirent->rec_len;
2739                 safe_print(dirent->name, len);
2740                 break;
2741         case 'r':
2742                 printf("%u", dirent->rec_len);
2743                 break;
2744         case 'l':
2745                 printf("%u", dirent->name_len & 0xFF);
2746                 break;
2747         case 't':
2748                 printf("%u", dirent->name_len >> 8);
2749                 break;
2750         default:
2751         no_dirent:
2752                 printf("%%D%c", ch);
2753                 break;
2754         }
2755 }
2756
2757 static void expand_percent_expression(ext2_filsys fs, char ch,
2758                                                struct problem_context *ctx)
2759 {
2760         if (!ctx)
2761                 goto no_context;
2762
2763         switch (ch) {
2764         case '%':
2765                 fputc('%', stdout);
2766                 break;
2767         case 'b':
2768                 printf("%u", ctx->blk);
2769                 break;
2770         case 'B':
2771 #ifdef EXT2_NO_64_TYPE
2772                 printf("%d", ctx->blkcount);
2773 #else
2774                 printf("%lld", ctx->blkcount);
2775 #endif
2776                 break;
2777         case 'c':
2778                 printf("%u", ctx->blk2);
2779                 break;
2780         case 'd':
2781                 printf("%u", ctx->dir);
2782                 break;
2783         case 'g':
2784                 printf("%d", ctx->group);
2785                 break;
2786         case 'i':
2787                 printf("%u", ctx->ino);
2788                 break;
2789         case 'j':
2790                 printf("%u", ctx->ino2);
2791                 break;
2792         case 'm':
2793                 printf("%s", error_message(ctx->errcode));
2794                 break;
2795         case 'N':
2796 #ifdef EXT2_NO_64_TYPE
2797                 printf("%u", ctx->num);
2798 #else
2799                 printf("%llu", ctx->num);
2800 #endif
2801                 break;
2802         case 'p':
2803                 print_pathname(fs, ctx->ino, 0);
2804                 break;
2805         case 'P':
2806                 print_pathname(fs, ctx->ino2,
2807                                ctx->dirent ? ctx->dirent->inode : 0);
2808                 break;
2809         case 'q':
2810                 print_pathname(fs, ctx->dir, 0);
2811                 break;
2812         case 'Q':
2813                 print_pathname(fs, ctx->dir, ctx->ino);
2814                 break;
2815         case 'S':
2816                 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2817                 break;
2818         case 's':
2819                 printf("%s", ctx->str ? ctx->str : "NULL");
2820                 break;
2821         case 'X':
2822 #ifdef EXT2_NO_64_TYPE
2823                 printf("0x%x", ctx->num);
2824 #else
2825                 printf("0x%llx", ctx->num);
2826 #endif
2827                 break;
2828         default:
2829         no_context:
2830                 printf("%%%c", ch);
2831                 break;
2832         }
2833 }
2834
2835
2836 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2837                           struct problem_context *pctx, int first)
2838 {
2839         ext2_filsys fs = ctx->fs;
2840         const char *    cp;
2841         int             i;
2842
2843         e2fsck_clear_progbar(ctx);
2844         for (cp = msg; *cp; cp++) {
2845                 if (cp[0] == '@') {
2846                         cp++;
2847                         expand_at_expression(ctx, *cp, pctx, &first);
2848                 } else if (cp[0] == '%' && cp[1] == 'I') {
2849                         cp += 2;
2850                         expand_inode_expression(*cp, pctx);
2851                 } else if (cp[0] == '%' && cp[1] == 'D') {
2852                         cp += 2;
2853                         expand_dirent_expression(*cp, pctx);
2854                 } else if ((cp[0] == '%')) {
2855                         cp++;
2856                         expand_percent_expression(fs, *cp, pctx);
2857                 } else {
2858                         for (i=0; cp[i]; i++)
2859                                 if ((cp[i] == '@') || cp[i] == '%')
2860                                         break;
2861                         printf("%.*s", i, cp);
2862                         cp += i-1;
2863                 }
2864                 first = 0;
2865         }
2866 }
2867
2868
2869 /*
2870  * region.c --- code which manages allocations within a region.
2871  */
2872
2873 struct region_el {
2874         region_addr_t   start;
2875         region_addr_t   end;
2876         struct region_el *next;
2877 };
2878
2879 struct region_struct {
2880         region_addr_t   min;
2881         region_addr_t   max;
2882         struct region_el *allocated;
2883 };
2884
2885 static region_t region_create(region_addr_t min, region_addr_t max)
2886 {
2887         region_t        region;
2888
2889         region = malloc(sizeof(struct region_struct));
2890         if (!region)
2891                 return NULL;
2892         memset(region, 0, sizeof(struct region_struct));
2893         region->min = min;
2894         region->max = max;
2895         return region;
2896 }
2897
2898 static void region_free(region_t region)
2899 {
2900         struct region_el        *r, *next;
2901
2902         for (r = region->allocated; r; r = next) {
2903                 next = r->next;
2904                 free(r);
2905         }
2906         memset(region, 0, sizeof(struct region_struct));
2907         free(region);
2908 }
2909
2910 static int region_allocate(region_t region, region_addr_t start, int n)
2911 {
2912         struct region_el        *r, *new_region, *prev, *next;
2913         region_addr_t end;
2914
2915         end = start+n;
2916         if ((start < region->min) || (end > region->max))
2917                 return -1;
2918         if (n == 0)
2919                 return 1;
2920
2921         /*
2922          * Search through the linked list.  If we find that it
2923          * conflicts witih something that's already allocated, return
2924          * 1; if we can find an existing region which we can grow, do
2925          * so.  Otherwise, stop when we find the appropriate place
2926          * insert a new region element into the linked list.
2927          */
2928         for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2929                 if (((start >= r->start) && (start < r->end)) ||
2930                     ((end > r->start) && (end <= r->end)) ||
2931                     ((start <= r->start) && (end >= r->end)))
2932                         return 1;
2933                 if (end == r->start) {
2934                         r->start = start;
2935                         return 0;
2936                 }
2937                 if (start == r->end) {
2938                         if ((next = r->next)) {
2939                                 if (end > next->start)
2940                                         return 1;
2941                                 if (end == next->start) {
2942                                         r->end = next->end;
2943                                         r->next = next->next;
2944                                         free(next);
2945                                         return 0;
2946                                 }
2947                         }
2948                         r->end = end;
2949                         return 0;
2950                 }
2951                 if (start < r->start)
2952                         break;
2953         }
2954         /*
2955          * Insert a new region element structure into the linked list
2956          */
2957         new_region = malloc(sizeof(struct region_el));
2958         if (!new_region)
2959                 return -1;
2960         new_region->start = start;
2961         new_region->end = start + n;
2962         new_region->next = r;
2963         if (prev)
2964                 prev->next = new_region;
2965         else
2966                 region->allocated = new_region;
2967         return 0;
2968 }
2969
2970 /*
2971  * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2972  *
2973  * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2974  * and applies the following tests to each inode:
2975  *
2976  *      - The mode field of the inode must be legal.
2977  *      - The size and block count fields of the inode are correct.
2978  *      - A data block must not be used by another inode
2979  *
2980  * Pass 1 also gathers the collects the following information:
2981  *
2982  *      - A bitmap of which inodes are in use.          (inode_used_map)
2983  *      - A bitmap of which inodes are directories.     (inode_dir_map)
2984  *      - A bitmap of which inodes are regular files.   (inode_reg_map)
2985  *      - A bitmap of which inodes have bad fields.     (inode_bad_map)
2986  *      - A bitmap of which inodes are in bad blocks.   (inode_bb_map)
2987  *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
2988  *      - A bitmap of which blocks are in use.          (block_found_map)
2989  *      - A bitmap of which blocks are in use by two inodes     (block_dup_map)
2990  *      - The data blocks of the directory inodes.      (dir_map)
2991  *
2992  * Pass 1 is designed to stash away enough information so that the
2993  * other passes should not need to read in the inode information
2994  * during the normal course of a filesystem check.  (Althogh if an
2995  * inconsistency is detected, other passes may need to read in an
2996  * inode to fix it.)
2997  *
2998  * Note that pass 1B will be invoked if there are any duplicate blocks
2999  * found.
3000  */
3001
3002
3003 static int process_block(ext2_filsys fs, blk_t  *blocknr,
3004                          e2_blkcnt_t blockcnt, blk_t ref_blk,
3005                          int ref_offset, void *priv_data);
3006 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
3007                              e2_blkcnt_t blockcnt, blk_t ref_blk,
3008                              int ref_offset, void *priv_data);
3009 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3010                          char *block_buf);
3011 static void mark_table_blocks(e2fsck_t ctx);
3012 static void alloc_bb_map(e2fsck_t ctx);
3013 static void alloc_imagic_map(e2fsck_t ctx);
3014 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
3015 static void handle_fs_bad_blocks(e2fsck_t ctx);
3016 static void process_inodes(e2fsck_t ctx, char *block_buf);
3017 static int process_inode_cmp(const void *a, const void *b);
3018 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
3019                                   dgrp_t group, void * priv_data);
3020 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3021                                     char *block_buf, int adjust_sign);
3022 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
3023
3024 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
3025                                struct ext2_inode * inode, int bufsize,
3026                                const char *proc);
3027
3028 struct process_block_struct_1 {
3029         ext2_ino_t      ino;
3030         unsigned        is_dir:1, is_reg:1, clear:1, suppress:1,
3031                                 fragmented:1, compressed:1, bbcheck:1;
3032         blk_t           num_blocks;
3033         blk_t           max_blocks;
3034         e2_blkcnt_t     last_block;
3035         int             num_illegal_blocks;
3036         blk_t           previous_block;
3037         struct ext2_inode *inode;
3038         struct problem_context *pctx;
3039         ext2fs_block_bitmap fs_meta_blocks;
3040         e2fsck_t        ctx;
3041 };
3042
3043 struct process_inode_block {
3044         ext2_ino_t ino;
3045         struct ext2_inode inode;
3046 };
3047
3048 struct scan_callback_struct {
3049         e2fsck_t        ctx;
3050         char            *block_buf;
3051 };
3052
3053 /*
3054  * For the inodes to process list.
3055  */
3056 static struct process_inode_block *inodes_to_process;
3057 static int process_inode_count;
3058
3059 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
3060                             EXT2_MIN_BLOCK_LOG_SIZE + 1];
3061
3062 /*
3063  * Free all memory allocated by pass1 in preparation for restarting
3064  * things.
3065  */
3066 static void unwind_pass1(void)
3067 {
3068         ext2fs_free_mem(&inodes_to_process);
3069 }
3070
3071 /*
3072  * Check to make sure a device inode is real.  Returns 1 if the device
3073  * checks out, 0 if not.
3074  *
3075  * Note: this routine is now also used to check FIFO's and Sockets,
3076  * since they have the same requirement; the i_block fields should be
3077  * zero.
3078  */
3079 static int
3080 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
3081 {
3082         int     i;
3083
3084         /*
3085          * If i_blocks is non-zero, or the index flag is set, then
3086          * this is a bogus device/fifo/socket
3087          */
3088         if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
3089             (inode->i_flags & EXT2_INDEX_FL))
3090                 return 0;
3091
3092         /*
3093          * We should be able to do the test below all the time, but
3094          * because the kernel doesn't forcibly clear the device
3095          * inode's additional i_block fields, there are some rare
3096          * occasions when a legitimate device inode will have non-zero
3097          * additional i_block fields.  So for now, we only complain
3098          * when the immutable flag is set, which should never happen
3099          * for devices.  (And that's when the problem is caused, since
3100          * you can't set or clear immutable flags for devices.)  Once
3101          * the kernel has been fixed we can change this...
3102          */
3103         if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
3104                 for (i=4; i < EXT2_N_BLOCKS; i++)
3105                         if (inode->i_block[i])
3106                                 return 0;
3107         }
3108         return 1;
3109 }
3110
3111 /*
3112  * Check to make sure a symlink inode is real.  Returns 1 if the symlink
3113  * checks out, 0 if not.
3114  */
3115 static int
3116 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
3117 {
3118         unsigned int len;
3119         int i;
3120         blk_t   blocks;
3121
3122         if ((inode->i_size_high || inode->i_size == 0) ||
3123             (inode->i_flags & EXT2_INDEX_FL))
3124                 return 0;
3125
3126         blocks = ext2fs_inode_data_blocks(fs, inode);
3127         if (blocks) {
3128                 if ((inode->i_size >= fs->blocksize) ||
3129                     (blocks != fs->blocksize >> 9) ||
3130                     (inode->i_block[0] < fs->super->s_first_data_block) ||
3131                     (inode->i_block[0] >= fs->super->s_blocks_count))
3132                         return 0;
3133
3134                 for (i = 1; i < EXT2_N_BLOCKS; i++)
3135                         if (inode->i_block[i])
3136                                 return 0;
3137
3138                 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
3139                         return 0;
3140
3141                 len = strnlen(buf, fs->blocksize);
3142                 if (len == fs->blocksize)
3143                         return 0;
3144         } else {
3145                 if (inode->i_size >= sizeof(inode->i_block))
3146                         return 0;
3147
3148                 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3149                 if (len == sizeof(inode->i_block))
3150                         return 0;
3151         }
3152         if (len != inode->i_size)
3153                 return 0;
3154         return 1;
3155 }
3156
3157 /*
3158  * If the immutable (or append-only) flag is set on the inode, offer
3159  * to clear it.
3160  */
3161 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3162 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3163 {
3164         if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3165                 return;
3166
3167         if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3168                 return;
3169
3170         pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3171         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3172 }
3173
3174 /*
3175  * If device, fifo or socket, check size is zero -- if not offer to
3176  * clear it
3177  */
3178 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3179 {
3180         struct ext2_inode *inode = pctx->inode;
3181
3182         if ((inode->i_size == 0) && (inode->i_size_high == 0))
3183                 return;
3184
3185         if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3186                 return;
3187
3188         inode->i_size = 0;
3189         inode->i_size_high = 0;
3190         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3191 }
3192
3193 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3194 {
3195         struct ext2_super_block *sb = ctx->fs->super;
3196         struct ext2_inode_large *inode;
3197         struct ext2_ext_attr_entry *entry;
3198         char *start, *end;
3199         int storage_size, remain, offs;
3200         int problem = 0;
3201
3202         inode = (struct ext2_inode_large *) pctx->inode;
3203         storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3204                 inode->i_extra_isize;
3205         start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3206                 inode->i_extra_isize + sizeof(__u32);
3207         end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3208         entry = (struct ext2_ext_attr_entry *) start;
3209
3210         /* scan all entry's headers first */
3211
3212         /* take finish entry 0UL into account */
3213         remain = storage_size - sizeof(__u32);
3214         offs = end - start;
3215
3216         while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3217
3218                 /* header eats this space */
3219                 remain -= sizeof(struct ext2_ext_attr_entry);
3220
3221                 /* is attribute name valid? */
3222                 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3223                         pctx->num = entry->e_name_len;
3224                         problem = PR_1_ATTR_NAME_LEN;
3225                         goto fix;
3226                 }
3227
3228                 /* attribute len eats this space */
3229                 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3230
3231                 /* check value size */
3232                 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3233                         pctx->num = entry->e_value_size;
3234                         problem = PR_1_ATTR_VALUE_SIZE;
3235                         goto fix;
3236                 }
3237
3238                 /* check value placement */
3239                 if (entry->e_value_offs +
3240                     EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3241                         printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3242                         pctx->num = entry->e_value_offs;
3243                         problem = PR_1_ATTR_VALUE_OFFSET;
3244                         goto fix;
3245                 }
3246
3247                 /* e_value_block must be 0 in inode's ea */
3248                 if (entry->e_value_block != 0) {
3249                         pctx->num = entry->e_value_block;
3250                         problem = PR_1_ATTR_VALUE_BLOCK;
3251                         goto fix;
3252                 }
3253
3254                 /* e_hash must be 0 in inode's ea */
3255                 if (entry->e_hash != 0) {
3256                         pctx->num = entry->e_hash;
3257                         problem = PR_1_ATTR_HASH;
3258                         goto fix;
3259                 }
3260
3261                 remain -= entry->e_value_size;
3262                 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3263
3264                 entry = EXT2_EXT_ATTR_NEXT(entry);
3265         }
3266 fix:
3267         /*
3268          * it seems like a corruption. it's very unlikely we could repair
3269          * EA(s) in automatic fashion -bzzz
3270          */
3271         if (problem == 0 || !fix_problem(ctx, problem, pctx))
3272                 return;
3273
3274         /* simple remove all possible EA(s) */
3275         *((__u32 *)start) = 0UL;
3276         e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3277                                 EXT2_INODE_SIZE(sb), "pass1");
3278 }
3279
3280 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3281 {
3282         struct ext2_super_block *sb = ctx->fs->super;
3283         struct ext2_inode_large *inode;
3284         __u32 *eamagic;
3285         int min, max;
3286
3287         inode = (struct ext2_inode_large *) pctx->inode;
3288         if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3289                 /* this isn't large inode. so, nothing to check */
3290                 return;
3291         }
3292
3293         /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3294         min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3295         max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3296         /*
3297          * For now we will allow i_extra_isize to be 0, but really
3298          * implementations should never allow i_extra_isize to be 0
3299          */
3300         if (inode->i_extra_isize &&
3301             (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3302                 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3303                         return;
3304                 inode->i_extra_isize = min;
3305                 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3306                                         EXT2_INODE_SIZE(sb), "pass1");
3307                 return;
3308         }
3309
3310         eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3311                         inode->i_extra_isize);
3312         if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3313                 /* it seems inode has an extended attribute(s) in body */
3314                 check_ea_in_inode(ctx, pctx);
3315         }
3316 }
3317
3318 static void e2fsck_pass1(e2fsck_t ctx)
3319 {
3320         int     i;
3321         __u64   max_sizes;
3322         ext2_filsys fs = ctx->fs;
3323         ext2_ino_t      ino;
3324         struct ext2_inode *inode;
3325         ext2_inode_scan scan;
3326         char            *block_buf;
3327         unsigned char   frag, fsize;
3328         struct          problem_context pctx;
3329         struct          scan_callback_struct scan_struct;
3330         struct ext2_super_block *sb = ctx->fs->super;
3331         int             imagic_fs;
3332         int             busted_fs_time = 0;
3333         int             inode_size;
3334
3335         clear_problem_context(&pctx);
3336
3337         if (!(ctx->options & E2F_OPT_PREEN))
3338                 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3339
3340         if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3341             !(ctx->options & E2F_OPT_NO)) {
3342                 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3343                         ctx->dirs_to_hash = 0;
3344         }
3345
3346         /* Pass 1 */
3347
3348 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3349
3350         for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3351                 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3352                 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3353                 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3354                 max_sizes = (max_sizes * (1UL << i)) - 1;
3355                 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3356         }
3357 #undef EXT2_BPP
3358
3359         imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3360
3361         /*
3362          * Allocate bitmaps structures
3363          */
3364         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3365                                               &ctx->inode_used_map);
3366         if (pctx.errcode) {
3367                 pctx.num = 1;
3368                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3369                 ctx->flags |= E2F_FLAG_ABORT;
3370                 return;
3371         }
3372         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3373                                 _("directory inode map"), &ctx->inode_dir_map);
3374         if (pctx.errcode) {
3375                 pctx.num = 2;
3376                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3377                 ctx->flags |= E2F_FLAG_ABORT;
3378                 return;
3379         }
3380         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3381                         _("regular file inode map"), &ctx->inode_reg_map);
3382         if (pctx.errcode) {
3383                 pctx.num = 6;
3384                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3385                 ctx->flags |= E2F_FLAG_ABORT;
3386                 return;
3387         }
3388         pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3389                                               &ctx->block_found_map);
3390         if (pctx.errcode) {
3391                 pctx.num = 1;
3392                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3393                 ctx->flags |= E2F_FLAG_ABORT;
3394                 return;
3395         }
3396         pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3397                                              &ctx->inode_link_info);
3398         if (pctx.errcode) {
3399                 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3400                 ctx->flags |= E2F_FLAG_ABORT;
3401                 return;
3402         }
3403         inode_size = EXT2_INODE_SIZE(fs->super);
3404         inode = (struct ext2_inode *)
3405                 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3406
3407         inodes_to_process = (struct process_inode_block *)
3408                 e2fsck_allocate_memory(ctx,
3409                                        (ctx->process_inode_size *
3410                                         sizeof(struct process_inode_block)),
3411                                        "array of inodes to process");
3412         process_inode_count = 0;
3413
3414         pctx.errcode = ext2fs_init_dblist(fs, 0);
3415         if (pctx.errcode) {
3416                 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3417                 ctx->flags |= E2F_FLAG_ABORT;
3418                 return;
3419         }
3420
3421         /*
3422          * If the last orphan field is set, clear it, since the pass1
3423          * processing will automatically find and clear the orphans.
3424          * In the future, we may want to try using the last_orphan
3425          * linked list ourselves, but for now, we clear it so that the
3426          * ext3 mount code won't get confused.
3427          */
3428         if (!(ctx->options & E2F_OPT_READONLY)) {
3429                 if (fs->super->s_last_orphan) {
3430                         fs->super->s_last_orphan = 0;
3431                         ext2fs_mark_super_dirty(fs);
3432                 }
3433         }
3434
3435         mark_table_blocks(ctx);
3436         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3437                                                     "block interate buffer");
3438         e2fsck_use_inode_shortcuts(ctx, 1);
3439         ehandler_operation(_("doing inode scan"));
3440         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3441                                               &scan);
3442         if (pctx.errcode) {
3443                 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3444                 ctx->flags |= E2F_FLAG_ABORT;
3445                 return;
3446         }
3447         ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3448         ctx->stashed_inode = inode;
3449         scan_struct.ctx = ctx;
3450         scan_struct.block_buf = block_buf;
3451         ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3452         if (ctx->progress)
3453                 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3454                         return;
3455         if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3456             (fs->super->s_mtime < fs->super->s_inodes_count))
3457                 busted_fs_time = 1;
3458
3459         while (1) {
3460                 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3461                                                           inode, inode_size);
3462                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3463                         return;
3464                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3465                         if (!ctx->inode_bb_map)
3466                                 alloc_bb_map(ctx);
3467                         ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
3468                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3469                         continue;
3470                 }
3471                 if (pctx.errcode) {
3472                         fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3473                         ctx->flags |= E2F_FLAG_ABORT;
3474                         return;
3475                 }
3476                 if (!ino)
3477                         break;
3478                 pctx.ino = ino;
3479                 pctx.inode = inode;
3480                 ctx->stashed_ino = ino;
3481                 if (inode->i_links_count) {
3482                         pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3483                                            ino, inode->i_links_count);
3484                         if (pctx.errcode) {
3485                                 pctx.num = inode->i_links_count;
3486                                 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3487                                 ctx->flags |= E2F_FLAG_ABORT;
3488                                 return;
3489                         }
3490                 }
3491                 if (ino == EXT2_BAD_INO) {
3492                         struct process_block_struct_1 pb;
3493
3494                         pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3495                                                           &pb.fs_meta_blocks);
3496                         if (pctx.errcode) {
3497                                 pctx.num = 4;
3498                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3499                                 ctx->flags |= E2F_FLAG_ABORT;
3500                                 return;
3501                         }
3502                         pb.ino = EXT2_BAD_INO;
3503                         pb.num_blocks = pb.last_block = 0;
3504                         pb.num_illegal_blocks = 0;
3505                         pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3506                         pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3507                         pb.inode = inode;
3508                         pb.pctx = &pctx;
3509                         pb.ctx = ctx;
3510                         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3511                                      block_buf, process_bad_block, &pb);
3512                         ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3513                         if (pctx.errcode) {
3514                                 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3515                                 ctx->flags |= E2F_FLAG_ABORT;
3516                                 return;
3517                         }
3518                         if (pb.bbcheck)
3519                                 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3520                                 ctx->flags |= E2F_FLAG_ABORT;
3521                                 return;
3522                         }
3523                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3524                         clear_problem_context(&pctx);
3525                         continue;
3526                 } else if (ino == EXT2_ROOT_INO) {
3527                         /*
3528                          * Make sure the root inode is a directory; if
3529                          * not, offer to clear it.  It will be
3530                          * regnerated in pass #3.
3531                          */
3532                         if (!LINUX_S_ISDIR(inode->i_mode)) {
3533                                 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3534                                         inode->i_dtime = time(0);
3535                                         inode->i_links_count = 0;
3536                                         ext2fs_icount_store(ctx->inode_link_info,
3537                                                             ino, 0);
3538                                         e2fsck_write_inode(ctx, ino, inode,
3539                                                            "pass1");
3540                                 }
3541
3542                         }
3543                         /*
3544                          * If dtime is set, offer to clear it.  mke2fs
3545                          * version 0.2b created filesystems with the
3546                          * dtime field set for the root and lost+found
3547                          * directories.  We won't worry about
3548                          * /lost+found, since that can be regenerated
3549                          * easily.  But we will fix the root directory
3550                          * as a special case.
3551                          */
3552                         if (inode->i_dtime && inode->i_links_count) {
3553                                 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3554                                         inode->i_dtime = 0;
3555                                         e2fsck_write_inode(ctx, ino, inode,
3556                                                            "pass1");
3557                                 }
3558                         }
3559                 } else if (ino == EXT2_JOURNAL_INO) {
3560                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3561                         if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3562                                 if (!LINUX_S_ISREG(inode->i_mode) &&
3563                                     fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3564                                                 &pctx)) {
3565                                         inode->i_mode = LINUX_S_IFREG;
3566                                         e2fsck_write_inode(ctx, ino, inode,
3567                                                            "pass1");
3568                                 }
3569                                 check_blocks(ctx, &pctx, block_buf);
3570                                 continue;
3571                         }
3572                         if ((inode->i_links_count || inode->i_blocks ||
3573                              inode->i_blocks || inode->i_block[0]) &&
3574                             fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3575                                         &pctx)) {
3576                                 memset(inode, 0, inode_size);
3577                                 ext2fs_icount_store(ctx->inode_link_info,
3578                                                     ino, 0);
3579                                 e2fsck_write_inode_full(ctx, ino, inode,
3580                                                         inode_size, "pass1");
3581                         }
3582                 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3583                         int     problem = 0;
3584
3585                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3586                         if (ino == EXT2_BOOT_LOADER_INO) {
3587                                 if (LINUX_S_ISDIR(inode->i_mode))
3588                                         problem = PR_1_RESERVED_BAD_MODE;
3589                         } else if (ino == EXT2_RESIZE_INO) {
3590                                 if (inode->i_mode &&
3591                                     !LINUX_S_ISREG(inode->i_mode))
3592                                         problem = PR_1_RESERVED_BAD_MODE;
3593                         } else {
3594                                 if (inode->i_mode != 0)
3595                                         problem = PR_1_RESERVED_BAD_MODE;
3596                         }
3597                         if (problem) {
3598                                 if (fix_problem(ctx, problem, &pctx)) {
3599                                         inode->i_mode = 0;
3600                                         e2fsck_write_inode(ctx, ino, inode,
3601                                                            "pass1");
3602                                 }
3603                         }
3604                         check_blocks(ctx, &pctx, block_buf);
3605                         continue;
3606                 }
3607                 /*
3608                  * Check for inodes who might have been part of the
3609                  * orphaned list linked list.  They should have gotten
3610                  * dealt with by now, unless the list had somehow been
3611                  * corrupted.
3612                  *
3613                  * FIXME: In the future, inodes which are still in use
3614                  * (and which are therefore) pending truncation should
3615                  * be handled specially.  Right now we just clear the
3616                  * dtime field, and the normal e2fsck handling of
3617                  * inodes where i_size and the inode blocks are
3618                  * inconsistent is to fix i_size, instead of releasing
3619                  * the extra blocks.  This won't catch the inodes that
3620                  * was at the end of the orphan list, but it's better
3621                  * than nothing.  The right answer is that there
3622                  * shouldn't be any bugs in the orphan list handling.  :-)
3623                  */
3624                 if (inode->i_dtime && !busted_fs_time &&
3625                     inode->i_dtime < ctx->fs->super->s_inodes_count) {
3626                         if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3627                                 inode->i_dtime = inode->i_links_count ?
3628                                         0 : time(0);
3629                                 e2fsck_write_inode(ctx, ino, inode,
3630                                                    "pass1");
3631                         }
3632                 }
3633
3634                 /*
3635                  * This code assumes that deleted inodes have
3636                  * i_links_count set to 0.
3637                  */
3638                 if (!inode->i_links_count) {
3639                         if (!inode->i_dtime && inode->i_mode) {
3640                                 if (fix_problem(ctx,
3641                                             PR_1_ZERO_DTIME, &pctx)) {
3642                                         inode->i_dtime = time(0);
3643                                         e2fsck_write_inode(ctx, ino, inode,
3644                                                            "pass1");
3645                                 }
3646                         }
3647                         continue;
3648                 }
3649                 /*
3650                  * n.b.  0.3c ext2fs code didn't clear i_links_count for
3651                  * deleted files.  Oops.
3652                  *
3653                  * Since all new ext2 implementations get this right,
3654                  * we now assume that the case of non-zero
3655                  * i_links_count and non-zero dtime means that we
3656                  * should keep the file, not delete it.
3657                  *
3658                  */
3659                 if (inode->i_dtime) {
3660                         if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3661                                 inode->i_dtime = 0;
3662                                 e2fsck_write_inode(ctx, ino, inode, "pass1");
3663                         }
3664                 }
3665
3666                 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3667                 switch (fs->super->s_creator_os) {
3668                     case EXT2_OS_LINUX:
3669                         frag = inode->osd2.linux2.l_i_frag;
3670                         fsize = inode->osd2.linux2.l_i_fsize;
3671                         break;
3672                     case EXT2_OS_HURD:
3673                         frag = inode->osd2.hurd2.h_i_frag;
3674                         fsize = inode->osd2.hurd2.h_i_fsize;
3675                         break;
3676                     case EXT2_OS_MASIX:
3677                         frag = inode->osd2.masix2.m_i_frag;
3678                         fsize = inode->osd2.masix2.m_i_fsize;
3679                         break;
3680                     default:
3681                         frag = fsize = 0;
3682                 }
3683
3684                 if (inode->i_faddr || frag || fsize ||
3685                     (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3686                         mark_inode_bad(ctx, ino);
3687                 if (inode->i_flags & EXT2_IMAGIC_FL) {
3688                         if (imagic_fs) {
3689                                 if (!ctx->inode_imagic_map)
3690                                         alloc_imagic_map(ctx);
3691                                 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3692                                                          ino);
3693                         } else {
3694                                 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3695                                         inode->i_flags &= ~EXT2_IMAGIC_FL;
3696                                         e2fsck_write_inode(ctx, ino,
3697                                                            inode, "pass1");
3698                                 }
3699                         }
3700                 }
3701
3702                 check_inode_extra_space(ctx, &pctx);
3703
3704                 if (LINUX_S_ISDIR(inode->i_mode)) {
3705                         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3706                         e2fsck_add_dir_info(ctx, ino, 0);
3707                         ctx->fs_directory_count++;
3708                 } else if (LINUX_S_ISREG (inode->i_mode)) {
3709                         ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3710                         ctx->fs_regular_count++;
3711                 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3712                            e2fsck_pass1_check_device_inode(fs, inode)) {
3713                         check_immutable(ctx, &pctx);
3714                         check_size(ctx, &pctx);
3715                         ctx->fs_chardev_count++;
3716                 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3717                            e2fsck_pass1_check_device_inode(fs, inode)) {
3718                         check_immutable(ctx, &pctx);
3719                         check_size(ctx, &pctx);
3720                         ctx->fs_blockdev_count++;
3721                 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3722                            e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3723                         check_immutable(ctx, &pctx);
3724                         ctx->fs_symlinks_count++;
3725                         if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3726                                 ctx->fs_fast_symlinks_count++;
3727                                 check_blocks(ctx, &pctx, block_buf);
3728                                 continue;
3729                         }
3730                 }
3731                 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3732                          e2fsck_pass1_check_device_inode(fs, inode)) {
3733                         check_immutable(ctx, &pctx);
3734                         check_size(ctx, &pctx);
3735                         ctx->fs_fifo_count++;
3736                 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3737                            e2fsck_pass1_check_device_inode(fs, inode)) {
3738                         check_immutable(ctx, &pctx);
3739                         check_size(ctx, &pctx);
3740                         ctx->fs_sockets_count++;
3741                 } else
3742                         mark_inode_bad(ctx, ino);
3743                 if (inode->i_block[EXT2_IND_BLOCK])
3744                         ctx->fs_ind_count++;
3745                 if (inode->i_block[EXT2_DIND_BLOCK])
3746                         ctx->fs_dind_count++;
3747                 if (inode->i_block[EXT2_TIND_BLOCK])
3748                         ctx->fs_tind_count++;
3749                 if (inode->i_block[EXT2_IND_BLOCK] ||
3750                     inode->i_block[EXT2_DIND_BLOCK] ||
3751                     inode->i_block[EXT2_TIND_BLOCK] ||
3752                     inode->i_file_acl) {
3753                         inodes_to_process[process_inode_count].ino = ino;
3754                         inodes_to_process[process_inode_count].inode = *inode;
3755                         process_inode_count++;
3756                 } else
3757                         check_blocks(ctx, &pctx, block_buf);
3758
3759                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3760                         return;
3761
3762                 if (process_inode_count >= ctx->process_inode_size) {
3763                         process_inodes(ctx, block_buf);
3764
3765                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3766                                 return;
3767                 }
3768         }
3769         process_inodes(ctx, block_buf);
3770         ext2fs_close_inode_scan(scan);
3771         ehandler_operation(0);
3772
3773         /*
3774          * If any extended attribute blocks' reference counts need to
3775          * be adjusted, either up (ctx->refcount_extra), or down
3776          * (ctx->refcount), then fix them.
3777          */
3778         if (ctx->refcount) {
3779                 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3780                 ea_refcount_free(ctx->refcount);
3781                 ctx->refcount = 0;
3782         }
3783         if (ctx->refcount_extra) {
3784                 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3785                                         block_buf, +1);
3786                 ea_refcount_free(ctx->refcount_extra);
3787                 ctx->refcount_extra = 0;
3788         }
3789
3790         if (ctx->invalid_bitmaps)
3791                 handle_fs_bad_blocks(ctx);
3792
3793         /* We don't need the block_ea_map any more */
3794         ext2fs_free_block_bitmap(ctx->block_ea_map);
3795         ctx->block_ea_map = 0;
3796
3797         if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3798                 ext2fs_block_bitmap save_bmap;
3799
3800                 save_bmap = fs->block_map;
3801                 fs->block_map = ctx->block_found_map;
3802                 clear_problem_context(&pctx);
3803                 pctx.errcode = ext2fs_create_resize_inode(fs);
3804                 if (pctx.errcode) {
3805                         fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3806                         /* Should never get here */
3807                         ctx->flags |= E2F_FLAG_ABORT;
3808                         return;
3809                 }
3810                 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3811                                   "recreate inode");
3812                 inode->i_mtime = time(0);
3813                 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode, 
3814                                   "recreate inode");
3815                 fs->block_map = save_bmap;
3816                 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3817         }
3818
3819         if (ctx->flags & E2F_FLAG_RESTART) {
3820                 /*
3821                  * Only the master copy of the superblock and block
3822                  * group descriptors are going to be written during a
3823                  * restart, so set the superblock to be used to be the
3824                  * master superblock.
3825                  */
3826                 ctx->use_superblock = 0;
3827                 unwind_pass1();
3828                 goto endit;
3829         }
3830
3831         if (ctx->block_dup_map) {
3832                 if (ctx->options & E2F_OPT_PREEN) {
3833                         clear_problem_context(&pctx);
3834                         fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3835                 }
3836                 e2fsck_pass1_dupblocks(ctx, block_buf);
3837         }
3838         ext2fs_free_mem(&inodes_to_process);
3839 endit:
3840         e2fsck_use_inode_shortcuts(ctx, 0);
3841
3842         ext2fs_free_mem(&block_buf);
3843         ext2fs_free_mem(&inode);
3844
3845 }
3846
3847 /*
3848  * When the inode_scan routines call this callback at the end of the
3849  * glock group, call process_inodes.
3850  */
3851 static errcode_t scan_callback(ext2_filsys fs,
3852                                ext2_inode_scan scan FSCK_ATTR((unused)),
3853                                dgrp_t group, void * priv_data)
3854 {
3855         struct scan_callback_struct *scan_struct;
3856         e2fsck_t ctx;
3857
3858         scan_struct = (struct scan_callback_struct *) priv_data;
3859         ctx = scan_struct->ctx;
3860
3861         process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3862
3863         if (ctx->progress)
3864                 if ((ctx->progress)(ctx, 1, group+1,
3865                                     ctx->fs->group_desc_count))
3866                         return EXT2_ET_CANCEL_REQUESTED;
3867
3868         return 0;
3869 }
3870
3871 /*
3872  * Process the inodes in the "inodes to process" list.
3873  */
3874 static void process_inodes(e2fsck_t ctx, char *block_buf)
3875 {
3876         int                     i;
3877         struct ext2_inode       *old_stashed_inode;
3878         ext2_ino_t              old_stashed_ino;
3879         const char              *old_operation;
3880         char                    buf[80];
3881         struct problem_context  pctx;
3882
3883         /* begin process_inodes */
3884         if (process_inode_count == 0)
3885                 return;
3886         old_operation = ehandler_operation(0);
3887         old_stashed_inode = ctx->stashed_inode;
3888         old_stashed_ino = ctx->stashed_ino;
3889         qsort(inodes_to_process, process_inode_count,
3890                       sizeof(struct process_inode_block), process_inode_cmp);
3891         clear_problem_context(&pctx);
3892         for (i=0; i < process_inode_count; i++) {
3893                 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3894                 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3895                 sprintf(buf, _("reading indirect blocks of inode %u"),
3896                         pctx.ino);
3897                 ehandler_operation(buf);
3898                 check_blocks(ctx, &pctx, block_buf);
3899                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3900                         break;
3901         }
3902         ctx->stashed_inode = old_stashed_inode;
3903         ctx->stashed_ino = old_stashed_ino;
3904         process_inode_count = 0;
3905         /* end process inodes */
3906
3907         ehandler_operation(old_operation);
3908 }
3909
3910 static int process_inode_cmp(const void *a, const void *b)
3911 {
3912         const struct process_inode_block *ib_a =
3913                 (const struct process_inode_block *) a;
3914         const struct process_inode_block *ib_b =
3915                 (const struct process_inode_block *) b;
3916         int     ret;
3917
3918         ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3919                ib_b->inode.i_block[EXT2_IND_BLOCK]);
3920         if (ret == 0)
3921                 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3922         return ret;
3923 }
3924
3925 /*
3926  * Mark an inode as being bad in some what
3927  */
3928 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3929 {
3930         struct          problem_context pctx;
3931
3932         if (!ctx->inode_bad_map) {
3933                 clear_problem_context(&pctx);
3934
3935                 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3936                             _("bad inode map"), &ctx->inode_bad_map);
3937                 if (pctx.errcode) {
3938                         pctx.num = 3;
3939                         fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3940                         /* Should never get here */
3941                         ctx->flags |= E2F_FLAG_ABORT;
3942                         return;
3943                 }
3944         }
3945         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3946 }
3947
3948
3949 /*
3950  * This procedure will allocate the inode "bb" (badblock) map table
3951  */
3952 static void alloc_bb_map(e2fsck_t ctx)
3953 {
3954         struct          problem_context pctx;
3955
3956         clear_problem_context(&pctx);
3957         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3958                                               _("inode in bad block map"),
3959                                               &ctx->inode_bb_map);
3960         if (pctx.errcode) {
3961                 pctx.num = 4;
3962                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3963                 /* Should never get here */
3964                 ctx->flags |= E2F_FLAG_ABORT;
3965                 return;
3966         }
3967 }
3968
3969 /*
3970  * This procedure will allocate the inode imagic table
3971  */
3972 static void alloc_imagic_map(e2fsck_t ctx)
3973 {
3974         struct          problem_context pctx;
3975
3976         clear_problem_context(&pctx);
3977         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3978                                               _("imagic inode map"),
3979                                               &ctx->inode_imagic_map);
3980         if (pctx.errcode) {
3981                 pctx.num = 5;
3982                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3983                 /* Should never get here */
3984                 ctx->flags |= E2F_FLAG_ABORT;
3985                 return;
3986         }
3987 }
3988
3989 /*
3990  * Marks a block as in use, setting the dup_map if it's been set
3991  * already.  Called by process_block and process_bad_block.
3992  *
3993  * WARNING: Assumes checks have already been done to make sure block
3994  * is valid.  This is true in both process_block and process_bad_block.
3995  */
3996 static void mark_block_used(e2fsck_t ctx, blk_t block)
3997 {
3998         struct          problem_context pctx;
3999
4000         clear_problem_context(&pctx);
4001
4002         if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
4003                 if (!ctx->block_dup_map) {
4004                         pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
4005                               _("multiply claimed block map"),
4006                               &ctx->block_dup_map);
4007                         if (pctx.errcode) {
4008                                 pctx.num = 3;
4009                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
4010                                             &pctx);
4011                                 /* Should never get here */
4012                                 ctx->flags |= E2F_FLAG_ABORT;
4013                                 return;
4014                         }
4015                 }
4016                 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
4017         } else {
4018                 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
4019         }
4020 }
4021
4022 /*
4023  * Adjust the extended attribute block's reference counts at the end
4024  * of pass 1, either by subtracting out references for EA blocks that
4025  * are still referenced in ctx->refcount, or by adding references for
4026  * EA blocks that had extra references as accounted for in
4027  * ctx->refcount_extra.
4028  */
4029 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4030                                     char *block_buf, int adjust_sign)
4031 {
4032         struct ext2_ext_attr_header     *header;
4033         struct problem_context          pctx;
4034         ext2_filsys                     fs = ctx->fs;
4035         blk_t                           blk;
4036         __u32                           should_be;
4037         int                             count;
4038
4039         clear_problem_context(&pctx);
4040
4041         ea_refcount_intr_begin(refcount);
4042         while (1) {
4043                 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
4044                         break;
4045                 pctx.blk = blk;
4046                 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4047                 if (pctx.errcode) {
4048                         fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
4049                         return;
4050                 }
4051                 header = (struct ext2_ext_attr_header *) block_buf;
4052                 pctx.blkcount = header->h_refcount;
4053                 should_be = header->h_refcount + adjust_sign * count;
4054                 pctx.num = should_be;
4055                 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
4056                         header->h_refcount = should_be;
4057                         pctx.errcode = ext2fs_write_ext_attr(fs, blk,
4058                                                              block_buf);
4059                         if (pctx.errcode) {
4060                                 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
4061                                 continue;
4062                         }
4063                 }
4064         }
4065 }
4066
4067 /*
4068  * Handle processing the extended attribute blocks
4069  */
4070 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
4071                            char *block_buf)
4072 {
4073         ext2_filsys fs = ctx->fs;
4074         ext2_ino_t      ino = pctx->ino;
4075         struct ext2_inode *inode = pctx->inode;
4076         blk_t           blk;
4077         char *          end;
4078         struct ext2_ext_attr_header *header;
4079         struct ext2_ext_attr_entry *entry;
4080         int             count;
4081         region_t        region;
4082
4083         blk = inode->i_file_acl;
4084         if (blk == 0)
4085                 return 0;
4086
4087         /*
4088          * If the Extended attribute flag isn't set, then a non-zero
4089          * file acl means that the inode is corrupted.
4090          *
4091          * Or if the extended attribute block is an invalid block,
4092          * then the inode is also corrupted.
4093          */
4094         if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
4095             (blk < fs->super->s_first_data_block) ||
4096             (blk >= fs->super->s_blocks_count)) {
4097                 mark_inode_bad(ctx, ino);
4098                 return 0;
4099         }
4100
4101         /* If ea bitmap hasn't been allocated, create it */
4102         if (!ctx->block_ea_map) {
4103                 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
4104                                                       _("ext attr block map"),
4105                                                       &ctx->block_ea_map);
4106                 if (pctx->errcode) {
4107                         pctx->num = 2;
4108                         fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
4109                         ctx->flags |= E2F_FLAG_ABORT;
4110                         return 0;
4111                 }
4112         }
4113
4114         /* Create the EA refcount structure if necessary */
4115         if (!ctx->refcount) {
4116                 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
4117                 if (pctx->errcode) {
4118                         pctx->num = 1;
4119                         fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4120                         ctx->flags |= E2F_FLAG_ABORT;
4121                         return 0;
4122                 }
4123         }
4124
4125         /* Have we seen this EA block before? */
4126         if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
4127                 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
4128                         return 1;
4129                 /* Ooops, this EA was referenced more than it stated */
4130                 if (!ctx->refcount_extra) {
4131                         pctx->errcode = ea_refcount_create(0,
4132                                            &ctx->refcount_extra);
4133                         if (pctx->errcode) {
4134                                 pctx->num = 2;
4135                                 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4136                                 ctx->flags |= E2F_FLAG_ABORT;
4137                                 return 0;
4138                         }
4139                 }
4140                 ea_refcount_increment(ctx->refcount_extra, blk, 0);
4141                 return 1;
4142         }
4143
4144         /*
4145          * OK, we haven't seen this EA block yet.  So we need to
4146          * validate it
4147          */
4148         pctx->blk = blk;
4149         pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4150         if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
4151                 goto clear_extattr;
4152         header = (struct ext2_ext_attr_header *) block_buf;
4153         pctx->blk = inode->i_file_acl;
4154         if (((ctx->ext_attr_ver == 1) &&
4155              (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
4156             ((ctx->ext_attr_ver == 2) &&
4157              (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
4158                 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
4159                         goto clear_extattr;
4160         }
4161
4162         if (header->h_blocks != 1) {
4163                 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
4164                         goto clear_extattr;
4165         }
4166
4167         region = region_create(0, fs->blocksize);
4168         if (!region) {
4169                 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
4170                 ctx->flags |= E2F_FLAG_ABORT;
4171                 return 0;
4172         }
4173         if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4174                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4175                         goto clear_extattr;
4176         }
4177
4178         entry = (struct ext2_ext_attr_entry *)(header+1);
4179         end = block_buf + fs->blocksize;
4180         while ((char *)entry < end && *(__u32 *)entry) {
4181                 if (region_allocate(region, (char *)entry - (char *)header,
4182                                    EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4183                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4184                                 goto clear_extattr;
4185                 }
4186                 if ((ctx->ext_attr_ver == 1 &&
4187                      (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4188                     (ctx->ext_attr_ver == 2 &&
4189                      entry->e_name_index == 0)) {
4190                         if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4191                                 goto clear_extattr;
4192                 }
4193                 if (entry->e_value_block != 0) {
4194                         if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4195                                 goto clear_extattr;
4196                 }
4197                 if (entry->e_value_size &&
4198                     region_allocate(region, entry->e_value_offs,
4199                                     EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4200                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4201                                 goto clear_extattr;
4202                 }
4203                 entry = EXT2_EXT_ATTR_NEXT(entry);
4204         }
4205         if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4206                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4207                         goto clear_extattr;
4208         }
4209         region_free(region);
4210
4211         count = header->h_refcount - 1;
4212         if (count)
4213                 ea_refcount_store(ctx->refcount, blk, count);
4214         mark_block_used(ctx, blk);
4215         ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4216
4217         return 1;
4218
4219 clear_extattr:
4220         inode->i_file_acl = 0;
4221         e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4222         return 0;
4223 }
4224
4225 /* Returns 1 if bad htree, 0 if OK */
4226 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4227                         ext2_ino_t ino FSCK_ATTR((unused)),
4228                         struct ext2_inode *inode,
4229                         char *block_buf)
4230 {
4231         struct ext2_dx_root_info        *root;
4232         ext2_filsys                     fs = ctx->fs;
4233         errcode_t                       retval;
4234         blk_t                           blk;
4235
4236         if ((!LINUX_S_ISDIR(inode->i_mode) &&
4237              fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4238             (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4239              fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4240                 return 1;
4241
4242         blk = inode->i_block[0];
4243         if (((blk == 0) ||
4244              (blk < fs->super->s_first_data_block) ||
4245              (blk >= fs->super->s_blocks_count)) &&
4246             fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4247                 return 1;
4248
4249         retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4250         if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4251                 return 1;
4252
4253         /* XXX should check that beginning matches a directory */
4254         root = (struct ext2_dx_root_info *) (block_buf + 24);
4255
4256         if ((root->reserved_zero || root->info_length < 8) &&
4257             fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4258                 return 1;
4259
4260         pctx->num = root->hash_version;
4261         if ((root->hash_version != EXT2_HASH_LEGACY) &&
4262             (root->hash_version != EXT2_HASH_HALF_MD4) &&
4263             (root->hash_version != EXT2_HASH_TEA) &&
4264             fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4265                 return 1;
4266
4267         if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4268             fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4269                 return 1;
4270
4271         pctx->num = root->indirect_levels;
4272         if ((root->indirect_levels > 1) &&
4273             fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4274                 return 1;
4275
4276         return 0;
4277 }
4278
4279 /*
4280  * This subroutine is called on each inode to account for all of the
4281  * blocks used by that inode.
4282  */
4283 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4284                          char *block_buf)
4285 {
4286         ext2_filsys fs = ctx->fs;
4287         struct process_block_struct_1 pb;
4288         ext2_ino_t      ino = pctx->ino;
4289         struct ext2_inode *inode = pctx->inode;
4290         int             bad_size = 0;
4291         int             dirty_inode = 0;
4292         __u64           size;
4293
4294         pb.ino = ino;
4295         pb.num_blocks = 0;
4296         pb.last_block = -1;
4297         pb.num_illegal_blocks = 0;
4298         pb.suppress = 0; pb.clear = 0;
4299         pb.fragmented = 0;
4300         pb.compressed = 0;
4301         pb.previous_block = 0;
4302         pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4303         pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4304         pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4305         pb.inode = inode;
4306         pb.pctx = pctx;
4307         pb.ctx = ctx;
4308         pctx->ino = ino;
4309         pctx->errcode = 0;
4310
4311         if (inode->i_flags & EXT2_COMPRBLK_FL) {
4312                 if (fs->super->s_feature_incompat &
4313                     EXT2_FEATURE_INCOMPAT_COMPRESSION)
4314                         pb.compressed = 1;
4315                 else {
4316                         if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4317                                 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4318                                 dirty_inode++;
4319                         }
4320                 }
4321         }
4322
4323         if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4324                 pb.num_blocks++;
4325
4326         if (ext2fs_inode_has_valid_blocks(inode))
4327                 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4328                                        pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4329                                        block_buf, process_block, &pb);
4330         end_problem_latch(ctx, PR_LATCH_BLOCK);
4331         end_problem_latch(ctx, PR_LATCH_TOOBIG);
4332         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4333                 goto out;
4334         if (pctx->errcode)
4335                 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4336
4337         if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4338                 ctx->fs_fragmented++;
4339
4340         if (pb.clear) {
4341                 inode->i_links_count = 0;
4342                 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4343                 inode->i_dtime = time(0);
4344                 dirty_inode++;
4345                 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4346                 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4347                 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4348                 /*
4349                  * The inode was probably partially accounted for
4350                  * before processing was aborted, so we need to
4351                  * restart the pass 1 scan.
4352                  */
4353                 ctx->flags |= E2F_FLAG_RESTART;
4354                 goto out;
4355         }
4356
4357         if (inode->i_flags & EXT2_INDEX_FL) {
4358                 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4359                         inode->i_flags &= ~EXT2_INDEX_FL;
4360                         dirty_inode++;
4361                 } else {
4362 #ifdef ENABLE_HTREE
4363                         e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4364 #endif
4365                 }
4366         }
4367         if (ctx->dirs_to_hash && pb.is_dir &&
4368             !(inode->i_flags & EXT2_INDEX_FL) &&
4369             ((inode->i_size / fs->blocksize) >= 3))
4370                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4371
4372         if (!pb.num_blocks && pb.is_dir) {
4373                 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4374                         inode->i_links_count = 0;
4375                         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4376                         inode->i_dtime = time(0);
4377                         dirty_inode++;
4378                         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4379                         ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4380                         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4381                         ctx->fs_directory_count--;
4382                         goto out;
4383                 }
4384         }
4385
4386         pb.num_blocks *= (fs->blocksize / 512);
4387
4388         if (pb.is_dir) {
4389                 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4390                 if (nblock > (pb.last_block + 1))
4391                         bad_size = 1;
4392                 else if (nblock < (pb.last_block + 1)) {
4393                         if (((pb.last_block + 1) - nblock) >
4394                             fs->super->s_prealloc_dir_blocks)
4395                                 bad_size = 2;
4396                 }
4397         } else {
4398                 size = EXT2_I_SIZE(inode);
4399                 if ((pb.last_block >= 0) &&
4400                     (size < (__u64) pb.last_block * fs->blocksize))
4401                         bad_size = 3;
4402                 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4403                         bad_size = 4;
4404         }
4405         /* i_size for symlinks is checked elsewhere */
4406         if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4407                 pctx->num = (pb.last_block+1) * fs->blocksize;
4408                 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4409                         inode->i_size = pctx->num;
4410                         if (!LINUX_S_ISDIR(inode->i_mode))
4411                                 inode->i_size_high = pctx->num >> 32;
4412                         dirty_inode++;
4413                 }
4414                 pctx->num = 0;
4415         }
4416         if (LINUX_S_ISREG(inode->i_mode) &&
4417             (inode->i_size_high || inode->i_size & 0x80000000UL))
4418                 ctx->large_files++;
4419         if (pb.num_blocks != inode->i_blocks) {
4420                 pctx->num = pb.num_blocks;
4421                 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4422                         inode->i_blocks = pb.num_blocks;
4423                         dirty_inode++;
4424                 }
4425                 pctx->num = 0;
4426         }
4427 out:
4428         if (dirty_inode)
4429                 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4430 }
4431
4432
4433 /*
4434  * This is a helper function for check_blocks().
4435  */
4436 static int process_block(ext2_filsys fs,
4437                   blk_t *block_nr,
4438                   e2_blkcnt_t blockcnt,
4439                   blk_t ref_block FSCK_ATTR((unused)),
4440                   int ref_offset FSCK_ATTR((unused)),
4441                   void *priv_data)
4442 {
4443         struct process_block_struct_1 *p;
4444         struct problem_context *pctx;
4445         blk_t   blk = *block_nr;
4446         int     ret_code = 0;
4447         int     problem = 0;
4448         e2fsck_t        ctx;
4449
4450         p = (struct process_block_struct_1 *) priv_data;
4451         pctx = p->pctx;
4452         ctx = p->ctx;
4453
4454         if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4455                 /* todo: Check that the comprblk_fl is high, that the
4456                    blkaddr pattern looks right (all non-holes up to
4457                    first EXT2FS_COMPRESSED_BLKADDR, then all
4458                    EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4459                    that the feature_incompat bit is high, and that the
4460                    inode is a regular file.  If we're doing a "full
4461                    check" (a concept introduced to e2fsck by e2compr,
4462                    meaning that we look at data blocks as well as
4463                    metadata) then call some library routine that
4464                    checks the compressed data.  I'll have to think
4465                    about this, because one particularly important
4466                    problem to be able to fix is to recalculate the
4467                    cluster size if necessary.  I think that perhaps
4468                    we'd better do most/all e2compr-specific checks
4469                    separately, after the non-e2compr checks.  If not
4470                    doing a full check, it may be useful to test that
4471                    the personality is linux; e.g. if it isn't then
4472                    perhaps this really is just an illegal block. */
4473                 return 0;
4474         }
4475
4476         if (blk == 0) {
4477                 if (p->is_dir == 0) {
4478                         /*
4479                          * Should never happen, since only directories
4480                          * get called with BLOCK_FLAG_HOLE
4481                          */
4482 #if DEBUG_E2FSCK
4483                         printf("process_block() called with blk == 0, "
4484                                "blockcnt=%d, inode %lu???\n",
4485                                blockcnt, p->ino);
4486 #endif
4487                         return 0;
4488                 }
4489                 if (blockcnt < 0)
4490                         return 0;
4491                 if (blockcnt * fs->blocksize < p->inode->i_size) {
4492                         goto mark_dir;
4493                 }
4494                 return 0;
4495         }
4496
4497         /*
4498          * Simplistic fragmentation check.  We merely require that the
4499          * file be contiguous.  (Which can never be true for really
4500          * big files that are greater than a block group.)
4501          */
4502         if (!HOLE_BLKADDR(p->previous_block)) {
4503                 if (p->previous_block+1 != blk)
4504                         p->fragmented = 1;
4505         }
4506         p->previous_block = blk;
4507
4508         if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4509                 problem = PR_1_TOOBIG_DIR;
4510         if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4511                 problem = PR_1_TOOBIG_REG;
4512         if (!p->is_dir && !p->is_reg && blockcnt > 0)
4513                 problem = PR_1_TOOBIG_SYMLINK;
4514
4515         if (blk < fs->super->s_first_data_block ||
4516             blk >= fs->super->s_blocks_count)
4517                 problem = PR_1_ILLEGAL_BLOCK_NUM;
4518
4519         if (problem) {
4520                 p->num_illegal_blocks++;
4521                 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4522                         if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4523                                 p->clear = 1;
4524                                 return BLOCK_ABORT;
4525                         }
4526                         if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4527                                 p->suppress = 1;
4528                                 set_latch_flags(PR_LATCH_BLOCK,
4529                                                 PRL_SUPPRESS, 0);
4530                         }
4531                 }
4532                 pctx->blk = blk;
4533                 pctx->blkcount = blockcnt;
4534                 if (fix_problem(ctx, problem, pctx)) {
4535                         blk = *block_nr = 0;
4536                         ret_code = BLOCK_CHANGED;
4537                         goto mark_dir;
4538                 } else
4539                         return 0;
4540         }
4541
4542         if (p->ino == EXT2_RESIZE_INO) {
4543                 /*
4544                  * The resize inode has already be sanity checked
4545                  * during pass #0 (the superblock checks).  All we
4546                  * have to do is mark the double indirect block as
4547                  * being in use; all of the other blocks are handled
4548                  * by mark_table_blocks()).
4549                  */
4550                 if (blockcnt == BLOCK_COUNT_DIND)
4551                         mark_block_used(ctx, blk);
4552         } else
4553                 mark_block_used(ctx, blk);
4554         p->num_blocks++;
4555         if (blockcnt >= 0)
4556                 p->last_block = blockcnt;
4557 mark_dir:
4558         if (p->is_dir && (blockcnt >= 0)) {
4559                 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4560                                                     blk, blockcnt);
4561                 if (pctx->errcode) {
4562                         pctx->blk = blk;
4563                         pctx->num = blockcnt;
4564                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4565                         /* Should never get here */
4566                         ctx->flags |= E2F_FLAG_ABORT;
4567                         return BLOCK_ABORT;
4568                 }
4569         }
4570         return ret_code;
4571 }
4572
4573 static int process_bad_block(ext2_filsys fs,
4574                       blk_t *block_nr,
4575                       e2_blkcnt_t blockcnt,
4576                       blk_t ref_block FSCK_ATTR((unused)),
4577                       int ref_offset FSCK_ATTR((unused)),
4578                       void *priv_data)
4579 {
4580         struct process_block_struct_1 *p;
4581         blk_t           blk = *block_nr;
4582         blk_t           first_block;
4583         dgrp_t          i;
4584         struct problem_context *pctx;
4585         e2fsck_t        ctx;
4586
4587         /*
4588          * Note: This function processes blocks for the bad blocks
4589          * inode, which is never compressed.  So we don't use HOLE_BLKADDR().
4590          */
4591
4592         if (!blk)
4593                 return 0;
4594
4595         p = (struct process_block_struct_1 *) priv_data;
4596         ctx = p->ctx;
4597         pctx = p->pctx;
4598
4599         pctx->ino = EXT2_BAD_INO;
4600         pctx->blk = blk;
4601         pctx->blkcount = blockcnt;
4602
4603         if ((blk < fs->super->s_first_data_block) ||
4604             (blk >= fs->super->s_blocks_count)) {
4605                 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
4606                         *block_nr = 0;
4607                         return BLOCK_CHANGED;
4608                 } else
4609                         return 0;
4610         }
4611
4612         if (blockcnt < 0) {
4613                 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
4614                         p->bbcheck = 1;
4615                         if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
4616                                 *block_nr = 0;
4617                                 return BLOCK_CHANGED;
4618                         }
4619                 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
4620                                                     blk)) {
4621                         p->bbcheck = 1;
4622                         if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
4623                                         pctx)) {
4624                                 *block_nr = 0;
4625                                 return BLOCK_CHANGED;
4626                         }
4627                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4628                                 return BLOCK_ABORT;
4629                 } else
4630                         mark_block_used(ctx, blk);
4631                 return 0;
4632         }
4633
4634         ctx->fs_badblocks_count++;
4635         /*
4636          * If the block is not used, then mark it as used and return.
4637          * If it is already marked as found, this must mean that
4638          * there's an overlap between the filesystem table blocks
4639          * (bitmaps and inode table) and the bad block list.
4640          */
4641         if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
4642                 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
4643                 return 0;
4644         }
4645         /*
4646          * Try to find the where the filesystem block was used...
4647          */
4648         first_block = fs->super->s_first_data_block;
4649
4650         for (i = 0; i < fs->group_desc_count; i++ ) {
4651                 pctx->group = i;
4652                 pctx->blk = blk;
4653                 if (!ext2fs_bg_has_super(fs, i))
4654                         goto skip_super;
4655                 if (blk == first_block) {
4656                         if (i == 0) {
4657                                 if (fix_problem(ctx,
4658                                                 PR_1_BAD_PRIMARY_SUPERBLOCK,
4659                                                 pctx)) {
4660                                         *block_nr = 0;
4661                                         return BLOCK_CHANGED;
4662                                 }
4663                                 return 0;
4664                         }
4665                         fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
4666                         return 0;
4667                 }
4668                 if ((blk > first_block) &&
4669                     (blk <= first_block + fs->desc_blocks)) {
4670                         if (i == 0) {
4671                                 pctx->blk = *block_nr;
4672                                 if (fix_problem(ctx,
4673                         PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
4674                                         *block_nr = 0;
4675                                         return BLOCK_CHANGED;
4676                                 }
4677                                 return 0;
4678                         }
4679                         fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
4680                         return 0;
4681                 }
4682         skip_super:
4683                 if (blk == fs->group_desc[i].bg_block_bitmap) {
4684                         if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
4685                                 ctx->invalid_block_bitmap_flag[i]++;
4686                                 ctx->invalid_bitmaps++;
4687                         }
4688                         return 0;
4689                 }
4690                 if (blk == fs->group_desc[i].bg_inode_bitmap) {
4691                         if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
4692                                 ctx->invalid_inode_bitmap_flag[i]++;
4693                                 ctx->invalid_bitmaps++;
4694                         }
4695                         return 0;
4696                 }
4697                 if ((blk >= fs->group_desc[i].bg_inode_table) &&
4698                     (blk < (fs->group_desc[i].bg_inode_table +
4699                             fs->inode_blocks_per_group))) {
4700                         /*
4701                          * If there are bad blocks in the inode table,
4702                          * the inode scan code will try to do
4703                          * something reasonable automatically.
4704                          */
4705                         return 0;
4706                 }
4707                 first_block += fs->super->s_blocks_per_group;
4708         }
4709         /*
4710          * If we've gotten to this point, then the only
4711          * possibility is that the bad block inode meta data
4712          * is using a bad block.
4713          */
4714         if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
4715             (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
4716             (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
4717                 p->bbcheck = 1;
4718                 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
4719                         *block_nr = 0;
4720                         return BLOCK_CHANGED;
4721                 }
4722                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4723                         return BLOCK_ABORT;
4724                 return 0;
4725         }
4726
4727         pctx->group = -1;
4728
4729         /* Warn user that the block wasn't claimed */
4730         fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
4731
4732         return 0;
4733 }
4734
4735 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
4736                             const char *name, int num, blk_t *new_block)
4737 {
4738         ext2_filsys fs = ctx->fs;
4739         blk_t           old_block = *new_block;
4740         int             i;
4741         char            *buf;
4742         struct problem_context  pctx;
4743
4744         clear_problem_context(&pctx);
4745
4746         pctx.group = group;
4747         pctx.blk = old_block;
4748         pctx.str = name;
4749
4750         pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
4751                         first_block + fs->super->s_blocks_per_group,
4752                                         num, ctx->block_found_map, new_block);
4753         if (pctx.errcode) {
4754                 pctx.num = num;
4755                 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
4756                 ext2fs_unmark_valid(fs);
4757                 return;
4758         }
4759         pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
4760         if (pctx.errcode) {
4761                 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
4762                 ext2fs_unmark_valid(fs);
4763                 return;
4764         }
4765         ext2fs_mark_super_dirty(fs);
4766         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
4767         pctx.blk2 = *new_block;
4768         fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
4769                           PR_1_RELOC_TO), &pctx);
4770         pctx.blk2 = 0;
4771         for (i = 0; i < num; i++) {
4772                 pctx.blk = i;
4773                 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
4774                 if (old_block) {
4775                         pctx.errcode = io_channel_read_blk(fs->io,
4776                                    old_block + i, 1, buf);
4777                         if (pctx.errcode)
4778                                 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
4779                 } else
4780                         memset(buf, 0, fs->blocksize);
4781
4782                 pctx.blk = (*new_block) + i;
4783                 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
4784                                               1, buf);
4785                 if (pctx.errcode)
4786                         fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
4787         }
4788         ext2fs_free_mem(&buf);
4789 }
4790
4791 /*
4792  * This routine gets called at the end of pass 1 if bad blocks are
4793  * detected in the superblock, group descriptors, inode_bitmaps, or
4794  * block bitmaps.  At this point, all of the blocks have been mapped
4795  * out, so we can try to allocate new block(s) to replace the bad
4796  * blocks.
4797  */
4798 static void handle_fs_bad_blocks(e2fsck_t ctx)
4799 {
4800         ext2_filsys fs = ctx->fs;
4801         dgrp_t          i;
4802         int             first_block = fs->super->s_first_data_block;
4803
4804         for (i = 0; i < fs->group_desc_count; i++) {
4805                 if (ctx->invalid_block_bitmap_flag[i]) {
4806                         new_table_block(ctx, first_block, i, _("block bitmap"),
4807                                         1, &fs->group_desc[i].bg_block_bitmap);
4808                 }
4809                 if (ctx->invalid_inode_bitmap_flag[i]) {
4810                         new_table_block(ctx, first_block, i, _("inode bitmap"),
4811                                         1, &fs->group_desc[i].bg_inode_bitmap);
4812                 }
4813                 if (ctx->invalid_inode_table_flag[i]) {
4814                         new_table_block(ctx, first_block, i, _("inode table"),
4815                                         fs->inode_blocks_per_group,
4816                                         &fs->group_desc[i].bg_inode_table);
4817                         ctx->flags |= E2F_FLAG_RESTART;
4818                 }
4819                 first_block += fs->super->s_blocks_per_group;
4820         }
4821         ctx->invalid_bitmaps = 0;
4822 }
4823
4824 /*
4825  * This routine marks all blocks which are used by the superblock,
4826  * group descriptors, inode bitmaps, and block bitmaps.
4827  */
4828 static void mark_table_blocks(e2fsck_t ctx)
4829 {
4830         ext2_filsys fs = ctx->fs;
4831         blk_t   block, b;
4832         dgrp_t  i;
4833         int     j;
4834         struct problem_context pctx;
4835
4836         clear_problem_context(&pctx);
4837
4838         block = fs->super->s_first_data_block;
4839         for (i = 0; i < fs->group_desc_count; i++) {
4840                 pctx.group = i;
4841
4842                 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4843
4844                 /*
4845                  * Mark the blocks used for the inode table
4846                  */
4847                 if (fs->group_desc[i].bg_inode_table) {
4848                         for (j = 0, b = fs->group_desc[i].bg_inode_table;
4849                              j < fs->inode_blocks_per_group;
4850                              j++, b++) {
4851                                 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4852                                                              b)) {
4853                                         pctx.blk = b;
4854                                         if (fix_problem(ctx,
4855                                                 PR_1_ITABLE_CONFLICT, &pctx)) {
4856                                                 ctx->invalid_inode_table_flag[i]++;
4857                                                 ctx->invalid_bitmaps++;
4858                                         }
4859                                 } else {
4860                                     ext2fs_mark_block_bitmap(ctx->block_found_map,
4861                                                              b);
4862                                 }
4863                         }
4864                 }
4865
4866                 /*
4867                  * Mark block used for the block bitmap
4868                  */
4869                 if (fs->group_desc[i].bg_block_bitmap) {
4870                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
4871                                      fs->group_desc[i].bg_block_bitmap)) {
4872                                 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4873                                 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4874                                         ctx->invalid_block_bitmap_flag[i]++;
4875                                         ctx->invalid_bitmaps++;
4876                                 }
4877                         } else {
4878                             ext2fs_mark_block_bitmap(ctx->block_found_map,
4879                                      fs->group_desc[i].bg_block_bitmap);
4880                     }
4881
4882                 }
4883                 /*
4884                  * Mark block used for the inode bitmap
4885                  */
4886                 if (fs->group_desc[i].bg_inode_bitmap) {
4887                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
4888                                      fs->group_desc[i].bg_inode_bitmap)) {
4889                                 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4890                                 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4891                                         ctx->invalid_inode_bitmap_flag[i]++;
4892                                         ctx->invalid_bitmaps++;
4893                                 }
4894                         } else {
4895                             ext2fs_mark_block_bitmap(ctx->block_found_map,
4896                                      fs->group_desc[i].bg_inode_bitmap);
4897                         }
4898                 }
4899                 block += fs->super->s_blocks_per_group;
4900         }
4901 }
4902
4903 /*
4904  * Thes subroutines short circuits ext2fs_get_blocks and
4905  * ext2fs_check_directory; we use them since we already have the inode
4906  * structure, so there's no point in letting the ext2fs library read
4907  * the inode again.
4908  */
4909 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4910                                   blk_t *blocks)
4911 {
4912         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4913         int     i;
4914
4915         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4916                 return EXT2_ET_CALLBACK_NOTHANDLED;
4917
4918         for (i=0; i < EXT2_N_BLOCKS; i++)
4919                 blocks[i] = ctx->stashed_inode->i_block[i];
4920         return 0;
4921 }
4922
4923 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4924                                   struct ext2_inode *inode)
4925 {
4926         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4927
4928         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4929                 return EXT2_ET_CALLBACK_NOTHANDLED;
4930         *inode = *ctx->stashed_inode;
4931         return 0;
4932 }
4933
4934 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4935                             struct ext2_inode *inode)
4936 {
4937         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4938
4939         if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4940                 *ctx->stashed_inode = *inode;
4941         return EXT2_ET_CALLBACK_NOTHANDLED;
4942 }
4943
4944 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4945 {
4946         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4947
4948         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4949                 return EXT2_ET_CALLBACK_NOTHANDLED;
4950
4951         if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4952                 return EXT2_ET_NO_DIRECTORY;
4953         return 0;
4954 }
4955
4956 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4957 {
4958         ext2_filsys fs = ctx->fs;
4959
4960         if (bool) {
4961                 fs->get_blocks = pass1_get_blocks;
4962                 fs->check_directory = pass1_check_directory;
4963                 fs->read_inode = pass1_read_inode;
4964                 fs->write_inode = pass1_write_inode;
4965                 ctx->stashed_ino = 0;
4966         } else {
4967                 fs->get_blocks = 0;
4968                 fs->check_directory = 0;
4969                 fs->read_inode = 0;
4970                 fs->write_inode = 0;
4971         }
4972 }
4973
4974 /*
4975  * pass1b.c --- Pass #1b of e2fsck
4976  *
4977  * This file contains pass1B, pass1C, and pass1D of e2fsck.  They are
4978  * only invoked if pass 1 discovered blocks which are in use by more
4979  * than one inode.
4980  *
4981  * Pass1B scans the data blocks of all the inodes again, generating a
4982  * complete list of duplicate blocks and which inodes have claimed
4983  * them.
4984  *
4985  * Pass1C does a tree-traversal of the filesystem, to determine the
4986  * parent directories of these inodes.  This step is necessary so that
4987  * e2fsck can print out the pathnames of affected inodes.
4988  *
4989  * Pass1D is a reconciliation pass.  For each inode with duplicate
4990  * blocks, the user is prompted if s/he would like to clone the file
4991  * (so that the file gets a fresh copy of the duplicated blocks) or
4992  * simply to delete the file.
4993  *
4994  */
4995
4996
4997 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4998 #define INT_TO_VOIDPTR(val)  ((void *)(intptr_t)(val))
4999 #define VOIDPTR_TO_INT(ptr)  ((int)(intptr_t)(ptr))
5000
5001 /* Define an extension to the ext2 library's block count information */
5002 #define BLOCK_COUNT_EXTATTR     (-5)
5003
5004 struct block_el {
5005         blk_t   block;
5006         struct block_el *next;
5007 };
5008
5009 struct inode_el {
5010         ext2_ino_t      inode;
5011         struct inode_el *next;
5012 };
5013
5014 struct dup_block {
5015         int             num_bad;
5016         struct inode_el *inode_list;
5017 };
5018
5019 /*
5020  * This structure stores information about a particular inode which
5021  * is sharing blocks with other inodes.  This information is collected
5022  * to display to the user, so that the user knows what files he or she
5023  * is dealing with, when trying to decide how to resolve the conflict
5024  * of multiply-claimed blocks.
5025  */
5026 struct dup_inode {
5027         ext2_ino_t              dir;
5028         int                     num_dupblocks;
5029         struct ext2_inode       inode;
5030         struct block_el         *block_list;
5031 };
5032
5033 static int process_pass1b_block(ext2_filsys fs, blk_t   *blocknr,
5034                                 e2_blkcnt_t blockcnt, blk_t ref_blk,
5035                                 int ref_offset, void *priv_data);
5036 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5037                         struct dup_inode *dp, char *block_buf);
5038 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5039                       struct dup_inode *dp, char* block_buf);
5040 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
5041
5042 static void pass1b(e2fsck_t ctx, char *block_buf);
5043 static void pass1c(e2fsck_t ctx, char *block_buf);
5044 static void pass1d(e2fsck_t ctx, char *block_buf);
5045
5046 static int dup_inode_count = 0;
5047
5048 static dict_t blk_dict, ino_dict;
5049
5050 static ext2fs_inode_bitmap inode_dup_map;
5051
5052 static int dict_int_cmp(const void *a, const void *b)
5053 {
5054         intptr_t        ia, ib;
5055
5056         ia = (intptr_t)a;
5057         ib = (intptr_t)b;
5058
5059         return (ia-ib);
5060 }
5061
5062 /*
5063  * Add a duplicate block record
5064  */
5065 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
5066                      struct ext2_inode *inode)
5067 {
5068         dnode_t *n;
5069         struct dup_block        *db;
5070         struct dup_inode        *di;
5071         struct block_el         *blk_el;
5072         struct inode_el         *ino_el;
5073
5074         n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5075         if (n)
5076                 db = (struct dup_block *) dnode_get(n);
5077         else {
5078                 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
5079                          sizeof(struct dup_block), "duplicate block header");
5080                 db->num_bad = 0;
5081                 db->inode_list = 0;
5082                 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
5083         }
5084         ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
5085                          sizeof(struct inode_el), "inode element");
5086         ino_el->inode = ino;
5087         ino_el->next = db->inode_list;
5088         db->inode_list = ino_el;
5089         db->num_bad++;
5090
5091         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
5092         if (n)
5093                 di = (struct dup_inode *) dnode_get(n);
5094         else {
5095                 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
5096                          sizeof(struct dup_inode), "duplicate inode header");
5097                 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
5098                 di->num_dupblocks = 0;
5099                 di->block_list = 0;
5100                 di->inode = *inode;
5101                 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
5102         }
5103         blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
5104                          sizeof(struct block_el), "block element");
5105         blk_el->block = blk;
5106         blk_el->next = di->block_list;
5107         di->block_list = blk_el;
5108         di->num_dupblocks++;
5109 }
5110
5111 /*
5112  * Free a duplicate inode record
5113  */
5114 static void inode_dnode_free(dnode_t *node)
5115 {
5116         struct dup_inode        *di;
5117         struct block_el         *p, *next;
5118
5119         di = (struct dup_inode *) dnode_get(node);
5120         for (p = di->block_list; p; p = next) {
5121                 next = p->next;
5122                 free(p);
5123         }
5124         free(node);
5125 }
5126
5127 /*
5128  * Free a duplicate block record
5129  */
5130 static void block_dnode_free(dnode_t *node)
5131 {
5132         struct dup_block        *db;
5133         struct inode_el         *p, *next;
5134
5135         db = (struct dup_block *) dnode_get(node);
5136         for (p = db->inode_list; p; p = next) {
5137                 next = p->next;
5138                 free(p);
5139         }
5140         free(node);
5141 }
5142
5143
5144 /*
5145  * Main procedure for handling duplicate blocks
5146  */
5147 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
5148 {
5149         ext2_filsys             fs = ctx->fs;
5150         struct problem_context  pctx;
5151
5152         clear_problem_context(&pctx);
5153
5154         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
5155                       _("multiply claimed inode map"), &inode_dup_map);
5156         if (pctx.errcode) {
5157                 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
5158                 ctx->flags |= E2F_FLAG_ABORT;
5159                 return;
5160         }
5161
5162         dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
5163         dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
5164         dict_set_allocator(&ino_dict, inode_dnode_free);
5165         dict_set_allocator(&blk_dict, block_dnode_free);
5166
5167         pass1b(ctx, block_buf);
5168         pass1c(ctx, block_buf);
5169         pass1d(ctx, block_buf);
5170
5171         /*
5172          * Time to free all of the accumulated data structures that we
5173          * don't need anymore.
5174          */
5175         dict_free_nodes(&ino_dict);
5176         dict_free_nodes(&blk_dict);
5177 }
5178
5179 /*
5180  * Scan the inodes looking for inodes that contain duplicate blocks.
5181  */
5182 struct process_block_struct_1b {
5183         e2fsck_t        ctx;
5184         ext2_ino_t      ino;
5185         int             dup_blocks;
5186         struct ext2_inode *inode;
5187         struct problem_context *pctx;
5188 };
5189
5190 static void pass1b(e2fsck_t ctx, char *block_buf)
5191 {
5192         ext2_filsys fs = ctx->fs;
5193         ext2_ino_t ino;
5194         struct ext2_inode inode;
5195         ext2_inode_scan scan;
5196         struct process_block_struct_1b pb;
5197         struct problem_context pctx;
5198
5199         clear_problem_context(&pctx);
5200
5201         if (!(ctx->options & E2F_OPT_PREEN))
5202                 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
5203         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
5204                                               &scan);
5205         if (pctx.errcode) {
5206                 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
5207                 ctx->flags |= E2F_FLAG_ABORT;
5208                 return;
5209         }
5210         ctx->stashed_inode = &inode;
5211         pb.ctx = ctx;
5212         pb.pctx = &pctx;
5213         pctx.str = "pass1b";
5214         while (1) {
5215                 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
5216                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
5217                         continue;
5218                 if (pctx.errcode) {
5219                         fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
5220                         ctx->flags |= E2F_FLAG_ABORT;
5221                         return;
5222                 }
5223                 if (!ino)
5224                         break;
5225                 pctx.ino = ctx->stashed_ino = ino;
5226                 if ((ino != EXT2_BAD_INO) &&
5227                     !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
5228                         continue;
5229
5230                 pb.ino = ino;
5231                 pb.dup_blocks = 0;
5232                 pb.inode = &inode;
5233
5234                 if (ext2fs_inode_has_valid_blocks(&inode) ||
5235                     (ino == EXT2_BAD_INO))
5236                         pctx.errcode = ext2fs_block_iterate2(fs, ino,
5237                                      0, block_buf, process_pass1b_block, &pb);
5238                 if (inode.i_file_acl)
5239                         process_pass1b_block(fs, &inode.i_file_acl,
5240                                              BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5241                 if (pb.dup_blocks) {
5242                         end_problem_latch(ctx, PR_LATCH_DBLOCK);
5243                         if (ino >= EXT2_FIRST_INODE(fs->super) ||
5244                             ino == EXT2_ROOT_INO)
5245                                 dup_inode_count++;
5246                 }
5247                 if (pctx.errcode)
5248                         fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5249         }
5250         ext2fs_close_inode_scan(scan);
5251         e2fsck_use_inode_shortcuts(ctx, 0);
5252 }
5253
5254 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
5255                                 blk_t   *block_nr,
5256                                 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5257                                 blk_t ref_blk FSCK_ATTR((unused)),
5258                                 int ref_offset FSCK_ATTR((unused)),
5259                                 void *priv_data)
5260 {
5261         struct process_block_struct_1b *p;
5262         e2fsck_t ctx;
5263
5264         if (HOLE_BLKADDR(*block_nr))
5265                 return 0;
5266         p = (struct process_block_struct_1b *) priv_data;
5267         ctx = p->ctx;
5268
5269         if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
5270                 return 0;
5271
5272         /* OK, this is a duplicate block */
5273         if (p->ino != EXT2_BAD_INO) {
5274                 p->pctx->blk = *block_nr;
5275                 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
5276         }
5277         p->dup_blocks++;
5278         ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
5279
5280         add_dupe(ctx, p->ino, *block_nr, p->inode);
5281
5282         return 0;
5283 }
5284
5285 /*
5286  * Pass 1c: Scan directories for inodes with duplicate blocks.  This
5287  * is used so that we can print pathnames when prompting the user for
5288  * what to do.
5289  */
5290 struct search_dir_struct {
5291         int             count;
5292         ext2_ino_t      first_inode;
5293         ext2_ino_t      max_inode;
5294 };
5295
5296 static int search_dirent_proc(ext2_ino_t dir, int entry,
5297                               struct ext2_dir_entry *dirent,
5298                               int offset FSCK_ATTR((unused)),
5299                               int blocksize FSCK_ATTR((unused)),
5300                               char *buf FSCK_ATTR((unused)),
5301                               void *priv_data)
5302 {
5303         struct search_dir_struct *sd;
5304         struct dup_inode        *p;
5305         dnode_t                 *n;
5306
5307         sd = (struct search_dir_struct *) priv_data;
5308
5309         if (dirent->inode > sd->max_inode)
5310                 /* Should abort this inode, but not everything */
5311                 return 0;
5312
5313         if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
5314             !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
5315                 return 0;
5316
5317         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
5318         if (!n)
5319                 return 0;
5320         p = (struct dup_inode *) dnode_get(n);
5321         p->dir = dir;
5322         sd->count--;
5323
5324         return(sd->count ? 0 : DIRENT_ABORT);
5325 }
5326
5327
5328 static void pass1c(e2fsck_t ctx, char *block_buf)
5329 {
5330         ext2_filsys fs = ctx->fs;
5331         struct search_dir_struct sd;
5332         struct problem_context pctx;
5333
5334         clear_problem_context(&pctx);
5335
5336         if (!(ctx->options & E2F_OPT_PREEN))
5337                 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
5338
5339         /*
5340          * Search through all directories to translate inodes to names
5341          * (by searching for the containing directory for that inode.)
5342          */
5343         sd.count = dup_inode_count;
5344         sd.first_inode = EXT2_FIRST_INODE(fs->super);
5345         sd.max_inode = fs->super->s_inodes_count;
5346         ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
5347                                   search_dirent_proc, &sd);
5348 }
5349
5350 static void pass1d(e2fsck_t ctx, char *block_buf)
5351 {
5352         ext2_filsys fs = ctx->fs;
5353         struct dup_inode        *p, *t;
5354         struct dup_block        *q;
5355         ext2_ino_t              *shared, ino;
5356         int     shared_len;
5357         int     i;
5358         int     file_ok;
5359         int     meta_data = 0;
5360         struct problem_context pctx;
5361         dnode_t *n, *m;
5362         struct block_el *s;
5363         struct inode_el *r;
5364
5365         clear_problem_context(&pctx);
5366
5367         if (!(ctx->options & E2F_OPT_PREEN))
5368                 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
5369         e2fsck_read_bitmaps(ctx);
5370
5371         pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
5372         fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
5373         shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
5374                                 sizeof(ext2_ino_t) * dict_count(&ino_dict),
5375                                 "Shared inode list");
5376         for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
5377                 p = (struct dup_inode *) dnode_get(n);
5378                 shared_len = 0;
5379                 file_ok = 1;
5380                 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
5381                 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
5382                         continue;
5383
5384                 /*
5385                  * Find all of the inodes which share blocks with this
5386                  * one.  First we find all of the duplicate blocks
5387                  * belonging to this inode, and then search each block
5388                  * get the list of inodes, and merge them together.
5389                  */
5390                 for (s = p->block_list; s; s = s->next) {
5391                         m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5392                         if (!m)
5393                                 continue; /* Should never happen... */
5394                         q = (struct dup_block *) dnode_get(m);
5395                         if (q->num_bad > 1)
5396                                 file_ok = 0;
5397                         if (check_if_fs_block(ctx, s->block)) {
5398                                 file_ok = 0;
5399                                 meta_data = 1;
5400                         }
5401
5402                         /*
5403                          * Add all inodes used by this block to the
5404                          * shared[] --- which is a unique list, so
5405                          * if an inode is already in shared[], don't
5406                          * add it again.
5407                          */
5408                         for (r = q->inode_list; r; r = r->next) {
5409                                 if (r->inode == ino)
5410                                         continue;
5411                                 for (i = 0; i < shared_len; i++)
5412                                         if (shared[i] == r->inode)
5413                                                 break;
5414                                 if (i == shared_len) {
5415                                         shared[shared_len++] = r->inode;
5416                                 }
5417                         }
5418                 }
5419
5420                 /*
5421                  * Report the inode that we are working on
5422                  */
5423                 pctx.inode = &p->inode;
5424                 pctx.ino = ino;
5425                 pctx.dir = p->dir;
5426                 pctx.blkcount = p->num_dupblocks;
5427                 pctx.num = meta_data ? shared_len+1 : shared_len;
5428                 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5429                 pctx.blkcount = 0;
5430                 pctx.num = 0;
5431
5432                 if (meta_data)
5433                         fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5434
5435                 for (i = 0; i < shared_len; i++) {
5436                         m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5437                         if (!m)
5438                                 continue; /* should never happen */
5439                         t = (struct dup_inode *) dnode_get(m);
5440                         /*
5441                          * Report the inode that we are sharing with
5442                          */
5443                         pctx.inode = &t->inode;
5444                         pctx.ino = shared[i];
5445                         pctx.dir = t->dir;
5446                         fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5447                 }
5448                 if (file_ok) {
5449                         fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5450                         continue;
5451                 }
5452                 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5453                         pctx.errcode = clone_file(ctx, ino, p, block_buf);
5454                         if (pctx.errcode)
5455                                 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5456                         else
5457                                 continue;
5458                 }
5459                 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5460                         delete_file(ctx, ino, p, block_buf);
5461                 else
5462                         ext2fs_unmark_valid(fs);
5463         }
5464         ext2fs_free_mem(&shared);
5465 }
5466
5467 /*
5468  * Drop the refcount on the dup_block structure, and clear the entry
5469  * in the block_dup_map if appropriate.
5470  */
5471 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5472 {
5473         p->num_bad--;
5474         if (p->num_bad <= 0 ||
5475             (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5476                 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5477 }
5478
5479 static int delete_file_block(ext2_filsys fs,
5480                              blk_t      *block_nr,
5481                              e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5482                              blk_t ref_block FSCK_ATTR((unused)),
5483                              int ref_offset FSCK_ATTR((unused)),
5484                              void *priv_data)
5485 {
5486         struct process_block_struct_1b *pb;
5487         struct dup_block *p;
5488         dnode_t *n;
5489         e2fsck_t ctx;
5490
5491         pb = (struct process_block_struct_1b *) priv_data;
5492         ctx = pb->ctx;
5493
5494         if (HOLE_BLKADDR(*block_nr))
5495                 return 0;
5496
5497         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5498                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5499                 if (n) {
5500                         p = (struct dup_block *) dnode_get(n);
5501                         decrement_badcount(ctx, *block_nr, p);
5502                 } else
5503                         bb_error_msg(_("internal error; can't find dup_blk for %d\n"),
5504                                 *block_nr);
5505         } else {
5506                 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5507                 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5508         }
5509
5510         return 0;
5511 }
5512
5513 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5514                         struct dup_inode *dp, char* block_buf)
5515 {
5516         ext2_filsys fs = ctx->fs;
5517         struct process_block_struct_1b pb;
5518         struct ext2_inode       inode;
5519         struct problem_context  pctx;
5520         unsigned int            count;
5521
5522         clear_problem_context(&pctx);
5523         pctx.ino = pb.ino = ino;
5524         pb.dup_blocks = dp->num_dupblocks;
5525         pb.ctx = ctx;
5526         pctx.str = "delete_file";
5527
5528         e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5529         if (ext2fs_inode_has_valid_blocks(&inode))
5530                 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5531                                                      delete_file_block, &pb);
5532         if (pctx.errcode)
5533                 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5534         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5535         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5536         if (ctx->inode_bad_map)
5537                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5538         ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5539
5540         /* Inode may have changed by block_iterate, so reread it */
5541         e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5542         inode.i_links_count = 0;
5543         inode.i_dtime = time(0);
5544         if (inode.i_file_acl &&
5545             (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5546                 count = 1;
5547                 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5548                                                    block_buf, -1, &count);
5549                 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5550                         pctx.errcode = 0;
5551                         count = 1;
5552                 }
5553                 if (pctx.errcode) {
5554                         pctx.blk = inode.i_file_acl;
5555                         fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5556                 }
5557                 /*
5558                  * If the count is zero, then arrange to have the
5559                  * block deleted.  If the block is in the block_dup_map,
5560                  * also call delete_file_block since it will take care
5561                  * of keeping the accounting straight.
5562                  */
5563                 if ((count == 0) ||
5564                     ext2fs_test_block_bitmap(ctx->block_dup_map,
5565                                              inode.i_file_acl))
5566                         delete_file_block(fs, &inode.i_file_acl,
5567                                           BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5568         }
5569         e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5570 }
5571
5572 struct clone_struct {
5573         errcode_t       errcode;
5574         ext2_ino_t      dir;
5575         char    *buf;
5576         e2fsck_t ctx;
5577 };
5578
5579 static int clone_file_block(ext2_filsys fs,
5580                             blk_t       *block_nr,
5581                             e2_blkcnt_t blockcnt,
5582                             blk_t ref_block FSCK_ATTR((unused)),
5583                             int ref_offset FSCK_ATTR((unused)),
5584                             void *priv_data)
5585 {
5586         struct dup_block *p;
5587         blk_t   new_block;
5588         errcode_t       retval;
5589         struct clone_struct *cs = (struct clone_struct *) priv_data;
5590         dnode_t *n;
5591         e2fsck_t ctx;
5592
5593         ctx = cs->ctx;
5594
5595         if (HOLE_BLKADDR(*block_nr))
5596                 return 0;
5597
5598         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5599                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5600                 if (n) {
5601                         p = (struct dup_block *) dnode_get(n);
5602                         retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5603                                                   &new_block);
5604                         if (retval) {
5605                                 cs->errcode = retval;
5606                                 return BLOCK_ABORT;
5607                         }
5608                         if (cs->dir && (blockcnt >= 0)) {
5609                                 retval = ext2fs_set_dir_block(fs->dblist,
5610                                       cs->dir, new_block, blockcnt);
5611                                 if (retval) {
5612                                         cs->errcode = retval;
5613                                         return BLOCK_ABORT;
5614                                 }
5615                         }
5616
5617                         retval = io_channel_read_blk(fs->io, *block_nr, 1,
5618                                                      cs->buf);
5619                         if (retval) {
5620                                 cs->errcode = retval;
5621                                 return BLOCK_ABORT;
5622                         }
5623                         retval = io_channel_write_blk(fs->io, new_block, 1,
5624                                                       cs->buf);
5625                         if (retval) {
5626                                 cs->errcode = retval;
5627                                 return BLOCK_ABORT;
5628                         }
5629                         decrement_badcount(ctx, *block_nr, p);
5630                         *block_nr = new_block;
5631                         ext2fs_mark_block_bitmap(ctx->block_found_map,
5632                                                  new_block);
5633                         ext2fs_mark_block_bitmap(fs->block_map, new_block);
5634                         return BLOCK_CHANGED;
5635                 } else
5636                         bb_error_msg(_("internal error; can't find dup_blk for %d\n"),
5637                                 *block_nr);
5638         }
5639         return 0;
5640 }
5641
5642 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5643                       struct dup_inode *dp, char* block_buf)
5644 {
5645         ext2_filsys fs = ctx->fs;
5646         errcode_t       retval;
5647         struct clone_struct cs;
5648         struct problem_context  pctx;
5649         blk_t           blk;
5650         dnode_t         *n;
5651         struct inode_el *ino_el;
5652         struct dup_block        *db;
5653         struct dup_inode        *di;
5654
5655         clear_problem_context(&pctx);
5656         cs.errcode = 0;
5657         cs.dir = 0;
5658         cs.ctx = ctx;
5659         retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5660         if (retval)
5661                 return retval;
5662
5663         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5664                 cs.dir = ino;
5665
5666         pctx.ino = ino;
5667         pctx.str = "clone_file";
5668         if (ext2fs_inode_has_valid_blocks(&dp->inode))
5669                 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5670                                                      clone_file_block, &cs);
5671         ext2fs_mark_bb_dirty(fs);
5672         if (pctx.errcode) {
5673                 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5674                 retval = pctx.errcode;
5675                 goto errout;
5676         }
5677         if (cs.errcode) {
5678                 bb_error_msg(_("returned from clone_file_block"));
5679                 retval = cs.errcode;
5680                 goto errout;
5681         }
5682         /* The inode may have changed on disk, so we have to re-read it */
5683         e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5684         blk = dp->inode.i_file_acl;
5685         if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5686                                      BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5687                     BLOCK_CHANGED)) {
5688                 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5689                 /*
5690                  * If we cloned the EA block, find all other inodes
5691                  * which refered to that EA block, and modify
5692                  * them to point to the new EA block.
5693                  */
5694                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5695                 db = (struct dup_block *) dnode_get(n);
5696                 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5697                         if (ino_el->inode == ino)
5698                                 continue;
5699                         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5700                         di = (struct dup_inode *) dnode_get(n);
5701                         if (di->inode.i_file_acl == blk) {
5702                                 di->inode.i_file_acl = dp->inode.i_file_acl;
5703                                 e2fsck_write_inode(ctx, ino_el->inode,
5704                                            &di->inode, "clone file EA");
5705                                 decrement_badcount(ctx, blk, db);
5706                         }
5707                 }
5708         }
5709         retval = 0;
5710 errout:
5711         ext2fs_free_mem(&cs.buf);
5712         return retval;
5713 }
5714
5715 /*
5716  * This routine returns 1 if a block overlaps with one of the superblocks,
5717  * group descriptors, inode bitmaps, or block bitmaps.
5718  */
5719 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5720 {
5721         ext2_filsys fs = ctx->fs;
5722         blk_t   block;
5723         dgrp_t  i;
5724
5725         block = fs->super->s_first_data_block;
5726         for (i = 0; i < fs->group_desc_count; i++) {
5727
5728                 /* Check superblocks/block group descriptros */
5729                 if (ext2fs_bg_has_super(fs, i)) {
5730                         if (test_block >= block &&
5731                             (test_block <= block + fs->desc_blocks))
5732                                 return 1;
5733                 }
5734
5735                 /* Check the inode table */
5736                 if ((fs->group_desc[i].bg_inode_table) &&
5737                     (test_block >= fs->group_desc[i].bg_inode_table) &&
5738                     (test_block < (fs->group_desc[i].bg_inode_table +
5739                                    fs->inode_blocks_per_group)))
5740                         return 1;
5741
5742                 /* Check the bitmap blocks */
5743                 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5744                     (test_block == fs->group_desc[i].bg_inode_bitmap))
5745                         return 1;
5746
5747                 block += fs->super->s_blocks_per_group;
5748         }
5749         return 0;
5750 }
5751 /*
5752  * pass2.c --- check directory structure
5753  *
5754  * Pass 2 of e2fsck iterates through all active directory inodes, and
5755  * applies to following tests to each directory entry in the directory
5756  * blocks in the inodes:
5757  *
5758  *      - The length of the directory entry (rec_len) should be at
5759  *              least 8 bytes, and no more than the remaining space
5760  *              left in the directory block.
5761  *      - The length of the name in the directory entry (name_len)
5762  *              should be less than (rec_len - 8).
5763  *      - The inode number in the directory entry should be within
5764  *              legal bounds.
5765  *      - The inode number should refer to a in-use inode.
5766  *      - The first entry should be '.', and its inode should be
5767  *              the inode of the directory.
5768  *      - The second entry should be '..'.
5769  *
5770  * To minimize disk seek time, the directory blocks are processed in
5771  * sorted order of block numbers.
5772  *
5773  * Pass 2 also collects the following information:
5774  *      - The inode numbers of the subdirectories for each directory.
5775  *
5776  * Pass 2 relies on the following information from previous passes:
5777  *      - The directory information collected in pass 1.
5778  *      - The inode_used_map bitmap
5779  *      - The inode_bad_map bitmap
5780  *      - The inode_dir_map bitmap
5781  *
5782  * Pass 2 frees the following data structures
5783  *      - The inode_bad_map bitmap
5784  *      - The inode_reg_map bitmap
5785  */
5786
5787 /*
5788  * Keeps track of how many times an inode is referenced.
5789  */
5790 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5791 static int check_dir_block(ext2_filsys fs,
5792                            struct ext2_db_entry *dir_blocks_info,
5793                            void *priv_data);
5794 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5795                               struct problem_context *pctx);
5796 static int update_dir_block(ext2_filsys fs,
5797                             blk_t       *block_nr,
5798                             e2_blkcnt_t blockcnt,
5799                             blk_t       ref_block,
5800                             int         ref_offset,
5801                             void        *priv_data);
5802 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5803 static int htree_depth(struct dx_dir_info *dx_dir,
5804                        struct dx_dirblock_info *dx_db);
5805 static int special_dir_block_cmp(const void *a, const void *b);
5806
5807 struct check_dir_struct {
5808         char *buf;
5809         struct problem_context  pctx;
5810         int     count, max;
5811         e2fsck_t ctx;
5812 };
5813
5814 static void e2fsck_pass2(e2fsck_t ctx)
5815 {
5816         struct ext2_super_block *sb = ctx->fs->super;
5817         struct problem_context  pctx;
5818         ext2_filsys             fs = ctx->fs;
5819         char                    *buf;
5820         struct dir_info         *dir;
5821         struct check_dir_struct cd;
5822         struct dx_dir_info      *dx_dir;
5823         struct dx_dirblock_info *dx_db, *dx_parent;
5824         int                     b;
5825         int                     i, depth;
5826         problem_t               code;
5827         int                     bad_dir;
5828
5829         clear_problem_context(&cd.pctx);
5830
5831         /* Pass 2 */
5832
5833         if (!(ctx->options & E2F_OPT_PREEN))
5834                 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5835
5836         cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5837                                                 0, ctx->inode_link_info,
5838                                                 &ctx->inode_count);
5839         if (cd.pctx.errcode) {
5840                 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5841                 ctx->flags |= E2F_FLAG_ABORT;
5842                 return;
5843         }
5844         buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5845                                               "directory scan buffer");
5846
5847         /*
5848          * Set up the parent pointer for the root directory, if
5849          * present.  (If the root directory is not present, we will
5850          * create it in pass 3.)
5851          */
5852         dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5853         if (dir)
5854                 dir->parent = EXT2_ROOT_INO;
5855
5856         cd.buf = buf;
5857         cd.ctx = ctx;
5858         cd.count = 1;
5859         cd.max = ext2fs_dblist_count(fs->dblist);
5860
5861         if (ctx->progress)
5862                 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5863
5864         if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5865                 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5866
5867         cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5868                                                 &cd);
5869         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5870                 return;
5871         if (cd.pctx.errcode) {
5872                 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5873                 ctx->flags |= E2F_FLAG_ABORT;
5874                 return;
5875         }
5876
5877 #ifdef ENABLE_HTREE
5878         for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5879                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5880                         return;
5881                 if (dx_dir->numblocks == 0)
5882                         continue;
5883                 clear_problem_context(&pctx);
5884                 bad_dir = 0;
5885                 pctx.dir = dx_dir->ino;
5886                 dx_db = dx_dir->dx_block;
5887                 if (dx_db->flags & DX_FLAG_REFERENCED)
5888                         dx_db->flags |= DX_FLAG_DUP_REF;
5889                 else
5890                         dx_db->flags |= DX_FLAG_REFERENCED;
5891                 /*
5892                  * Find all of the first and last leaf blocks, and
5893                  * update their parent's min and max hash values
5894                  */
5895                 for (b=0, dx_db = dx_dir->dx_block;
5896                      b < dx_dir->numblocks;
5897                      b++, dx_db++) {
5898                         if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5899                             !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5900                                 continue;
5901                         dx_parent = &dx_dir->dx_block[dx_db->parent];
5902                         /*
5903                          * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5904                          */
5905                         if (dx_db->flags & DX_FLAG_FIRST)
5906                                 dx_parent->min_hash = dx_db->min_hash;
5907                         /*
5908                          * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5909                          */
5910                         if (dx_db->flags & DX_FLAG_LAST)
5911                                 dx_parent->max_hash = dx_db->max_hash;
5912                 }
5913
5914                 for (b=0, dx_db = dx_dir->dx_block;
5915                      b < dx_dir->numblocks;
5916                      b++, dx_db++) {
5917                         pctx.blkcount = b;
5918                         pctx.group = dx_db->parent;
5919                         code = 0;
5920                         if (!(dx_db->flags & DX_FLAG_FIRST) &&
5921                             (dx_db->min_hash < dx_db->node_min_hash)) {
5922                                 pctx.blk = dx_db->min_hash;
5923                                 pctx.blk2 = dx_db->node_min_hash;
5924                                 code = PR_2_HTREE_MIN_HASH;
5925                                 fix_problem(ctx, code, &pctx);
5926                                 bad_dir++;
5927                         }
5928                         if (dx_db->type == DX_DIRBLOCK_LEAF) {
5929                                 depth = htree_depth(dx_dir, dx_db);
5930                                 if (depth != dx_dir->depth) {
5931                                         code = PR_2_HTREE_BAD_DEPTH;
5932                                         fix_problem(ctx, code, &pctx);
5933                                         bad_dir++;
5934                                 }
5935                         }
5936                         /*
5937                          * This test doesn't apply for the root block
5938                          * at block #0
5939                          */
5940                         if (b &&
5941                             (dx_db->max_hash > dx_db->node_max_hash)) {
5942                                 pctx.blk = dx_db->max_hash;
5943                                 pctx.blk2 = dx_db->node_max_hash;
5944                                 code = PR_2_HTREE_MAX_HASH;
5945                                 fix_problem(ctx, code, &pctx);
5946                                 bad_dir++;
5947                         }
5948                         if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5949                                 code = PR_2_HTREE_NOTREF;
5950                                 fix_problem(ctx, code, &pctx);
5951                                 bad_dir++;
5952                         } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5953                                 code = PR_2_HTREE_DUPREF;
5954                                 fix_problem(ctx, code, &pctx);
5955                                 bad_dir++;
5956                         }
5957                         if (code == 0)
5958                                 continue;
5959                 }
5960                 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5961                         clear_htree(ctx, dx_dir->ino);
5962                         dx_dir->numblocks = 0;
5963                 }
5964         }
5965 #endif
5966         ext2fs_free_mem(&buf);
5967         ext2fs_free_dblist(fs->dblist);
5968
5969         ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5970         ctx->inode_bad_map = 0;
5971         ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5972         ctx->inode_reg_map = 0;
5973
5974         clear_problem_context(&pctx);
5975         if (ctx->large_files) {
5976                 if (!(sb->s_feature_ro_compat &
5977                       EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5978                     fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5979                         sb->s_feature_ro_compat |=
5980                                 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5981                         ext2fs_mark_super_dirty(fs);
5982                 }
5983                 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5984                     fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5985                         ext2fs_update_dynamic_rev(fs);
5986                         ext2fs_mark_super_dirty(fs);
5987                 }
5988         } else if (!ctx->large_files &&
5989             (sb->s_feature_ro_compat &
5990               EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5991                 if (fs->flags & EXT2_FLAG_RW) {
5992                         sb->s_feature_ro_compat &=
5993                                 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5994                         ext2fs_mark_super_dirty(fs);
5995                 }
5996         }
5997
5998 }
5999
6000 #define MAX_DEPTH 32000
6001 static int htree_depth(struct dx_dir_info *dx_dir,
6002                        struct dx_dirblock_info *dx_db)
6003 {
6004         int     depth = 0;
6005
6006         while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
6007                 dx_db = &dx_dir->dx_block[dx_db->parent];
6008                 depth++;
6009         }
6010         return depth;
6011 }
6012
6013 static int dict_de_cmp(const void *a, const void *b)
6014 {
6015         const struct ext2_dir_entry *de_a, *de_b;
6016         int     a_len, b_len;
6017
6018         de_a = (const struct ext2_dir_entry *) a;
6019         a_len = de_a->name_len & 0xFF;
6020         de_b = (const struct ext2_dir_entry *) b;
6021         b_len = de_b->name_len & 0xFF;
6022
6023         if (a_len != b_len)
6024                 return (a_len - b_len);
6025
6026         return strncmp(de_a->name, de_b->name, a_len);
6027 }
6028
6029 /*
6030  * This is special sort function that makes sure that directory blocks
6031  * with a dirblock of zero are sorted to the beginning of the list.
6032  * This guarantees that the root node of the htree directories are
6033  * processed first, so we know what hash version to use.
6034  */
6035 static int special_dir_block_cmp(const void *a, const void *b)
6036 {
6037         const struct ext2_db_entry *db_a =
6038                 (const struct ext2_db_entry *) a;
6039         const struct ext2_db_entry *db_b =
6040                 (const struct ext2_db_entry *) b;
6041
6042         if (db_a->blockcnt && !db_b->blockcnt)
6043                 return 1;
6044
6045         if (!db_a->blockcnt && db_b->blockcnt)
6046                 return -1;
6047
6048         if (db_a->blk != db_b->blk)
6049                 return (int) (db_a->blk - db_b->blk);
6050
6051         if (db_a->ino != db_b->ino)
6052                 return (int) (db_a->ino - db_b->ino);
6053
6054         return (int) (db_a->blockcnt - db_b->blockcnt);
6055 }
6056
6057
6058 /*
6059  * Make sure the first entry in the directory is '.', and that the
6060  * directory entry is sane.
6061  */
6062 static int check_dot(e2fsck_t ctx,
6063                      struct ext2_dir_entry *dirent,
6064                      ext2_ino_t ino, struct problem_context *pctx)
6065 {
6066         struct ext2_dir_entry *nextdir;
6067         int     status = 0;
6068         int     created = 0;
6069         int     new_len;
6070         int     problem = 0;
6071
6072         if (!dirent->inode)
6073                 problem = PR_2_MISSING_DOT;
6074         else if (((dirent->name_len & 0xFF) != 1) ||
6075                  (dirent->name[0] != '.'))
6076                 problem = PR_2_1ST_NOT_DOT;
6077         else if (dirent->name[1] != '\0')
6078                 problem = PR_2_DOT_NULL_TERM;
6079
6080         if (problem) {
6081                 if (fix_problem(ctx, problem, pctx)) {
6082                         if (dirent->rec_len < 12)
6083                                 dirent->rec_len = 12;
6084                         dirent->inode = ino;
6085                         dirent->name_len = 1;
6086                         dirent->name[0] = '.';
6087                         dirent->name[1] = '\0';
6088                         status = 1;
6089                         created = 1;
6090                 }
6091         }
6092         if (dirent->inode != ino) {
6093                 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
6094                         dirent->inode = ino;
6095                         status = 1;
6096                 }
6097         }
6098         if (dirent->rec_len > 12) {
6099                 new_len = dirent->rec_len - 12;
6100                 if (new_len > 12) {
6101                         if (created ||
6102                             fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
6103                                 nextdir = (struct ext2_dir_entry *)
6104                                         ((char *) dirent + 12);
6105                                 dirent->rec_len = 12;
6106                                 nextdir->rec_len = new_len;
6107                                 nextdir->inode = 0;
6108                                 nextdir->name_len = 0;
6109                                 status = 1;
6110                         }
6111                 }
6112         }
6113         return status;
6114 }
6115
6116 /*
6117  * Make sure the second entry in the directory is '..', and that the
6118  * directory entry is sane.  We do not check the inode number of '..'
6119  * here; this gets done in pass 3.
6120  */
6121 static int check_dotdot(e2fsck_t ctx,
6122                         struct ext2_dir_entry *dirent,
6123                         struct dir_info *dir, struct problem_context *pctx)
6124 {
6125         int             problem = 0;
6126
6127         if (!dirent->inode)
6128                 problem = PR_2_MISSING_DOT_DOT;
6129         else if (((dirent->name_len & 0xFF) != 2) ||
6130                  (dirent->name[0] != '.') ||
6131                  (dirent->name[1] != '.'))
6132                 problem = PR_2_2ND_NOT_DOT_DOT;
6133         else if (dirent->name[2] != '\0')
6134                 problem = PR_2_DOT_DOT_NULL_TERM;
6135
6136         if (problem) {
6137                 if (fix_problem(ctx, problem, pctx)) {
6138                         if (dirent->rec_len < 12)
6139                                 dirent->rec_len = 12;
6140                         /*
6141                          * Note: we don't have the parent inode just
6142                          * yet, so we will fill it in with the root
6143                          * inode.  This will get fixed in pass 3.
6144                          */
6145                         dirent->inode = EXT2_ROOT_INO;
6146                         dirent->name_len = 2;
6147                         dirent->name[0] = '.';
6148                         dirent->name[1] = '.';
6149                         dirent->name[2] = '\0';
6150                         return 1;
6151                 }
6152                 return 0;
6153         }
6154         dir->dotdot = dirent->inode;
6155         return 0;
6156 }
6157
6158 /*
6159  * Check to make sure a directory entry doesn't contain any illegal
6160  * characters.
6161  */
6162 static int check_name(e2fsck_t ctx,
6163                       struct ext2_dir_entry *dirent,
6164                       struct problem_context *pctx)
6165 {
6166         int     i;
6167         int     fixup = -1;
6168         int     ret = 0;
6169
6170         for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
6171                 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
6172                         if (fixup < 0) {
6173                                 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
6174                         }
6175                         if (fixup) {
6176                                 dirent->name[i] = '.';
6177                                 ret = 1;
6178                         }
6179                 }
6180         }
6181         return ret;
6182 }
6183
6184 /*
6185  * Check the directory filetype (if present)
6186  */
6187
6188 /*
6189  * Given a mode, return the ext2 file type
6190  */
6191 static int ext2_file_type(unsigned int mode)
6192 {
6193         if (LINUX_S_ISREG(mode))
6194                 return EXT2_FT_REG_FILE;
6195
6196         if (LINUX_S_ISDIR(mode))
6197                 return EXT2_FT_DIR;
6198
6199         if (LINUX_S_ISCHR(mode))
6200                 return EXT2_FT_CHRDEV;
6201
6202         if (LINUX_S_ISBLK(mode))
6203                 return EXT2_FT_BLKDEV;
6204
6205         if (LINUX_S_ISLNK(mode))
6206                 return EXT2_FT_SYMLINK;
6207
6208         if (LINUX_S_ISFIFO(mode))
6209                 return EXT2_FT_FIFO;
6210
6211         if (LINUX_S_ISSOCK(mode))
6212                 return EXT2_FT_SOCK;
6213
6214         return 0;
6215 }
6216
6217 static int check_filetype(e2fsck_t ctx,
6218                                    struct ext2_dir_entry *dirent,
6219                                    struct problem_context *pctx)
6220 {
6221         int     filetype = dirent->name_len >> 8;
6222         int     should_be = EXT2_FT_UNKNOWN;
6223         struct ext2_inode       inode;
6224
6225         if (!(ctx->fs->super->s_feature_incompat &
6226               EXT2_FEATURE_INCOMPAT_FILETYPE)) {
6227                 if (filetype == 0 ||
6228                     !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
6229                         return 0;
6230                 dirent->name_len = dirent->name_len & 0xFF;
6231                 return 1;
6232         }
6233
6234         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
6235                 should_be = EXT2_FT_DIR;
6236         } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
6237                                             dirent->inode)) {
6238                 should_be = EXT2_FT_REG_FILE;
6239         } else if (ctx->inode_bad_map &&
6240                    ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6241                                             dirent->inode))
6242                 should_be = 0;
6243         else {
6244                 e2fsck_read_inode(ctx, dirent->inode, &inode,
6245                                   "check_filetype");
6246                 should_be = ext2_file_type(inode.i_mode);
6247         }
6248         if (filetype == should_be)
6249                 return 0;
6250         pctx->num = should_be;
6251
6252         if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
6253                         pctx) == 0)
6254                 return 0;
6255
6256         dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
6257         return 1;
6258 }
6259
6260 #ifdef ENABLE_HTREE
6261 static void parse_int_node(ext2_filsys fs,
6262                            struct ext2_db_entry *db,
6263                            struct check_dir_struct *cd,
6264                            struct dx_dir_info   *dx_dir,
6265                            char *block_buf)
6266 {
6267         struct          ext2_dx_root_info  *root;
6268         struct          ext2_dx_entry *ent;
6269         struct          ext2_dx_countlimit *limit;
6270         struct dx_dirblock_info *dx_db;
6271         int             i, expect_limit, count;
6272         blk_t           blk;
6273         ext2_dirhash_t  min_hash = 0xffffffff;
6274         ext2_dirhash_t  max_hash = 0;
6275         ext2_dirhash_t  hash = 0, prev_hash;
6276
6277         if (db->blockcnt == 0) {
6278                 root = (struct ext2_dx_root_info *) (block_buf + 24);
6279                 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
6280         } else {
6281                 ent = (struct ext2_dx_entry *) (block_buf+8);
6282         }
6283         limit = (struct ext2_dx_countlimit *) ent;
6284
6285         count = ext2fs_le16_to_cpu(limit->count);
6286         expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
6287                 sizeof(struct ext2_dx_entry);
6288         if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
6289                 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
6290                 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
6291                         goto clear_and_exit;
6292         }
6293         if (count > expect_limit) {
6294                 cd->pctx.num = count;
6295                 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
6296                         goto clear_and_exit;
6297                 count = expect_limit;
6298         }
6299
6300         for (i=0; i < count; i++) {
6301                 prev_hash = hash;
6302                 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
6303                 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
6304                 /* Check to make sure the block is valid */
6305                 if (blk > (blk_t) dx_dir->numblocks) {
6306                         cd->pctx.blk = blk;
6307                         if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
6308                                         &cd->pctx))
6309                                 goto clear_and_exit;
6310                 }
6311                 if (hash < prev_hash &&
6312                     fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
6313                         goto clear_and_exit;
6314                 dx_db = &dx_dir->dx_block[blk];
6315                 if (dx_db->flags & DX_FLAG_REFERENCED) {
6316                         dx_db->flags |= DX_FLAG_DUP_REF;
6317                 } else {
6318                         dx_db->flags |= DX_FLAG_REFERENCED;
6319                         dx_db->parent = db->blockcnt;
6320                 }
6321                 if (hash < min_hash)
6322                         min_hash = hash;
6323                 if (hash > max_hash)
6324                         max_hash = hash;
6325                 dx_db->node_min_hash = hash;
6326                 if ((i+1) < count)
6327                         dx_db->node_max_hash =
6328                           ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
6329                 else {
6330                         dx_db->node_max_hash = 0xfffffffe;
6331                         dx_db->flags |= DX_FLAG_LAST;
6332                 }
6333                 if (i == 0)
6334                         dx_db->flags |= DX_FLAG_FIRST;
6335         }
6336         dx_db = &dx_dir->dx_block[db->blockcnt];
6337         dx_db->min_hash = min_hash;
6338         dx_db->max_hash = max_hash;
6339         return;
6340
6341 clear_and_exit:
6342         clear_htree(cd->ctx, cd->pctx.ino);
6343         dx_dir->numblocks = 0;
6344 }
6345 #endif /* ENABLE_HTREE */
6346
6347 /*
6348  * Given a busted directory, try to salvage it somehow.
6349  *
6350  */
6351 static void salvage_directory(ext2_filsys fs,
6352                               struct ext2_dir_entry *dirent,
6353                               struct ext2_dir_entry *prev,
6354                               unsigned int *offset)
6355 {
6356         char    *cp = (char *) dirent;
6357         int left = fs->blocksize - *offset - dirent->rec_len;
6358         int name_len = dirent->name_len & 0xFF;
6359
6360         /*
6361          * Special case of directory entry of size 8: copy what's left
6362          * of the directory block up to cover up the invalid hole.
6363          */
6364         if ((left >= 12) && (dirent->rec_len == 8)) {
6365                 memmove(cp, cp+8, left);
6366                 memset(cp + left, 0, 8);
6367                 return;
6368         }
6369         /*
6370          * If the directory entry overruns the end of the directory
6371          * block, and the name is small enough to fit, then adjust the
6372          * record length.
6373          */
6374         if ((left < 0) &&
6375             (name_len + 8 <= dirent->rec_len + left) &&
6376             dirent->inode <= fs->super->s_inodes_count &&
6377             strnlen(dirent->name, name_len) == name_len) {
6378                 dirent->rec_len += left;
6379                 return;
6380         }
6381         /*
6382          * If the directory entry is a multiple of four, so it is
6383          * valid, let the previous directory entry absorb the invalid
6384          * one.
6385          */
6386         if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
6387                 prev->rec_len += dirent->rec_len;
6388                 *offset += dirent->rec_len;
6389                 return;
6390         }
6391         /*
6392          * Default salvage method --- kill all of the directory
6393          * entries for the rest of the block.  We will either try to
6394          * absorb it into the previous directory entry, or create a
6395          * new empty directory entry the rest of the directory block.
6396          */
6397         if (prev) {
6398                 prev->rec_len += fs->blocksize - *offset;
6399                 *offset = fs->blocksize;
6400         } else {
6401                 dirent->rec_len = fs->blocksize - *offset;
6402                 dirent->name_len = 0;
6403                 dirent->inode = 0;
6404         }
6405 }
6406
6407 static int check_dir_block(ext2_filsys fs,
6408                            struct ext2_db_entry *db,
6409                            void *priv_data)
6410 {
6411         struct dir_info         *subdir, *dir;
6412         struct dx_dir_info      *dx_dir;
6413 #ifdef ENABLE_HTREE
6414         struct dx_dirblock_info *dx_db = 0;
6415 #endif /* ENABLE_HTREE */
6416         struct ext2_dir_entry   *dirent, *prev;
6417         ext2_dirhash_t          hash;
6418         unsigned int            offset = 0;
6419         int                     dir_modified = 0;
6420         int                     dot_state;
6421         blk_t                   block_nr = db->blk;
6422         ext2_ino_t              ino = db->ino;
6423         __u16                   links;
6424         struct check_dir_struct *cd;
6425         char                    *buf;
6426         e2fsck_t                ctx;
6427         int                     problem;
6428         struct ext2_dx_root_info *root;
6429         struct ext2_dx_countlimit *limit;
6430         static dict_t de_dict;
6431         struct problem_context  pctx;
6432         int     dups_found = 0;
6433
6434         cd = (struct check_dir_struct *) priv_data;
6435         buf = cd->buf;
6436         ctx = cd->ctx;
6437
6438         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6439                 return DIRENT_ABORT;
6440
6441         if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6442                 return DIRENT_ABORT;
6443
6444         /*
6445          * Make sure the inode is still in use (could have been
6446          * deleted in the duplicate/bad blocks pass.
6447          */
6448         if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6449                 return 0;
6450
6451         cd->pctx.ino = ino;
6452         cd->pctx.blk = block_nr;
6453         cd->pctx.blkcount = db->blockcnt;
6454         cd->pctx.ino2 = 0;
6455         cd->pctx.dirent = 0;
6456         cd->pctx.num = 0;
6457
6458         if (db->blk == 0) {
6459                 if (allocate_dir_block(ctx, db, &cd->pctx))
6460                         return 0;
6461                 block_nr = db->blk;
6462         }
6463
6464         if (db->blockcnt)
6465                 dot_state = 2;
6466         else
6467                 dot_state = 0;
6468
6469         if (ctx->dirs_to_hash &&
6470             ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6471                 dups_found++;
6472
6473         cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6474         if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6475                 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6476         if (cd->pctx.errcode) {
6477                 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6478                         ctx->flags |= E2F_FLAG_ABORT;
6479                         return DIRENT_ABORT;
6480                 }
6481                 memset(buf, 0, fs->blocksize);
6482         }
6483 #ifdef ENABLE_HTREE
6484         dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6485         if (dx_dir && dx_dir->numblocks) {
6486                 if (db->blockcnt >= dx_dir->numblocks) {
6487                         printf("XXX should never happen!!!\n");
6488                         abort();
6489                 }
6490                 dx_db = &dx_dir->dx_block[db->blockcnt];
6491                 dx_db->type = DX_DIRBLOCK_LEAF;
6492                 dx_db->phys = block_nr;
6493                 dx_db->min_hash = ~0;
6494                 dx_db->max_hash = 0;
6495
6496                 dirent = (struct ext2_dir_entry *) buf;
6497                 limit = (struct ext2_dx_countlimit *) (buf+8);
6498                 if (db->blockcnt == 0) {
6499                         root = (struct ext2_dx_root_info *) (buf + 24);
6500                         dx_db->type = DX_DIRBLOCK_ROOT;
6501                         dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6502                         if ((root->reserved_zero ||
6503                              root->info_length < 8 ||
6504                              root->indirect_levels > 1) &&
6505                             fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6506                                 clear_htree(ctx, ino);
6507                                 dx_dir->numblocks = 0;
6508                                 dx_db = 0;
6509                         }
6510                         dx_dir->hashversion = root->hash_version;
6511                         dx_dir->depth = root->indirect_levels + 1;
6512                 } else if ((dirent->inode == 0) &&
6513                            (dirent->rec_len == fs->blocksize) &&
6514                            (dirent->name_len == 0) &&
6515                            (ext2fs_le16_to_cpu(limit->limit) ==
6516                             ((fs->blocksize-8) /
6517                              sizeof(struct ext2_dx_entry))))
6518                         dx_db->type = DX_DIRBLOCK_NODE;
6519         }
6520 #endif /* ENABLE_HTREE */
6521
6522         dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6523         prev = 0;
6524         do {
6525                 problem = 0;
6526                 dirent = (struct ext2_dir_entry *) (buf + offset);
6527                 cd->pctx.dirent = dirent;
6528                 cd->pctx.num = offset;
6529                 if (((offset + dirent->rec_len) > fs->blocksize) ||
6530                     (dirent->rec_len < 12) ||
6531                     ((dirent->rec_len % 4) != 0) ||
6532                     (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6533                         if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6534                                 salvage_directory(fs, dirent, prev, &offset);
6535                                 dir_modified++;
6536                                 continue;
6537                         } else
6538                                 goto abort_free_dict;
6539                 }
6540                 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6541                         if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6542                                 dirent->name_len = EXT2_NAME_LEN;
6543                                 dir_modified++;
6544                         }
6545                 }
6546
6547                 if (dot_state == 0) {
6548                         if (check_dot(ctx, dirent, ino, &cd->pctx))
6549                                 dir_modified++;
6550                 } else if (dot_state == 1) {
6551                         dir = e2fsck_get_dir_info(ctx, ino);
6552                         if (!dir) {
6553                                 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6554                                 goto abort_free_dict;
6555                         }
6556                         if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6557                                 dir_modified++;
6558                 } else if (dirent->inode == ino) {
6559                         problem = PR_2_LINK_DOT;
6560                         if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6561                                 dirent->inode = 0;
6562                                 dir_modified++;
6563                                 goto next;
6564                         }
6565                 }
6566                 if (!dirent->inode)
6567                         goto next;
6568
6569                 /*
6570                  * Make sure the inode listed is a legal one.
6571                  */
6572                 if (((dirent->inode != EXT2_ROOT_INO) &&
6573                      (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6574                     (dirent->inode > fs->super->s_inodes_count)) {
6575                         problem = PR_2_BAD_INO;
6576                 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6577                                                dirent->inode))) {
6578                         /*
6579                          * If the inode is unused, offer to clear it.
6580                          */
6581                         problem = PR_2_UNUSED_INODE;
6582                 } else if (ctx->inode_bb_map &&
6583                            (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
6584                                                      dirent->inode))) {
6585                         /*
6586                          * If the inode is in a bad block, offer to
6587                          * clear it.
6588                          */
6589                         problem = PR_2_BB_INODE;
6590                 } else if ((dot_state > 1) &&
6591                            ((dirent->name_len & 0xFF) == 1) &&
6592                            (dirent->name[0] == '.')) {
6593                         /*
6594                          * If there's a '.' entry in anything other
6595                          * than the first directory entry, it's a
6596                          * duplicate entry that should be removed.
6597                          */
6598                         problem = PR_2_DUP_DOT;
6599                 } else if ((dot_state > 1) &&
6600                            ((dirent->name_len & 0xFF) == 2) &&
6601                            (dirent->name[0] == '.') &&
6602                            (dirent->name[1] == '.')) {
6603                         /*
6604                          * If there's a '..' entry in anything other
6605                          * than the second directory entry, it's a
6606                          * duplicate entry that should be removed.
6607                          */
6608                         problem = PR_2_DUP_DOT_DOT;
6609                 } else if ((dot_state > 1) &&
6610                            (dirent->inode == EXT2_ROOT_INO)) {
6611                         /*
6612                          * Don't allow links to the root directory.
6613                          * We check this specially to make sure we
6614                          * catch this error case even if the root
6615                          * directory hasn't been created yet.
6616                          */
6617                         problem = PR_2_LINK_ROOT;
6618                 } else if ((dot_state > 1) &&
6619                            (dirent->name_len & 0xFF) == 0) {
6620                         /*
6621                          * Don't allow zero-length directory names.
6622                          */
6623                         problem = PR_2_NULL_NAME;
6624                 }
6625
6626                 if (problem) {
6627                         if (fix_problem(ctx, problem, &cd->pctx)) {
6628                                 dirent->inode = 0;
6629                                 dir_modified++;
6630                                 goto next;
6631                         } else {
6632                                 ext2fs_unmark_valid(fs);
6633                                 if (problem == PR_2_BAD_INO)
6634                                         goto next;
6635                         }
6636                 }
6637
6638                 /*
6639                  * If the inode was marked as having bad fields in
6640                  * pass1, process it and offer to fix/clear it.
6641                  * (We wait until now so that we can display the
6642                  * pathname to the user.)
6643                  */
6644                 if (ctx->inode_bad_map &&
6645                     ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6646                                              dirent->inode)) {
6647                         if (e2fsck_process_bad_inode(ctx, ino,
6648                                                      dirent->inode,
6649                                                      buf + fs->blocksize)) {
6650                                 dirent->inode = 0;
6651                                 dir_modified++;
6652                                 goto next;
6653                         }
6654                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6655                                 return DIRENT_ABORT;
6656                 }
6657
6658                 if (check_name(ctx, dirent, &cd->pctx))
6659                         dir_modified++;
6660
6661                 if (check_filetype(ctx, dirent, &cd->pctx))
6662                         dir_modified++;
6663
6664 #ifdef ENABLE_HTREE
6665                 if (dx_db) {
6666                         ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6667                                        (dirent->name_len & 0xFF),
6668                                        fs->super->s_hash_seed, &hash, 0);
6669                         if (hash < dx_db->min_hash)
6670                                 dx_db->min_hash = hash;
6671                         if (hash > dx_db->max_hash)
6672                                 dx_db->max_hash = hash;
6673                 }
6674 #endif
6675
6676                 /*
6677                  * If this is a directory, then mark its parent in its
6678                  * dir_info structure.  If the parent field is already
6679                  * filled in, then this directory has more than one
6680                  * hard link.  We assume the first link is correct,
6681                  * and ask the user if he/she wants to clear this one.
6682                  */
6683                 if ((dot_state > 1) &&
6684                     (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6685                                               dirent->inode))) {
6686                         subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6687                         if (!subdir) {
6688                                 cd->pctx.ino = dirent->inode;
6689                                 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6690                                 goto abort_free_dict;
6691                         }
6692                         if (subdir->parent) {
6693                                 cd->pctx.ino2 = subdir->parent;
6694                                 if (fix_problem(ctx, PR_2_LINK_DIR,
6695                                                 &cd->pctx)) {
6696                                         dirent->inode = 0;
6697                                         dir_modified++;
6698                                         goto next;
6699                                 }
6700                                 cd->pctx.ino2 = 0;
6701                         } else
6702                                 subdir->parent = ino;
6703                 }
6704
6705                 if (dups_found) {
6706                         ;
6707                 } else if (dict_lookup(&de_dict, dirent)) {
6708                         clear_problem_context(&pctx);
6709                         pctx.ino = ino;
6710                         pctx.dirent = dirent;
6711                         fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6712                         if (!ctx->dirs_to_hash)
6713                                 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6714                         if (ctx->dirs_to_hash)
6715                                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6716                         dups_found++;
6717                 } else
6718                         dict_alloc_insert(&de_dict, dirent, dirent);
6719
6720                 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6721                                         &links);
6722                 if (links > 1)
6723                         ctx->fs_links_count++;
6724                 ctx->fs_total_count++;
6725         next:
6726                 prev = dirent;
6727                 offset += dirent->rec_len;
6728                 dot_state++;
6729         } while (offset < fs->blocksize);
6730 #ifdef ENABLE_HTREE
6731         if (dx_db) {
6732                 cd->pctx.dir = cd->pctx.ino;
6733                 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6734                     (dx_db->type == DX_DIRBLOCK_NODE))
6735                         parse_int_node(fs, db, cd, dx_dir, buf);
6736         }
6737 #endif /* ENABLE_HTREE */
6738         if (offset != fs->blocksize) {
6739                 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6740                 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6741                         dirent->rec_len = cd->pctx.num;
6742                         dir_modified++;
6743                 }
6744         }
6745         if (dir_modified) {
6746                 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6747                 if (cd->pctx.errcode) {
6748                         if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6749                                          &cd->pctx))
6750                                 goto abort_free_dict;
6751                 }
6752                 ext2fs_mark_changed(fs);
6753         }
6754         dict_free_nodes(&de_dict);
6755         return 0;
6756 abort_free_dict:
6757         dict_free_nodes(&de_dict);
6758         ctx->flags |= E2F_FLAG_ABORT;
6759         return DIRENT_ABORT;
6760 }
6761
6762 /*
6763  * This function is called to deallocate a block, and is an interator
6764  * functioned called by deallocate inode via ext2fs_iterate_block().
6765  */
6766 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6767                                   e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6768                                   blk_t ref_block FSCK_ATTR((unused)),
6769                                   int ref_offset FSCK_ATTR((unused)),
6770                                   void *priv_data)
6771 {
6772         e2fsck_t        ctx = (e2fsck_t) priv_data;
6773
6774         if (HOLE_BLKADDR(*block_nr))
6775                 return 0;
6776         if ((*block_nr < fs->super->s_first_data_block) ||
6777             (*block_nr >= fs->super->s_blocks_count))
6778                 return 0;
6779         ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6780         ext2fs_block_alloc_stats(fs, *block_nr, -1);
6781         return 0;
6782 }
6783
6784 /*
6785  * This fuction deallocates an inode
6786  */
6787 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6788 {
6789         ext2_filsys fs = ctx->fs;
6790         struct ext2_inode       inode;
6791         struct problem_context  pctx;
6792         __u32                   count;
6793
6794         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6795         e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6796         inode.i_links_count = 0;
6797         inode.i_dtime = time(0);
6798         e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6799         clear_problem_context(&pctx);
6800         pctx.ino = ino;
6801
6802         /*
6803          * Fix up the bitmaps...
6804          */
6805         e2fsck_read_bitmaps(ctx);
6806         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6807         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6808         if (ctx->inode_bad_map)
6809                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6810         ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6811
6812         if (inode.i_file_acl &&
6813             (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6814                 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6815                                                    block_buf, -1, &count);
6816                 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6817                         pctx.errcode = 0;
6818                         count = 1;
6819                 }
6820                 if (pctx.errcode) {
6821                         pctx.blk = inode.i_file_acl;
6822                         fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6823                         ctx->flags |= E2F_FLAG_ABORT;
6824                         return;
6825                 }
6826                 if (count == 0) {
6827                         ext2fs_unmark_block_bitmap(ctx->block_found_map,
6828                                                    inode.i_file_acl);
6829                         ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6830                 }
6831                 inode.i_file_acl = 0;
6832         }
6833
6834         if (!ext2fs_inode_has_valid_blocks(&inode))
6835                 return;
6836
6837         if (LINUX_S_ISREG(inode.i_mode) &&
6838             (inode.i_size_high || inode.i_size & 0x80000000UL))
6839                 ctx->large_files--;
6840
6841         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6842                                             deallocate_inode_block, ctx);
6843         if (pctx.errcode) {
6844                 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6845                 ctx->flags |= E2F_FLAG_ABORT;
6846                 return;
6847         }
6848 }
6849
6850 /*
6851  * This fuction clears the htree flag on an inode
6852  */
6853 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6854 {
6855         struct ext2_inode       inode;
6856
6857         e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6858         inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6859         e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6860         if (ctx->dirs_to_hash)
6861                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6862 }
6863
6864
6865 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6866                                     ext2_ino_t ino, char *buf)
6867 {
6868         ext2_filsys fs = ctx->fs;
6869         struct ext2_inode       inode;
6870         int                     inode_modified = 0;
6871         int                     not_fixed = 0;
6872         unsigned char           *frag, *fsize;
6873         struct problem_context  pctx;
6874         int     problem = 0;
6875
6876         e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6877
6878         clear_problem_context(&pctx);
6879         pctx.ino = ino;
6880         pctx.dir = dir;
6881         pctx.inode = &inode;
6882
6883         if (inode.i_file_acl &&
6884             !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6885             fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6886                 inode.i_file_acl = 0;
6887 #if BB_BIG_ENDIAN
6888                 /*
6889                  * This is a special kludge to deal with long symlinks
6890                  * on big endian systems.  i_blocks had already been
6891                  * decremented earlier in pass 1, but since i_file_acl
6892                  * hadn't yet been cleared, ext2fs_read_inode()
6893                  * assumed that the file was short symlink and would
6894                  * not have byte swapped i_block[0].  Hence, we have
6895                  * to byte-swap it here.
6896                  */
6897                 if (LINUX_S_ISLNK(inode.i_mode) &&
6898                     (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6899                     (inode.i_blocks == fs->blocksize >> 9))
6900                         inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6901 #endif
6902                 inode_modified++;
6903         } else
6904                 not_fixed++;
6905
6906         if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6907             !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6908             !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6909             !(LINUX_S_ISSOCK(inode.i_mode)))
6910                 problem = PR_2_BAD_MODE;
6911         else if (LINUX_S_ISCHR(inode.i_mode)
6912                  && !e2fsck_pass1_check_device_inode(fs, &inode))
6913                 problem = PR_2_BAD_CHAR_DEV;
6914         else if (LINUX_S_ISBLK(inode.i_mode)
6915                  && !e2fsck_pass1_check_device_inode(fs, &inode))
6916                 problem = PR_2_BAD_BLOCK_DEV;
6917         else if (LINUX_S_ISFIFO(inode.i_mode)
6918                  && !e2fsck_pass1_check_device_inode(fs, &inode))
6919                 problem = PR_2_BAD_FIFO;
6920         else if (LINUX_S_ISSOCK(inode.i_mode)
6921                  && !e2fsck_pass1_check_device_inode(fs, &inode))
6922                 problem = PR_2_BAD_SOCKET;
6923         else if (LINUX_S_ISLNK(inode.i_mode)
6924                  && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6925                 problem = PR_2_INVALID_SYMLINK;
6926         }
6927
6928         if (problem) {
6929                 if (fix_problem(ctx, problem, &pctx)) {
6930                         deallocate_inode(ctx, ino, 0);
6931                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6932                                 return 0;
6933                         return 1;
6934                 } else
6935                         not_fixed++;
6936                 problem = 0;
6937         }
6938
6939         if (inode.i_faddr) {
6940                 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6941                         inode.i_faddr = 0;
6942                         inode_modified++;
6943                 } else
6944                         not_fixed++;
6945         }
6946
6947         switch (fs->super->s_creator_os) {
6948             case EXT2_OS_LINUX:
6949                 frag = &inode.osd2.linux2.l_i_frag;
6950                 fsize = &inode.osd2.linux2.l_i_fsize;
6951                 break;
6952             case EXT2_OS_HURD:
6953                 frag = &inode.osd2.hurd2.h_i_frag;
6954                 fsize = &inode.osd2.hurd2.h_i_fsize;
6955                 break;
6956             case EXT2_OS_MASIX:
6957                 frag = &inode.osd2.masix2.m_i_frag;
6958                 fsize = &inode.osd2.masix2.m_i_fsize;
6959                 break;
6960             default:
6961                 frag = fsize = 0;
6962         }
6963         if (frag && *frag) {
6964                 pctx.num = *frag;
6965                 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6966                         *frag = 0;
6967                         inode_modified++;
6968                 } else
6969                         not_fixed++;
6970                 pctx.num = 0;
6971         }
6972         if (fsize && *fsize) {
6973                 pctx.num = *fsize;
6974                 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6975                         *fsize = 0;
6976                         inode_modified++;
6977                 } else
6978                         not_fixed++;
6979                 pctx.num = 0;
6980         }
6981
6982         if (inode.i_file_acl &&
6983             ((inode.i_file_acl < fs->super->s_first_data_block) ||
6984              (inode.i_file_acl >= fs->super->s_blocks_count))) {
6985                 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6986                         inode.i_file_acl = 0;
6987                         inode_modified++;
6988                 } else
6989                         not_fixed++;
6990         }
6991         if (inode.i_dir_acl &&
6992             LINUX_S_ISDIR(inode.i_mode)) {
6993                 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6994                         inode.i_dir_acl = 0;
6995                         inode_modified++;
6996                 } else
6997                         not_fixed++;
6998         }
6999
7000         if (inode_modified)
7001                 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
7002         if (!not_fixed)
7003                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7004         return 0;
7005 }
7006
7007
7008 /*
7009  * allocate_dir_block --- this function allocates a new directory
7010  *      block for a particular inode; this is done if a directory has
7011  *      a "hole" in it, or if a directory has a illegal block number
7012  *      that was zeroed out and now needs to be replaced.
7013  */
7014 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
7015                               struct problem_context *pctx)
7016 {
7017         ext2_filsys fs = ctx->fs;
7018         blk_t                   blk;
7019         char                    *block;
7020         struct ext2_inode       inode;
7021
7022         if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
7023                 return 1;
7024
7025         /*
7026          * Read the inode and block bitmaps in; we'll be messing with
7027          * them.
7028          */
7029         e2fsck_read_bitmaps(ctx);
7030
7031         /*
7032          * First, find a free block
7033          */
7034         pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7035         if (pctx->errcode) {
7036                 pctx->str = "ext2fs_new_block";
7037                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7038                 return 1;
7039         }
7040         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7041         ext2fs_mark_block_bitmap(fs->block_map, blk);
7042         ext2fs_mark_bb_dirty(fs);
7043
7044         /*
7045          * Now let's create the actual data block for the inode
7046          */
7047         if (db->blockcnt)
7048                 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
7049         else
7050                 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
7051                                                      EXT2_ROOT_INO, &block);
7052
7053         if (pctx->errcode) {
7054                 pctx->str = "ext2fs_new_dir_block";
7055                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7056                 return 1;
7057         }
7058
7059         pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
7060         ext2fs_free_mem(&block);
7061         if (pctx->errcode) {
7062                 pctx->str = "ext2fs_write_dir_block";
7063                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7064                 return 1;
7065         }
7066
7067         /*
7068          * Update the inode block count
7069          */
7070         e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
7071         inode.i_blocks += fs->blocksize / 512;
7072         if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
7073                 inode.i_size = (db->blockcnt+1) * fs->blocksize;
7074         e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
7075
7076         /*
7077          * Finally, update the block pointers for the inode
7078          */
7079         db->blk = blk;
7080         pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
7081                                       0, update_dir_block, db);
7082         if (pctx->errcode) {
7083                 pctx->str = "ext2fs_block_iterate";
7084                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7085                 return 1;
7086         }
7087
7088         return 0;
7089 }
7090
7091 /*
7092  * This is a helper function for allocate_dir_block().
7093  */
7094 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
7095                             blk_t       *block_nr,
7096                             e2_blkcnt_t blockcnt,
7097                             blk_t ref_block FSCK_ATTR((unused)),
7098                             int ref_offset FSCK_ATTR((unused)),
7099                             void *priv_data)
7100 {
7101         struct ext2_db_entry *db;
7102
7103         db = (struct ext2_db_entry *) priv_data;
7104         if (db->blockcnt == (int) blockcnt) {
7105                 *block_nr = db->blk;
7106                 return BLOCK_CHANGED;
7107         }
7108         return 0;
7109 }
7110
7111 /*
7112  * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
7113  *
7114  * Pass #3 assures that all directories are connected to the
7115  * filesystem tree, using the following algorithm:
7116  *
7117  * First, the root directory is checked to make sure it exists; if
7118  * not, e2fsck will offer to create a new one.  It is then marked as
7119  * "done".
7120  *
7121  * Then, pass3 interates over all directory inodes; for each directory
7122  * it attempts to trace up the filesystem tree, using dirinfo.parent
7123  * until it reaches a directory which has been marked "done".  If it
7124  * can not do so, then the directory must be disconnected, and e2fsck
7125  * will offer to reconnect it to /lost+found.  While it is chasing
7126  * parent pointers up the filesystem tree, if pass3 sees a directory
7127  * twice, then it has detected a filesystem loop, and it will again
7128  * offer to reconnect the directory to /lost+found in to break the
7129  * filesystem loop.
7130  *
7131  * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
7132  * reconnect inodes to /lost+found; this subroutine is also used by
7133  * pass 4.  e2fsck_reconnect_file() calls get_lost_and_found(), which
7134  * is responsible for creating /lost+found if it does not exist.
7135  *
7136  * Pass 3 frees the following data structures:
7137  *      - The dirinfo directory information cache.
7138  */
7139
7140 static void check_root(e2fsck_t ctx);
7141 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
7142                            struct problem_context *pctx);
7143 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
7144
7145 static ext2fs_inode_bitmap inode_loop_detect;
7146 static ext2fs_inode_bitmap inode_done_map;
7147
7148 static void e2fsck_pass3(e2fsck_t ctx)
7149 {
7150         ext2_filsys fs = ctx->fs;
7151         int             i;
7152         struct problem_context  pctx;
7153         struct dir_info *dir;
7154         unsigned long maxdirs, count;
7155
7156         clear_problem_context(&pctx);
7157
7158         /* Pass 3 */
7159
7160         if (!(ctx->options & E2F_OPT_PREEN))
7161                 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
7162
7163         /*
7164          * Allocate some bitmaps to do loop detection.
7165          */
7166         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
7167                                                     &inode_done_map);
7168         if (pctx.errcode) {
7169                 pctx.num = 2;
7170                 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
7171                 ctx->flags |= E2F_FLAG_ABORT;
7172                 goto abort_exit;
7173         }
7174         check_root(ctx);
7175         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7176                 goto abort_exit;
7177
7178         ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
7179
7180         maxdirs = e2fsck_get_num_dirinfo(ctx);
7181         count = 1;
7182
7183         if (ctx->progress)
7184                 if ((ctx->progress)(ctx, 3, 0, maxdirs))
7185                         goto abort_exit;
7186
7187         for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
7188                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7189                         goto abort_exit;
7190                 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
7191                         goto abort_exit;
7192                 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
7193                         if (check_directory(ctx, dir, &pctx))
7194                                 goto abort_exit;
7195         }
7196
7197         /*
7198          * Force the creation of /lost+found if not present
7199          */
7200         if ((ctx->flags & E2F_OPT_READONLY) == 0)
7201                 e2fsck_get_lost_and_found(ctx, 1);
7202
7203         /*
7204          * If there are any directories that need to be indexed or
7205          * optimized, do it here.
7206          */
7207         e2fsck_rehash_directories(ctx);
7208
7209 abort_exit:
7210         e2fsck_free_dir_info(ctx);
7211         ext2fs_free_inode_bitmap(inode_loop_detect);
7212         inode_loop_detect = 0;
7213         ext2fs_free_inode_bitmap(inode_done_map);
7214         inode_done_map = 0;
7215 }
7216
7217 /*
7218  * This makes sure the root inode is present; if not, we ask if the
7219  * user wants us to create it.  Not creating it is a fatal error.
7220  */
7221 static void check_root(e2fsck_t ctx)
7222 {
7223         ext2_filsys fs = ctx->fs;
7224         blk_t                   blk;
7225         struct ext2_inode       inode;
7226         char *                  block;
7227         struct problem_context  pctx;
7228
7229         clear_problem_context(&pctx);
7230
7231         if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
7232                 /*
7233                  * If the root inode is not a directory, die here.  The
7234                  * user must have answered 'no' in pass1 when we
7235                  * offered to clear it.
7236                  */
7237                 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
7238                                                EXT2_ROOT_INO))) {
7239                         fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
7240                         ctx->flags |= E2F_FLAG_ABORT;
7241                 }
7242                 return;
7243         }
7244
7245         if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
7246                 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
7247                 ctx->flags |= E2F_FLAG_ABORT;
7248                 return;
7249         }
7250
7251         e2fsck_read_bitmaps(ctx);
7252
7253         /*
7254          * First, find a free block
7255          */
7256         pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7257         if (pctx.errcode) {
7258                 pctx.str = "ext2fs_new_block";
7259                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7260                 ctx->flags |= E2F_FLAG_ABORT;
7261                 return;
7262         }
7263         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7264         ext2fs_mark_block_bitmap(fs->block_map, blk);
7265         ext2fs_mark_bb_dirty(fs);
7266
7267         /*
7268          * Now let's create the actual data block for the inode
7269          */
7270         pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
7271                                             &block);
7272         if (pctx.errcode) {
7273                 pctx.str = "ext2fs_new_dir_block";
7274                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7275                 ctx->flags |= E2F_FLAG_ABORT;
7276                 return;
7277         }
7278
7279         pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
7280         if (pctx.errcode) {
7281                 pctx.str = "ext2fs_write_dir_block";
7282                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7283                 ctx->flags |= E2F_FLAG_ABORT;
7284                 return;
7285         }
7286         ext2fs_free_mem(&block);
7287
7288         /*
7289          * Set up the inode structure
7290          */
7291         memset(&inode, 0, sizeof(inode));
7292         inode.i_mode = 040755;
7293         inode.i_size = fs->blocksize;
7294         inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7295         inode.i_links_count = 2;
7296         inode.i_blocks = fs->blocksize / 512;
7297         inode.i_block[0] = blk;
7298
7299         /*
7300          * Write out the inode.
7301          */
7302         pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
7303         if (pctx.errcode) {
7304                 pctx.str = "ext2fs_write_inode";
7305                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7306                 ctx->flags |= E2F_FLAG_ABORT;
7307                 return;
7308         }
7309
7310         /*
7311          * Miscellaneous bookkeeping...
7312          */
7313         e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
7314         ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
7315         ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
7316
7317         ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
7318         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
7319         ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
7320         ext2fs_mark_ib_dirty(fs);
7321 }
7322
7323 /*
7324  * This subroutine is responsible for making sure that a particular
7325  * directory is connected to the root; if it isn't we trace it up as
7326  * far as we can go, and then offer to connect the resulting parent to
7327  * the lost+found.  We have to do loop detection; if we ever discover
7328  * a loop, we treat that as a disconnected directory and offer to
7329  * reparent it to lost+found.
7330  *
7331  * However, loop detection is expensive, because for very large
7332  * filesystems, the inode_loop_detect bitmap is huge, and clearing it
7333  * is non-trivial.  Loops in filesystems are also a rare error case,
7334  * and we shouldn't optimize for error cases.  So we try two passes of
7335  * the algorithm.  The first time, we ignore loop detection and merely
7336  * increment a counter; if the counter exceeds some extreme threshold,
7337  * then we try again with the loop detection bitmap enabled.
7338  */
7339 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
7340                            struct problem_context *pctx)
7341 {
7342         ext2_filsys     fs = ctx->fs;
7343         struct dir_info *p = dir;
7344         int             loop_pass = 0, parent_count = 0;
7345
7346         if (!p)
7347                 return 0;
7348
7349         while (1) {
7350                 /*
7351                  * Mark this inode as being "done"; by the time we
7352                  * return from this function, the inode we either be
7353                  * verified as being connected to the directory tree,
7354                  * or we will have offered to reconnect this to
7355                  * lost+found.
7356                  *
7357                  * If it was marked done already, then we've reached a
7358                  * parent we've already checked.
7359                  */
7360                 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
7361                         break;
7362
7363                 /*
7364                  * If this directory doesn't have a parent, or we've
7365                  * seen the parent once already, then offer to
7366                  * reparent it to lost+found
7367                  */
7368                 if (!p->parent ||
7369                     (loop_pass &&
7370                      (ext2fs_test_inode_bitmap(inode_loop_detect,
7371                                               p->parent)))) {
7372                         pctx->ino = p->ino;
7373                         if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
7374                                 if (e2fsck_reconnect_file(ctx, pctx->ino))
7375                                         ext2fs_unmark_valid(fs);
7376                                 else {
7377                                         p = e2fsck_get_dir_info(ctx, pctx->ino);
7378                                         p->parent = ctx->lost_and_found;
7379                                         fix_dotdot(ctx, p, ctx->lost_and_found);
7380                                 }
7381                         }
7382                         break;
7383                 }
7384                 p = e2fsck_get_dir_info(ctx, p->parent);
7385                 if (!p) {
7386                         fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
7387                         return 0;
7388                 }
7389                 if (loop_pass) {
7390                         ext2fs_mark_inode_bitmap(inode_loop_detect,
7391                                                  p->ino);
7392                 } else if (parent_count++ > 2048) {
7393                         /*
7394                          * If we've run into a path depth that's
7395                          * greater than 2048, try again with the inode
7396                          * loop bitmap turned on and start from the
7397                          * top.
7398                          */
7399                         loop_pass = 1;
7400                         if (inode_loop_detect)
7401                                 ext2fs_clear_inode_bitmap(inode_loop_detect);
7402                         else {
7403                                 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7404                                 if (pctx->errcode) {
7405                                         pctx->num = 1;
7406                                         fix_problem(ctx,
7407                                     PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7408                                         ctx->flags |= E2F_FLAG_ABORT;
7409                                         return -1;
7410                                 }
7411                         }
7412                         p = dir;
7413                 }
7414         }
7415
7416         /*
7417          * Make sure that .. and the parent directory are the same;
7418          * offer to fix it if not.
7419          */
7420         if (dir->parent != dir->dotdot) {
7421                 pctx->ino = dir->ino;
7422                 pctx->ino2 = dir->dotdot;
7423                 pctx->dir = dir->parent;
7424                 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7425                         fix_dotdot(ctx, dir, dir->parent);
7426         }
7427         return 0;
7428 }
7429
7430 /*
7431  * This routine gets the lost_and_found inode, making it a directory
7432  * if necessary
7433  */
7434 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7435 {
7436         ext2_filsys fs = ctx->fs;
7437         ext2_ino_t                      ino;
7438         blk_t                   blk;
7439         errcode_t               retval;
7440         struct ext2_inode       inode;
7441         char *                  block;
7442         static const char       name[] = "lost+found";
7443         struct  problem_context pctx;
7444         struct dir_info         *dirinfo;
7445
7446         if (ctx->lost_and_found)
7447                 return ctx->lost_and_found;
7448
7449         clear_problem_context(&pctx);
7450
7451         retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7452                                sizeof(name)-1, 0, &ino);
7453         if (retval && !fix)
7454                 return 0;
7455         if (!retval) {
7456                 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7457                         ctx->lost_and_found = ino;
7458                         return ino;
7459                 }
7460
7461                 /* Lost+found isn't a directory! */
7462                 if (!fix)
7463                         return 0;
7464                 pctx.ino = ino;
7465                 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7466                         return 0;
7467
7468                 /* OK, unlink the old /lost+found file. */
7469                 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7470                 if (pctx.errcode) {
7471                         pctx.str = "ext2fs_unlink";
7472                         fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7473                         return 0;
7474                 }
7475                 dirinfo = e2fsck_get_dir_info(ctx, ino);
7476                 if (dirinfo)
7477                         dirinfo->parent = 0;
7478                 e2fsck_adjust_inode_count(ctx, ino, -1);
7479         } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7480                 pctx.errcode = retval;
7481                 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7482         }
7483         if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7484                 return 0;
7485
7486         /*
7487          * Read the inode and block bitmaps in; we'll be messing with
7488          * them.
7489          */
7490         e2fsck_read_bitmaps(ctx);
7491
7492         /*
7493          * First, find a free block
7494          */
7495         retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7496         if (retval) {
7497                 pctx.errcode = retval;
7498                 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7499                 return 0;
7500         }
7501         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7502         ext2fs_block_alloc_stats(fs, blk, +1);
7503
7504         /*
7505          * Next find a free inode.
7506          */
7507         retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7508                                   ctx->inode_used_map, &ino);
7509         if (retval) {
7510                 pctx.errcode = retval;
7511                 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7512                 return 0;
7513         }
7514         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7515         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7516         ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7517
7518         /*
7519          * Now let's create the actual data block for the inode
7520          */
7521         retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7522         if (retval) {
7523                 pctx.errcode = retval;
7524                 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7525                 return 0;
7526         }
7527
7528         retval = ext2fs_write_dir_block(fs, blk, block);
7529         ext2fs_free_mem(&block);
7530         if (retval) {
7531                 pctx.errcode = retval;
7532                 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7533                 return 0;
7534         }
7535
7536         /*
7537          * Set up the inode structure
7538          */
7539         memset(&inode, 0, sizeof(inode));
7540         inode.i_mode = 040700;
7541         inode.i_size = fs->blocksize;
7542         inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7543         inode.i_links_count = 2;
7544         inode.i_blocks = fs->blocksize / 512;
7545         inode.i_block[0] = blk;
7546
7547         /*
7548          * Next, write out the inode.
7549          */
7550         pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7551         if (pctx.errcode) {
7552                 pctx.str = "ext2fs_write_inode";
7553                 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7554                 return 0;
7555         }
7556         /*
7557          * Finally, create the directory link
7558          */
7559         pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7560         if (pctx.errcode) {
7561                 pctx.str = "ext2fs_link";
7562                 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7563                 return 0;
7564         }
7565
7566         /*
7567          * Miscellaneous bookkeeping that needs to be kept straight.
7568          */
7569         e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7570         e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7571         ext2fs_icount_store(ctx->inode_count, ino, 2);
7572         ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7573         ctx->lost_and_found = ino;
7574         return ino;
7575 }
7576
7577 /*
7578  * This routine will connect a file to lost+found
7579  */
7580 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7581 {
7582         ext2_filsys fs = ctx->fs;
7583         errcode_t       retval;
7584         char            name[80];
7585         struct problem_context  pctx;
7586         struct ext2_inode       inode;
7587         int             file_type = 0;
7588
7589         clear_problem_context(&pctx);
7590         pctx.ino = ino;
7591
7592         if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7593                 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7594                         ctx->bad_lost_and_found++;
7595         }
7596         if (ctx->bad_lost_and_found) {
7597                 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7598                 return 1;
7599         }
7600
7601         sprintf(name, "#%u", ino);
7602         if (ext2fs_read_inode(fs, ino, &inode) == 0)
7603                 file_type = ext2_file_type(inode.i_mode);
7604         retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7605         if (retval == EXT2_ET_DIR_NO_SPACE) {
7606                 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7607                         return 1;
7608                 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7609                                                  1, 0);
7610                 if (retval) {
7611                         pctx.errcode = retval;
7612                         fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7613                         return 1;
7614                 }
7615                 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7616                                      ino, file_type);
7617         }
7618         if (retval) {
7619                 pctx.errcode = retval;
7620                 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7621                 return 1;
7622         }
7623         e2fsck_adjust_inode_count(ctx, ino, 1);
7624
7625         return 0;
7626 }
7627
7628 /*
7629  * Utility routine to adjust the inode counts on an inode.
7630  */
7631 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7632 {
7633         ext2_filsys fs = ctx->fs;
7634         errcode_t               retval;
7635         struct ext2_inode       inode;
7636
7637         if (!ino)
7638                 return 0;
7639
7640         retval = ext2fs_read_inode(fs, ino, &inode);
7641         if (retval)
7642                 return retval;
7643
7644         if (adj == 1) {
7645                 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7646                 if (inode.i_links_count == (__u16) ~0)
7647                         return 0;
7648                 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7649                 inode.i_links_count++;
7650         } else if (adj == -1) {
7651                 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7652                 if (inode.i_links_count == 0)
7653                         return 0;
7654                 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7655                 inode.i_links_count--;
7656         }
7657
7658         retval = ext2fs_write_inode(fs, ino, &inode);
7659         if (retval)
7660                 return retval;
7661
7662         return 0;
7663 }
7664
7665 /*
7666  * Fix parent --- this routine fixes up the parent of a directory.
7667  */
7668 struct fix_dotdot_struct {
7669         ext2_filsys     fs;
7670         ext2_ino_t      parent;
7671         int             done;
7672         e2fsck_t        ctx;
7673 };
7674
7675 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7676                            int  offset FSCK_ATTR((unused)),
7677                            int  blocksize FSCK_ATTR((unused)),
7678                            char *buf FSCK_ATTR((unused)),
7679                            void *priv_data)
7680 {
7681         struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7682         errcode_t       retval;
7683         struct problem_context pctx;
7684
7685         if ((dirent->name_len & 0xFF) != 2)
7686                 return 0;
7687         if (strncmp(dirent->name, "..", 2))
7688                 return 0;
7689
7690         clear_problem_context(&pctx);
7691
7692         retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7693         if (retval) {
7694                 pctx.errcode = retval;
7695                 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7696         }
7697         retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7698         if (retval) {
7699                 pctx.errcode = retval;
7700                 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7701         }
7702         dirent->inode = fp->parent;
7703
7704         fp->done++;
7705         return DIRENT_ABORT | DIRENT_CHANGED;
7706 }
7707
7708 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7709 {
7710         ext2_filsys fs = ctx->fs;
7711         errcode_t       retval;
7712         struct fix_dotdot_struct fp;
7713         struct problem_context pctx;
7714
7715         fp.fs = fs;
7716         fp.parent = parent;
7717         fp.done = 0;
7718         fp.ctx = ctx;
7719
7720         retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7721                                     0, fix_dotdot_proc, &fp);
7722         if (retval || !fp.done) {
7723                 clear_problem_context(&pctx);
7724                 pctx.ino = dir->ino;
7725                 pctx.errcode = retval;
7726                 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7727                             PR_3_FIX_PARENT_NOFIND, &pctx);
7728                 ext2fs_unmark_valid(fs);
7729         }
7730         dir->dotdot = parent;
7731
7732         return;
7733 }
7734
7735 /*
7736  * These routines are responsible for expanding a /lost+found if it is
7737  * too small.
7738  */
7739
7740 struct expand_dir_struct {
7741         int                     num;
7742         int                     guaranteed_size;
7743         int                     newblocks;
7744         int                     last_block;
7745         errcode_t               err;
7746         e2fsck_t                ctx;
7747 };
7748
7749 static int expand_dir_proc(ext2_filsys fs,
7750                            blk_t        *blocknr,
7751                            e2_blkcnt_t  blockcnt,
7752                            blk_t ref_block FSCK_ATTR((unused)),
7753                            int ref_offset FSCK_ATTR((unused)),
7754                            void *priv_data)
7755 {
7756         struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7757         blk_t   new_blk;
7758         static blk_t    last_blk = 0;
7759         char            *block;
7760         errcode_t       retval;
7761         e2fsck_t        ctx;
7762
7763         ctx = es->ctx;
7764
7765         if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7766                 return BLOCK_ABORT;
7767
7768         if (blockcnt > 0)
7769                 es->last_block = blockcnt;
7770         if (*blocknr) {
7771                 last_blk = *blocknr;
7772                 return 0;
7773         }
7774         retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7775                                   &new_blk);
7776         if (retval) {
7777                 es->err = retval;
7778                 return BLOCK_ABORT;
7779         }
7780         if (blockcnt > 0) {
7781                 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7782                 if (retval) {
7783                         es->err = retval;
7784                         return BLOCK_ABORT;
7785                 }
7786                 es->num--;
7787                 retval = ext2fs_write_dir_block(fs, new_blk, block);
7788         } else {
7789                 retval = ext2fs_get_mem(fs->blocksize, &block);
7790                 if (retval) {
7791                         es->err = retval;
7792                         return BLOCK_ABORT;
7793                 }
7794                 memset(block, 0, fs->blocksize);
7795                 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7796         }
7797         if (retval) {
7798                 es->err = retval;
7799                 return BLOCK_ABORT;
7800         }
7801         ext2fs_free_mem(&block);
7802         *blocknr = new_blk;
7803         ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7804         ext2fs_block_alloc_stats(fs, new_blk, +1);
7805         es->newblocks++;
7806
7807         if (es->num == 0)
7808                 return (BLOCK_CHANGED | BLOCK_ABORT);
7809         else
7810                 return BLOCK_CHANGED;
7811 }
7812
7813 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7814                                   int num, int guaranteed_size)
7815 {
7816         ext2_filsys fs = ctx->fs;
7817         errcode_t       retval;
7818         struct expand_dir_struct es;
7819         struct ext2_inode       inode;
7820
7821         if (!(fs->flags & EXT2_FLAG_RW))
7822                 return EXT2_ET_RO_FILSYS;
7823
7824         /*
7825          * Read the inode and block bitmaps in; we'll be messing with
7826          * them.
7827          */
7828         e2fsck_read_bitmaps(ctx);
7829
7830         retval = ext2fs_check_directory(fs, dir);
7831         if (retval)
7832                 return retval;
7833
7834         es.num = num;
7835         es.guaranteed_size = guaranteed_size;
7836         es.last_block = 0;
7837         es.err = 0;
7838         es.newblocks = 0;
7839         es.ctx = ctx;
7840
7841         retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7842                                        0, expand_dir_proc, &es);
7843
7844         if (es.err)
7845                 return es.err;
7846
7847         /*
7848          * Update the size and block count fields in the inode.
7849          */
7850         retval = ext2fs_read_inode(fs, dir, &inode);
7851         if (retval)
7852                 return retval;
7853
7854         inode.i_size = (es.last_block + 1) * fs->blocksize;
7855         inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7856
7857         e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7858
7859         return 0;
7860 }
7861
7862 /*
7863  * pass4.c -- pass #4 of e2fsck: Check reference counts
7864  *
7865  * Pass 4 frees the following data structures:
7866  *      - A bitmap of which inodes are in bad blocks.   (inode_bb_map)
7867  *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
7868  */
7869
7870 /*
7871  * This routine is called when an inode is not connected to the
7872  * directory tree.
7873  *
7874  * This subroutine returns 1 then the caller shouldn't bother with the
7875  * rest of the pass 4 tests.
7876  */
7877 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7878 {
7879         ext2_filsys fs = ctx->fs;
7880         struct ext2_inode       inode;
7881         struct problem_context  pctx;
7882
7883         e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7884         clear_problem_context(&pctx);
7885         pctx.ino = i;
7886         pctx.inode = &inode;
7887
7888         /*
7889          * Offer to delete any zero-length files that does not have
7890          * blocks.  If there is an EA block, it might have useful
7891          * information, so we won't prompt to delete it, but let it be
7892          * reconnected to lost+found.
7893          */
7894         if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7895                                 LINUX_S_ISDIR(inode.i_mode))) {
7896                 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7897                         ext2fs_icount_store(ctx->inode_link_info, i, 0);
7898                         inode.i_links_count = 0;
7899                         inode.i_dtime = time(0);
7900                         e2fsck_write_inode(ctx, i, &inode,
7901                                            "disconnect_inode");
7902                         /*
7903                          * Fix up the bitmaps...
7904                          */
7905                         e2fsck_read_bitmaps(ctx);
7906                         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7907                         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7908                         ext2fs_inode_alloc_stats2(fs, i, -1,
7909                                                   LINUX_S_ISDIR(inode.i_mode));
7910                         return 0;
7911                 }
7912         }
7913
7914         /*
7915          * Prompt to reconnect.
7916          */
7917         if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7918                 if (e2fsck_reconnect_file(ctx, i))
7919                         ext2fs_unmark_valid(fs);
7920         } else {
7921                 /*
7922                  * If we don't attach the inode, then skip the
7923                  * i_links_test since there's no point in trying to
7924                  * force i_links_count to zero.
7925                  */
7926                 ext2fs_unmark_valid(fs);
7927                 return 1;
7928         }
7929         return 0;
7930 }
7931
7932
7933 static void e2fsck_pass4(e2fsck_t ctx)
7934 {
7935         ext2_filsys fs = ctx->fs;
7936         ext2_ino_t      i;
7937         struct ext2_inode       inode;
7938         struct problem_context  pctx;
7939         __u16   link_count, link_counted;
7940         char    *buf = 0;
7941         int     group, maxgroup;
7942
7943         /* Pass 4 */
7944
7945         clear_problem_context(&pctx);
7946
7947         if (!(ctx->options & E2F_OPT_PREEN))
7948                 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7949
7950         group = 0;
7951         maxgroup = fs->group_desc_count;
7952         if (ctx->progress)
7953                 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7954                         return;
7955
7956         for (i=1; i <= fs->super->s_inodes_count; i++) {
7957                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7958                         return;
7959                 if ((i % fs->super->s_inodes_per_group) == 0) {
7960                         group++;
7961                         if (ctx->progress)
7962                                 if ((ctx->progress)(ctx, 4, group, maxgroup))
7963                                         return;
7964                 }
7965                 if (i == EXT2_BAD_INO ||
7966                     (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7967                         continue;
7968                 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7969                     (ctx->inode_imagic_map &&
7970                      ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
7971                     (ctx->inode_bb_map &&
7972                      ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
7973                         continue;
7974                 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7975                 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7976                 if (link_counted == 0) {
7977                         if (!buf)
7978                                 buf = e2fsck_allocate_memory(ctx,
7979                                      fs->blocksize, "bad_inode buffer");
7980                         if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7981                                 continue;
7982                         if (disconnect_inode(ctx, i))
7983                                 continue;
7984                         ext2fs_icount_fetch(ctx->inode_link_info, i,
7985                                             &link_count);
7986                         ext2fs_icount_fetch(ctx->inode_count, i,
7987                                             &link_counted);
7988                 }
7989                 if (link_counted != link_count) {
7990                         e2fsck_read_inode(ctx, i, &inode, "pass4");
7991                         pctx.ino = i;
7992                         pctx.inode = &inode;
7993                         if (link_count != inode.i_links_count) {
7994                                 pctx.num = link_count;
7995                                 fix_problem(ctx,
7996                                             PR_4_INCONSISTENT_COUNT, &pctx);
7997                         }
7998                         pctx.num = link_counted;
7999                         if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
8000                                 inode.i_links_count = link_counted;
8001                                 e2fsck_write_inode(ctx, i, &inode, "pass4");
8002                         }
8003                 }
8004         }
8005         ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
8006         ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
8007         ext2fs_free_inode_bitmap(ctx->inode_bb_map);
8008         ctx->inode_bb_map = 0;
8009         ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
8010         ctx->inode_imagic_map = 0;
8011         ext2fs_free_mem(&buf);
8012 }
8013
8014 /*
8015  * pass5.c --- check block and inode bitmaps against on-disk bitmaps
8016  */
8017
8018 #define NO_BLK ((blk_t) -1)
8019
8020 static void print_bitmap_problem(e2fsck_t ctx, int problem,
8021                             struct problem_context *pctx)
8022 {
8023         switch (problem) {
8024         case PR_5_BLOCK_UNUSED:
8025                 if (pctx->blk == pctx->blk2)
8026                         pctx->blk2 = 0;
8027                 else
8028                         problem = PR_5_BLOCK_RANGE_UNUSED;
8029                 break;
8030         case PR_5_BLOCK_USED:
8031                 if (pctx->blk == pctx->blk2)
8032                         pctx->blk2 = 0;
8033                 else
8034                         problem = PR_5_BLOCK_RANGE_USED;
8035                 break;
8036         case PR_5_INODE_UNUSED:
8037                 if (pctx->ino == pctx->ino2)
8038                         pctx->ino2 = 0;
8039                 else
8040                         problem = PR_5_INODE_RANGE_UNUSED;
8041                 break;
8042         case PR_5_INODE_USED:
8043                 if (pctx->ino == pctx->ino2)
8044                         pctx->ino2 = 0;
8045                 else
8046                         problem = PR_5_INODE_RANGE_USED;
8047                 break;
8048         }
8049         fix_problem(ctx, problem, pctx);
8050         pctx->blk = pctx->blk2 = NO_BLK;
8051         pctx->ino = pctx->ino2 = 0;
8052 }
8053
8054 static void check_block_bitmaps(e2fsck_t ctx)
8055 {
8056         ext2_filsys fs = ctx->fs;
8057         blk_t   i;
8058         int     *free_array;
8059         int     group = 0;
8060         unsigned int    blocks = 0;
8061         unsigned int    free_blocks = 0;
8062         int     group_free = 0;
8063         int     actual, bitmap;
8064         struct problem_context  pctx;
8065         int     problem, save_problem, fixit, had_problem;
8066         errcode_t       retval;
8067
8068         clear_problem_context(&pctx);
8069         free_array = (int *) e2fsck_allocate_memory(ctx,
8070             fs->group_desc_count * sizeof(int), "free block count array");
8071
8072         if ((fs->super->s_first_data_block <
8073              ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
8074             (fs->super->s_blocks_count-1 >
8075              ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
8076                 pctx.num = 1;
8077                 pctx.blk = fs->super->s_first_data_block;
8078                 pctx.blk2 = fs->super->s_blocks_count -1;
8079                 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
8080                 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
8081                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8082
8083                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8084                 return;
8085         }
8086
8087         if ((fs->super->s_first_data_block <
8088              ext2fs_get_block_bitmap_start(fs->block_map)) ||
8089             (fs->super->s_blocks_count-1 >
8090              ext2fs_get_block_bitmap_end(fs->block_map))) {
8091                 pctx.num = 2;
8092                 pctx.blk = fs->super->s_first_data_block;
8093                 pctx.blk2 = fs->super->s_blocks_count -1;
8094                 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
8095                 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
8096                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8097
8098                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8099                 return;
8100         }
8101
8102 redo_counts:
8103         had_problem = 0;
8104         save_problem = 0;
8105         pctx.blk = pctx.blk2 = NO_BLK;
8106         for (i = fs->super->s_first_data_block;
8107              i < fs->super->s_blocks_count;
8108              i++) {
8109                 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
8110                 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
8111
8112                 if (actual == bitmap)
8113                         goto do_counts;
8114
8115                 if (!actual && bitmap) {
8116                         /*
8117                          * Block not used, but marked in use in the bitmap.
8118                          */
8119                         problem = PR_5_BLOCK_UNUSED;
8120                 } else {
8121                         /*
8122                          * Block used, but not marked in use in the bitmap.
8123                          */
8124                         problem = PR_5_BLOCK_USED;
8125                 }
8126                 if (pctx.blk == NO_BLK) {
8127                         pctx.blk = pctx.blk2 = i;
8128                         save_problem = problem;
8129                 } else {
8130                         if ((problem == save_problem) &&
8131                             (pctx.blk2 == i-1))
8132                                 pctx.blk2++;
8133                         else {
8134                                 print_bitmap_problem(ctx, save_problem, &pctx);
8135                                 pctx.blk = pctx.blk2 = i;
8136                                 save_problem = problem;
8137                         }
8138                 }
8139                 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
8140                 had_problem++;
8141
8142         do_counts:
8143                 if (!bitmap) {
8144                         group_free++;
8145                         free_blocks++;
8146                 }
8147                 blocks ++;
8148                 if ((blocks == fs->super->s_blocks_per_group) ||
8149                     (i == fs->super->s_blocks_count-1)) {
8150                         free_array[group] = group_free;
8151                         group ++;
8152                         blocks = 0;
8153                         group_free = 0;
8154                         if (ctx->progress)
8155                                 if ((ctx->progress)(ctx, 5, group,
8156                                                     fs->group_desc_count*2))
8157                                         return;
8158                 }
8159         }
8160         if (pctx.blk != NO_BLK)
8161                 print_bitmap_problem(ctx, save_problem, &pctx);
8162         if (had_problem)
8163                 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
8164         else
8165                 fixit = -1;
8166         ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
8167
8168         if (fixit == 1) {
8169                 ext2fs_free_block_bitmap(fs->block_map);
8170                 retval = ext2fs_copy_bitmap(ctx->block_found_map,
8171                                                   &fs->block_map);
8172                 if (retval) {
8173                         clear_problem_context(&pctx);
8174                         fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
8175                         ctx->flags |= E2F_FLAG_ABORT;
8176                         return;
8177                 }
8178                 ext2fs_set_bitmap_padding(fs->block_map);
8179                 ext2fs_mark_bb_dirty(fs);
8180
8181                 /* Redo the counts */
8182                 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
8183                 memset(free_array, 0, fs->group_desc_count * sizeof(int));
8184                 goto redo_counts;
8185         } else if (fixit == 0)
8186                 ext2fs_unmark_valid(fs);
8187
8188         for (i = 0; i < fs->group_desc_count; i++) {
8189                 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
8190                         pctx.group = i;
8191                         pctx.blk = fs->group_desc[i].bg_free_blocks_count;
8192                         pctx.blk2 = free_array[i];
8193
8194                         if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
8195                                         &pctx)) {
8196                                 fs->group_desc[i].bg_free_blocks_count =
8197                                         free_array[i];
8198                                 ext2fs_mark_super_dirty(fs);
8199                         } else
8200                                 ext2fs_unmark_valid(fs);
8201                 }
8202         }
8203         if (free_blocks != fs->super->s_free_blocks_count) {
8204                 pctx.group = 0;
8205                 pctx.blk = fs->super->s_free_blocks_count;
8206                 pctx.blk2 = free_blocks;
8207
8208                 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
8209                         fs->super->s_free_blocks_count = free_blocks;
8210                         ext2fs_mark_super_dirty(fs);
8211                 } else
8212                         ext2fs_unmark_valid(fs);
8213         }
8214         ext2fs_free_mem(&free_array);
8215 }
8216
8217 static void check_inode_bitmaps(e2fsck_t ctx)
8218 {
8219         ext2_filsys fs = ctx->fs;
8220         ext2_ino_t      i;
8221         unsigned int    free_inodes = 0;
8222         int             group_free = 0;
8223         int             dirs_count = 0;
8224         int             group = 0;
8225         unsigned int    inodes = 0;
8226         int             *free_array;
8227         int             *dir_array;
8228         int             actual, bitmap;
8229         errcode_t       retval;
8230         struct problem_context  pctx;
8231         int             problem, save_problem, fixit, had_problem;
8232
8233         clear_problem_context(&pctx);
8234         free_array = (int *) e2fsck_allocate_memory(ctx,
8235             fs->group_desc_count * sizeof(int), "free inode count array");
8236
8237         dir_array = (int *) e2fsck_allocate_memory(ctx,
8238            fs->group_desc_count * sizeof(int), "directory count array");
8239
8240         if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
8241             (fs->super->s_inodes_count >
8242              ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
8243                 pctx.num = 3;
8244                 pctx.blk = 1;
8245                 pctx.blk2 = fs->super->s_inodes_count;
8246                 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
8247                 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
8248                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8249
8250                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8251                 return;
8252         }
8253         if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
8254             (fs->super->s_inodes_count >
8255              ext2fs_get_inode_bitmap_end(fs->inode_map))) {
8256                 pctx.num = 4;
8257                 pctx.blk = 1;
8258                 pctx.blk2 = fs->super->s_inodes_count;
8259                 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
8260                 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
8261                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8262
8263                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8264                 return;
8265         }
8266
8267 redo_counts:
8268         had_problem = 0;
8269         save_problem = 0;
8270         pctx.ino = pctx.ino2 = 0;
8271         for (i = 1; i <= fs->super->s_inodes_count; i++) {
8272                 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
8273                 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
8274
8275                 if (actual == bitmap)
8276                         goto do_counts;
8277
8278                 if (!actual && bitmap) {
8279                         /*
8280                          * Inode wasn't used, but marked in bitmap
8281                          */
8282                         problem = PR_5_INODE_UNUSED;
8283                 } else /* if (actual && !bitmap) */ {
8284                         /*
8285                          * Inode used, but not in bitmap
8286                          */
8287                         problem = PR_5_INODE_USED;
8288                 }
8289                 if (pctx.ino == 0) {
8290                         pctx.ino = pctx.ino2 = i;
8291                         save_problem = problem;
8292                 } else {
8293                         if ((problem == save_problem) &&
8294                             (pctx.ino2 == i-1))
8295                                 pctx.ino2++;
8296                         else {
8297                                 print_bitmap_problem(ctx, save_problem, &pctx);
8298                                 pctx.ino = pctx.ino2 = i;
8299                                 save_problem = problem;
8300                         }
8301                 }
8302                 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
8303                 had_problem++;
8304
8305 do_counts:
8306                 if (!bitmap) {
8307                         group_free++;
8308                         free_inodes++;
8309                 } else {
8310                         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
8311                                 dirs_count++;
8312                 }
8313                 inodes++;
8314                 if ((inodes == fs->super->s_inodes_per_group) ||
8315                     (i == fs->super->s_inodes_count)) {
8316                         free_array[group] = group_free;
8317                         dir_array[group] = dirs_count;
8318                         group ++;
8319                         inodes = 0;
8320                         group_free = 0;
8321                         dirs_count = 0;
8322                         if (ctx->progress)
8323                                 if ((ctx->progress)(ctx, 5,
8324                                             group + fs->group_desc_count,
8325                                             fs->group_desc_count*2))
8326                                         return;
8327                 }
8328         }
8329         if (pctx.ino)
8330                 print_bitmap_problem(ctx, save_problem, &pctx);
8331
8332         if (had_problem)
8333                 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
8334         else
8335                 fixit = -1;
8336         ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
8337
8338         if (fixit == 1) {
8339                 ext2fs_free_inode_bitmap(fs->inode_map);
8340                 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
8341                                                   &fs->inode_map);
8342                 if (retval) {
8343                         clear_problem_context(&pctx);
8344                         fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
8345                         ctx->flags |= E2F_FLAG_ABORT;
8346                         return;
8347                 }
8348                 ext2fs_set_bitmap_padding(fs->inode_map);
8349                 ext2fs_mark_ib_dirty(fs);
8350
8351                 /* redo counts */
8352                 inodes = 0; free_inodes = 0; group_free = 0;
8353                 dirs_count = 0; group = 0;
8354                 memset(free_array, 0, fs->group_desc_count * sizeof(int));
8355                 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
8356                 goto redo_counts;
8357         } else if (fixit == 0)
8358                 ext2fs_unmark_valid(fs);
8359
8360         for (i = 0; i < fs->group_desc_count; i++) {
8361                 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
8362                         pctx.group = i;
8363                         pctx.ino = fs->group_desc[i].bg_free_inodes_count;
8364                         pctx.ino2 = free_array[i];
8365                         if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
8366                                         &pctx)) {
8367                                 fs->group_desc[i].bg_free_inodes_count =
8368                                         free_array[i];
8369                                 ext2fs_mark_super_dirty(fs);
8370                         } else
8371                                 ext2fs_unmark_valid(fs);
8372                 }
8373                 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
8374                         pctx.group = i;
8375                         pctx.ino = fs->group_desc[i].bg_used_dirs_count;
8376                         pctx.ino2 = dir_array[i];
8377
8378                         if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
8379                                         &pctx)) {
8380                                 fs->group_desc[i].bg_used_dirs_count =
8381                                         dir_array[i];
8382                                 ext2fs_mark_super_dirty(fs);
8383                         } else
8384                                 ext2fs_unmark_valid(fs);
8385                 }
8386         }
8387         if (free_inodes != fs->super->s_free_inodes_count) {
8388                 pctx.group = -1;
8389                 pctx.ino = fs->super->s_free_inodes_count;
8390                 pctx.ino2 = free_inodes;
8391
8392                 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
8393                         fs->super->s_free_inodes_count = free_inodes;
8394                         ext2fs_mark_super_dirty(fs);
8395                 } else
8396                         ext2fs_unmark_valid(fs);
8397         }
8398         ext2fs_free_mem(&free_array);
8399         ext2fs_free_mem(&dir_array);
8400 }
8401
8402 static void check_inode_end(e2fsck_t ctx)
8403 {
8404         ext2_filsys fs = ctx->fs;
8405         ext2_ino_t      end, save_inodes_count, i;
8406         struct problem_context  pctx;
8407
8408         clear_problem_context(&pctx);
8409
8410         end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8411         pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8412                                                      &save_inodes_count);
8413         if (pctx.errcode) {
8414                 pctx.num = 1;
8415                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8416                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8417                 return;
8418         }
8419         if (save_inodes_count == end)
8420                 return;
8421
8422         for (i = save_inodes_count + 1; i <= end; i++) {
8423                 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8424                         if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8425                                 for (i = save_inodes_count + 1; i <= end; i++)
8426                                         ext2fs_mark_inode_bitmap(fs->inode_map,
8427                                                                  i);
8428                                 ext2fs_mark_ib_dirty(fs);
8429                         } else
8430                                 ext2fs_unmark_valid(fs);
8431                         break;
8432                 }
8433         }
8434
8435         pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8436                                                      save_inodes_count, 0);
8437         if (pctx.errcode) {
8438                 pctx.num = 2;
8439                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8440                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8441                 return;
8442         }
8443 }
8444
8445 static void check_block_end(e2fsck_t ctx)
8446 {
8447         ext2_filsys fs = ctx->fs;
8448         blk_t   end, save_blocks_count, i;
8449         struct problem_context  pctx;
8450
8451         clear_problem_context(&pctx);
8452
8453         end = fs->block_map->start +
8454                 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8455         pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8456                                                      &save_blocks_count);
8457         if (pctx.errcode) {
8458                 pctx.num = 3;
8459                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8460                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8461                 return;
8462         }
8463         if (save_blocks_count == end)
8464                 return;
8465
8466         for (i = save_blocks_count + 1; i <= end; i++) {
8467                 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8468                         if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8469                                 for (i = save_blocks_count + 1; i <= end; i++)
8470                                         ext2fs_mark_block_bitmap(fs->block_map,
8471                                                                  i);
8472                                 ext2fs_mark_bb_dirty(fs);
8473                         } else
8474                                 ext2fs_unmark_valid(fs);
8475                         break;
8476                 }
8477         }
8478
8479         pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8480                                                      save_blocks_count, 0);
8481         if (pctx.errcode) {
8482                 pctx.num = 4;
8483                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8484                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8485                 return;
8486         }
8487 }
8488
8489 static void e2fsck_pass5(e2fsck_t ctx)
8490 {
8491         struct problem_context  pctx;
8492
8493         /* Pass 5 */
8494
8495         clear_problem_context(&pctx);
8496
8497         if (!(ctx->options & E2F_OPT_PREEN))
8498                 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8499
8500         if (ctx->progress)
8501                 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8502                         return;
8503
8504         e2fsck_read_bitmaps(ctx);
8505
8506         check_block_bitmaps(ctx);
8507         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8508                 return;
8509         check_inode_bitmaps(ctx);
8510         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8511                 return;
8512         check_inode_end(ctx);
8513         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8514                 return;
8515         check_block_end(ctx);
8516         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8517                 return;
8518
8519         ext2fs_free_inode_bitmap(ctx->inode_used_map);
8520         ctx->inode_used_map = 0;
8521         ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8522         ctx->inode_dir_map = 0;
8523         ext2fs_free_block_bitmap(ctx->block_found_map);
8524         ctx->block_found_map = 0;
8525 }
8526
8527 /*
8528  * problem.c --- report filesystem problems to the user
8529  */
8530
8531 #define PR_PREEN_OK     0x000001 /* Don't need to do preenhalt */
8532 #define PR_NO_OK        0x000002 /* If user answers no, don't make fs invalid */
8533 #define PR_NO_DEFAULT   0x000004 /* Default to no */
8534 #define PR_MSG_ONLY     0x000008 /* Print message only */
8535
8536 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8537
8538 #define PR_FATAL        0x001000 /* Fatal error */
8539 #define PR_AFTER_CODE   0x002000 /* After asking the first question, */
8540                                  /* ask another */
8541 #define PR_PREEN_NOMSG  0x004000 /* Don't print a message if we're preening */
8542 #define PR_NOCOLLATE    0x008000 /* Don't collate answers for this latch */
8543 #define PR_NO_NOMSG     0x010000 /* Don't print a message if e2fsck -n */
8544 #define PR_PREEN_NO     0x020000 /* Use No as an answer if preening */
8545 #define PR_PREEN_NOHDR  0x040000 /* Don't print the preen header */
8546
8547
8548 #define PROMPT_NONE     0
8549 #define PROMPT_FIX      1
8550 #define PROMPT_CLEAR    2
8551 #define PROMPT_RELOCATE 3
8552 #define PROMPT_ALLOCATE 4
8553 #define PROMPT_EXPAND   5
8554 #define PROMPT_CONNECT  6
8555 #define PROMPT_CREATE   7
8556 #define PROMPT_SALVAGE  8
8557 #define PROMPT_TRUNCATE 9
8558 #define PROMPT_CLEAR_INODE 10
8559 #define PROMPT_ABORT    11
8560 #define PROMPT_SPLIT    12
8561 #define PROMPT_CONTINUE 13
8562 #define PROMPT_CLONE    14
8563 #define PROMPT_DELETE   15
8564 #define PROMPT_SUPPRESS 16
8565 #define PROMPT_UNLINK   17
8566 #define PROMPT_CLEAR_HTREE 18
8567 #define PROMPT_RECREATE 19
8568 #define PROMPT_NULL     20
8569
8570 struct e2fsck_problem {
8571         problem_t       e2p_code;
8572         const char *    e2p_description;
8573         char            prompt;
8574         int             flags;
8575         problem_t       second_code;
8576 };
8577
8578 struct latch_descr {
8579         int             latch_code;
8580         problem_t       question;
8581         problem_t       end_message;
8582         int             flags;
8583 };
8584
8585 /*
8586  * These are the prompts which are used to ask the user if they want
8587  * to fix a problem.
8588  */
8589 static const char * const prompt[] = {
8590         N_("(no prompt)"),      /* 0 */
8591         N_("Fix"),              /* 1 */
8592         N_("Clear"),            /* 2 */
8593         N_("Relocate"),         /* 3 */
8594         N_("Allocate"),         /* 4 */
8595         N_("Expand"),           /* 5 */
8596         N_("Connect to /lost+found"), /* 6 */
8597         N_("Create"),           /* 7 */
8598         N_("Salvage"),          /* 8 */
8599         N_("Truncate"),         /* 9 */
8600         N_("Clear inode"),      /* 10 */
8601         N_("Abort"),            /* 11 */
8602         N_("Split"),            /* 12 */
8603         N_("Continue"),         /* 13 */
8604         N_("Clone multiply-claimed blocks"), /* 14 */
8605         N_("Delete file"),      /* 15 */
8606         N_("Suppress messages"),/* 16 */
8607         N_("Unlink"),           /* 17 */
8608         N_("Clear HTree index"),/* 18 */
8609         N_("Recreate"),         /* 19 */
8610         "",                     /* 20 */
8611 };
8612
8613 /*
8614  * These messages are printed when we are preen mode and we will be
8615  * automatically fixing the problem.
8616  */
8617 static const char * const preen_msg[] = {
8618         N_("(NONE)"),           /* 0 */
8619         N_("FIXED"),            /* 1 */
8620         N_("CLEARED"),          /* 2 */
8621         N_("RELOCATED"),        /* 3 */
8622         N_("ALLOCATED"),        /* 4 */
8623         N_("EXPANDED"),         /* 5 */
8624         N_("RECONNECTED"),      /* 6 */
8625         N_("CREATED"),          /* 7 */
8626         N_("SALVAGED"),         /* 8 */
8627         N_("TRUNCATED"),        /* 9 */
8628         N_("INODE CLEARED"),    /* 10 */
8629         N_("ABORTED"),          /* 11 */
8630         N_("SPLIT"),            /* 12 */
8631         N_("CONTINUING"),       /* 13 */
8632         N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8633         N_("FILE DELETED"),     /* 15 */
8634         N_("SUPPRESSED"),       /* 16 */
8635         N_("UNLINKED"),         /* 17 */
8636         N_("HTREE INDEX CLEARED"),/* 18 */
8637         N_("WILL RECREATE"),    /* 19 */
8638         "",                     /* 20 */
8639 };
8640
8641 static const struct e2fsck_problem problem_table[] = {
8642
8643         /* Pre-Pass 1 errors */
8644
8645         /* Block bitmap not in group */
8646         { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g.  (@b %b)\n"),
8647           PROMPT_RELOCATE, PR_LATCH_RELOC },
8648
8649         /* Inode bitmap not in group */
8650         { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g.  (@b %b)\n"),
8651           PROMPT_RELOCATE, PR_LATCH_RELOC },
8652
8653         /* Inode table not in group */
8654         { PR_0_ITABLE_NOT_GROUP,
8655           N_("@i table for @g %g is not in @g.  (@b %b)\n"
8656           "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8657           PROMPT_RELOCATE, PR_LATCH_RELOC },
8658
8659         /* Superblock corrupt */
8660         { PR_0_SB_CORRUPT,
8661           N_("\nThe @S could not be read or does not describe a correct ext2\n"
8662           "@f.  If the @v is valid and it really contains an ext2\n"
8663           "@f (and not swap or ufs or something else), then the @S\n"
8664           "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8665           "    e2fsck -b %S <@v>\n\n"),
8666           PROMPT_NONE, PR_FATAL },
8667
8668         /* Filesystem size is wrong */
8669         { PR_0_FS_SIZE_WRONG,
8670           N_("The @f size (according to the @S) is %b @bs\n"
8671           "The physical size of the @v is %c @bs\n"
8672           "Either the @S or the partition table is likely to be corrupt!\n"),
8673           PROMPT_ABORT, 0 },
8674
8675         /* Fragments not supported */
8676         { PR_0_NO_FRAGMENTS,
8677           N_("@S @b_size = %b, fragsize = %c.\n"
8678           "This version of e2fsck does not support fragment sizes different\n"
8679           "from the @b size.\n"),
8680           PROMPT_NONE, PR_FATAL },
8681
8682           /* Bad blocks_per_group */
8683         { PR_0_BLOCKS_PER_GROUP,
8684           N_("@S @bs_per_group = %b, should have been %c\n"),
8685           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8686
8687         /* Bad first_data_block */
8688         { PR_0_FIRST_DATA_BLOCK,
8689           N_("@S first_data_@b = %b, should have been %c\n"),
8690           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8691
8692         /* Adding UUID to filesystem */
8693         { PR_0_ADD_UUID,
8694           N_("@f did not have a UUID; generating one.\n\n"),
8695           PROMPT_NONE, 0 },
8696
8697         /* Relocate hint */
8698         { PR_0_RELOCATE_HINT,
8699           N_("Note: if several inode or block bitmap blocks or part\n"
8700           "of the inode table require relocation, you may wish to try\n"
8701           "running e2fsck with the '-b %S' option first.  The problem\n"
8702           "may lie only with the primary block group descriptors, and\n"
8703           "the backup block group descriptors may be OK.\n\n"),
8704           PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8705
8706         /* Miscellaneous superblock corruption */
8707         { PR_0_MISC_CORRUPT_SUPER,
8708           N_("Corruption found in @S.  (%s = %N).\n"),
8709           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8710
8711         /* Error determing physical device size of filesystem */
8712         { PR_0_GETSIZE_ERROR,
8713           N_("Error determining size of the physical @v: %m\n"),
8714           PROMPT_NONE, PR_FATAL },
8715
8716         /* Inode count in superblock is incorrect */
8717         { PR_0_INODE_COUNT_WRONG,
8718           N_("@i count in @S is %i, @s %j.\n"),
8719           PROMPT_FIX, 0 },
8720
8721         { PR_0_HURD_CLEAR_FILETYPE,
8722           N_("The Hurd does not support the filetype feature.\n"),
8723           PROMPT_CLEAR, 0 },
8724
8725         /* Journal inode is invalid */
8726         { PR_0_JOURNAL_BAD_INODE,
8727           N_("@S has an @n ext3 @j (@i %i).\n"),
8728           PROMPT_CLEAR, PR_PREEN_OK },
8729
8730         /* The external journal has (unsupported) multiple filesystems */
8731         { PR_0_JOURNAL_UNSUPP_MULTIFS,
8732           N_("External @j has multiple @f users (unsupported).\n"),
8733           PROMPT_NONE, PR_FATAL },
8734
8735         /* Can't find external journal */
8736         { PR_0_CANT_FIND_JOURNAL,
8737           N_("Can't find external @j\n"),
8738           PROMPT_NONE, PR_FATAL },
8739
8740         /* External journal has bad superblock */
8741         { PR_0_EXT_JOURNAL_BAD_SUPER,
8742           N_("External @j has bad @S\n"),
8743           PROMPT_NONE, PR_FATAL },
8744
8745         /* Superblock has a bad journal UUID */
8746         { PR_0_JOURNAL_BAD_UUID,
8747           N_("External @j does not support this @f\n"),
8748           PROMPT_NONE, PR_FATAL },
8749
8750         /* Journal has an unknown superblock type */
8751         { PR_0_JOURNAL_UNSUPP_SUPER,
8752           N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8753              "It is likely that your copy of e2fsck is old and/or doesn't "
8754              "support this @j format.\n"
8755              "It is also possible the @j @S is corrupt.\n"),
8756           PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8757
8758         /* Journal superblock is corrupt */
8759         { PR_0_JOURNAL_BAD_SUPER,
8760           N_("Ext3 @j @S is corrupt.\n"),
8761           PROMPT_FIX, PR_PREEN_OK },
8762
8763         /* Superblock flag should be cleared */
8764         { PR_0_JOURNAL_HAS_JOURNAL,
8765           N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8766           PROMPT_CLEAR, PR_PREEN_OK },
8767
8768         /* Superblock flag is incorrect */
8769         { PR_0_JOURNAL_RECOVER_SET,
8770           N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8771           PROMPT_CLEAR, PR_PREEN_OK },
8772
8773         /* Journal has data, but recovery flag is clear */
8774         { PR_0_JOURNAL_RECOVERY_CLEAR,
8775           N_("ext3 recovery flag is clear, but @j has data.\n"),
8776           PROMPT_NONE, 0 },
8777
8778         /* Ask if we should clear the journal */
8779         { PR_0_JOURNAL_RESET_JOURNAL,
8780           N_("Clear @j"),
8781           PROMPT_NULL, PR_PREEN_NOMSG },
8782
8783         /* Ask if we should run the journal anyway */
8784         { PR_0_JOURNAL_RUN,
8785           N_("Run @j anyway"),
8786           PROMPT_NULL, 0 },
8787
8788         /* Run the journal by default */
8789         { PR_0_JOURNAL_RUN_DEFAULT,
8790           N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8791           PROMPT_NONE, 0 },
8792
8793         /* Clearing orphan inode */
8794         { PR_0_ORPHAN_CLEAR_INODE,
8795           N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8796           PROMPT_NONE, 0 },
8797
8798         /* Illegal block found in orphaned inode */
8799         { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8800            N_("@I @b #%B (%b) found in @o @i %i.\n"),
8801           PROMPT_NONE, 0 },
8802
8803         /* Already cleared block found in orphaned inode */
8804         { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8805            N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8806           PROMPT_NONE, 0 },
8807
8808         /* Illegal orphan inode in superblock */
8809         { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8810           N_("@I @o @i %i in @S.\n"),
8811           PROMPT_NONE, 0 },
8812
8813         /* Illegal inode in orphaned inode list */
8814         { PR_0_ORPHAN_ILLEGAL_INODE,
8815           N_("@I @i %i in @o @i list.\n"),
8816           PROMPT_NONE, 0 },
8817
8818         /* Filesystem revision is 0, but feature flags are set */
8819         { PR_0_FS_REV_LEVEL,
8820           N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
8821           PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8822
8823         /* Journal superblock has an unknown read-only feature flag set */
8824         { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8825           N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8826           PROMPT_ABORT, 0 },
8827
8828         /* Journal superblock has an unknown incompatible feature flag set */
8829         { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8830           N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8831           PROMPT_ABORT, 0 },
8832
8833         /* Journal has unsupported version number */
8834         { PR_0_JOURNAL_UNSUPP_VERSION,
8835           N_("@j version not supported by this e2fsck.\n"),
8836           PROMPT_ABORT, 0 },
8837
8838         /* Moving journal to hidden file */
8839         { PR_0_MOVE_JOURNAL,
8840           N_("Moving @j from /%s to hidden @i.\n\n"),
8841           PROMPT_NONE, 0 },
8842
8843         /* Error moving journal to hidden file */
8844         { PR_0_ERR_MOVE_JOURNAL,
8845           N_("Error moving @j: %m\n\n"),
8846           PROMPT_NONE, 0 },
8847
8848         /* Clearing V2 journal superblock */
8849         { PR_0_CLEAR_V2_JOURNAL,
8850           N_("Found @n V2 @j @S fields (from V1 @j).\n"
8851              "Clearing fields beyond the V1 @j @S...\n\n"),
8852           PROMPT_NONE, 0 },
8853
8854         /* Backup journal inode blocks */
8855         { PR_0_BACKUP_JNL,
8856           N_("Backing up @j @i @b information.\n\n"),
8857           PROMPT_NONE, 0 },
8858
8859         /* Reserved blocks w/o resize_inode */
8860         { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8861           N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8862              "is %N; @s zero.  "),
8863           PROMPT_FIX, 0 },
8864
8865         /* Resize_inode not enabled, but resize inode is non-zero */
8866         { PR_0_CLEAR_RESIZE_INODE,
8867           N_("Resize_@i not enabled, but the resize @i is non-zero.  "),
8868           PROMPT_CLEAR, 0 },
8869
8870         /* Resize inode invalid */
8871         { PR_0_RESIZE_INODE_INVALID,
8872           N_("Resize @i not valid.  "),
8873           PROMPT_RECREATE, 0 },
8874
8875         /* Pass 1 errors */
8876
8877         /* Pass 1: Checking inodes, blocks, and sizes */
8878         { PR_1_PASS_HEADER,
8879           N_("Pass 1: Checking @is, @bs, and sizes\n"),
8880           PROMPT_NONE, 0 },
8881
8882         /* Root directory is not an inode */
8883         { PR_1_ROOT_NO_DIR, N_("@r is not a @d.  "),
8884           PROMPT_CLEAR, 0 },
8885
8886         /* Root directory has dtime set */
8887         { PR_1_ROOT_DTIME,
8888           N_("@r has dtime set (probably due to old mke2fs).  "),
8889           PROMPT_FIX, PR_PREEN_OK },
8890
8891         /* Reserved inode has bad mode */
8892         { PR_1_RESERVED_BAD_MODE,
8893           N_("Reserved @i %i (%Q) has @n mode.  "),
8894           PROMPT_CLEAR, PR_PREEN_OK },
8895
8896         /* Deleted inode has zero dtime */
8897         { PR_1_ZERO_DTIME,
8898           N_("@D @i %i has zero dtime.  "),
8899           PROMPT_FIX, PR_PREEN_OK },
8900
8901         /* Inode in use, but dtime set */
8902         { PR_1_SET_DTIME,
8903           N_("@i %i is in use, but has dtime set.  "),
8904           PROMPT_FIX, PR_PREEN_OK },
8905
8906         /* Zero-length directory */
8907         { PR_1_ZERO_LENGTH_DIR,
8908           N_("@i %i is a @z @d.  "),
8909           PROMPT_CLEAR, PR_PREEN_OK },
8910
8911         /* Block bitmap conflicts with some other fs block */
8912         { PR_1_BB_CONFLICT,
8913           N_("@g %g's @b @B at %b @C.\n"),
8914           PROMPT_RELOCATE, 0 },
8915
8916         /* Inode bitmap conflicts with some other fs block */
8917         { PR_1_IB_CONFLICT,
8918           N_("@g %g's @i @B at %b @C.\n"),
8919           PROMPT_RELOCATE, 0 },
8920
8921         /* Inode table conflicts with some other fs block */
8922         { PR_1_ITABLE_CONFLICT,
8923           N_("@g %g's @i table at %b @C.\n"),
8924           PROMPT_RELOCATE, 0 },
8925
8926         /* Block bitmap is on a bad block */
8927         { PR_1_BB_BAD_BLOCK,
8928           N_("@g %g's @b @B (%b) is bad.  "),
8929           PROMPT_RELOCATE, 0 },
8930
8931         /* Inode bitmap is on a bad block */
8932         { PR_1_IB_BAD_BLOCK,
8933           N_("@g %g's @i @B (%b) is bad.  "),
8934           PROMPT_RELOCATE, 0 },
8935
8936         /* Inode has incorrect i_size */
8937         { PR_1_BAD_I_SIZE,
8938           N_("@i %i, i_size is %Is, @s %N.  "),
8939           PROMPT_FIX, PR_PREEN_OK },
8940
8941         /* Inode has incorrect i_blocks */
8942         { PR_1_BAD_I_BLOCKS,
8943           N_("@i %i, i_@bs is %Ib, @s %N.  "),
8944           PROMPT_FIX, PR_PREEN_OK },
8945
8946         /* Illegal blocknumber in inode */
8947         { PR_1_ILLEGAL_BLOCK_NUM,
8948           N_("@I @b #%B (%b) in @i %i.  "),
8949           PROMPT_CLEAR, PR_LATCH_BLOCK },
8950
8951         /* Block number overlaps fs metadata */
8952         { PR_1_BLOCK_OVERLAPS_METADATA,
8953           N_("@b #%B (%b) overlaps @f metadata in @i %i.  "),
8954           PROMPT_CLEAR, PR_LATCH_BLOCK },
8955
8956         /* Inode has illegal blocks (latch question) */
8957         { PR_1_INODE_BLOCK_LATCH,
8958           N_("@i %i has illegal @b(s).  "),
8959           PROMPT_CLEAR, 0 },
8960
8961         /* Too many bad blocks in inode */
8962         { PR_1_TOO_MANY_BAD_BLOCKS,
8963           N_("Too many illegal @bs in @i %i.\n"),
8964           PROMPT_CLEAR_INODE, PR_NO_OK },
8965
8966         /* Illegal block number in bad block inode */
8967         { PR_1_BB_ILLEGAL_BLOCK_NUM,
8968           N_("@I @b #%B (%b) in bad @b @i.  "),
8969           PROMPT_CLEAR, PR_LATCH_BBLOCK },
8970
8971         /* Bad block inode has illegal blocks (latch question) */
8972         { PR_1_INODE_BBLOCK_LATCH,
8973           N_("Bad @b @i has illegal @b(s).  "),
8974           PROMPT_CLEAR, 0 },
8975
8976         /* Duplicate or bad blocks in use! */
8977         { PR_1_DUP_BLOCKS_PREENSTOP,
8978           N_("Duplicate or bad @b in use!\n"),
8979           PROMPT_NONE, 0 },
8980
8981         /* Bad block used as bad block indirect block */
8982         { PR_1_BBINODE_BAD_METABLOCK,
8983           N_("Bad @b %b used as bad @b @i indirect @b.  "),
8984           PROMPT_CLEAR, PR_LATCH_BBLOCK },
8985
8986         /* Inconsistency can't be fixed prompt */
8987         { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8988           N_("\nThe bad @b @i has probably been corrupted.  You probably\n"
8989              "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8990              "in the @f.\n"),
8991           PROMPT_CONTINUE, PR_PREEN_NOMSG },
8992
8993         /* Bad primary block */
8994         { PR_1_BAD_PRIMARY_BLOCK,
8995           N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
8996           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8997
8998         /* Bad primary block prompt */
8999         { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
9000           N_("You can remove this @b from the bad @b list and hope\n"
9001              "that the @b is really OK.  But there are no guarantees.\n\n"),
9002           PROMPT_CLEAR, PR_PREEN_NOMSG },
9003
9004         /* Bad primary superblock */
9005         { PR_1_BAD_PRIMARY_SUPERBLOCK,
9006           N_("The primary @S (%b) is on the bad @b list.\n"),
9007           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9008
9009         /* Bad primary block group descriptors */
9010         { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
9011           N_("Block %b in the primary @g descriptors "
9012           "is on the bad @b list\n"),
9013           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9014
9015         /* Bad superblock in group */
9016         { PR_1_BAD_SUPERBLOCK,
9017           N_("Warning: Group %g's @S (%b) is bad.\n"),
9018           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9019
9020         /* Bad block group descriptors in group */
9021         { PR_1_BAD_GROUP_DESCRIPTORS,
9022           N_("Warning: Group %g's copy of the @g descriptors has a bad "
9023           "@b (%b).\n"),
9024           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9025
9026         /* Block claimed for no reason */
9027         { PR_1_PROGERR_CLAIMED_BLOCK,
9028           N_("Programming error?  @b #%b claimed for no reason in "
9029           "process_bad_@b.\n"),
9030           PROMPT_NONE, PR_PREEN_OK },
9031
9032         /* Error allocating blocks for relocating metadata */
9033         { PR_1_RELOC_BLOCK_ALLOCATE,
9034           N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
9035           PROMPT_NONE, PR_PREEN_OK },
9036
9037         /* Error allocating block buffer during relocation process */
9038         { PR_1_RELOC_MEMORY_ALLOCATE,
9039           N_("@A @b buffer for relocating %s\n"),
9040           PROMPT_NONE, PR_PREEN_OK },
9041
9042         /* Relocating metadata group information from X to Y */
9043         { PR_1_RELOC_FROM_TO,
9044           N_("Relocating @g %g's %s from %b to %c...\n"),
9045           PROMPT_NONE, PR_PREEN_OK },
9046
9047         /* Relocating metatdata group information to X */
9048         { PR_1_RELOC_TO,
9049           N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
9050           PROMPT_NONE, PR_PREEN_OK },
9051
9052         /* Block read error during relocation process */
9053         { PR_1_RELOC_READ_ERR,
9054           N_("Warning: could not read @b %b of %s: %m\n"),
9055           PROMPT_NONE, PR_PREEN_OK },
9056
9057         /* Block write error during relocation process */
9058         { PR_1_RELOC_WRITE_ERR,
9059           N_("Warning: could not write @b %b for %s: %m\n"),
9060           PROMPT_NONE, PR_PREEN_OK },
9061
9062         /* Error allocating inode bitmap */
9063         { PR_1_ALLOCATE_IBITMAP_ERROR,
9064           N_("@A @i @B (%N): %m\n"),
9065           PROMPT_NONE, PR_FATAL },
9066
9067         /* Error allocating block bitmap */
9068         { PR_1_ALLOCATE_BBITMAP_ERROR,
9069           N_("@A @b @B (%N): %m\n"),
9070           PROMPT_NONE, PR_FATAL },
9071
9072         /* Error allocating icount structure */
9073         { PR_1_ALLOCATE_ICOUNT,
9074           N_("@A icount link information: %m\n"),
9075           PROMPT_NONE, PR_FATAL },
9076
9077         /* Error allocating dbcount */
9078         { PR_1_ALLOCATE_DBCOUNT,
9079           N_("@A @d @b array: %m\n"),
9080           PROMPT_NONE, PR_FATAL },
9081
9082         /* Error while scanning inodes */
9083         { PR_1_ISCAN_ERROR,
9084           N_("Error while scanning @is (%i): %m\n"),
9085           PROMPT_NONE, PR_FATAL },
9086
9087         /* Error while iterating over blocks */
9088         { PR_1_BLOCK_ITERATE,
9089           N_("Error while iterating over @bs in @i %i: %m\n"),
9090           PROMPT_NONE, PR_FATAL },
9091
9092         /* Error while storing inode count information */
9093         { PR_1_ICOUNT_STORE,
9094           N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
9095           PROMPT_NONE, PR_FATAL },
9096
9097         /* Error while storing directory block information */
9098         { PR_1_ADD_DBLOCK,
9099           N_("Error storing @d @b information "
9100           "(@i=%i, @b=%b, num=%N): %m\n"),
9101           PROMPT_NONE, PR_FATAL },
9102
9103         /* Error while reading inode (for clearing) */
9104         { PR_1_READ_INODE,
9105           N_("Error reading @i %i: %m\n"),
9106           PROMPT_NONE, PR_FATAL },
9107
9108         /* Suppress messages prompt */
9109         { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
9110
9111         /* Imagic flag set on an inode when filesystem doesn't support it */
9112         { PR_1_SET_IMAGIC,
9113           N_("@i %i has imagic flag set.  "),
9114           PROMPT_CLEAR, 0 },
9115
9116         /* Immutable flag set on a device or socket inode */
9117         { PR_1_SET_IMMUTABLE,
9118           N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
9119              "or append-only flag set.  "),
9120           PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
9121
9122         /* Compression flag set on an inode when filesystem doesn't support it */
9123         { PR_1_COMPR_SET,
9124           N_("@i %i has @cion flag set on @f without @cion support.  "),
9125           PROMPT_CLEAR, 0 },
9126
9127         /* Non-zero size for device, fifo or socket inode */
9128         { PR_1_SET_NONZSIZE,
9129           N_("Special (@v/socket/fifo) @i %i has non-zero size.  "),
9130           PROMPT_FIX, PR_PREEN_OK },
9131
9132         /* Filesystem revision is 0, but feature flags are set */
9133         { PR_1_FS_REV_LEVEL,
9134           N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
9135           PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
9136
9137         /* Journal inode is not in use, but contains data */
9138         { PR_1_JOURNAL_INODE_NOT_CLEAR,
9139           N_("@j @i is not in use, but contains data.  "),
9140           PROMPT_CLEAR, PR_PREEN_OK },
9141
9142         /* Journal has bad mode */
9143         { PR_1_JOURNAL_BAD_MODE,
9144           N_("@j is not regular file.  "),
9145           PROMPT_FIX, PR_PREEN_OK },
9146
9147         /* Deal with inodes that were part of orphan linked list */
9148         { PR_1_LOW_DTIME,
9149           N_("@i %i was part of the @o @i list.  "),
9150           PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
9151
9152         /* Deal with inodes that were part of corrupted orphan linked
9153            list (latch question) */
9154         { PR_1_ORPHAN_LIST_REFUGEES,
9155           N_("@is that were part of a corrupted orphan linked list found.  "),
9156           PROMPT_FIX, 0 },
9157
9158         /* Error allocating refcount structure */
9159         { PR_1_ALLOCATE_REFCOUNT,
9160           N_("@A refcount structure (%N): %m\n"),
9161           PROMPT_NONE, PR_FATAL },
9162
9163         /* Error reading extended attribute block */
9164         { PR_1_READ_EA_BLOCK,
9165           N_("Error reading @a @b %b for @i %i.  "),
9166           PROMPT_CLEAR, 0 },
9167
9168         /* Invalid extended attribute block */
9169         { PR_1_BAD_EA_BLOCK,
9170           N_("@i %i has a bad @a @b %b.  "),
9171           PROMPT_CLEAR, 0 },
9172
9173         /* Error reading Extended Attribute block while fixing refcount */
9174         { PR_1_EXTATTR_READ_ABORT,
9175           N_("Error reading @a @b %b (%m).  "),
9176           PROMPT_ABORT, 0 },
9177
9178         /* Extended attribute reference count incorrect */
9179         { PR_1_EXTATTR_REFCOUNT,
9180           N_("@a @b %b has reference count %B, @s %N.  "),
9181           PROMPT_FIX, 0 },
9182
9183         /* Error writing Extended Attribute block while fixing refcount */
9184         { PR_1_EXTATTR_WRITE,
9185           N_("Error writing @a @b %b (%m).  "),
9186           PROMPT_ABORT, 0 },
9187
9188         /* Multiple EA blocks not supported */
9189         { PR_1_EA_MULTI_BLOCK,
9190           N_("@a @b %b has h_@bs > 1.  "),
9191           PROMPT_CLEAR, 0},
9192
9193         /* Error allocating EA region allocation structure */
9194         { PR_1_EA_ALLOC_REGION,
9195           N_("@A @a @b %b.  "),
9196           PROMPT_ABORT, 0},
9197
9198         /* Error EA allocation collision */
9199         { PR_1_EA_ALLOC_COLLISION,
9200           N_("@a @b %b is corrupt (allocation collision).  "),
9201           PROMPT_CLEAR, 0},
9202
9203         /* Bad extended attribute name */
9204         { PR_1_EA_BAD_NAME,
9205           N_("@a @b %b is corrupt (@n name).  "),
9206           PROMPT_CLEAR, 0},
9207
9208         /* Bad extended attribute value */
9209         { PR_1_EA_BAD_VALUE,
9210           N_("@a @b %b is corrupt (@n value).  "),
9211           PROMPT_CLEAR, 0},
9212
9213         /* Inode too big (latch question) */
9214         { PR_1_INODE_TOOBIG,
9215           N_("@i %i is too big.  "), PROMPT_TRUNCATE, 0 },
9216
9217         /* Directory too big */
9218         { PR_1_TOOBIG_DIR,
9219           N_("@b #%B (%b) causes @d to be too big.  "),
9220           PROMPT_CLEAR, PR_LATCH_TOOBIG },
9221
9222         /* Regular file too big */
9223         { PR_1_TOOBIG_REG,
9224           N_("@b #%B (%b) causes file to be too big.  "),
9225           PROMPT_CLEAR, PR_LATCH_TOOBIG },
9226
9227         /* Symlink too big */
9228         { PR_1_TOOBIG_SYMLINK,
9229           N_("@b #%B (%b) causes symlink to be too big.  "),
9230           PROMPT_CLEAR, PR_LATCH_TOOBIG },
9231
9232         /* INDEX_FL flag set on a non-HTREE filesystem */
9233         { PR_1_HTREE_SET,
9234           N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
9235           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9236
9237         /* INDEX_FL flag set on a non-directory */
9238         { PR_1_HTREE_NODIR,
9239           N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
9240           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9241
9242         /* Invalid root node in HTREE directory */
9243         { PR_1_HTREE_BADROOT,
9244           N_("@h %i has an @n root node.\n"),
9245           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9246
9247         /* Unsupported hash version in HTREE directory */
9248         { PR_1_HTREE_HASHV,
9249           N_("@h %i has an unsupported hash version (%N)\n"),
9250           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9251
9252         /* Incompatible flag in HTREE root node */
9253         { PR_1_HTREE_INCOMPAT,
9254           N_("@h %i uses an incompatible htree root node flag.\n"),
9255           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9256
9257         /* HTREE too deep */
9258         { PR_1_HTREE_DEPTH,
9259           N_("@h %i has a tree depth (%N) which is too big\n"),
9260           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9261
9262         /* Bad block has indirect block that conflicts with filesystem block */
9263         { PR_1_BB_FS_BLOCK,
9264           N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
9265              "@f metadata.  "),
9266           PROMPT_CLEAR, PR_LATCH_BBLOCK },
9267
9268         /* Resize inode failed */
9269         { PR_1_RESIZE_INODE_CREATE,
9270           N_("Resize @i (re)creation failed: %m."),
9271           PROMPT_ABORT, 0 },
9272
9273         /* invalid inode->i_extra_isize */
9274         { PR_1_EXTRA_ISIZE,
9275           N_("@i %i has a extra size (%IS) which is @n\n"),
9276           PROMPT_FIX, PR_PREEN_OK },
9277
9278         /* invalid ea entry->e_name_len */
9279         { PR_1_ATTR_NAME_LEN,
9280           N_("@a in @i %i has a namelen (%N) which is @n\n"),
9281           PROMPT_CLEAR, PR_PREEN_OK },
9282
9283         /* invalid ea entry->e_value_size */
9284         { PR_1_ATTR_VALUE_SIZE,
9285           N_("@a in @i %i has a value size (%N) which is @n\n"),
9286           PROMPT_CLEAR, PR_PREEN_OK },
9287
9288         /* invalid ea entry->e_value_offs */
9289         { PR_1_ATTR_VALUE_OFFSET,
9290           N_("@a in @i %i has a value offset (%N) which is @n\n"),
9291           PROMPT_CLEAR, PR_PREEN_OK },
9292
9293         /* invalid ea entry->e_value_block */
9294         { PR_1_ATTR_VALUE_BLOCK,
9295           N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
9296           PROMPT_CLEAR, PR_PREEN_OK },
9297
9298         /* invalid ea entry->e_hash */
9299         { PR_1_ATTR_HASH,
9300           N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
9301           PROMPT_CLEAR, PR_PREEN_OK },
9302
9303         /* Pass 1b errors */
9304
9305         /* Pass 1B: Rescan for duplicate/bad blocks */
9306         { PR_1B_PASS_HEADER,
9307           N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
9308           "Pass 1B: Rescanning for @m @bs\n"),
9309           PROMPT_NONE, 0 },
9310
9311         /* Duplicate/bad block(s) header */
9312         { PR_1B_DUP_BLOCK_HEADER,
9313           N_("@m @b(s) in @i %i:"),
9314           PROMPT_NONE, 0 },
9315
9316         /* Duplicate/bad block(s) in inode */
9317         { PR_1B_DUP_BLOCK,
9318           " %b",
9319           PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
9320
9321         /* Duplicate/bad block(s) end */
9322         { PR_1B_DUP_BLOCK_END,
9323           "\n",
9324           PROMPT_NONE, PR_PREEN_NOHDR },
9325
9326         /* Error while scanning inodes */
9327         { PR_1B_ISCAN_ERROR,
9328           N_("Error while scanning inodes (%i): %m\n"),
9329           PROMPT_NONE, PR_FATAL },
9330
9331         /* Error allocating inode bitmap */
9332         { PR_1B_ALLOCATE_IBITMAP_ERROR,
9333           N_("@A @i @B (@i_dup_map): %m\n"),
9334           PROMPT_NONE, PR_FATAL },
9335
9336         /* Error while iterating over blocks */
9337         { PR_1B_BLOCK_ITERATE,
9338           N_("Error while iterating over @bs in @i %i (%s): %m\n"),
9339           PROMPT_NONE, 0 },
9340
9341         /* Error adjusting EA refcount */
9342         { PR_1B_ADJ_EA_REFCOUNT,
9343           N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9344           PROMPT_NONE, 0 },
9345
9346
9347         /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
9348         { PR_1C_PASS_HEADER,
9349           N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
9350           PROMPT_NONE, 0 },
9351
9352
9353         /* Pass 1D: Reconciling multiply-claimed blocks */
9354         { PR_1D_PASS_HEADER,
9355           N_("Pass 1D: Reconciling @m @bs\n"),
9356           PROMPT_NONE, 0 },
9357
9358         /* File has duplicate blocks */
9359         { PR_1D_DUP_FILE,
9360           N_("File %Q (@i #%i, mod time %IM) \n"
9361           "  has %B @m @b(s), shared with %N file(s):\n"),
9362           PROMPT_NONE, 0 },
9363
9364         /* List of files sharing duplicate blocks */
9365         { PR_1D_DUP_FILE_LIST,
9366           N_("\t%Q (@i #%i, mod time %IM)\n"),
9367           PROMPT_NONE, 0 },
9368
9369         /* File sharing blocks with filesystem metadata  */
9370         { PR_1D_SHARE_METADATA,
9371           N_("\t<@f metadata>\n"),
9372           PROMPT_NONE, 0 },
9373
9374         /* Report of how many duplicate/bad inodes */
9375         { PR_1D_NUM_DUP_INODES,
9376           N_("(There are %N @is containing @m @bs.)\n\n"),
9377           PROMPT_NONE, 0 },
9378
9379         /* Duplicated blocks already reassigned or cloned. */
9380         { PR_1D_DUP_BLOCKS_DEALT,
9381           N_("@m @bs already reassigned or cloned.\n\n"),
9382           PROMPT_NONE, 0 },
9383
9384         /* Clone duplicate/bad blocks? */
9385         { PR_1D_CLONE_QUESTION,
9386           "", PROMPT_CLONE, PR_NO_OK },
9387
9388         /* Delete file? */
9389         { PR_1D_DELETE_QUESTION,
9390           "", PROMPT_DELETE, 0 },
9391
9392         /* Couldn't clone file (error) */
9393         { PR_1D_CLONE_ERROR,
9394           N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
9395
9396         /* Pass 2 errors */
9397
9398         /* Pass 2: Checking directory structure */
9399         { PR_2_PASS_HEADER,
9400           N_("Pass 2: Checking @d structure\n"),
9401           PROMPT_NONE, 0 },
9402
9403         /* Bad inode number for '.' */
9404         { PR_2_BAD_INODE_DOT,
9405           N_("@n @i number for '.' in @d @i %i.\n"),
9406           PROMPT_FIX, 0 },
9407
9408         /* Directory entry has bad inode number */
9409         { PR_2_BAD_INO,
9410           N_("@E has @n @i #: %Di.\n"),
9411           PROMPT_CLEAR, 0 },
9412
9413         /* Directory entry has deleted or unused inode */
9414         { PR_2_UNUSED_INODE,
9415           N_("@E has @D/unused @i %Di.  "),
9416           PROMPT_CLEAR, PR_PREEN_OK },
9417
9418         /* Directry entry is link to '.' */
9419         { PR_2_LINK_DOT,
9420           N_("@E @L to '.'  "),
9421           PROMPT_CLEAR, 0 },
9422
9423         /* Directory entry points to inode now located in a bad block */
9424         { PR_2_BB_INODE,
9425           N_("@E points to @i (%Di) located in a bad @b.\n"),
9426           PROMPT_CLEAR, 0 },
9427
9428         /* Directory entry contains a link to a directory */
9429         { PR_2_LINK_DIR,
9430           N_("@E @L to @d %P (%Di).\n"),
9431           PROMPT_CLEAR, 0 },
9432
9433         /* Directory entry contains a link to the root directry */
9434         { PR_2_LINK_ROOT,
9435           N_("@E @L to the @r.\n"),
9436           PROMPT_CLEAR, 0 },
9437
9438         /* Directory entry has illegal characters in its name */
9439         { PR_2_BAD_NAME,
9440           N_("@E has illegal characters in its name.\n"),
9441           PROMPT_FIX, 0 },
9442
9443         /* Missing '.' in directory inode */
9444         { PR_2_MISSING_DOT,
9445           N_("Missing '.' in @d @i %i.\n"),
9446           PROMPT_FIX, 0 },
9447
9448         /* Missing '..' in directory inode */
9449         { PR_2_MISSING_DOT_DOT,
9450           N_("Missing '..' in @d @i %i.\n"),
9451           PROMPT_FIX, 0 },
9452
9453         /* First entry in directory inode doesn't contain '.' */
9454         { PR_2_1ST_NOT_DOT,
9455           N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9456           PROMPT_FIX, 0 },
9457
9458         /* Second entry in directory inode doesn't contain '..' */
9459         { PR_2_2ND_NOT_DOT_DOT,
9460           N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9461           PROMPT_FIX, 0 },
9462
9463         /* i_faddr should be zero */
9464         { PR_2_FADDR_ZERO,
9465           N_("i_faddr @F %IF, @s zero.\n"),
9466           PROMPT_CLEAR, 0 },
9467
9468         /* i_file_acl should be zero */
9469         { PR_2_FILE_ACL_ZERO,
9470           N_("i_file_acl @F %If, @s zero.\n"),
9471           PROMPT_CLEAR, 0 },
9472
9473         /* i_dir_acl should be zero */
9474         { PR_2_DIR_ACL_ZERO,
9475           N_("i_dir_acl @F %Id, @s zero.\n"),
9476           PROMPT_CLEAR, 0 },
9477
9478         /* i_frag should be zero */
9479         { PR_2_FRAG_ZERO,
9480           N_("i_frag @F %N, @s zero.\n"),
9481           PROMPT_CLEAR, 0 },
9482
9483         /* i_fsize should be zero */
9484         { PR_2_FSIZE_ZERO,
9485           N_("i_fsize @F %N, @s zero.\n"),
9486           PROMPT_CLEAR, 0 },
9487
9488         /* inode has bad mode */
9489         { PR_2_BAD_MODE,
9490           N_("@i %i (%Q) has @n mode (%Im).\n"),
9491           PROMPT_CLEAR, 0 },
9492
9493         /* directory corrupted */
9494         { PR_2_DIR_CORRUPTED,
9495           N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9496           PROMPT_SALVAGE, 0 },
9497
9498         /* filename too long */
9499         { PR_2_FILENAME_LONG,
9500           N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9501           PROMPT_TRUNCATE, 0 },
9502
9503         /* Directory inode has a missing block (hole) */
9504         { PR_2_DIRECTORY_HOLE,
9505           N_("@d @i %i has an unallocated @b #%B.  "),
9506           PROMPT_ALLOCATE, 0 },
9507
9508         /* '.' is not NULL terminated */
9509         { PR_2_DOT_NULL_TERM,
9510           N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9511           PROMPT_FIX, 0 },
9512
9513         /* '..' is not NULL terminated */
9514         { PR_2_DOT_DOT_NULL_TERM,
9515           N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9516           PROMPT_FIX, 0 },
9517
9518         /* Illegal character device inode */
9519         { PR_2_BAD_CHAR_DEV,
9520           N_("@i %i (%Q) is an @I character @v.\n"),
9521           PROMPT_CLEAR, 0 },
9522
9523         /* Illegal block device inode */
9524         { PR_2_BAD_BLOCK_DEV,
9525           N_("@i %i (%Q) is an @I @b @v.\n"),
9526           PROMPT_CLEAR, 0 },
9527
9528         /* Duplicate '.' entry */
9529         { PR_2_DUP_DOT,
9530           N_("@E is duplicate '.' @e.\n"),
9531           PROMPT_FIX, 0 },
9532
9533         /* Duplicate '..' entry */
9534         { PR_2_DUP_DOT_DOT,
9535           N_("@E is duplicate '..' @e.\n"),
9536           PROMPT_FIX, 0 },
9537
9538         /* Internal error: couldn't find dir_info */
9539         { PR_2_NO_DIRINFO,
9540           N_("Internal error: couldn't find dir_info for %i.\n"),
9541           PROMPT_NONE, PR_FATAL },
9542
9543         /* Final rec_len is wrong */
9544         { PR_2_FINAL_RECLEN,
9545           N_("@E has rec_len of %Dr, @s %N.\n"),
9546           PROMPT_FIX, 0 },
9547
9548         /* Error allocating icount structure */
9549         { PR_2_ALLOCATE_ICOUNT,
9550           N_("@A icount structure: %m\n"),
9551           PROMPT_NONE, PR_FATAL },
9552
9553         /* Error iterating over directory blocks */
9554         { PR_2_DBLIST_ITERATE,
9555           N_("Error iterating over @d @bs: %m\n"),
9556           PROMPT_NONE, PR_FATAL },
9557
9558         /* Error reading directory block */
9559         { PR_2_READ_DIRBLOCK,
9560           N_("Error reading @d @b %b (@i %i): %m\n"),
9561           PROMPT_CONTINUE, 0 },
9562
9563         /* Error writing directory block */
9564         { PR_2_WRITE_DIRBLOCK,
9565           N_("Error writing @d @b %b (@i %i): %m\n"),
9566           PROMPT_CONTINUE, 0 },
9567
9568         /* Error allocating new directory block */
9569         { PR_2_ALLOC_DIRBOCK,
9570           N_("@A new @d @b for @i %i (%s): %m\n"),
9571           PROMPT_NONE, 0 },
9572
9573         /* Error deallocating inode */
9574         { PR_2_DEALLOC_INODE,
9575           N_("Error deallocating @i %i: %m\n"),
9576           PROMPT_NONE, PR_FATAL },
9577
9578         /* Directory entry for '.' is big.  Split? */
9579         { PR_2_SPLIT_DOT,
9580           N_("@d @e for '.' is big.  "),
9581           PROMPT_SPLIT, PR_NO_OK },
9582
9583         /* Illegal FIFO inode */
9584         { PR_2_BAD_FIFO,
9585           N_("@i %i (%Q) is an @I FIFO.\n"),
9586           PROMPT_CLEAR, 0 },
9587
9588         /* Illegal socket inode */
9589         { PR_2_BAD_SOCKET,
9590           N_("@i %i (%Q) is an @I socket.\n"),
9591           PROMPT_CLEAR, 0 },
9592
9593         /* Directory filetype not set */
9594         { PR_2_SET_FILETYPE,
9595           N_("Setting filetype for @E to %N.\n"),
9596           PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9597
9598         /* Directory filetype incorrect */
9599         { PR_2_BAD_FILETYPE,
9600           N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9601           PROMPT_FIX, 0 },
9602
9603         /* Directory filetype set on filesystem */
9604         { PR_2_CLEAR_FILETYPE,
9605           N_("@E has filetype set.\n"),
9606           PROMPT_CLEAR, PR_PREEN_OK },
9607
9608         /* Directory filename is null */
9609         { PR_2_NULL_NAME,
9610           N_("@E has a @z name.\n"),
9611           PROMPT_CLEAR, 0 },
9612
9613         /* Invalid symlink */
9614         { PR_2_INVALID_SYMLINK,
9615           N_("Symlink %Q (@i #%i) is @n.\n"),
9616           PROMPT_CLEAR, 0 },
9617
9618         /* i_file_acl (extended attribute block) is bad */
9619         { PR_2_FILE_ACL_BAD,
9620           N_("@a @b @F @n (%If).\n"),
9621           PROMPT_CLEAR, 0 },
9622
9623         /* Filesystem contains large files, but has no such flag in sb */
9624         { PR_2_FEATURE_LARGE_FILES,
9625           N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9626           PROMPT_FIX, 0 },
9627
9628         /* Node in HTREE directory not referenced */
9629         { PR_2_HTREE_NOTREF,
9630           N_("@p @h %d: node (%B) not referenced\n"),
9631           PROMPT_NONE, 0 },
9632
9633         /* Node in HTREE directory referenced twice */
9634         { PR_2_HTREE_DUPREF,
9635           N_("@p @h %d: node (%B) referenced twice\n"),
9636           PROMPT_NONE, 0 },
9637
9638         /* Node in HTREE directory has bad min hash */
9639         { PR_2_HTREE_MIN_HASH,
9640           N_("@p @h %d: node (%B) has bad min hash\n"),
9641           PROMPT_NONE, 0 },
9642
9643         /* Node in HTREE directory has bad max hash */
9644         { PR_2_HTREE_MAX_HASH,
9645           N_("@p @h %d: node (%B) has bad max hash\n"),
9646           PROMPT_NONE, 0 },
9647
9648         /* Clear invalid HTREE directory */
9649         { PR_2_HTREE_CLEAR,
9650           N_("@n @h %d (%q).  "), PROMPT_CLEAR, 0 },
9651
9652         /* Bad block in htree interior node */
9653         { PR_2_HTREE_BADBLK,
9654           N_("@p @h %d (%q): bad @b number %b.\n"),
9655           PROMPT_CLEAR_HTREE, 0 },
9656
9657         /* Error adjusting EA refcount */
9658         { PR_2_ADJ_EA_REFCOUNT,
9659           N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9660           PROMPT_NONE, PR_FATAL },
9661
9662         /* Invalid HTREE root node */
9663         { PR_2_HTREE_BAD_ROOT,
9664           N_("@p @h %d: root node is @n\n"),
9665           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9666
9667         /* Invalid HTREE limit */
9668         { PR_2_HTREE_BAD_LIMIT,
9669           N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9670           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9671
9672         /* Invalid HTREE count */
9673         { PR_2_HTREE_BAD_COUNT,
9674           N_("@p @h %d: node (%B) has @n count (%N)\n"),
9675           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9676
9677         /* HTREE interior node has out-of-order hashes in table */
9678         { PR_2_HTREE_HASH_ORDER,
9679           N_("@p @h %d: node (%B) has an unordered hash table\n"),
9680           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9681
9682         /* Node in HTREE directory has invalid depth */
9683         { PR_2_HTREE_BAD_DEPTH,
9684           N_("@p @h %d: node (%B) has @n depth\n"),
9685           PROMPT_NONE, 0 },
9686
9687         /* Duplicate directory entry found */
9688         { PR_2_DUPLICATE_DIRENT,
9689           N_("Duplicate @E found.  "),
9690           PROMPT_CLEAR, 0 },
9691
9692         /* Non-unique filename found */
9693         { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9694           N_("@E has a non-unique filename.\nRename to %s"),
9695           PROMPT_NULL, 0 },
9696
9697         /* Duplicate directory entry found */
9698         { PR_2_REPORT_DUP_DIRENT,
9699           N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9700           PROMPT_NONE, 0 },
9701
9702         /* Pass 3 errors */
9703
9704         /* Pass 3: Checking directory connectivity */
9705         { PR_3_PASS_HEADER,
9706           N_("Pass 3: Checking @d connectivity\n"),
9707           PROMPT_NONE, 0 },
9708
9709         /* Root inode not allocated */
9710         { PR_3_NO_ROOT_INODE,
9711           N_("@r not allocated.  "),
9712           PROMPT_ALLOCATE, 0 },
9713
9714         /* No room in lost+found */
9715         { PR_3_EXPAND_LF_DIR,
9716           N_("No room in @l @d.  "),
9717           PROMPT_EXPAND, 0 },
9718
9719         /* Unconnected directory inode */
9720         { PR_3_UNCONNECTED_DIR,
9721           N_("Unconnected @d @i %i (%p)\n"),
9722           PROMPT_CONNECT, 0 },
9723
9724         /* /lost+found not found */
9725         { PR_3_NO_LF_DIR,
9726           N_("/@l not found.  "),
9727           PROMPT_CREATE, PR_PREEN_OK },
9728
9729         /* .. entry is incorrect */
9730         { PR_3_BAD_DOT_DOT,
9731           N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9732           PROMPT_FIX, 0 },
9733
9734         /* Bad or non-existent /lost+found.  Cannot reconnect */
9735         { PR_3_NO_LPF,
9736           N_("Bad or non-existent /@l.  Cannot reconnect.\n"),
9737           PROMPT_NONE, 0 },
9738
9739         /* Could not expand /lost+found */
9740         { PR_3_CANT_EXPAND_LPF,
9741           N_("Could not expand /@l: %m\n"),
9742           PROMPT_NONE, 0 },
9743
9744         /* Could not reconnect inode */
9745         { PR_3_CANT_RECONNECT,
9746           N_("Could not reconnect %i: %m\n"),
9747           PROMPT_NONE, 0 },
9748
9749         /* Error while trying to find /lost+found */
9750         { PR_3_ERR_FIND_LPF,
9751           N_("Error while trying to find /@l: %m\n"),
9752           PROMPT_NONE, 0 },
9753
9754         /* Error in ext2fs_new_block while creating /lost+found */
9755         { PR_3_ERR_LPF_NEW_BLOCK,
9756           N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9757           PROMPT_NONE, 0 },
9758
9759         /* Error in ext2fs_new_inode while creating /lost+found */
9760         { PR_3_ERR_LPF_NEW_INODE,
9761           N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9762           PROMPT_NONE, 0 },
9763
9764         /* Error in ext2fs_new_dir_block while creating /lost+found */
9765         { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9766           N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9767           PROMPT_NONE, 0 },
9768
9769         /* Error while writing directory block for /lost+found */
9770         { PR_3_ERR_LPF_WRITE_BLOCK,
9771           N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9772           PROMPT_NONE, 0 },
9773
9774         /* Error while adjusting inode count */
9775         { PR_3_ADJUST_INODE,
9776           N_("Error while adjusting @i count on @i %i\n"),
9777           PROMPT_NONE, 0 },
9778
9779         /* Couldn't fix parent directory -- error */
9780         { PR_3_FIX_PARENT_ERR,
9781           N_("Couldn't fix parent of @i %i: %m\n\n"),
9782           PROMPT_NONE, 0 },
9783
9784         /* Couldn't fix parent directory -- couldn't find it */
9785         { PR_3_FIX_PARENT_NOFIND,
9786           N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9787           PROMPT_NONE, 0 },
9788
9789         /* Error allocating inode bitmap */
9790         { PR_3_ALLOCATE_IBITMAP_ERROR,
9791           N_("@A @i @B (%N): %m\n"),
9792           PROMPT_NONE, PR_FATAL },
9793
9794         /* Error creating root directory */
9795         { PR_3_CREATE_ROOT_ERROR,
9796           N_("Error creating root @d (%s): %m\n"),
9797           PROMPT_NONE, PR_FATAL },
9798
9799         /* Error creating lost and found directory */
9800         { PR_3_CREATE_LPF_ERROR,
9801           N_("Error creating /@l @d (%s): %m\n"),
9802           PROMPT_NONE, PR_FATAL },
9803
9804         /* Root inode is not directory; aborting */
9805         { PR_3_ROOT_NOT_DIR_ABORT,
9806           N_("@r is not a @d; aborting.\n"),
9807           PROMPT_NONE, PR_FATAL },
9808
9809         /* Cannot proceed without a root inode. */
9810         { PR_3_NO_ROOT_INODE_ABORT,
9811           N_("Cannot proceed without a @r.\n"),
9812           PROMPT_NONE, PR_FATAL },
9813
9814         /* Internal error: couldn't find dir_info */
9815         { PR_3_NO_DIRINFO,
9816           N_("Internal error: couldn't find dir_info for %i.\n"),
9817           PROMPT_NONE, PR_FATAL },
9818
9819         /* Lost+found not a directory */
9820         { PR_3_LPF_NOTDIR,
9821           N_("/@l is not a @d (ino=%i)\n"),
9822           PROMPT_UNLINK, 0 },
9823
9824         /* Pass 3A Directory Optimization       */
9825
9826         /* Pass 3A: Optimizing directories */
9827         { PR_3A_PASS_HEADER,
9828           N_("Pass 3A: Optimizing directories\n"),
9829           PROMPT_NONE, PR_PREEN_NOMSG },
9830
9831         /* Error iterating over directories */
9832         { PR_3A_OPTIMIZE_ITER,
9833           N_("Failed to create dirs_to_hash iterator: %m"),
9834           PROMPT_NONE, 0 },
9835
9836         /* Error rehash directory */
9837         { PR_3A_OPTIMIZE_DIR_ERR,
9838           N_("Failed to optimize directory %q (%d): %m"),
9839           PROMPT_NONE, 0 },
9840
9841         /* Rehashing dir header */
9842         { PR_3A_OPTIMIZE_DIR_HEADER,
9843           N_("Optimizing directories: "),
9844           PROMPT_NONE, PR_MSG_ONLY },
9845
9846         /* Rehashing directory %d */
9847         { PR_3A_OPTIMIZE_DIR,
9848           " %d",
9849           PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9850
9851         /* Rehashing dir end */
9852         { PR_3A_OPTIMIZE_DIR_END,
9853           "\n",
9854           PROMPT_NONE, PR_PREEN_NOHDR },
9855
9856         /* Pass 4 errors */
9857
9858         /* Pass 4: Checking reference counts */
9859         { PR_4_PASS_HEADER,
9860           N_("Pass 4: Checking reference counts\n"),
9861           PROMPT_NONE, 0 },
9862
9863         /* Unattached zero-length inode */
9864         { PR_4_ZERO_LEN_INODE,
9865           N_("@u @z @i %i.  "),
9866           PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9867
9868         /* Unattached inode */
9869         { PR_4_UNATTACHED_INODE,
9870           N_("@u @i %i\n"),
9871           PROMPT_CONNECT, 0 },
9872
9873         /* Inode ref count wrong */
9874         { PR_4_BAD_REF_COUNT,
9875           N_("@i %i ref count is %Il, @s %N.  "),
9876           PROMPT_FIX, PR_PREEN_OK },
9877
9878         { PR_4_INCONSISTENT_COUNT,
9879           N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9880           "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9881           "@i_link_info[%i] is %N, @i.i_links_count is %Il.  "
9882           "They @s the same!\n"),
9883           PROMPT_NONE, 0 },
9884
9885         /* Pass 5 errors */
9886
9887         /* Pass 5: Checking group summary information */
9888         { PR_5_PASS_HEADER,
9889           N_("Pass 5: Checking @g summary information\n"),
9890           PROMPT_NONE, 0 },
9891
9892         /* Padding at end of inode bitmap is not set. */
9893         { PR_5_INODE_BMAP_PADDING,
9894           N_("Padding at end of @i @B is not set. "),
9895           PROMPT_FIX, PR_PREEN_OK },
9896
9897         /* Padding at end of block bitmap is not set. */
9898         { PR_5_BLOCK_BMAP_PADDING,
9899           N_("Padding at end of @b @B is not set. "),
9900           PROMPT_FIX, PR_PREEN_OK },
9901
9902         /* Block bitmap differences header */
9903         { PR_5_BLOCK_BITMAP_HEADER,
9904           N_("@b @B differences: "),
9905           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9906
9907         /* Block not used, but marked in bitmap */
9908         { PR_5_BLOCK_UNUSED,
9909           " -%b",
9910           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9911
9912         /* Block used, but not marked used in bitmap */
9913         { PR_5_BLOCK_USED,
9914           " +%b",
9915           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9916
9917         /* Block bitmap differences end */
9918         { PR_5_BLOCK_BITMAP_END,
9919           "\n",
9920           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9921
9922         /* Inode bitmap differences header */
9923         { PR_5_INODE_BITMAP_HEADER,
9924           N_("@i @B differences: "),
9925           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9926
9927         /* Inode not used, but marked in bitmap */
9928         { PR_5_INODE_UNUSED,
9929           " -%i",
9930           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9931
9932         /* Inode used, but not marked used in bitmap */
9933         { PR_5_INODE_USED,
9934           " +%i",
9935           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9936
9937         /* Inode bitmap differences end */
9938         { PR_5_INODE_BITMAP_END,
9939           "\n",
9940           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9941
9942         /* Free inodes count for group wrong */
9943         { PR_5_FREE_INODE_COUNT_GROUP,
9944           N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9945           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9946
9947         /* Directories count for group wrong */
9948         { PR_5_FREE_DIR_COUNT_GROUP,
9949           N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9950           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9951
9952         /* Free inodes count wrong */
9953         { PR_5_FREE_INODE_COUNT,
9954           N_("Free @is count wrong (%i, counted=%j).\n"),
9955           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9956
9957         /* Free blocks count for group wrong */
9958         { PR_5_FREE_BLOCK_COUNT_GROUP,
9959           N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9960           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9961
9962         /* Free blocks count wrong */
9963         { PR_5_FREE_BLOCK_COUNT,
9964           N_("Free @bs count wrong (%b, counted=%c).\n"),
9965           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9966
9967         /* Programming error: bitmap endpoints don't match */
9968         { PR_5_BMAP_ENDPOINTS,
9969           N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9970           "match calculated @B endpoints (%i, %j)\n"),
9971           PROMPT_NONE, PR_FATAL },
9972
9973         /* Internal error: fudging end of bitmap */
9974         { PR_5_FUDGE_BITMAP_ERROR,
9975           N_("Internal error: fudging end of bitmap (%N)\n"),
9976           PROMPT_NONE, PR_FATAL },
9977
9978         /* Error copying in replacement inode bitmap */
9979         { PR_5_COPY_IBITMAP_ERROR,
9980           N_("Error copying in replacement @i @B: %m\n"),
9981           PROMPT_NONE, PR_FATAL },
9982
9983         /* Error copying in replacement block bitmap */
9984         { PR_5_COPY_BBITMAP_ERROR,
9985           N_("Error copying in replacement @b @B: %m\n"),
9986           PROMPT_NONE, PR_FATAL },
9987
9988         /* Block range not used, but marked in bitmap */
9989         { PR_5_BLOCK_RANGE_UNUSED,
9990           " -(%b--%c)",
9991           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9992
9993         /* Block range used, but not marked used in bitmap */
9994         { PR_5_BLOCK_RANGE_USED,
9995           " +(%b--%c)",
9996           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9997
9998         /* Inode range not used, but marked in bitmap */
9999         { PR_5_INODE_RANGE_UNUSED,
10000           " -(%i--%j)",
10001           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10002
10003         /* Inode range used, but not marked used in bitmap */
10004         { PR_5_INODE_RANGE_USED,
10005           " +(%i--%j)",
10006           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10007
10008         { 0 }
10009 };
10010
10011 /*
10012  * This is the latch flags register.  It allows several problems to be
10013  * "latched" together.  This means that the user has to answer but one
10014  * question for the set of problems, and all of the associated
10015  * problems will be either fixed or not fixed.
10016  */
10017 static struct latch_descr pr_latch_info[] = {
10018         { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
10019         { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
10020         { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
10021         { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
10022         { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
10023         { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
10024         { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
10025         { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
10026         { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
10027         { -1, 0, 0 },
10028 };
10029
10030 static const struct e2fsck_problem *find_problem(problem_t code)
10031 {
10032         int     i;
10033
10034         for (i=0; problem_table[i].e2p_code; i++) {
10035                 if (problem_table[i].e2p_code == code)
10036                         return &problem_table[i];
10037         }
10038         return 0;
10039 }
10040
10041 static struct latch_descr *find_latch(int code)
10042 {
10043         int     i;
10044
10045         for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
10046                 if (pr_latch_info[i].latch_code == code)
10047                         return &pr_latch_info[i];
10048         }
10049         return 0;
10050 }
10051
10052 int end_problem_latch(e2fsck_t ctx, int mask)
10053 {
10054         struct latch_descr *ldesc;
10055         struct problem_context pctx;
10056         int answer = -1;
10057
10058         ldesc = find_latch(mask);
10059         if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
10060                 clear_problem_context(&pctx);
10061                 answer = fix_problem(ctx, ldesc->end_message, &pctx);
10062         }
10063         ldesc->flags &= ~(PRL_VARIABLE);
10064         return answer;
10065 }
10066
10067 int set_latch_flags(int mask, int setflags, int clearflags)
10068 {
10069         struct latch_descr *ldesc;
10070
10071         ldesc = find_latch(mask);
10072         if (!ldesc)
10073                 return -1;
10074         ldesc->flags |= setflags;
10075         ldesc->flags &= ~clearflags;
10076         return 0;
10077 }
10078
10079 void clear_problem_context(struct problem_context *ctx)
10080 {
10081         memset(ctx, 0, sizeof(struct problem_context));
10082         ctx->blkcount = -1;
10083         ctx->group = -1;
10084 }
10085
10086 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
10087 {
10088         ext2_filsys fs = ctx->fs;
10089         const struct e2fsck_problem *ptr;
10090         struct latch_descr *ldesc = 0;
10091         const char *message;
10092         int             def_yn, answer, ans;
10093         int             print_answer = 0;
10094         int             suppress = 0;
10095
10096         ptr = find_problem(code);
10097         if (!ptr) {
10098                 printf(_("Unhandled error code (0x%x)!\n"), code);
10099                 return 0;
10100         }
10101         def_yn = 1;
10102         if ((ptr->flags & PR_NO_DEFAULT) ||
10103             ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
10104             (ctx->options & E2F_OPT_NO))
10105                 def_yn= 0;
10106
10107         /*
10108          * Do special latch processing.  This is where we ask the
10109          * latch question, if it exists
10110          */
10111         if (ptr->flags & PR_LATCH_MASK) {
10112                 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
10113                 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
10114                         ans = fix_problem(ctx, ldesc->question, pctx);
10115                         if (ans == 1)
10116                                 ldesc->flags |= PRL_YES;
10117                         if (ans == 0)
10118                                 ldesc->flags |= PRL_NO;
10119                         ldesc->flags |= PRL_LATCHED;
10120                 }
10121                 if (ldesc->flags & PRL_SUPPRESS)
10122                         suppress++;
10123         }
10124         if ((ptr->flags & PR_PREEN_NOMSG) &&
10125             (ctx->options & E2F_OPT_PREEN))
10126                 suppress++;
10127         if ((ptr->flags & PR_NO_NOMSG) &&
10128             (ctx->options & E2F_OPT_NO))
10129                 suppress++;
10130         if (!suppress) {
10131                 message = ptr->e2p_description;
10132                 if ((ctx->options & E2F_OPT_PREEN) &&
10133                     !(ptr->flags & PR_PREEN_NOHDR)) {
10134                         printf("%s: ", ctx->device_name ?
10135                                ctx->device_name : ctx->filesystem_name);
10136                 }
10137                 if (*message)
10138                         print_e2fsck_message(ctx, _(message), pctx, 1);
10139         }
10140         if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
10141                 preenhalt(ctx);
10142
10143         if (ptr->flags & PR_FATAL)
10144                 bb_error_msg_and_die(0);
10145
10146         if (ptr->prompt == PROMPT_NONE) {
10147                 if (ptr->flags & PR_NOCOLLATE)
10148                         answer = -1;
10149                 else
10150                         answer = def_yn;
10151         } else {
10152                 if (ctx->options & E2F_OPT_PREEN) {
10153                         answer = def_yn;
10154                         if (!(ptr->flags & PR_PREEN_NOMSG))
10155                                 print_answer = 1;
10156                 } else if ((ptr->flags & PR_LATCH_MASK) &&
10157                            (ldesc->flags & (PRL_YES | PRL_NO))) {
10158                         if (!suppress)
10159                                 print_answer = 1;
10160                         if (ldesc->flags & PRL_YES)
10161                                 answer = 1;
10162                         else
10163                                 answer = 0;
10164                 } else
10165                         answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
10166                 if (!answer && !(ptr->flags & PR_NO_OK))
10167                         ext2fs_unmark_valid(fs);
10168
10169                 if (print_answer)
10170                         printf("%s.\n", answer ?
10171                                _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
10172
10173         }
10174
10175         if ((ptr->prompt == PROMPT_ABORT) && answer)
10176                 bb_error_msg_and_die(0);
10177
10178         if (ptr->flags & PR_AFTER_CODE)
10179                 answer = fix_problem(ctx, ptr->second_code, pctx);
10180
10181         return answer;
10182 }
10183
10184 /*
10185  * linux/fs/recovery.c
10186  *
10187  * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
10188  */
10189
10190 /*
10191  * Maintain information about the progress of the recovery job, so that
10192  * the different passes can carry information between them.
10193  */
10194 struct recovery_info
10195 {
10196         tid_t           start_transaction;
10197         tid_t           end_transaction;
10198
10199         int             nr_replays;
10200         int             nr_revokes;
10201         int             nr_revoke_hits;
10202 };
10203
10204 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
10205 static int do_one_pass(journal_t *journal,
10206                                 struct recovery_info *info, enum passtype pass);
10207 static int scan_revoke_records(journal_t *, struct buffer_head *,
10208                                 tid_t, struct recovery_info *);
10209
10210 /*
10211  * Read a block from the journal
10212  */
10213
10214 static int jread(struct buffer_head **bhp, journal_t *journal,
10215                  unsigned int offset)
10216 {
10217         int err;
10218         unsigned long blocknr;
10219         struct buffer_head *bh;
10220
10221         *bhp = NULL;
10222
10223         err = journal_bmap(journal, offset, &blocknr);
10224
10225         if (err) {
10226                 printf ("JBD: bad block at offset %u\n", offset);
10227                 return err;
10228         }
10229
10230         bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
10231         if (!bh)
10232                 return -ENOMEM;
10233
10234         if (!buffer_uptodate(bh)) {
10235                 /* If this is a brand new buffer, start readahead.
10236                    Otherwise, we assume we are already reading it.  */
10237                 if (!buffer_req(bh))
10238                         do_readahead(journal, offset);
10239                 wait_on_buffer(bh);
10240         }
10241
10242         if (!buffer_uptodate(bh)) {
10243                 printf ("JBD: Failed to read block at offset %u\n", offset);
10244                 brelse(bh);
10245                 return -EIO;
10246         }
10247
10248         *bhp = bh;
10249         return 0;
10250 }
10251
10252
10253 /*
10254  * Count the number of in-use tags in a journal descriptor block.
10255  */
10256
10257 static int count_tags(struct buffer_head *bh, int size)
10258 {
10259         char *                  tagp;
10260         journal_block_tag_t *   tag;
10261         int                     nr = 0;
10262
10263         tagp = &bh->b_data[sizeof(journal_header_t)];
10264
10265         while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
10266                 tag = (journal_block_tag_t *) tagp;
10267
10268                 nr++;
10269                 tagp += sizeof(journal_block_tag_t);
10270                 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
10271                         tagp += 16;
10272
10273                 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
10274                         break;
10275         }
10276
10277         return nr;
10278 }
10279
10280
10281 /* Make sure we wrap around the log correctly! */
10282 #define wrap(journal, var)                                            \
10283 do {                                                                \
10284         if (var >= (journal)->j_last)                                   \
10285                 var -= ((journal)->j_last - (journal)->j_first);        \
10286 } while (0)
10287
10288 /**
10289  * int journal_recover(journal_t *journal) - recovers a on-disk journal
10290  * @journal: the journal to recover
10291  *
10292  * The primary function for recovering the log contents when mounting a
10293  * journaled device.
10294  *
10295  * Recovery is done in three passes.  In the first pass, we look for the
10296  * end of the log.  In the second, we assemble the list of revoke
10297  * blocks.  In the third and final pass, we replay any un-revoked blocks
10298  * in the log.
10299  */
10300 int journal_recover(journal_t *journal)
10301 {
10302         int                     err;
10303         journal_superblock_t *  sb;
10304
10305         struct recovery_info    info;
10306
10307         memset(&info, 0, sizeof(info));
10308         sb = journal->j_superblock;
10309
10310         /*
10311          * The journal superblock's s_start field (the current log head)
10312          * is always zero if, and only if, the journal was cleanly
10313          * unmounted.
10314          */
10315
10316         if (!sb->s_start) {
10317                 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
10318                 return 0;
10319         }
10320
10321         err = do_one_pass(journal, &info, PASS_SCAN);
10322         if (!err)
10323                 err = do_one_pass(journal, &info, PASS_REVOKE);
10324         if (!err)
10325                 err = do_one_pass(journal, &info, PASS_REPLAY);
10326
10327         /* Restart the log at the next transaction ID, thus invalidating
10328          * any existing commit records in the log. */
10329         journal->j_transaction_sequence = ++info.end_transaction;
10330
10331         journal_clear_revoke(journal);
10332         sync_blockdev(journal->j_fs_dev);
10333         return err;
10334 }
10335
10336 static int do_one_pass(journal_t *journal,
10337                         struct recovery_info *info, enum passtype pass)
10338 {
10339         unsigned int            first_commit_ID, next_commit_ID;
10340         unsigned long           next_log_block;
10341         int                     err, success = 0;
10342         journal_superblock_t *  sb;
10343         journal_header_t *      tmp;
10344         struct buffer_head *    bh;
10345         unsigned int            sequence;
10346         int                     blocktype;
10347
10348         /* Precompute the maximum metadata descriptors in a descriptor block */
10349         int                     MAX_BLOCKS_PER_DESC;
10350         MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
10351                                / sizeof(journal_block_tag_t));
10352
10353         /*
10354          * First thing is to establish what we expect to find in the log
10355          * (in terms of transaction IDs), and where (in terms of log
10356          * block offsets): query the superblock.
10357          */
10358
10359         sb = journal->j_superblock;
10360         next_commit_ID = ntohl(sb->s_sequence);
10361         next_log_block = ntohl(sb->s_start);
10362
10363         first_commit_ID = next_commit_ID;
10364         if (pass == PASS_SCAN)
10365                 info->start_transaction = first_commit_ID;
10366
10367         /*
10368          * Now we walk through the log, transaction by transaction,
10369          * making sure that each transaction has a commit block in the
10370          * expected place.  Each complete transaction gets replayed back
10371          * into the main filesystem.
10372          */
10373
10374         while (1) {
10375                 int                     flags;
10376                 char *                  tagp;
10377                 journal_block_tag_t *   tag;
10378                 struct buffer_head *    obh;
10379                 struct buffer_head *    nbh;
10380
10381                 /* If we already know where to stop the log traversal,
10382                  * check right now that we haven't gone past the end of
10383                  * the log. */
10384
10385                 if (pass != PASS_SCAN)
10386                         if (tid_geq(next_commit_ID, info->end_transaction))
10387                                 break;
10388
10389                 /* Skip over each chunk of the transaction looking
10390                  * either the next descriptor block or the final commit
10391                  * record. */
10392
10393                 err = jread(&bh, journal, next_log_block);
10394                 if (err)
10395                         goto failed;
10396
10397                 next_log_block++;
10398                 wrap(journal, next_log_block);
10399
10400                 /* What kind of buffer is it?
10401                  *
10402                  * If it is a descriptor block, check that it has the
10403                  * expected sequence number.  Otherwise, we're all done
10404                  * here. */
10405
10406                 tmp = (journal_header_t *)bh->b_data;
10407
10408                 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10409                         brelse(bh);
10410                         break;
10411                 }
10412
10413                 blocktype = ntohl(tmp->h_blocktype);
10414                 sequence = ntohl(tmp->h_sequence);
10415
10416                 if (sequence != next_commit_ID) {
10417                         brelse(bh);
10418                         break;
10419                 }
10420
10421                 /* OK, we have a valid descriptor block which matches
10422                  * all of the sequence number checks.  What are we going
10423                  * to do with it?  That depends on the pass... */
10424
10425                 switch(blocktype) {
10426                 case JFS_DESCRIPTOR_BLOCK:
10427                         /* If it is a valid descriptor block, replay it
10428                          * in pass REPLAY; otherwise, just skip over the
10429                          * blocks it describes. */
10430                         if (pass != PASS_REPLAY) {
10431                                 next_log_block +=
10432                                         count_tags(bh, journal->j_blocksize);
10433                                 wrap(journal, next_log_block);
10434                                 brelse(bh);
10435                                 continue;
10436                         }
10437
10438                         /* A descriptor block: we can now write all of
10439                          * the data blocks.  Yay, useful work is finally
10440                          * getting done here! */
10441
10442                         tagp = &bh->b_data[sizeof(journal_header_t)];
10443                         while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10444                                <= journal->j_blocksize) {
10445                                 unsigned long io_block;
10446
10447                                 tag = (journal_block_tag_t *) tagp;
10448                                 flags = ntohl(tag->t_flags);
10449
10450                                 io_block = next_log_block++;
10451                                 wrap(journal, next_log_block);
10452                                 err = jread(&obh, journal, io_block);
10453                                 if (err) {
10454                                         /* Recover what we can, but
10455                                          * report failure at the end. */
10456                                         success = err;
10457                                         printf ("JBD: IO error %d recovering "
10458                                                 "block %ld in log\n",
10459                                                 err, io_block);
10460                                 } else {
10461                                         unsigned long blocknr;
10462
10463                                         blocknr = ntohl(tag->t_blocknr);
10464
10465                                         /* If the block has been
10466                                          * revoked, then we're all done
10467                                          * here. */
10468                                         if (journal_test_revoke
10469                                             (journal, blocknr,
10470                                              next_commit_ID)) {
10471                                                 brelse(obh);
10472                                                 ++info->nr_revoke_hits;
10473                                                 goto skip_write;
10474                                         }
10475
10476                                         /* Find a buffer for the new
10477                                          * data being restored */
10478                                         nbh = getblk(journal->j_fs_dev,
10479                                                        blocknr,
10480                                                      journal->j_blocksize);
10481                                         if (nbh == NULL) {
10482                                                 printf ("JBD: Out of memory "
10483                                                        "during recovery.\n");
10484                                                 err = -ENOMEM;
10485                                                 brelse(bh);
10486                                                 brelse(obh);
10487                                                 goto failed;
10488                                         }
10489
10490                                         lock_buffer(nbh);
10491                                         memcpy(nbh->b_data, obh->b_data,
10492                                                         journal->j_blocksize);
10493                                         if (flags & JFS_FLAG_ESCAPE) {
10494                                                 *((unsigned int *)bh->b_data) =
10495                                                         htonl(JFS_MAGIC_NUMBER);
10496                                         }
10497
10498                                         mark_buffer_uptodate(nbh, 1);
10499                                         mark_buffer_dirty(nbh);
10500                                         ++info->nr_replays;
10501                                         /* ll_rw_block(WRITE, 1, &nbh); */
10502                                         unlock_buffer(nbh);
10503                                         brelse(obh);
10504                                         brelse(nbh);
10505                                 }
10506
10507                         skip_write:
10508                                 tagp += sizeof(journal_block_tag_t);
10509                                 if (!(flags & JFS_FLAG_SAME_UUID))
10510                                         tagp += 16;
10511
10512                                 if (flags & JFS_FLAG_LAST_TAG)
10513                                         break;
10514                         }
10515
10516                         brelse(bh);
10517                         continue;
10518
10519                 case JFS_COMMIT_BLOCK:
10520                         /* Found an expected commit block: not much to
10521                          * do other than move on to the next sequence
10522                          * number. */
10523                         brelse(bh);
10524                         next_commit_ID++;
10525                         continue;
10526
10527                 case JFS_REVOKE_BLOCK:
10528                         /* If we aren't in the REVOKE pass, then we can
10529                          * just skip over this block. */
10530                         if (pass != PASS_REVOKE) {
10531                                 brelse(bh);
10532                                 continue;
10533                         }
10534
10535                         err = scan_revoke_records(journal, bh,
10536                                                   next_commit_ID, info);
10537                         brelse(bh);
10538                         if (err)
10539                                 goto failed;
10540                         continue;
10541
10542                 default:
10543                         goto done;
10544                 }
10545         }
10546
10547  done:
10548         /*
10549          * We broke out of the log scan loop: either we came to the
10550          * known end of the log or we found an unexpected block in the
10551          * log.  If the latter happened, then we know that the "current"
10552          * transaction marks the end of the valid log.
10553          */
10554
10555         if (pass == PASS_SCAN)
10556                 info->end_transaction = next_commit_ID;
10557         else {
10558                 /* It's really bad news if different passes end up at
10559                  * different places (but possible due to IO errors). */
10560                 if (info->end_transaction != next_commit_ID) {
10561                         printf ("JBD: recovery pass %d ended at "
10562                                 "transaction %u, expected %u\n",
10563                                 pass, next_commit_ID, info->end_transaction);
10564                         if (!success)
10565                                 success = -EIO;
10566                 }
10567         }
10568
10569         return success;
10570
10571  failed:
10572         return err;
10573 }
10574
10575
10576 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10577
10578 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10579                                tid_t sequence, struct recovery_info *info)
10580 {
10581         journal_revoke_header_t *header;
10582         int offset, max;
10583
10584         header = (journal_revoke_header_t *) bh->b_data;
10585         offset = sizeof(journal_revoke_header_t);
10586         max = ntohl(header->r_count);
10587
10588         while (offset < max) {
10589                 unsigned long blocknr;
10590                 int err;
10591
10592                 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10593                 offset += 4;
10594                 err = journal_set_revoke(journal, blocknr, sequence);
10595                 if (err)
10596                         return err;
10597                 ++info->nr_revokes;
10598         }
10599         return 0;
10600 }
10601
10602
10603 /*
10604  * rehash.c --- rebuild hash tree directories
10605  *
10606  * This algorithm is designed for simplicity of implementation and to
10607  * pack the directory as much as possible.  It however requires twice
10608  * as much memory as the size of the directory.  The maximum size
10609  * directory supported using a 4k blocksize is roughly a gigabyte, and
10610  * so there may very well be problems with machines that don't have
10611  * virtual memory, and obscenely large directories.
10612  *
10613  * An alternate algorithm which is much more disk intensive could be
10614  * written, and probably will need to be written in the future.  The
10615  * design goals of such an algorithm are: (a) use (roughly) constant
10616  * amounts of memory, no matter how large the directory, (b) the
10617  * directory must be safe at all times, even if e2fsck is interrupted
10618  * in the middle, (c) we must use minimal amounts of extra disk
10619  * blocks.  This pretty much requires an incremental approach, where
10620  * we are reading from one part of the directory, and inserting into
10621  * the front half.  So the algorithm will have to keep track of a
10622  * moving block boundary between the new tree and the old tree, and
10623  * files will need to be moved from the old directory and inserted
10624  * into the new tree.  If the new directory requires space which isn't
10625  * yet available, blocks from the beginning part of the old directory
10626  * may need to be moved to the end of the directory to make room for
10627  * the new tree:
10628  *
10629  *    --------------------------------------------------------
10630  *    |  new tree   |        | old tree                      |
10631  *    --------------------------------------------------------
10632  *                  ^ ptr    ^ptr
10633  *                tail new   head old
10634  *
10635  * This is going to be a pain in the tuckus to implement, and will
10636  * require a lot more disk accesses.  So I'm going to skip it for now;
10637  * it's only really going to be an issue for really, really big
10638  * filesystems (when we reach the level of tens of millions of files
10639  * in a single directory).  It will probably be easier to simply
10640  * require that e2fsck use VM first.
10641  */
10642
10643 struct fill_dir_struct {
10644         char *buf;
10645         struct ext2_inode *inode;
10646         int err;
10647         e2fsck_t ctx;
10648         struct hash_entry *harray;
10649         int max_array, num_array;
10650         int dir_size;
10651         int compress;
10652         ino_t parent;
10653 };
10654
10655 struct hash_entry {
10656         ext2_dirhash_t  hash;
10657         ext2_dirhash_t  minor_hash;
10658         struct ext2_dir_entry   *dir;
10659 };
10660
10661 struct out_dir {
10662         int             num;
10663         int             max;
10664         char            *buf;
10665         ext2_dirhash_t  *hashes;
10666 };
10667
10668 static int fill_dir_block(ext2_filsys fs,
10669                           blk_t *block_nr,
10670                           e2_blkcnt_t blockcnt,
10671                           blk_t ref_block FSCK_ATTR((unused)),
10672                           int ref_offset FSCK_ATTR((unused)),
10673                           void *priv_data)
10674 {
10675         struct fill_dir_struct  *fd = (struct fill_dir_struct *) priv_data;
10676         struct hash_entry       *new_array, *ent;
10677         struct ext2_dir_entry   *dirent;
10678         char                    *dir;
10679         unsigned int            offset, dir_offset;
10680
10681         if (blockcnt < 0)
10682                 return 0;
10683
10684         offset = blockcnt * fs->blocksize;
10685         if (offset + fs->blocksize > fd->inode->i_size) {
10686                 fd->err = EXT2_ET_DIR_CORRUPTED;
10687                 return BLOCK_ABORT;
10688         }
10689         dir = (fd->buf+offset);
10690         if (HOLE_BLKADDR(*block_nr)) {
10691                 memset(dir, 0, fs->blocksize);
10692                 dirent = (struct ext2_dir_entry *) dir;
10693                 dirent->rec_len = fs->blocksize;
10694         } else {
10695                 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10696                 if (fd->err)
10697                         return BLOCK_ABORT;
10698         }
10699         /* While the directory block is "hot", index it. */
10700         dir_offset = 0;
10701         while (dir_offset < fs->blocksize) {
10702                 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10703                 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10704                     (dirent->rec_len < 8) ||
10705                     ((dirent->rec_len % 4) != 0) ||
10706                     (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10707                         fd->err = EXT2_ET_DIR_CORRUPTED;
10708                         return BLOCK_ABORT;
10709                 }
10710                 dir_offset += dirent->rec_len;
10711                 if (dirent->inode == 0)
10712                         continue;
10713                 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10714                     (dirent->name[0] == '.'))
10715                         continue;
10716                 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10717                     (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10718                         fd->parent = dirent->inode;
10719                         continue;
10720                 }
10721                 if (fd->num_array >= fd->max_array) {
10722                         new_array = realloc(fd->harray,
10723                             sizeof(struct hash_entry) * (fd->max_array+500));
10724                         if (!new_array) {
10725                                 fd->err = ENOMEM;
10726                                 return BLOCK_ABORT;
10727                         }
10728                         fd->harray = new_array;
10729                         fd->max_array += 500;
10730                 }
10731                 ent = fd->harray + fd->num_array++;
10732                 ent->dir = dirent;
10733                 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10734                 if (fd->compress)
10735                         ent->hash = ent->minor_hash = 0;
10736                 else {
10737                         fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10738                                                  dirent->name,
10739                                                  dirent->name_len & 0xFF,
10740                                                  fs->super->s_hash_seed,
10741                                                  &ent->hash, &ent->minor_hash);
10742                         if (fd->err)
10743                                 return BLOCK_ABORT;
10744                 }
10745         }
10746
10747         return 0;
10748 }
10749
10750 /* Used for sorting the hash entry */
10751 static int name_cmp(const void *a, const void *b)
10752 {
10753         const struct hash_entry *he_a = (const struct hash_entry *) a;
10754         const struct hash_entry *he_b = (const struct hash_entry *) b;
10755         int     ret;
10756         int     min_len;
10757
10758         min_len = he_a->dir->name_len;
10759         if (min_len > he_b->dir->name_len)
10760                 min_len = he_b->dir->name_len;
10761
10762         ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10763         if (ret == 0) {
10764                 if (he_a->dir->name_len > he_b->dir->name_len)
10765                         ret = 1;
10766                 else if (he_a->dir->name_len < he_b->dir->name_len)
10767                         ret = -1;
10768                 else
10769                         ret = he_b->dir->inode - he_a->dir->inode;
10770         }
10771         return ret;
10772 }
10773
10774 /* Used for sorting the hash entry */
10775 static int hash_cmp(const void *a, const void *b)
10776 {
10777         const struct hash_entry *he_a = (const struct hash_entry *) a;
10778         const struct hash_entry *he_b = (const struct hash_entry *) b;
10779         int     ret;
10780
10781         if (he_a->hash > he_b->hash)
10782                 ret = 1;
10783         else if (he_a->hash < he_b->hash)
10784                 ret = -1;
10785         else {
10786                 if (he_a->minor_hash > he_b->minor_hash)
10787                         ret = 1;
10788                 else if (he_a->minor_hash < he_b->minor_hash)
10789                         ret = -1;
10790                 else
10791                         ret = name_cmp(a, b);
10792         }
10793         return ret;
10794 }
10795
10796 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10797                                 int blocks)
10798 {
10799         void                    *new_mem;
10800
10801         if (outdir->max) {
10802                 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10803                 if (!new_mem)
10804                         return ENOMEM;
10805                 outdir->buf = new_mem;
10806                 new_mem = realloc(outdir->hashes,
10807                                   blocks * sizeof(ext2_dirhash_t));
10808                 if (!new_mem)
10809                         return ENOMEM;
10810                 outdir->hashes = new_mem;
10811         } else {
10812                 outdir->buf = malloc(blocks * fs->blocksize);
10813                 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10814                 outdir->num = 0;
10815         }
10816         outdir->max = blocks;
10817         return 0;
10818 }
10819
10820 static void free_out_dir(struct out_dir *outdir)
10821 {
10822         free(outdir->buf);
10823         free(outdir->hashes);
10824         outdir->max = 0;
10825         outdir->num =0;
10826 }
10827
10828 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10829                          char ** ret)
10830 {
10831         errcode_t       retval;
10832
10833         if (outdir->num >= outdir->max) {
10834                 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10835                 if (retval)
10836                         return retval;
10837         }
10838         *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10839         memset(*ret, 0, fs->blocksize);
10840         return 0;
10841 }
10842
10843 /*
10844  * This function is used to make a unique filename.  We do this by
10845  * appending ~0, and then incrementing the number.  However, we cannot
10846  * expand the length of the filename beyond the padding available in
10847  * the directory entry.
10848  */
10849 static void mutate_name(char *str, __u16 *len)
10850 {
10851         int     i;
10852         __u16   l = *len & 0xFF, h = *len & 0xff00;
10853
10854         /*
10855          * First check to see if it looks the name has been mutated
10856          * already
10857          */
10858         for (i = l-1; i > 0; i--) {
10859                 if (!isdigit(str[i]))
10860                         break;
10861         }
10862         if ((i == l-1) || (str[i] != '~')) {
10863                 if (((l-1) & 3) < 2)
10864                         l += 2;
10865                 else
10866                         l = (l+3) & ~3;
10867                 str[l-2] = '~';
10868                 str[l-1] = '0';
10869                 *len = l | h;
10870                 return;
10871         }
10872         for (i = l-1; i >= 0; i--) {
10873                 if (isdigit(str[i])) {
10874                         if (str[i] == '9')
10875                                 str[i] = '0';
10876                         else {
10877                                 str[i]++;
10878                                 return;
10879                         }
10880                         continue;
10881                 }
10882                 if (i == 1) {
10883                         if (str[0] == 'z')
10884                                 str[0] = 'A';
10885                         else if (str[0] == 'Z') {
10886                                 str[0] = '~';
10887                                 str[1] = '0';
10888                         } else
10889                                 str[0]++;
10890                 } else if (i > 0) {
10891                         str[i] = '1';
10892                         str[i-1] = '~';
10893                 } else {
10894                         if (str[0] == '~')
10895                                 str[0] = 'a';
10896                         else
10897                                 str[0]++;
10898                 }
10899                 break;
10900         }
10901 }
10902
10903 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10904                                     ext2_ino_t ino,
10905                                     struct fill_dir_struct *fd)
10906 {
10907         struct problem_context  pctx;
10908         struct hash_entry       *ent, *prev;
10909         int                     i, j;
10910         int                     fixed = 0;
10911         char                    new_name[256];
10912         __u16                   new_len;
10913
10914         clear_problem_context(&pctx);
10915         pctx.ino = ino;
10916
10917         for (i=1; i < fd->num_array; i++) {
10918                 ent = fd->harray + i;
10919                 prev = ent - 1;
10920                 if (!ent->dir->inode ||
10921                     ((ent->dir->name_len & 0xFF) !=
10922                      (prev->dir->name_len & 0xFF)) ||
10923                     (strncmp(ent->dir->name, prev->dir->name,
10924                              ent->dir->name_len & 0xFF)))
10925                         continue;
10926                 pctx.dirent = ent->dir;
10927                 if ((ent->dir->inode == prev->dir->inode) &&
10928                     fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10929                         e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10930                         ent->dir->inode = 0;
10931                         fixed++;
10932                         continue;
10933                 }
10934                 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10935                 new_len = ent->dir->name_len;
10936                 mutate_name(new_name, &new_len);
10937                 for (j=0; j < fd->num_array; j++) {
10938                         if ((i==j) ||
10939                             ((ent->dir->name_len & 0xFF) !=
10940                              (fd->harray[j].dir->name_len & 0xFF)) ||
10941                             (strncmp(new_name, fd->harray[j].dir->name,
10942                                      new_len & 0xFF)))
10943                                 continue;
10944                         mutate_name(new_name, &new_len);
10945
10946                         j = -1;
10947                 }
10948                 new_name[new_len & 0xFF] = 0;
10949                 pctx.str = new_name;
10950                 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10951                         memcpy(ent->dir->name, new_name, new_len & 0xFF);
10952                         ent->dir->name_len = new_len;
10953                         ext2fs_dirhash(fs->super->s_def_hash_version,
10954                                        ent->dir->name,
10955                                        ent->dir->name_len & 0xFF,
10956                                        fs->super->s_hash_seed,
10957                                        &ent->hash, &ent->minor_hash);
10958                         fixed++;
10959                 }
10960         }
10961         return fixed;
10962 }
10963
10964
10965 static errcode_t copy_dir_entries(ext2_filsys fs,
10966                                   struct fill_dir_struct *fd,
10967                                   struct out_dir *outdir)
10968 {
10969         errcode_t               retval;
10970         char                    *block_start;
10971         struct hash_entry       *ent;
10972         struct ext2_dir_entry   *dirent;
10973         int                     i, rec_len, left;
10974         ext2_dirhash_t          prev_hash;
10975         int                     offset;
10976
10977         outdir->max = 0;
10978         retval = alloc_size_dir(fs, outdir,
10979                                 (fd->dir_size / fs->blocksize) + 2);
10980         if (retval)
10981                 return retval;
10982         outdir->num = fd->compress ? 0 : 1;
10983         offset = 0;
10984         outdir->hashes[0] = 0;
10985         prev_hash = 1;
10986         if ((retval = get_next_block(fs, outdir, &block_start)))
10987                 return retval;
10988         dirent = (struct ext2_dir_entry *) block_start;
10989         left = fs->blocksize;
10990         for (i=0; i < fd->num_array; i++) {
10991                 ent = fd->harray + i;
10992                 if (ent->dir->inode == 0)
10993                         continue;
10994                 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10995                 if (rec_len > left) {
10996                         if (left)
10997                                 dirent->rec_len += left;
10998                         if ((retval = get_next_block(fs, outdir,
10999                                                       &block_start)))
11000                                 return retval;
11001                         offset = 0;
11002                 }
11003                 left = fs->blocksize - offset;
11004                 dirent = (struct ext2_dir_entry *) (block_start + offset);
11005                 if (offset == 0) {
11006                         if (ent->hash == prev_hash)
11007                                 outdir->hashes[outdir->num-1] = ent->hash | 1;
11008                         else
11009                                 outdir->hashes[outdir->num-1] = ent->hash;
11010                 }
11011                 dirent->inode = ent->dir->inode;
11012                 dirent->name_len = ent->dir->name_len;
11013                 dirent->rec_len = rec_len;
11014                 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
11015                 offset += rec_len;
11016                 left -= rec_len;
11017                 if (left < 12) {
11018                         dirent->rec_len += left;
11019                         offset += left;
11020                         left = 0;
11021                 }
11022                 prev_hash = ent->hash;
11023         }
11024         if (left)
11025                 dirent->rec_len += left;
11026
11027         return 0;
11028 }
11029
11030
11031 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
11032                                     ext2_ino_t ino, ext2_ino_t parent)
11033 {
11034         struct ext2_dir_entry           *dir;
11035         struct ext2_dx_root_info        *root;
11036         struct ext2_dx_countlimit       *limits;
11037         int                             filetype = 0;
11038
11039         if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
11040                 filetype = EXT2_FT_DIR << 8;
11041
11042         memset(buf, 0, fs->blocksize);
11043         dir = (struct ext2_dir_entry *) buf;
11044         dir->inode = ino;
11045         dir->name[0] = '.';
11046         dir->name_len = 1 | filetype;
11047         dir->rec_len = 12;
11048         dir = (struct ext2_dir_entry *) (buf + 12);
11049         dir->inode = parent;
11050         dir->name[0] = '.';
11051         dir->name[1] = '.';
11052         dir->name_len = 2 | filetype;
11053         dir->rec_len = fs->blocksize - 12;
11054
11055         root = (struct ext2_dx_root_info *) (buf+24);
11056         root->reserved_zero = 0;
11057         root->hash_version = fs->super->s_def_hash_version;
11058         root->info_length = 8;
11059         root->indirect_levels = 0;
11060         root->unused_flags = 0;
11061
11062         limits = (struct ext2_dx_countlimit *) (buf+32);
11063         limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
11064         limits->count = 0;
11065
11066         return root;
11067 }
11068
11069
11070 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
11071 {
11072         struct ext2_dir_entry           *dir;
11073         struct ext2_dx_countlimit       *limits;
11074
11075         memset(buf, 0, fs->blocksize);
11076         dir = (struct ext2_dir_entry *) buf;
11077         dir->inode = 0;
11078         dir->rec_len = fs->blocksize;
11079
11080         limits = (struct ext2_dx_countlimit *) (buf+8);
11081         limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
11082         limits->count = 0;
11083
11084         return (struct ext2_dx_entry *) limits;
11085 }
11086
11087 /*
11088  * This function takes the leaf nodes which have been written in
11089  * outdir, and populates the root node and any necessary interior nodes.
11090  */
11091 static errcode_t calculate_tree(ext2_filsys fs,
11092                                 struct out_dir *outdir,
11093                                 ext2_ino_t ino,
11094                                 ext2_ino_t parent)
11095 {
11096         struct ext2_dx_root_info        *root_info;
11097         struct ext2_dx_entry            *root, *dx_ent = 0;
11098         struct ext2_dx_countlimit       *root_limit, *limit;
11099         errcode_t                       retval;
11100         char                            * block_start;
11101         int                             i, c1, c2, nblks;
11102         int                             limit_offset, root_offset;
11103
11104         root_info = set_root_node(fs, outdir->buf, ino, parent);
11105         root_offset = limit_offset = ((char *) root_info - outdir->buf) +
11106                 root_info->info_length;
11107         root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11108         c1 = root_limit->limit;
11109         nblks = outdir->num;
11110
11111         /* Write out the pointer blocks */
11112         if (nblks-1 <= c1) {
11113                 /* Just write out the root block, and we're done */
11114                 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
11115                 for (i=1; i < nblks; i++) {
11116                         root->block = ext2fs_cpu_to_le32(i);
11117                         if (i != 1)
11118                                 root->hash =
11119                                         ext2fs_cpu_to_le32(outdir->hashes[i]);
11120                         root++;
11121                         c1--;
11122                 }
11123         } else {
11124                 c2 = 0;
11125                 limit = 0;
11126                 root_info->indirect_levels = 1;
11127                 for (i=1; i < nblks; i++) {
11128                         if (c1 == 0)
11129                                 return ENOSPC;
11130                         if (c2 == 0) {
11131                                 if (limit)
11132                                         limit->limit = limit->count =
11133                 ext2fs_cpu_to_le16(limit->limit);
11134                                 root = (struct ext2_dx_entry *)
11135                                         (outdir->buf + root_offset);
11136                                 root->block = ext2fs_cpu_to_le32(outdir->num);
11137                                 if (i != 1)
11138                                         root->hash =
11139                         ext2fs_cpu_to_le32(outdir->hashes[i]);
11140                                 if ((retval =  get_next_block(fs, outdir,
11141                                                               &block_start)))
11142                                         return retval;
11143                                 dx_ent = set_int_node(fs, block_start);
11144                                 limit = (struct ext2_dx_countlimit *) dx_ent;
11145                                 c2 = limit->limit;
11146                                 root_offset += sizeof(struct ext2_dx_entry);
11147                                 c1--;
11148                         }
11149                         dx_ent->block = ext2fs_cpu_to_le32(i);
11150                         if (c2 != limit->limit)
11151                                 dx_ent->hash =
11152                                         ext2fs_cpu_to_le32(outdir->hashes[i]);
11153                         dx_ent++;
11154                         c2--;
11155                 }
11156                 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
11157                 limit->limit = ext2fs_cpu_to_le16(limit->limit);
11158         }
11159         root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11160         root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
11161         root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
11162
11163         return 0;
11164 }
11165
11166 struct write_dir_struct {
11167         struct out_dir *outdir;
11168         errcode_t       err;
11169         e2fsck_t        ctx;
11170         int             cleared;
11171 };
11172
11173 /*
11174  * Helper function which writes out a directory block.
11175  */
11176 static int write_dir_block(ext2_filsys fs,
11177                            blk_t        *block_nr,
11178                            e2_blkcnt_t blockcnt,
11179                            blk_t ref_block FSCK_ATTR((unused)),
11180                            int ref_offset FSCK_ATTR((unused)),
11181                            void *priv_data)
11182 {
11183         struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
11184         blk_t   blk;
11185         char    *dir;
11186
11187         if (*block_nr == 0)
11188                 return 0;
11189         if (blockcnt >= wd->outdir->num) {
11190                 e2fsck_read_bitmaps(wd->ctx);
11191                 blk = *block_nr;
11192                 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
11193                 ext2fs_block_alloc_stats(fs, blk, -1);
11194                 *block_nr = 0;
11195                 wd->cleared++;
11196                 return BLOCK_CHANGED;
11197         }
11198         if (blockcnt < 0)
11199                 return 0;
11200
11201         dir = wd->outdir->buf + (blockcnt * fs->blocksize);
11202         wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
11203         if (wd->err)
11204                 return BLOCK_ABORT;
11205         return 0;
11206 }
11207
11208 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
11209                                  struct out_dir *outdir,
11210                                  ext2_ino_t ino, int compress)
11211 {
11212         struct write_dir_struct wd;
11213         errcode_t       retval;
11214         struct ext2_inode       inode;
11215
11216         retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
11217         if (retval)
11218                 return retval;
11219
11220         wd.outdir = outdir;
11221         wd.err = 0;
11222         wd.ctx = ctx;
11223         wd.cleared = 0;
11224
11225         retval = ext2fs_block_iterate2(fs, ino, 0, 0,
11226                                        write_dir_block, &wd);
11227         if (retval)
11228                 return retval;
11229         if (wd.err)
11230                 return wd.err;
11231
11232         e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
11233         if (compress)
11234                 inode.i_flags &= ~EXT2_INDEX_FL;
11235         else
11236                 inode.i_flags |= EXT2_INDEX_FL;
11237         inode.i_size = outdir->num * fs->blocksize;
11238         inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
11239         e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
11240
11241         return 0;
11242 }
11243
11244 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
11245 {
11246         ext2_filsys             fs = ctx->fs;
11247         errcode_t               retval;
11248         struct ext2_inode       inode;
11249         char                    *dir_buf = 0;
11250         struct fill_dir_struct  fd;
11251         struct out_dir          outdir;
11252
11253         outdir.max = outdir.num = 0;
11254         outdir.buf = 0;
11255         outdir.hashes = 0;
11256         e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
11257
11258         retval = ENOMEM;
11259         fd.harray = 0;
11260         dir_buf = malloc(inode.i_size);
11261         if (!dir_buf)
11262                 goto errout;
11263
11264         fd.max_array = inode.i_size / 32;
11265         fd.num_array = 0;
11266         fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
11267         if (!fd.harray)
11268                 goto errout;
11269
11270         fd.ctx = ctx;
11271         fd.buf = dir_buf;
11272         fd.inode = &inode;
11273         fd.err = 0;
11274         fd.dir_size = 0;
11275         fd.compress = 0;
11276         if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
11277             (inode.i_size / fs->blocksize) < 2)
11278                 fd.compress = 1;
11279         fd.parent = 0;
11280
11281         /* Read in the entire directory into memory */
11282         retval = ext2fs_block_iterate2(fs, ino, 0, 0,
11283                                        fill_dir_block, &fd);
11284         if (fd.err) {
11285                 retval = fd.err;
11286                 goto errout;
11287         }
11288
11289         /* Sort the list */
11290 resort:
11291         if (fd.compress)
11292                 qsort(fd.harray+2, fd.num_array-2,
11293                       sizeof(struct hash_entry), name_cmp);
11294         else
11295                 qsort(fd.harray, fd.num_array,
11296                       sizeof(struct hash_entry), hash_cmp);
11297
11298         /*
11299          * Look for duplicates
11300          */
11301         if (duplicate_search_and_fix(ctx, fs, ino, &fd))
11302                 goto resort;
11303
11304         if (ctx->options & E2F_OPT_NO) {
11305                 retval = 0;
11306                 goto errout;
11307         }
11308
11309         /*
11310          * Copy the directory entries.  In a htree directory these
11311          * will become the leaf nodes.
11312          */
11313         retval = copy_dir_entries(fs, &fd, &outdir);
11314         if (retval)
11315                 goto errout;
11316
11317         free(dir_buf); dir_buf = 0;
11318
11319         if (!fd.compress) {
11320                 /* Calculate the interior nodes */
11321                 retval = calculate_tree(fs, &outdir, ino, fd.parent);
11322                 if (retval)
11323                         goto errout;
11324         }
11325
11326         retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
11327
11328 errout:
11329         free(dir_buf);
11330         free(fd.harray);
11331
11332         free_out_dir(&outdir);
11333         return retval;
11334 }
11335
11336 void e2fsck_rehash_directories(e2fsck_t ctx)
11337 {
11338         struct problem_context  pctx;
11339         struct dir_info         *dir;
11340         ext2_u32_iterate        iter;
11341         ext2_ino_t              ino;
11342         errcode_t               retval;
11343         int                     i, cur, max, all_dirs, dir_index, first = 1;
11344
11345         all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
11346
11347         if (!ctx->dirs_to_hash && !all_dirs)
11348                 return;
11349
11350         e2fsck_get_lost_and_found(ctx, 0);
11351
11352         clear_problem_context(&pctx);
11353
11354         dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
11355         cur = 0;
11356         if (all_dirs) {
11357                 i = 0;
11358                 max = e2fsck_get_num_dirinfo(ctx);
11359         } else {
11360                 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
11361                                                        &iter);
11362                 if (retval) {
11363                         pctx.errcode = retval;
11364                         fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
11365                         return;
11366                 }
11367                 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
11368         }
11369         while (1) {
11370                 if (all_dirs) {
11371                         if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
11372                                 break;
11373                         ino = dir->ino;
11374                 } else {
11375                         if (!ext2fs_u32_list_iterate(iter, &ino))
11376                                 break;
11377                 }
11378                 if (ino == ctx->lost_and_found)
11379                         continue;
11380                 pctx.dir = ino;
11381                 if (first) {
11382                         fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
11383                         first = 0;
11384                 }
11385                 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
11386                 if (pctx.errcode) {
11387                         end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11388                         fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
11389                 }
11390                 if (ctx->progress && !ctx->progress_fd)
11391                         e2fsck_simple_progress(ctx, "Rebuilding directory",
11392                                100.0 * (float) (++cur) / (float) max, ino);
11393         }
11394         end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11395         if (!all_dirs)
11396                 ext2fs_u32_list_iterate_end(iter);
11397
11398         ext2fs_u32_list_free(ctx->dirs_to_hash);
11399         ctx->dirs_to_hash = 0;
11400 }
11401
11402 /*
11403  * linux/fs/revoke.c
11404  *
11405  * Journal revoke routines for the generic filesystem journaling code;
11406  * part of the ext2fs journaling system.
11407  *
11408  * Revoke is the mechanism used to prevent old log records for deleted
11409  * metadata from being replayed on top of newer data using the same
11410  * blocks.  The revoke mechanism is used in two separate places:
11411  *
11412  * + Commit: during commit we write the entire list of the current
11413  *   transaction's revoked blocks to the journal
11414  *
11415  * + Recovery: during recovery we record the transaction ID of all
11416  *   revoked blocks.  If there are multiple revoke records in the log
11417  *   for a single block, only the last one counts, and if there is a log
11418  *   entry for a block beyond the last revoke, then that log entry still
11419  *   gets replayed.
11420  *
11421  * We can get interactions between revokes and new log data within a
11422  * single transaction:
11423  *
11424  * Block is revoked and then journaled:
11425  *   The desired end result is the journaling of the new block, so we
11426  *   cancel the revoke before the transaction commits.
11427  *
11428  * Block is journaled and then revoked:
11429  *   The revoke must take precedence over the write of the block, so we
11430  *   need either to cancel the journal entry or to write the revoke
11431  *   later in the log than the log block.  In this case, we choose the
11432  *   latter: journaling a block cancels any revoke record for that block
11433  *   in the current transaction, so any revoke for that block in the
11434  *   transaction must have happened after the block was journaled and so
11435  *   the revoke must take precedence.
11436  *
11437  * Block is revoked and then written as data:
11438  *   The data write is allowed to succeed, but the revoke is _not_
11439  *   cancelled.  We still need to prevent old log records from
11440  *   overwriting the new data.  We don't even need to clear the revoke
11441  *   bit here.
11442  *
11443  * Revoke information on buffers is a tri-state value:
11444  *
11445  * RevokeValid clear:   no cached revoke status, need to look it up
11446  * RevokeValid set, Revoked clear:
11447  *                      buffer has not been revoked, and cancel_revoke
11448  *                      need do nothing.
11449  * RevokeValid set, Revoked set:
11450  *                      buffer has been revoked.
11451  */
11452
11453 static kmem_cache_t *revoke_record_cache;
11454 static kmem_cache_t *revoke_table_cache;
11455
11456 /* Each revoke record represents one single revoked block.  During
11457    journal replay, this involves recording the transaction ID of the
11458    last transaction to revoke this block. */
11459
11460 struct jbd_revoke_record_s
11461 {
11462         struct list_head  hash;
11463         tid_t             sequence;     /* Used for recovery only */
11464         unsigned long     blocknr;
11465 };
11466
11467
11468 /* The revoke table is just a simple hash table of revoke records. */
11469 struct jbd_revoke_table_s
11470 {
11471         /* It is conceivable that we might want a larger hash table
11472          * for recovery.  Must be a power of two. */
11473         int               hash_size;
11474         int               hash_shift;
11475         struct list_head *hash_table;
11476 };
11477
11478
11479 /* Utility functions to maintain the revoke table */
11480
11481 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11482 static inline int hash(journal_t *journal, unsigned long block)
11483 {
11484         struct jbd_revoke_table_s *table = journal->j_revoke;
11485         int hash_shift = table->hash_shift;
11486
11487         return ((block << (hash_shift - 6)) ^
11488                 (block >> 13) ^
11489                 (block << (hash_shift - 12))) & (table->hash_size - 1);
11490 }
11491
11492 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11493                               tid_t seq)
11494 {
11495         struct list_head *hash_list;
11496         struct jbd_revoke_record_s *record;
11497
11498         record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11499         if (!record)
11500                 goto oom;
11501
11502         record->sequence = seq;
11503         record->blocknr = blocknr;
11504         hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11505         list_add(&record->hash, hash_list);
11506         return 0;
11507
11508 oom:
11509         return -ENOMEM;
11510 }
11511
11512 /* Find a revoke record in the journal's hash table. */
11513
11514 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11515                                                       unsigned long blocknr)
11516 {
11517         struct list_head *hash_list;
11518         struct jbd_revoke_record_s *record;
11519
11520         hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11521
11522         record = (struct jbd_revoke_record_s *) hash_list->next;
11523         while (&(record->hash) != hash_list) {
11524                 if (record->blocknr == blocknr)
11525                         return record;
11526                 record = (struct jbd_revoke_record_s *) record->hash.next;
11527         }
11528         return NULL;
11529 }
11530
11531 int journal_init_revoke_caches(void)
11532 {
11533         revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11534         if (revoke_record_cache == 0)
11535                 return -ENOMEM;
11536
11537         revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11538         if (revoke_table_cache == 0) {
11539                 do_cache_destroy(revoke_record_cache);
11540                 revoke_record_cache = NULL;
11541                 return -ENOMEM;
11542         }
11543         return 0;
11544 }
11545
11546 void journal_destroy_revoke_caches(void)
11547 {
11548         do_cache_destroy(revoke_record_cache);
11549         revoke_record_cache = 0;
11550         do_cache_destroy(revoke_table_cache);
11551         revoke_table_cache = 0;
11552 }
11553
11554 /* Initialise the revoke table for a given journal to a given size. */
11555
11556 int journal_init_revoke(journal_t *journal, int hash_size)
11557 {
11558         int shift, tmp;
11559
11560         journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11561         if (!journal->j_revoke)
11562                 return -ENOMEM;
11563
11564         /* Check that the hash_size is a power of two */
11565         journal->j_revoke->hash_size = hash_size;
11566
11567         shift = 0;
11568         tmp = hash_size;
11569         while((tmp >>= 1UL) != 0UL)
11570                 shift++;
11571         journal->j_revoke->hash_shift = shift;
11572
11573         journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11574         if (!journal->j_revoke->hash_table) {
11575                 free(journal->j_revoke);
11576                 journal->j_revoke = NULL;
11577                 return -ENOMEM;
11578         }
11579
11580         for (tmp = 0; tmp < hash_size; tmp++)
11581                 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11582
11583         return 0;
11584 }
11585
11586 /* Destoy a journal's revoke table.  The table must already be empty! */
11587
11588 void journal_destroy_revoke(journal_t *journal)
11589 {
11590         struct jbd_revoke_table_s *table;
11591         struct list_head *hash_list;
11592         int i;
11593
11594         table = journal->j_revoke;
11595         if (!table)
11596                 return;
11597
11598         for (i=0; i<table->hash_size; i++) {
11599                 hash_list = &table->hash_table[i];
11600         }
11601
11602         free(table->hash_table);
11603         free(table);
11604         journal->j_revoke = NULL;
11605 }
11606
11607 /*
11608  * Revoke support for recovery.
11609  *
11610  * Recovery needs to be able to:
11611  *
11612  *  record all revoke records, including the tid of the latest instance
11613  *  of each revoke in the journal
11614  *
11615  *  check whether a given block in a given transaction should be replayed
11616  *  (ie. has not been revoked by a revoke record in that or a subsequent
11617  *  transaction)
11618  *
11619  *  empty the revoke table after recovery.
11620  */
11621
11622 /*
11623  * First, setting revoke records.  We create a new revoke record for
11624  * every block ever revoked in the log as we scan it for recovery, and
11625  * we update the existing records if we find multiple revokes for a
11626  * single block.
11627  */
11628
11629 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11630                        tid_t sequence)
11631 {
11632         struct jbd_revoke_record_s *record;
11633
11634         record = find_revoke_record(journal, blocknr);
11635         if (record) {
11636                 /* If we have multiple occurences, only record the
11637                  * latest sequence number in the hashed record */
11638                 if (tid_gt(sequence, record->sequence))
11639                         record->sequence = sequence;
11640                 return 0;
11641         }
11642         return insert_revoke_hash(journal, blocknr, sequence);
11643 }
11644
11645 /*
11646  * Test revoke records.  For a given block referenced in the log, has
11647  * that block been revoked?  A revoke record with a given transaction
11648  * sequence number revokes all blocks in that transaction and earlier
11649  * ones, but later transactions still need replayed.
11650  */
11651
11652 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11653                         tid_t sequence)
11654 {
11655         struct jbd_revoke_record_s *record;
11656
11657         record = find_revoke_record(journal, blocknr);
11658         if (!record)
11659                 return 0;
11660         if (tid_gt(sequence, record->sequence))
11661                 return 0;
11662         return 1;
11663 }
11664
11665 /*
11666  * Finally, once recovery is over, we need to clear the revoke table so
11667  * that it can be reused by the running filesystem.
11668  */
11669
11670 void journal_clear_revoke(journal_t *journal)
11671 {
11672         int i;
11673         struct list_head *hash_list;
11674         struct jbd_revoke_record_s *record;
11675         struct jbd_revoke_table_s *revoke_var;
11676
11677         revoke_var = journal->j_revoke;
11678
11679         for (i = 0; i < revoke_var->hash_size; i++) {
11680                 hash_list = &revoke_var->hash_table[i];
11681                 while (!list_empty(hash_list)) {
11682                         record = (struct jbd_revoke_record_s*) hash_list->next;
11683                         list_del(&record->hash);
11684                         free(record);
11685                 }
11686         }
11687 }
11688
11689 /*
11690  * e2fsck.c - superblock checks
11691  */
11692
11693 #define MIN_CHECK 1
11694 #define MAX_CHECK 2
11695
11696 static void check_super_value(e2fsck_t ctx, const char *descr,
11697                               unsigned long value, int flags,
11698                               unsigned long min_val, unsigned long max_val)
11699 {
11700         struct          problem_context pctx;
11701
11702         if (((flags & MIN_CHECK) && (value < min_val)) ||
11703             ((flags & MAX_CHECK) && (value > max_val))) {
11704                 clear_problem_context(&pctx);
11705                 pctx.num = value;
11706                 pctx.str = descr;
11707                 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11708                 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11709         }
11710 }
11711
11712 /*
11713  * This routine may get stubbed out in special compilations of the
11714  * e2fsck code..
11715  */
11716 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11717 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11718 {
11719         return (ext2fs_get_device_size(ctx->filesystem_name,
11720                                        EXT2_BLOCK_SIZE(ctx->fs->super),
11721                                        &ctx->num_blocks));
11722 }
11723 #endif
11724
11725 /*
11726  * helper function to release an inode
11727  */
11728 struct process_block_struct {
11729         e2fsck_t        ctx;
11730         char            *buf;
11731         struct problem_context *pctx;
11732         int             truncating;
11733         int             truncate_offset;
11734         e2_blkcnt_t     truncate_block;
11735         int             truncated_blocks;
11736         int             abort;
11737         errcode_t       errcode;
11738 };
11739
11740 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11741                                e2_blkcnt_t blockcnt,
11742                                blk_t    ref_blk FSCK_ATTR((unused)),
11743                                int      ref_offset FSCK_ATTR((unused)),
11744                                void *priv_data)
11745 {
11746         struct process_block_struct *pb;
11747         e2fsck_t                ctx;
11748         struct problem_context  *pctx;
11749         blk_t                   blk = *block_nr;
11750         int                     retval = 0;
11751
11752         pb = (struct process_block_struct *) priv_data;
11753         ctx = pb->ctx;
11754         pctx = pb->pctx;
11755
11756         pctx->blk = blk;
11757         pctx->blkcount = blockcnt;
11758
11759         if (HOLE_BLKADDR(blk))
11760                 return 0;
11761
11762         if ((blk < fs->super->s_first_data_block) ||
11763             (blk >= fs->super->s_blocks_count)) {
11764                 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11765         return_abort:
11766                 pb->abort = 1;
11767                 return BLOCK_ABORT;
11768         }
11769
11770         if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11771                 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11772                 goto return_abort;
11773         }
11774
11775         /*
11776          * If we are deleting an orphan, then we leave the fields alone.
11777          * If we are truncating an orphan, then update the inode fields
11778          * and clean up any partial block data.
11779          */
11780         if (pb->truncating) {
11781                 /*
11782                  * We only remove indirect blocks if they are
11783                  * completely empty.
11784                  */
11785                 if (blockcnt < 0) {
11786                         int     i, limit;
11787                         blk_t   *bp;
11788
11789                         pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11790                                                         pb->buf);
11791                         if (pb->errcode)
11792                                 goto return_abort;
11793
11794                         limit = fs->blocksize >> 2;
11795                         for (i = 0, bp = (blk_t *) pb->buf;
11796                              i < limit;  i++, bp++)
11797                                 if (*bp)
11798                                         return 0;
11799                 }
11800                 /*
11801                  * We don't remove direct blocks until we've reached
11802                  * the truncation block.
11803                  */
11804                 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11805                         return 0;
11806                 /*
11807                  * If part of the last block needs truncating, we do
11808                  * it here.
11809                  */
11810                 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11811                         pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11812                                                         pb->buf);
11813                         if (pb->errcode)
11814                                 goto return_abort;
11815                         memset(pb->buf + pb->truncate_offset, 0,
11816                                fs->blocksize - pb->truncate_offset);
11817                         pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11818                                                          pb->buf);
11819                         if (pb->errcode)
11820                                 goto return_abort;
11821                 }
11822                 pb->truncated_blocks++;
11823                 *block_nr = 0;
11824                 retval |= BLOCK_CHANGED;
11825         }
11826
11827         ext2fs_block_alloc_stats(fs, blk, -1);
11828         return retval;
11829 }
11830
11831 /*
11832  * This function releases an inode.  Returns 1 if an inconsistency was
11833  * found.  If the inode has a link count, then it is being truncated and
11834  * not deleted.
11835  */
11836 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11837                                 struct ext2_inode *inode, char *block_buf,
11838                                 struct problem_context *pctx)
11839 {
11840         struct process_block_struct     pb;
11841         ext2_filsys                     fs = ctx->fs;
11842         errcode_t                       retval;
11843         __u32                           count;
11844
11845         if (!ext2fs_inode_has_valid_blocks(inode))
11846                 return 0;
11847
11848         pb.buf = block_buf + 3 * ctx->fs->blocksize;
11849         pb.ctx = ctx;
11850         pb.abort = 0;
11851         pb.errcode = 0;
11852         pb.pctx = pctx;
11853         if (inode->i_links_count) {
11854                 pb.truncating = 1;
11855                 pb.truncate_block = (e2_blkcnt_t)
11856                         ((((long long)inode->i_size_high << 32) +
11857                           inode->i_size + fs->blocksize - 1) /
11858                          fs->blocksize);
11859                 pb.truncate_offset = inode->i_size % fs->blocksize;
11860         } else {
11861                 pb.truncating = 0;
11862                 pb.truncate_block = 0;
11863                 pb.truncate_offset = 0;
11864         }
11865         pb.truncated_blocks = 0;
11866         retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11867                                       block_buf, release_inode_block, &pb);
11868         if (retval) {
11869                 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11870                         ino);
11871                 return 1;
11872         }
11873         if (pb.abort)
11874                 return 1;
11875
11876         /* Refresh the inode since ext2fs_block_iterate may have changed it */
11877         e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11878
11879         if (pb.truncated_blocks)
11880                 inode->i_blocks -= pb.truncated_blocks *
11881                         (fs->blocksize / 512);
11882
11883         if (inode->i_file_acl) {
11884                 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11885                                                    block_buf, -1, &count);
11886                 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11887                         retval = 0;
11888                         count = 1;
11889                 }
11890                 if (retval) {
11891                         bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11892                                 ino);
11893                         return 1;
11894                 }
11895                 if (count == 0)
11896                         ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11897                 inode->i_file_acl = 0;
11898         }
11899         return 0;
11900 }
11901
11902 /*
11903  * This function releases all of the orphan inodes.  It returns 1 if
11904  * it hit some error, and 0 on success.
11905  */
11906 static int release_orphan_inodes(e2fsck_t ctx)
11907 {
11908         ext2_filsys fs = ctx->fs;
11909         ext2_ino_t      ino, next_ino;
11910         struct ext2_inode inode;
11911         struct problem_context pctx;
11912         char *block_buf;
11913
11914         if ((ino = fs->super->s_last_orphan) == 0)
11915                 return 0;
11916
11917         /*
11918          * Win or lose, we won't be using the head of the orphan inode
11919          * list again.
11920          */
11921         fs->super->s_last_orphan = 0;
11922         ext2fs_mark_super_dirty(fs);
11923
11924         /*
11925          * If the filesystem contains errors, don't run the orphan
11926          * list, since the orphan list can't be trusted; and we're
11927          * going to be running a full e2fsck run anyway...
11928          */
11929         if (fs->super->s_state & EXT2_ERROR_FS)
11930                 return 0;
11931
11932         if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11933             (ino > fs->super->s_inodes_count)) {
11934                 clear_problem_context(&pctx);
11935                 pctx.ino = ino;
11936                 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11937                 return 1;
11938         }
11939
11940         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11941                                                     "block iterate buffer");
11942         e2fsck_read_bitmaps(ctx);
11943
11944         while (ino) {
11945                 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11946                 clear_problem_context(&pctx);
11947                 pctx.ino = ino;
11948                 pctx.inode = &inode;
11949                 pctx.str = inode.i_links_count ? _("Truncating") :
11950                         _("Clearing");
11951
11952                 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11953
11954                 next_ino = inode.i_dtime;
11955                 if (next_ino &&
11956                     ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11957                      (next_ino > fs->super->s_inodes_count))) {
11958                         pctx.ino = next_ino;
11959                         fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11960                         goto return_abort;
11961                 }
11962
11963                 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11964                         goto return_abort;
11965
11966                 if (!inode.i_links_count) {
11967                         ext2fs_inode_alloc_stats2(fs, ino, -1,
11968                                                   LINUX_S_ISDIR(inode.i_mode));
11969                         inode.i_dtime = time(0);
11970                 } else {
11971                         inode.i_dtime = 0;
11972                 }
11973                 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11974                 ino = next_ino;
11975         }
11976         ext2fs_free_mem(&block_buf);
11977         return 0;
11978 return_abort:
11979         ext2fs_free_mem(&block_buf);
11980         return 1;
11981 }
11982
11983 /*
11984  * Check the resize inode to make sure it is sane.  We check both for
11985  * the case where on-line resizing is not enabled (in which case the
11986  * resize inode should be cleared) as well as the case where on-line
11987  * resizing is enabled.
11988  */
11989 static void check_resize_inode(e2fsck_t ctx)
11990 {
11991         ext2_filsys fs = ctx->fs;
11992         struct ext2_inode inode;
11993         struct problem_context  pctx;
11994         int             i, j, gdt_off, ind_off;
11995         blk_t           blk, pblk, expect;
11996         __u32           *dind_buf = 0, *ind_buf;
11997         errcode_t       retval;
11998
11999         clear_problem_context(&pctx);
12000
12001         /*
12002          * If the resize inode feature isn't set, then
12003          * s_reserved_gdt_blocks must be zero.
12004          */
12005         if (!(fs->super->s_feature_compat &
12006               EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12007                 if (fs->super->s_reserved_gdt_blocks) {
12008                         pctx.num = fs->super->s_reserved_gdt_blocks;
12009                         if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
12010                                         &pctx)) {
12011                                 fs->super->s_reserved_gdt_blocks = 0;
12012                                 ext2fs_mark_super_dirty(fs);
12013                         }
12014                 }
12015         }
12016
12017         /* Read the resize inode */
12018         pctx.ino = EXT2_RESIZE_INO;
12019         retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
12020         if (retval) {
12021                 if (fs->super->s_feature_compat &
12022                     EXT2_FEATURE_COMPAT_RESIZE_INODE)
12023                         ctx->flags |= E2F_FLAG_RESIZE_INODE;
12024                 return;
12025         }
12026
12027         /*
12028          * If the resize inode feature isn't set, check to make sure
12029          * the resize inode is cleared; then we're done.
12030          */
12031         if (!(fs->super->s_feature_compat &
12032               EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12033                 for (i=0; i < EXT2_N_BLOCKS; i++) {
12034                         if (inode.i_block[i])
12035                                 break;
12036                 }
12037                 if ((i < EXT2_N_BLOCKS) &&
12038                     fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
12039                         memset(&inode, 0, sizeof(inode));
12040                         e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12041                                            "clear_resize");
12042                 }
12043                 return;
12044         }
12045
12046         /*
12047          * The resize inode feature is enabled; check to make sure the
12048          * only block in use is the double indirect block
12049          */
12050         blk = inode.i_block[EXT2_DIND_BLOCK];
12051         for (i=0; i < EXT2_N_BLOCKS; i++) {
12052                 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
12053                         break;
12054         }
12055         if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
12056             !(inode.i_mode & LINUX_S_IFREG) ||
12057             (blk < fs->super->s_first_data_block ||
12058              blk >= fs->super->s_blocks_count)) {
12059         resize_inode_invalid:
12060                 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
12061                         memset(&inode, 0, sizeof(inode));
12062                         e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12063                                            "clear_resize");
12064                         ctx->flags |= E2F_FLAG_RESIZE_INODE;
12065                 }
12066                 if (!(ctx->options & E2F_OPT_READONLY)) {
12067                         fs->super->s_state &= ~EXT2_VALID_FS;
12068                         ext2fs_mark_super_dirty(fs);
12069                 }
12070                 goto cleanup;
12071         }
12072         dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
12073                                                     "resize dind buffer");
12074         ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
12075
12076         retval = ext2fs_read_ind_block(fs, blk, dind_buf);
12077         if (retval)
12078                 goto resize_inode_invalid;
12079
12080         gdt_off = fs->desc_blocks;
12081         pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
12082         for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
12083              i++, gdt_off++, pblk++) {
12084                 gdt_off %= fs->blocksize/4;
12085                 if (dind_buf[gdt_off] != pblk)
12086                         goto resize_inode_invalid;
12087                 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
12088                 if (retval)
12089                         goto resize_inode_invalid;
12090                 ind_off = 0;
12091                 for (j = 1; j < fs->group_desc_count; j++) {
12092                         if (!ext2fs_bg_has_super(fs, j))
12093                                 continue;
12094                         expect = pblk + (j * fs->super->s_blocks_per_group);
12095                         if (ind_buf[ind_off] != expect)
12096                                 goto resize_inode_invalid;
12097                         ind_off++;
12098                 }
12099         }
12100
12101 cleanup:
12102         ext2fs_free_mem(&dind_buf);
12103
12104  }
12105
12106 static void check_super_block(e2fsck_t ctx)
12107 {
12108         ext2_filsys fs = ctx->fs;
12109         blk_t   first_block, last_block;
12110         struct ext2_super_block *sb = fs->super;
12111         struct ext2_group_desc *gd;
12112         blk_t   blocks_per_group = fs->super->s_blocks_per_group;
12113         blk_t   bpg_max;
12114         int     inodes_per_block;
12115         int     ipg_max;
12116         int     inode_size;
12117         dgrp_t  i;
12118         blk_t   should_be;
12119         struct problem_context  pctx;
12120         __u32   free_blocks = 0, free_inodes = 0;
12121
12122         inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
12123         ipg_max = inodes_per_block * (blocks_per_group - 4);
12124         if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
12125                 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
12126         bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
12127         if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
12128                 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
12129
12130         ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
12131                  sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
12132         ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
12133                  sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
12134         ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
12135                 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
12136
12137         clear_problem_context(&pctx);
12138
12139         /*
12140          * Verify the super block constants...
12141          */
12142         check_super_value(ctx, "inodes_count", sb->s_inodes_count,
12143                           MIN_CHECK, 1, 0);
12144         check_super_value(ctx, "blocks_count", sb->s_blocks_count,
12145                           MIN_CHECK, 1, 0);
12146         check_super_value(ctx, "first_data_block", sb->s_first_data_block,
12147                           MAX_CHECK, 0, sb->s_blocks_count);
12148         check_super_value(ctx, "log_block_size", sb->s_log_block_size,
12149                           MIN_CHECK | MAX_CHECK, 0,
12150                           EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
12151         check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
12152                           MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
12153         check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
12154                           MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
12155                           bpg_max);
12156         check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
12157                           MIN_CHECK | MAX_CHECK, 8, bpg_max);
12158         check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
12159                           MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
12160         check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
12161                           MAX_CHECK, 0, sb->s_blocks_count / 2);
12162         check_super_value(ctx, "reserved_gdt_blocks",
12163                           sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
12164                           fs->blocksize/4);
12165         inode_size = EXT2_INODE_SIZE(sb);
12166         check_super_value(ctx, "inode_size",
12167                           inode_size, MIN_CHECK | MAX_CHECK,
12168                           EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
12169         if (inode_size & (inode_size - 1)) {
12170                 pctx.num = inode_size;
12171                 pctx.str = "inode_size";
12172                 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
12173                 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
12174                 return;
12175         }
12176
12177         if (!ctx->num_blocks) {
12178                 pctx.errcode = e2fsck_get_device_size(ctx);
12179                 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
12180                         fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
12181                         ctx->flags |= E2F_FLAG_ABORT;
12182                         return;
12183                 }
12184                 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
12185                     (ctx->num_blocks < sb->s_blocks_count)) {
12186                         pctx.blk = sb->s_blocks_count;
12187                         pctx.blk2 = ctx->num_blocks;
12188                         if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
12189                                 ctx->flags |= E2F_FLAG_ABORT;
12190                                 return;
12191                         }
12192                 }
12193         }
12194
12195         if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
12196                 pctx.blk = EXT2_BLOCK_SIZE(sb);
12197                 pctx.blk2 = EXT2_FRAG_SIZE(sb);
12198                 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
12199                 ctx->flags |= E2F_FLAG_ABORT;
12200                 return;
12201         }
12202
12203         should_be = sb->s_frags_per_group >>
12204                 (sb->s_log_block_size - sb->s_log_frag_size);
12205         if (sb->s_blocks_per_group != should_be) {
12206                 pctx.blk = sb->s_blocks_per_group;
12207                 pctx.blk2 = should_be;
12208                 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
12209                 ctx->flags |= E2F_FLAG_ABORT;
12210                 return;
12211         }
12212
12213         should_be = (sb->s_log_block_size == 0) ? 1 : 0;
12214         if (sb->s_first_data_block != should_be) {
12215                 pctx.blk = sb->s_first_data_block;
12216                 pctx.blk2 = should_be;
12217                 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
12218                 ctx->flags |= E2F_FLAG_ABORT;
12219                 return;
12220         }
12221
12222         should_be = sb->s_inodes_per_group * fs->group_desc_count;
12223         if (sb->s_inodes_count != should_be) {
12224                 pctx.ino = sb->s_inodes_count;
12225                 pctx.ino2 = should_be;
12226                 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
12227                         sb->s_inodes_count = should_be;
12228                         ext2fs_mark_super_dirty(fs);
12229                 }
12230         }
12231
12232         /*
12233          * Verify the group descriptors....
12234          */
12235         first_block =  sb->s_first_data_block;
12236         last_block = first_block + blocks_per_group;
12237
12238         for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
12239                 pctx.group = i;
12240
12241                 if (i == fs->group_desc_count - 1)
12242                         last_block = sb->s_blocks_count;
12243                 if ((gd->bg_block_bitmap < first_block) ||
12244                     (gd->bg_block_bitmap >= last_block)) {
12245                         pctx.blk = gd->bg_block_bitmap;
12246                         if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
12247                                 gd->bg_block_bitmap = 0;
12248                 }
12249                 if (gd->bg_block_bitmap == 0) {
12250                         ctx->invalid_block_bitmap_flag[i]++;
12251                         ctx->invalid_bitmaps++;
12252                 }
12253                 if ((gd->bg_inode_bitmap < first_block) ||
12254                     (gd->bg_inode_bitmap >= last_block)) {
12255                         pctx.blk = gd->bg_inode_bitmap;
12256                         if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
12257                                 gd->bg_inode_bitmap = 0;
12258                 }
12259                 if (gd->bg_inode_bitmap == 0) {
12260                         ctx->invalid_inode_bitmap_flag[i]++;
12261                         ctx->invalid_bitmaps++;
12262                 }
12263                 if ((gd->bg_inode_table < first_block) ||
12264                     ((gd->bg_inode_table +
12265                       fs->inode_blocks_per_group - 1) >= last_block)) {
12266                         pctx.blk = gd->bg_inode_table;
12267                         if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
12268                                 gd->bg_inode_table = 0;
12269                 }
12270                 if (gd->bg_inode_table == 0) {
12271                         ctx->invalid_inode_table_flag[i]++;
12272                         ctx->invalid_bitmaps++;
12273                 }
12274                 free_blocks += gd->bg_free_blocks_count;
12275                 free_inodes += gd->bg_free_inodes_count;
12276                 first_block += sb->s_blocks_per_group;
12277                 last_block += sb->s_blocks_per_group;
12278
12279                 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
12280                     (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
12281                     (gd->bg_used_dirs_count > sb->s_inodes_per_group))
12282                         ext2fs_unmark_valid(fs);
12283
12284         }
12285
12286         /*
12287          * Update the global counts from the block group counts.  This
12288          * is needed for an experimental patch which eliminates
12289          * locking the entire filesystem when allocating blocks or
12290          * inodes; if the filesystem is not unmounted cleanly, the
12291          * global counts may not be accurate.
12292          */
12293         if ((free_blocks != sb->s_free_blocks_count) ||
12294             (free_inodes != sb->s_free_inodes_count)) {
12295                 if (ctx->options & E2F_OPT_READONLY)
12296                         ext2fs_unmark_valid(fs);
12297                 else {
12298                         sb->s_free_blocks_count = free_blocks;
12299                         sb->s_free_inodes_count = free_inodes;
12300                         ext2fs_mark_super_dirty(fs);
12301                 }
12302         }
12303
12304         if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
12305             (sb->s_free_inodes_count > sb->s_inodes_count))
12306                 ext2fs_unmark_valid(fs);
12307
12308
12309         /*
12310          * If we have invalid bitmaps, set the error state of the
12311          * filesystem.
12312          */
12313         if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
12314                 sb->s_state &= ~EXT2_VALID_FS;
12315                 ext2fs_mark_super_dirty(fs);
12316         }
12317
12318         clear_problem_context(&pctx);
12319
12320         /*
12321          * If the UUID field isn't assigned, assign it.
12322          */
12323         if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
12324                 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
12325                         uuid_generate(sb->s_uuid);
12326                         ext2fs_mark_super_dirty(fs);
12327                         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12328                 }
12329         }
12330
12331         /* FIXME - HURD support?
12332          * For the Hurd, check to see if the filetype option is set,
12333          * since it doesn't support it.
12334          */
12335         if (!(ctx->options & E2F_OPT_READONLY) &&
12336             fs->super->s_creator_os == EXT2_OS_HURD &&
12337             (fs->super->s_feature_incompat &
12338              EXT2_FEATURE_INCOMPAT_FILETYPE)) {
12339                 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
12340                         fs->super->s_feature_incompat &=
12341                                 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
12342                         ext2fs_mark_super_dirty(fs);
12343
12344                 }
12345         }
12346
12347         /*
12348          * If we have any of the compatibility flags set, we need to have a
12349          * revision 1 filesystem.  Most kernels will not check the flags on
12350          * a rev 0 filesystem and we may have corruption issues because of
12351          * the incompatible changes to the filesystem.
12352          */
12353         if (!(ctx->options & E2F_OPT_READONLY) &&
12354             fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
12355             (fs->super->s_feature_compat ||
12356              fs->super->s_feature_ro_compat ||
12357              fs->super->s_feature_incompat) &&
12358             fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
12359                 ext2fs_update_dynamic_rev(fs);
12360                 ext2fs_mark_super_dirty(fs);
12361         }
12362
12363         check_resize_inode(ctx);
12364
12365         /*
12366          * Clean up any orphan inodes, if present.
12367          */
12368         if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
12369                 fs->super->s_state &= ~EXT2_VALID_FS;
12370                 ext2fs_mark_super_dirty(fs);
12371         }
12372
12373         /*
12374          * Move the ext3 journal file, if necessary.
12375          */
12376         e2fsck_move_ext3_journal(ctx);
12377         return;
12378 }
12379
12380 /*
12381  * swapfs.c --- byte-swap an ext2 filesystem
12382  */
12383
12384 #ifdef ENABLE_SWAPFS
12385
12386 struct swap_block_struct {
12387         ext2_ino_t      ino;
12388         int             isdir;
12389         errcode_t       errcode;
12390         char            *dir_buf;
12391         struct ext2_inode *inode;
12392 };
12393
12394 /*
12395  * This is a helper function for block_iterate.  We mark all of the
12396  * indirect and direct blocks as changed, so that block_iterate will
12397  * write them out.
12398  */
12399 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
12400                       void *priv_data)
12401 {
12402         errcode_t       retval;
12403
12404         struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
12405
12406         if (sb->isdir && (blockcnt >= 0) && *block_nr) {
12407                 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
12408                 if (retval) {
12409                         sb->errcode = retval;
12410                         return BLOCK_ABORT;
12411                 }
12412                 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
12413                 if (retval) {
12414                         sb->errcode = retval;
12415                         return BLOCK_ABORT;
12416                 }
12417         }
12418         if (blockcnt >= 0) {
12419                 if (blockcnt < EXT2_NDIR_BLOCKS)
12420                         return 0;
12421                 return BLOCK_CHANGED;
12422         }
12423         if (blockcnt == BLOCK_COUNT_IND) {
12424                 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
12425                         return 0;
12426                 return BLOCK_CHANGED;
12427         }
12428         if (blockcnt == BLOCK_COUNT_DIND) {
12429                 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12430                         return 0;
12431                 return BLOCK_CHANGED;
12432         }
12433         if (blockcnt == BLOCK_COUNT_TIND) {
12434                 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12435                         return 0;
12436                 return BLOCK_CHANGED;
12437         }
12438         return BLOCK_CHANGED;
12439 }
12440
12441 /*
12442  * This function is responsible for byte-swapping all of the indirect,
12443  * block pointers.  It is also responsible for byte-swapping directories.
12444  */
12445 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12446                               struct ext2_inode *inode)
12447 {
12448         errcode_t                       retval;
12449         struct swap_block_struct        sb;
12450
12451         sb.ino = ino;
12452         sb.inode = inode;
12453         sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12454         sb.errcode = 0;
12455         sb.isdir = 0;
12456         if (LINUX_S_ISDIR(inode->i_mode))
12457                 sb.isdir = 1;
12458
12459         retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12460                                       swap_block, &sb);
12461         if (retval) {
12462                 bb_error_msg(_("while calling ext2fs_block_iterate"));
12463                 ctx->flags |= E2F_FLAG_ABORT;
12464                 return;
12465         }
12466         if (sb.errcode) {
12467                 bb_error_msg(_("while calling iterator function"));
12468                 ctx->flags |= E2F_FLAG_ABORT;
12469                 return;
12470         }
12471 }
12472
12473 static void swap_inodes(e2fsck_t ctx)
12474 {
12475         ext2_filsys fs = ctx->fs;
12476         dgrp_t                  group;
12477         unsigned int            i;
12478         ext2_ino_t              ino = 1;
12479         char                    *buf, *block_buf;
12480         errcode_t               retval;
12481         struct ext2_inode *     inode;
12482
12483         e2fsck_use_inode_shortcuts(ctx, 1);
12484
12485         retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12486                                 &buf);
12487         if (retval) {
12488                 bb_error_msg(_("while allocating inode buffer"));
12489                 ctx->flags |= E2F_FLAG_ABORT;
12490                 return;
12491         }
12492         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12493                                                     "block interate buffer");
12494         for (group = 0; group < fs->group_desc_count; group++) {
12495                 retval = io_channel_read_blk(fs->io,
12496                       fs->group_desc[group].bg_inode_table,
12497                       fs->inode_blocks_per_group, buf);
12498                 if (retval) {
12499                         bb_error_msg(_("while reading inode table (group %d)"),
12500                                 group);
12501                         ctx->flags |= E2F_FLAG_ABORT;
12502                         return;
12503                 }
12504                 inode = (struct ext2_inode *) buf;
12505                 for (i=0; i < fs->super->s_inodes_per_group;
12506                      i++, ino++, inode++) {
12507                         ctx->stashed_ino = ino;
12508                         ctx->stashed_inode = inode;
12509
12510                         if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12511                                 ext2fs_swap_inode(fs, inode, inode, 0);
12512
12513                         /*
12514                          * Skip deleted files.
12515                          */
12516                         if (inode->i_links_count == 0)
12517                                 continue;
12518
12519                         if (LINUX_S_ISDIR(inode->i_mode) ||
12520                             ((inode->i_block[EXT2_IND_BLOCK] ||
12521                               inode->i_block[EXT2_DIND_BLOCK] ||
12522                               inode->i_block[EXT2_TIND_BLOCK]) &&
12523                              ext2fs_inode_has_valid_blocks(inode)))
12524                                 swap_inode_blocks(ctx, ino, block_buf, inode);
12525
12526                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12527                                 return;
12528
12529                         if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12530                                 ext2fs_swap_inode(fs, inode, inode, 1);
12531                 }
12532                 retval = io_channel_write_blk(fs->io,
12533                       fs->group_desc[group].bg_inode_table,
12534                       fs->inode_blocks_per_group, buf);
12535                 if (retval) {
12536                         bb_error_msg(_("while writing inode table (group %d)"),
12537                                 group);
12538                         ctx->flags |= E2F_FLAG_ABORT;
12539                         return;
12540                 }
12541         }
12542         ext2fs_free_mem(&buf);
12543         ext2fs_free_mem(&block_buf);
12544         e2fsck_use_inode_shortcuts(ctx, 0);
12545         ext2fs_flush_icache(fs);
12546 }
12547
12548 #if defined(__powerpc__) && BB_BIG_ENDIAN
12549 /*
12550  * On the PowerPC, the big-endian variant of the ext2 filesystem
12551  * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12552  * of each word.  Thus a bitmap with only bit 0 set would be, as
12553  * a string of bytes, 00 00 00 01 00 ...
12554  * To cope with this, we byte-reverse each word of a bitmap if
12555  * we have a big-endian filesystem, that is, if we are *not*
12556  * byte-swapping other word-sized numbers.
12557  */
12558 #define EXT2_BIG_ENDIAN_BITMAPS
12559 #endif
12560
12561 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12562 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12563 {
12564         __u32 *p = (__u32 *) bmap->bitmap;
12565         int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12566
12567         for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12568                 *p = ext2fs_swab32(*p);
12569 }
12570 #endif
12571
12572
12573 #ifdef ENABLE_SWAPFS
12574 static void swap_filesys(e2fsck_t ctx)
12575 {
12576         ext2_filsys fs = ctx->fs;
12577         if (!(ctx->options & E2F_OPT_PREEN))
12578                 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12579
12580         /* Byte swap */
12581
12582         if (fs->super->s_mnt_count) {
12583                 fprintf(stderr, _("%s: the filesystem must be freshly "
12584                         "checked using fsck\n"
12585                         "and not mounted before trying to "
12586                         "byte-swap it.\n"), ctx->device_name);
12587                 ctx->flags |= E2F_FLAG_ABORT;
12588                 return;
12589         }
12590         if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12591                 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12592                                EXT2_FLAG_SWAP_BYTES_WRITE);
12593                 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12594         } else {
12595                 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12596                 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12597         }
12598         swap_inodes(ctx);
12599         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12600                 return;
12601         if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12602                 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12603         fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12604                        EXT2_FLAG_SWAP_BYTES_WRITE);
12605
12606 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12607         e2fsck_read_bitmaps(ctx);
12608         ext2fs_swap_bitmap(fs->inode_map);
12609         ext2fs_swap_bitmap(fs->block_map);
12610         fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12611 #endif
12612         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12613         ext2fs_flush(fs);
12614         fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12615 }
12616 #endif  /* ENABLE_SWAPFS */
12617
12618 #endif
12619
12620 /*
12621  * util.c --- miscellaneous utilities
12622  */
12623
12624
12625 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12626                              const char *description)
12627 {
12628         void *ret;
12629         char buf[256];
12630
12631         ret = malloc(size);
12632         if (!ret) {
12633                 sprintf(buf, "Can't allocate %s\n", description);
12634                 bb_error_msg_and_die(buf);
12635         }
12636         memset(ret, 0, size);
12637         return ret;
12638 }
12639
12640 static char *string_copy(const char *str, int len)
12641 {
12642         char    *ret;
12643
12644         if (!str)
12645                 return NULL;
12646         if (!len)
12647                 len = strlen(str);
12648         ret = malloc(len+1);
12649         if (ret) {
12650                 strncpy(ret, str, len);
12651                 ret[len] = 0;
12652         }
12653         return ret;
12654 }
12655
12656 #ifndef HAVE_CONIO_H
12657 static int read_a_char(void)
12658 {
12659         char    c;
12660         int     r;
12661         int     fail = 0;
12662
12663         while(1) {
12664                 if (e2fsck_global_ctx &&
12665                     (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12666                         return 3;
12667                 }
12668                 r = read(0, &c, 1);
12669                 if (r == 1)
12670                         return c;
12671                 if (fail++ > 100)
12672                         break;
12673         }
12674         return EOF;
12675 }
12676 #endif
12677
12678 static int ask_yn(const char * string, int def)
12679 {
12680         int             c;
12681         const char      *defstr;
12682         static const char short_yes[] = "yY";
12683         static const char short_no[] = "nN";
12684
12685 #ifdef HAVE_TERMIOS_H
12686         struct termios  termios, tmp;
12687
12688         tcgetattr (0, &termios);
12689         tmp = termios;
12690         tmp.c_lflag &= ~(ICANON | ECHO);
12691         tmp.c_cc[VMIN] = 1;
12692         tmp.c_cc[VTIME] = 0;
12693         tcsetattr (0, TCSANOW, &tmp);
12694 #endif
12695
12696         if (def == 1)
12697                 defstr = "<y>";
12698         else if (def == 0)
12699                 defstr = "<n>";
12700         else
12701                 defstr = " (y/n)";
12702         printf("%s%s? ", string, defstr);
12703         while (1) {
12704                 fflush (stdout);
12705                 if ((c = read_a_char()) == EOF)
12706                         break;
12707                 if (c == 3) {
12708 #ifdef HAVE_TERMIOS_H
12709                         tcsetattr (0, TCSANOW, &termios);
12710 #endif
12711                         if (e2fsck_global_ctx &&
12712                             e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12713                                 puts("\n");
12714                                 longjmp(e2fsck_global_ctx->abort_loc, 1);
12715                         }
12716                         puts(_("cancelled!\n"));
12717                         return 0;
12718                 }
12719                 if (strchr(short_yes, (char) c)) {
12720                         def = 1;
12721                         break;
12722                 }
12723                 else if (strchr(short_no, (char) c)) {
12724                         def = 0;
12725                         break;
12726                 }
12727                 else if ((c == ' ' || c == '\n') && (def != -1))
12728                         break;
12729         }
12730         if (def)
12731                 puts("yes\n");
12732         else
12733                 puts ("no\n");
12734 #ifdef HAVE_TERMIOS_H
12735         tcsetattr (0, TCSANOW, &termios);
12736 #endif
12737         return def;
12738 }
12739
12740 int ask (e2fsck_t ctx, const char * string, int def)
12741 {
12742         if (ctx->options & E2F_OPT_NO) {
12743                 printf (_("%s? no\n\n"), string);
12744                 return 0;
12745         }
12746         if (ctx->options & E2F_OPT_YES) {
12747                 printf (_("%s? yes\n\n"), string);
12748                 return 1;
12749         }
12750         if (ctx->options & E2F_OPT_PREEN) {
12751                 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
12752                 return def;
12753         }
12754         return ask_yn(string, def);
12755 }
12756
12757 void e2fsck_read_bitmaps(e2fsck_t ctx)
12758 {
12759         ext2_filsys fs = ctx->fs;
12760         errcode_t       retval;
12761
12762         if (ctx->invalid_bitmaps) {
12763                 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12764                         ctx->device_name);
12765                 bb_error_msg_and_die(0);
12766         }
12767
12768         ehandler_operation(_("reading inode and block bitmaps"));
12769         retval = ext2fs_read_bitmaps(fs);
12770         ehandler_operation(0);
12771         if (retval) {
12772                 bb_error_msg(_("while retrying to read bitmaps for %s"),
12773                         ctx->device_name);
12774                 bb_error_msg_and_die(0);
12775         }
12776 }
12777
12778 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12779 {
12780         ext2_filsys fs = ctx->fs;
12781         errcode_t       retval;
12782
12783         if (ext2fs_test_bb_dirty(fs)) {
12784                 ehandler_operation(_("writing block bitmaps"));
12785                 retval = ext2fs_write_block_bitmap(fs);
12786                 ehandler_operation(0);
12787                 if (retval) {
12788                         bb_error_msg(_("while retrying to write block bitmaps for %s"),
12789                                 ctx->device_name);
12790                         bb_error_msg_and_die(0);
12791                 }
12792         }
12793
12794         if (ext2fs_test_ib_dirty(fs)) {
12795                 ehandler_operation(_("writing inode bitmaps"));
12796                 retval = ext2fs_write_inode_bitmap(fs);
12797                 ehandler_operation(0);
12798                 if (retval) {
12799                         bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12800                                 ctx->device_name);
12801                         bb_error_msg_and_die(0);
12802                 }
12803         }
12804 }
12805
12806 void preenhalt(e2fsck_t ctx)
12807 {
12808         ext2_filsys fs = ctx->fs;
12809
12810         if (!(ctx->options & E2F_OPT_PREEN))
12811                 return;
12812         fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12813                 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12814                ctx->device_name);
12815         if (fs != NULL) {
12816                 fs->super->s_state |= EXT2_ERROR_FS;
12817                 ext2fs_mark_super_dirty(fs);
12818                 ext2fs_close(fs);
12819         }
12820         exit(EXIT_UNCORRECTED);
12821 }
12822
12823 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12824                               struct ext2_inode * inode, const char *proc)
12825 {
12826         int retval;
12827
12828         retval = ext2fs_read_inode(ctx->fs, ino, inode);
12829         if (retval) {
12830                 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12831                 bb_error_msg_and_die(0);
12832         }
12833 }
12834
12835 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12836                                struct ext2_inode * inode, int bufsize,
12837                                const char *proc)
12838 {
12839         int retval;
12840
12841         retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12842         if (retval) {
12843                 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12844                 bb_error_msg_and_die(0);
12845         }
12846 }
12847
12848 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12849                                struct ext2_inode * inode, const char *proc)
12850 {
12851         int retval;
12852
12853         retval = ext2fs_write_inode(ctx->fs, ino, inode);
12854         if (retval) {
12855                 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12856                 bb_error_msg_and_die(0);
12857         }
12858 }
12859
12860 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12861                    io_manager manager)
12862 {
12863         struct ext2_super_block *sb;
12864         io_channel              io = NULL;
12865         void                    *buf = NULL;
12866         int                     blocksize;
12867         blk_t                   superblock, ret_sb = 8193;
12868
12869         if (fs && fs->super) {
12870                 ret_sb = (fs->super->s_blocks_per_group +
12871                           fs->super->s_first_data_block);
12872                 if (ctx) {
12873                         ctx->superblock = ret_sb;
12874                         ctx->blocksize = fs->blocksize;
12875                 }
12876                 return ret_sb;
12877         }
12878
12879         if (ctx) {
12880                 if (ctx->blocksize) {
12881                         ret_sb = ctx->blocksize * 8;
12882                         if (ctx->blocksize == 1024)
12883                                 ret_sb++;
12884                         ctx->superblock = ret_sb;
12885                         return ret_sb;
12886                 }
12887                 ctx->superblock = ret_sb;
12888                 ctx->blocksize = 1024;
12889         }
12890
12891         if (!name || !manager)
12892                 goto cleanup;
12893
12894         if (manager->open(name, 0, &io) != 0)
12895                 goto cleanup;
12896
12897         if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12898                 goto cleanup;
12899         sb = (struct ext2_super_block *) buf;
12900
12901         for (blocksize = EXT2_MIN_BLOCK_SIZE;
12902              blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
12903                 superblock = blocksize*8;
12904                 if (blocksize == 1024)
12905                         superblock++;
12906                 io_channel_set_blksize(io, blocksize);
12907                 if (io_channel_read_blk(io, superblock,
12908                                         -SUPERBLOCK_SIZE, buf))
12909                         continue;
12910 #if BB_BIG_ENDIAN
12911                 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12912                         ext2fs_swap_super(sb);
12913 #endif
12914                 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12915                         ret_sb = superblock;
12916                         if (ctx) {
12917                                 ctx->superblock = superblock;
12918                                 ctx->blocksize = blocksize;
12919                         }
12920                         break;
12921                 }
12922         }
12923
12924 cleanup:
12925         if (io)
12926                 io_channel_close(io);
12927         ext2fs_free_mem(&buf);
12928         return (ret_sb);
12929 }
12930
12931
12932 /*
12933  * This function runs through the e2fsck passes and calls them all,
12934  * returning restart, abort, or cancel as necessary...
12935  */
12936 typedef void (*pass_t)(e2fsck_t ctx);
12937
12938 static const pass_t e2fsck_passes[] = {
12939         e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12940         e2fsck_pass5, 0 };
12941
12942 #define E2F_FLAG_RUN_RETURN     (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12943
12944 static int e2fsck_run(e2fsck_t ctx)
12945 {
12946         int     i;
12947         pass_t  e2fsck_pass;
12948
12949         if (setjmp(ctx->abort_loc)) {
12950                 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12951                 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12952         }
12953         ctx->flags |= E2F_FLAG_SETJMP_OK;
12954
12955         for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12956                 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12957                         break;
12958                 e2fsck_pass(ctx);
12959                 if (ctx->progress)
12960                         (void) (ctx->progress)(ctx, 0, 0, 0);
12961         }
12962         ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12963
12964         if (ctx->flags & E2F_FLAG_RUN_RETURN)
12965                 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12966         return 0;
12967 }
12968
12969
12970 /*
12971  * unix.c - The unix-specific code for e2fsck
12972  */
12973
12974
12975 /* Command line options */
12976 static int swapfs;
12977 #ifdef ENABLE_SWAPFS
12978 static int normalize_swapfs;
12979 #endif
12980 static int cflag;               /* check disk */
12981 static int show_version_only;
12982 static int verbose;
12983
12984 static int replace_bad_blocks;
12985 static int keep_bad_blocks;
12986 static char *bad_blocks_file;
12987
12988 #define P_E2(singular, plural, n)       n, ((n) == 1 ? singular : plural)
12989
12990 static void show_stats(e2fsck_t ctx)
12991 {
12992         ext2_filsys fs = ctx->fs;
12993         int inodes, inodes_used, blocks, blocks_used;
12994         int dir_links;
12995         int num_files, num_links;
12996         int frag_percent;
12997
12998         dir_links = 2 * ctx->fs_directory_count - 1;
12999         num_files = ctx->fs_total_count - dir_links;
13000         num_links = ctx->fs_links_count - dir_links;
13001         inodes = fs->super->s_inodes_count;
13002         inodes_used = (fs->super->s_inodes_count -
13003                        fs->super->s_free_inodes_count);
13004         blocks = fs->super->s_blocks_count;
13005         blocks_used = (fs->super->s_blocks_count -
13006                        fs->super->s_free_blocks_count);
13007
13008         frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
13009         frag_percent = (frag_percent + 5) / 10;
13010
13011         if (!verbose) {
13012                 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
13013                        ctx->device_name, inodes_used, inodes,
13014                        frag_percent / 10, frag_percent % 10,
13015                        blocks_used, blocks);
13016                 return;
13017         }
13018         printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
13019                 100 * inodes_used / inodes);
13020         printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
13021                 P_E2("", "s", ctx->fs_fragmented),
13022                 frag_percent / 10, frag_percent % 10);
13023         printf (_("         # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
13024                 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
13025         printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
13026                 (int) ((long long) 100 * blocks_used / blocks));
13027         printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count));
13028         printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
13029         printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
13030         printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
13031         printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
13032         printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
13033         printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
13034         printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
13035         printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
13036         printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
13037         printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
13038         printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
13039 }
13040
13041 static void check_mount(e2fsck_t ctx)
13042 {
13043         errcode_t       retval;
13044         int             cont;
13045
13046         retval = ext2fs_check_if_mounted(ctx->filesystem_name,
13047                                          &ctx->mount_flags);
13048         if (retval) {
13049                 bb_error_msg(_("while determining whether %s is mounted."),
13050                         ctx->filesystem_name);
13051                 return;
13052         }
13053
13054         /*
13055          * If the filesystem isn't mounted, or it's the root filesystem
13056          * and it's mounted read-only, then everything's fine.
13057          */
13058         if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
13059             ((ctx->mount_flags & EXT2_MF_ISROOT) &&
13060              (ctx->mount_flags & EXT2_MF_READONLY)))
13061                 return;
13062
13063         if (ctx->options & E2F_OPT_READONLY) {
13064                 printf(_("Warning!  %s is mounted.\n"), ctx->filesystem_name);
13065                 return;
13066         }
13067
13068         printf(_("%s is mounted.  "), ctx->filesystem_name);
13069         if (!ctx->interactive)
13070                 bb_error_msg_and_die(_("Cannot continue, aborting.\n\n"));
13071         printf(_("\n\n\007\007\007\007WARNING!!!  "
13072                "Running e2fsck on a mounted filesystem may cause\n"
13073                "SEVERE filesystem damage.\007\007\007\n\n"));
13074         cont = ask_yn(_("Do you really want to continue"), -1);
13075         if (!cont) {
13076                 printf (_("check aborted.\n"));
13077                 exit (0);
13078         }
13079         return;
13080 }
13081
13082 static int is_on_batt(void)
13083 {
13084         FILE    *f;
13085         DIR     *d;
13086         char    tmp[80], tmp2[80], fname[80];
13087         unsigned int    acflag;
13088         struct dirent*  de;
13089
13090         f = fopen("/proc/apm", "r");
13091         if (f) {
13092                 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
13093                         acflag = 1;
13094                 fclose(f);
13095                 return (acflag != 1);
13096         }
13097         d = opendir("/proc/acpi/ac_adapter");
13098         if (d) {
13099                 while ((de=readdir(d)) != NULL) {
13100                         if (!strncmp(".", de->d_name, 1))
13101                                 continue;
13102                         snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
13103                                  de->d_name);
13104                         f = fopen(fname, "r");
13105                         if (!f)
13106                                 continue;
13107                         if (fscanf(f, "%s %s", tmp2, tmp) != 2)
13108                                 tmp[0] = 0;
13109                         fclose(f);
13110                         if (strncmp(tmp, "off-line", 8) == 0) {
13111                                 closedir(d);
13112                                 return 1;
13113                         }
13114                 }
13115                 closedir(d);
13116         }
13117         return 0;
13118 }
13119
13120 /*
13121  * This routine checks to see if a filesystem can be skipped; if so,
13122  * it will exit with EXIT_OK.  Under some conditions it will print a
13123  * message explaining why a check is being forced.
13124  */
13125 static void check_if_skip(e2fsck_t ctx)
13126 {
13127         ext2_filsys fs = ctx->fs;
13128         const char *reason = NULL;
13129         unsigned int reason_arg = 0;
13130         long next_check;
13131         int batt = is_on_batt();
13132         time_t now = time(0);
13133
13134         if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
13135             cflag || swapfs)
13136                 return;
13137
13138         if ((fs->super->s_state & EXT2_ERROR_FS) ||
13139             !ext2fs_test_valid(fs))
13140                 reason = _(" contains a file system with errors");
13141         else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
13142                 reason = _(" was not cleanly unmounted");
13143         else if ((fs->super->s_max_mnt_count > 0) &&
13144                  (fs->super->s_mnt_count >=
13145                   (unsigned) fs->super->s_max_mnt_count)) {
13146                 reason = _(" has been mounted %u times without being checked");
13147                 reason_arg = fs->super->s_mnt_count;
13148                 if (batt && (fs->super->s_mnt_count <
13149                              (unsigned) fs->super->s_max_mnt_count*2))
13150                         reason = 0;
13151         } else if (fs->super->s_checkinterval &&
13152                    ((now - fs->super->s_lastcheck) >=
13153                     fs->super->s_checkinterval)) {
13154                 reason = _(" has gone %u days without being checked");
13155                 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
13156                 if (batt && ((now - fs->super->s_lastcheck) <
13157                              fs->super->s_checkinterval*2))
13158                         reason = 0;
13159         }
13160         if (reason) {
13161                 fputs(ctx->device_name, stdout);
13162                 printf(reason, reason_arg);
13163                 fputs(_(", check forced.\n"), stdout);
13164                 return;
13165         }
13166         printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
13167                fs->super->s_inodes_count - fs->super->s_free_inodes_count,
13168                fs->super->s_inodes_count,
13169                fs->super->s_blocks_count - fs->super->s_free_blocks_count,
13170                fs->super->s_blocks_count);
13171         next_check = 100000;
13172         if (fs->super->s_max_mnt_count > 0) {
13173                 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
13174                 if (next_check <= 0)
13175                         next_check = 1;
13176         }
13177         if (fs->super->s_checkinterval &&
13178             ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
13179                 next_check = 1;
13180         if (next_check <= 5) {
13181                 if (next_check == 1)
13182                         fputs(_(" (check after next mount)"), stdout);
13183                 else
13184                         printf(_(" (check in %ld mounts)"), next_check);
13185         }
13186         fputc('\n', stdout);
13187         ext2fs_close(fs);
13188         ctx->fs = NULL;
13189         e2fsck_free_context(ctx);
13190         exit(EXIT_OK);
13191 }
13192
13193 /*
13194  * For completion notice
13195  */
13196 struct percent_tbl {
13197         int     max_pass;
13198         int     table[32];
13199 };
13200 static const struct percent_tbl e2fsck_tbl = {
13201         5, { 0, 70, 90, 92,  95, 100 }
13202 };
13203
13204 static char bar[128], spaces[128];
13205
13206 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
13207                           int max)
13208 {
13209         float   percent;
13210
13211         if (pass <= 0)
13212                 return 0.0;
13213         if (pass > tbl->max_pass || max == 0)
13214                 return 100.0;
13215         percent = ((float) curr) / ((float) max);
13216         return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
13217                 + tbl->table[pass-1]);
13218 }
13219
13220 void e2fsck_clear_progbar(e2fsck_t ctx)
13221 {
13222         if (!(ctx->flags & E2F_FLAG_PROG_BAR))
13223                 return;
13224
13225         printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
13226                ctx->stop_meta);
13227         fflush(stdout);
13228         ctx->flags &= ~E2F_FLAG_PROG_BAR;
13229 }
13230
13231 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
13232                            unsigned int dpynum)
13233 {
13234         static const char spinner[] = "\\|/-";
13235         int     i;
13236         unsigned int    tick;
13237         struct timeval  tv;
13238         int dpywidth;
13239         int fixed_percent;
13240
13241         if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
13242                 return 0;
13243
13244         /*
13245          * Calculate the new progress position.  If the
13246          * percentage hasn't changed, then we skip out right
13247          * away.
13248          */
13249         fixed_percent = (int) ((10 * percent) + 0.5);
13250         if (ctx->progress_last_percent == fixed_percent)
13251                 return 0;
13252         ctx->progress_last_percent = fixed_percent;
13253
13254         /*
13255          * If we've already updated the spinner once within
13256          * the last 1/8th of a second, no point doing it
13257          * again.
13258          */
13259         gettimeofday(&tv, NULL);
13260         tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
13261         if ((tick == ctx->progress_last_time) &&
13262             (fixed_percent != 0) && (fixed_percent != 1000))
13263                 return 0;
13264         ctx->progress_last_time = tick;
13265
13266         /*
13267          * Advance the spinner, and note that the progress bar
13268          * will be on the screen
13269          */
13270         ctx->progress_pos = (ctx->progress_pos+1) & 3;
13271         ctx->flags |= E2F_FLAG_PROG_BAR;
13272
13273         dpywidth = 66 - strlen(label);
13274         dpywidth = 8 * (dpywidth / 8);
13275         if (dpynum)
13276                 dpywidth -= 8;
13277
13278         i = ((percent * dpywidth) + 50) / 100;
13279         printf("%s%s: |%s%s", ctx->start_meta, label,
13280                bar + (sizeof(bar) - (i+1)),
13281                spaces + (sizeof(spaces) - (dpywidth - i + 1)));
13282         if (fixed_percent == 1000)
13283                 fputc('|', stdout);
13284         else
13285                 fputc(spinner[ctx->progress_pos & 3], stdout);
13286         printf(" %4.1f%%  ", percent);
13287         if (dpynum)
13288                 printf("%u\r", dpynum);
13289         else
13290                 fputs(" \r", stdout);
13291         fputs(ctx->stop_meta, stdout);
13292
13293         if (fixed_percent == 1000)
13294                 e2fsck_clear_progbar(ctx);
13295         fflush(stdout);
13296
13297         return 0;
13298 }
13299
13300 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
13301                                   unsigned long cur, unsigned long max)
13302 {
13303         char buf[80];
13304         float percent;
13305
13306         if (pass == 0)
13307                 return 0;
13308
13309         if (ctx->progress_fd) {
13310                 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
13311                 write(ctx->progress_fd, buf, strlen(buf));
13312         } else {
13313                 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
13314                 e2fsck_simple_progress(ctx, ctx->device_name,
13315                                        percent, 0);
13316         }
13317         return 0;
13318 }
13319
13320 static void reserve_stdio_fds(void)
13321 {
13322         int     fd;
13323
13324         while (1) {
13325                 fd = open(bb_dev_null, O_RDWR);
13326                 if (fd > 2)
13327                         break;
13328                 if (fd < 0) {
13329                         fprintf(stderr, _("ERROR: Couldn't open "
13330                                 "/dev/null (%s)\n"),
13331                                 strerror(errno));
13332                         break;
13333                 }
13334         }
13335         close(fd);
13336 }
13337
13338 static void signal_progress_on(int sig FSCK_ATTR((unused)))
13339 {
13340         e2fsck_t ctx = e2fsck_global_ctx;
13341
13342         if (!ctx)
13343                 return;
13344
13345         ctx->progress = e2fsck_update_progress;
13346         ctx->progress_fd = 0;
13347 }
13348
13349 static void signal_progress_off(int sig FSCK_ATTR((unused)))
13350 {
13351         e2fsck_t ctx = e2fsck_global_ctx;
13352
13353         if (!ctx)
13354                 return;
13355
13356         e2fsck_clear_progbar(ctx);
13357         ctx->progress = 0;
13358 }
13359
13360 static void signal_cancel(int sig FSCK_ATTR((unused)))
13361 {
13362         e2fsck_t ctx = e2fsck_global_ctx;
13363
13364         if (!ctx)
13365                 exit(FSCK_CANCELED);
13366
13367         ctx->flags |= E2F_FLAG_CANCEL;
13368 }
13369
13370 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
13371 {
13372         char    *buf, *token, *next, *p, *arg;
13373         int     ea_ver;
13374         int     extended_usage = 0;
13375
13376         buf = string_copy(opts, 0);
13377         for (token = buf; token && *token; token = next) {
13378                 p = strchr(token, ',');
13379                 next = 0;
13380                 if (p) {
13381                         *p = 0;
13382                         next = p+1;
13383                 }
13384                 arg = strchr(token, '=');
13385                 if (arg) {
13386                         *arg = 0;
13387                         arg++;
13388                 }
13389                 if (strcmp(token, "ea_ver") == 0) {
13390                         if (!arg) {
13391                                 extended_usage++;
13392                                 continue;
13393                         }
13394                         ea_ver = strtoul(arg, &p, 0);
13395                         if (*p ||
13396                             ((ea_ver != 1) && (ea_ver != 2))) {
13397                                 fprintf(stderr,
13398                                         _("Invalid EA version.\n"));
13399                                 extended_usage++;
13400                                 continue;
13401                         }
13402                         ctx->ext_attr_ver = ea_ver;
13403                 } else {
13404                         fprintf(stderr, _("Unknown extended option: %s\n"),
13405                                 token);
13406                         extended_usage++;
13407                 }
13408         }
13409         if (extended_usage) {
13410                 bb_error_msg_and_die(
13411                         "Extended options are separated by commas, "
13412                         "and may take an argument which\n"
13413                         "is set off by an equals ('=') sign.  "
13414                         "Valid extended options are:\n"
13415                         "\tea_ver=<ea_version (1 or 2)>\n\n");
13416         }
13417 }
13418
13419
13420 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
13421 {
13422         int             flush = 0;
13423         int             c, fd;
13424         e2fsck_t        ctx;
13425         errcode_t       retval;
13426         struct sigaction        sa;
13427         char            *extended_opts = 0;
13428
13429         retval = e2fsck_allocate_context(&ctx);
13430         if (retval)
13431                 return retval;
13432
13433         *ret_ctx = ctx;
13434
13435         setvbuf(stdout, NULL, _IONBF, BUFSIZ);
13436         setvbuf(stderr, NULL, _IONBF, BUFSIZ);
13437         if (isatty(0) && isatty(1)) {
13438                 ctx->interactive = 1;
13439         } else {
13440                 ctx->start_meta[0] = '\001';
13441                 ctx->stop_meta[0] = '\002';
13442         }
13443         memset(bar, '=', sizeof(bar)-1);
13444         memset(spaces, ' ', sizeof(spaces)-1);
13445         blkid_get_cache(&ctx->blkid, NULL);
13446
13447         if (argc && *argv)
13448                 ctx->program_name = *argv;
13449         else
13450                 ctx->program_name = "e2fsck";
13451         while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13452                 switch (c) {
13453                 case 'C':
13454                         ctx->progress = e2fsck_update_progress;
13455                         ctx->progress_fd = atoi(optarg);
13456                         if (!ctx->progress_fd)
13457                                 break;
13458                         /* Validate the file descriptor to avoid disasters */
13459                         fd = dup(ctx->progress_fd);
13460                         if (fd < 0) {
13461                                 fprintf(stderr,
13462                                 _("Error validating file descriptor %d: %s\n"),
13463                                         ctx->progress_fd,
13464                                         error_message(errno));
13465                                 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13466                         } else
13467                                 close(fd);
13468                         break;
13469                 case 'D':
13470                         ctx->options |= E2F_OPT_COMPRESS_DIRS;
13471                         break;
13472                 case 'E':
13473                         extended_opts = optarg;
13474                         break;
13475                 case 'p':
13476                 case 'a':
13477                         if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13478                         conflict_opt:
13479                                 bb_error_msg_and_die(_("Only one the options -p/-a, -n or -y may be specified."));
13480                         }
13481                         ctx->options |= E2F_OPT_PREEN;
13482                         break;
13483                 case 'n':
13484                         if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13485                                 goto conflict_opt;
13486                         ctx->options |= E2F_OPT_NO;
13487                         break;
13488                 case 'y':
13489                         if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13490                                 goto conflict_opt;
13491                         ctx->options |= E2F_OPT_YES;
13492                         break;
13493                 case 't':
13494                         /* FIXME - This needs to go away in a future path - will change binary */
13495                         fprintf(stderr, _("The -t option is not "
13496                                 "supported on this version of e2fsck.\n"));
13497                         break;
13498                 case 'c':
13499                         if (cflag++)
13500                                 ctx->options |= E2F_OPT_WRITECHECK;
13501                         ctx->options |= E2F_OPT_CHECKBLOCKS;
13502                         break;
13503                 case 'r':
13504                         /* What we do by default, anyway! */
13505                         break;
13506                 case 'b':
13507                         ctx->use_superblock = atoi(optarg);
13508                         ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13509                         break;
13510                 case 'B':
13511                         ctx->blocksize = atoi(optarg);
13512                         break;
13513                 case 'I':
13514                         ctx->inode_buffer_blocks = atoi(optarg);
13515                         break;
13516                 case 'j':
13517                         ctx->journal_name = string_copy(optarg, 0);
13518                         break;
13519                 case 'P':
13520                         ctx->process_inode_size = atoi(optarg);
13521                         break;
13522                 case 'L':
13523                         replace_bad_blocks++;
13524                 case 'l':
13525                         bad_blocks_file = string_copy(optarg, 0);
13526                         break;
13527                 case 'd':
13528                         ctx->options |= E2F_OPT_DEBUG;
13529                         break;
13530                 case 'f':
13531                         ctx->options |= E2F_OPT_FORCE;
13532                         break;
13533                 case 'F':
13534                         flush = 1;
13535                         break;
13536                 case 'v':
13537                         verbose = 1;
13538                         break;
13539                 case 'V':
13540                         show_version_only = 1;
13541                         break;
13542                 case 'N':
13543                         ctx->device_name = optarg;
13544                         break;
13545 #ifdef ENABLE_SWAPFS
13546                 case 's':
13547                         normalize_swapfs = 1;
13548                 case 'S':
13549                         swapfs = 1;
13550                         break;
13551 #else
13552                 case 's':
13553                 case 'S':
13554                         fprintf(stderr, _("Byte-swapping filesystems "
13555                                           "not compiled in this version "
13556                                           "of e2fsck\n"));
13557                         exit(1);
13558 #endif
13559                 case 'k':
13560                         keep_bad_blocks++;
13561                         break;
13562                 default:
13563                         bb_show_usage();
13564                 }
13565         if (show_version_only)
13566                 return 0;
13567         if (optind != argc - 1)
13568                 bb_show_usage();
13569         if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
13570             !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13571                 ctx->options |= E2F_OPT_READONLY;
13572         ctx->io_options = strchr(argv[optind], '?');
13573         if (ctx->io_options)
13574                 *ctx->io_options++ = 0;
13575         ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13576         if (!ctx->filesystem_name) {
13577                 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13578                 bb_error_msg_and_die(0);
13579         }
13580         if (extended_opts)
13581                 parse_extended_opts(ctx, extended_opts);
13582
13583         if (flush) {
13584                 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13585                 if (fd < 0) {
13586                         bb_error_msg(_("while opening %s for flushing"),
13587                                 ctx->filesystem_name);
13588                         bb_error_msg_and_die(0);
13589                 }
13590                 if ((retval = ext2fs_sync_device(fd, 1))) {
13591                         bb_error_msg(_("while trying to flush %s"),
13592                                 ctx->filesystem_name);
13593                         bb_error_msg_and_die(0);
13594                 }
13595                 close(fd);
13596         }
13597 #ifdef ENABLE_SWAPFS
13598         if (swapfs) {
13599                 if (cflag || bad_blocks_file) {
13600                         fprintf(stderr, _("Incompatible options not "
13601                                           "allowed when byte-swapping.\n"));
13602                         exit(EXIT_USAGE);
13603                 }
13604         }
13605 #endif
13606         if (cflag && bad_blocks_file) {
13607                 fprintf(stderr, _("The -c and the -l/-L options may "
13608                                   "not be both used at the same time.\n"));
13609                 exit(EXIT_USAGE);
13610         }
13611         /*
13612          * Set up signal action
13613          */
13614         memset(&sa, 0, sizeof(struct sigaction));
13615         sa.sa_handler = signal_cancel;
13616         sigaction(SIGINT, &sa, 0);
13617         sigaction(SIGTERM, &sa, 0);
13618 #ifdef SA_RESTART
13619         sa.sa_flags = SA_RESTART;
13620 #endif
13621         e2fsck_global_ctx = ctx;
13622         sa.sa_handler = signal_progress_on;
13623         sigaction(SIGUSR1, &sa, 0);
13624         sa.sa_handler = signal_progress_off;
13625         sigaction(SIGUSR2, &sa, 0);
13626
13627         /* Update our PATH to include /sbin if we need to run badblocks  */
13628         if (cflag)
13629                 e2fs_set_sbin_path();
13630         return 0;
13631 }
13632
13633 static const char my_ver_string[] = E2FSPROGS_VERSION;
13634 static const char my_ver_date[] = E2FSPROGS_DATE;
13635
13636 int e2fsck_main (int argc, char *argv[])
13637 {
13638         errcode_t       retval;
13639         int             exit_value = EXIT_OK;
13640         ext2_filsys     fs = 0;
13641         io_manager      io_ptr;
13642         struct ext2_super_block *sb;
13643         const char      *lib_ver_date;
13644         int             my_ver, lib_ver;
13645         e2fsck_t        ctx;
13646         struct problem_context pctx;
13647         int flags, run_result;
13648
13649         clear_problem_context(&pctx);
13650
13651         my_ver = ext2fs_parse_version_string(my_ver_string);
13652         lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13653         if (my_ver > lib_ver) {
13654                 fprintf( stderr, _("Error: ext2fs library version "
13655                         "out of date!\n"));
13656                 show_version_only++;
13657         }
13658
13659         retval = PRS(argc, argv, &ctx);
13660         if (retval) {
13661                 bb_error_msg(_("while trying to initialize program"));
13662                 exit(EXIT_ERROR);
13663         }
13664         reserve_stdio_fds();
13665
13666         if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13667                 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13668                          my_ver_date);
13669
13670         if (show_version_only) {
13671                 fprintf(stderr, _("\tUsing %s, %s\n"),
13672                         error_message(EXT2_ET_BASE), lib_ver_date);
13673                 exit(EXIT_OK);
13674         }
13675
13676         check_mount(ctx);
13677
13678         if (!(ctx->options & E2F_OPT_PREEN) &&
13679             !(ctx->options & E2F_OPT_NO) &&
13680             !(ctx->options & E2F_OPT_YES)) {
13681                 if (!ctx->interactive)
13682                         bb_error_msg_and_die(_("need terminal for interactive repairs"));
13683         }
13684         ctx->superblock = ctx->use_superblock;
13685 restart:
13686 #ifdef CONFIG_TESTIO_DEBUG
13687         io_ptr = test_io_manager;
13688         test_io_backing_manager = unix_io_manager;
13689 #else
13690         io_ptr = unix_io_manager;
13691 #endif
13692         flags = 0;
13693         if ((ctx->options & E2F_OPT_READONLY) == 0)
13694                 flags |= EXT2_FLAG_RW;
13695
13696         if (ctx->superblock && ctx->blocksize) {
13697                 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13698                                       flags, ctx->superblock, ctx->blocksize,
13699                                       io_ptr, &fs);
13700         } else if (ctx->superblock) {
13701                 int blocksize;
13702                 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13703                      blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13704                         retval = ext2fs_open2(ctx->filesystem_name,
13705                                               ctx->io_options, flags,
13706                                               ctx->superblock, blocksize,
13707                                               io_ptr, &fs);
13708                         if (!retval)
13709                                 break;
13710                 }
13711         } else
13712                 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13713                                       flags, 0, 0, io_ptr, &fs);
13714         if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13715             !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13716             ((retval == EXT2_ET_BAD_MAGIC) ||
13717              ((retval == 0) && ext2fs_check_desc(fs)))) {
13718                 if (!fs || (fs->group_desc_count > 1)) {
13719                         printf(_("%s trying backup blocks...\n"),
13720                                retval ? _("Couldn't find ext2 superblock,") :
13721                                _("Group descriptors look bad..."));
13722                         get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13723                         if (fs)
13724                                 ext2fs_close(fs);
13725                         goto restart;
13726                 }
13727         }
13728         if (retval) {
13729                 bb_error_msg(_("while trying to open %s"),
13730                         ctx->filesystem_name);
13731                 if (retval == EXT2_ET_REV_TOO_HIGH) {
13732                         printf(_("The filesystem revision is apparently "
13733                                "too high for this version of e2fsck.\n"
13734                                "(Or the filesystem superblock "
13735                                "is corrupt)\n\n"));
13736                         fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13737                 } else if (retval == EXT2_ET_SHORT_READ)
13738                         printf(_("Could this be a zero-length partition?\n"));
13739                 else if ((retval == EPERM) || (retval == EACCES))
13740                         printf(_("You must have %s access to the "
13741                                "filesystem or be root\n"),
13742                                (ctx->options & E2F_OPT_READONLY) ?
13743                                "r/o" : "r/w");
13744                 else if (retval == ENXIO)
13745                         printf(_("Possibly non-existent or swap device?\n"));
13746 #ifdef EROFS
13747                 else if (retval == EROFS)
13748                         printf(_("Disk write-protected; use the -n option "
13749                                "to do a read-only\n"
13750                                "check of the device.\n"));
13751 #endif
13752                 else
13753                         fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13754                 bb_error_msg_and_die(0);
13755         }
13756         ctx->fs = fs;
13757         fs->priv_data = ctx;
13758         sb = fs->super;
13759         if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13760                 bb_error_msg(_("while trying to open %s"),
13761                         ctx->filesystem_name);
13762         get_newer:
13763                 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13764         }
13765
13766         /*
13767          * Set the device name, which is used whenever we print error
13768          * or informational messages to the user.
13769          */
13770         if (ctx->device_name == 0 &&
13771             (sb->s_volume_name[0] != 0)) {
13772                 ctx->device_name = string_copy(sb->s_volume_name,
13773                                                sizeof(sb->s_volume_name));
13774         }
13775         if (ctx->device_name == 0)
13776                 ctx->device_name = ctx->filesystem_name;
13777
13778         /*
13779          * Make sure the ext3 superblock fields are consistent.
13780          */
13781         retval = e2fsck_check_ext3_journal(ctx);
13782         if (retval) {
13783                 bb_error_msg(_("while checking ext3 journal for %s"),
13784                         ctx->device_name);
13785                 bb_error_msg_and_die(0);
13786         }
13787
13788         /*
13789          * Check to see if we need to do ext3-style recovery.  If so,
13790          * do it, and then restart the fsck.
13791          */
13792         if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13793                 if (ctx->options & E2F_OPT_READONLY) {
13794                         printf(_("Warning: skipping journal recovery "
13795                                  "because doing a read-only filesystem "
13796                                  "check.\n"));
13797                         io_channel_flush(ctx->fs->io);
13798                 } else {
13799                         if (ctx->flags & E2F_FLAG_RESTARTED) {
13800                                 /*
13801                                  * Whoops, we attempted to run the
13802                                  * journal twice.  This should never
13803                                  * happen, unless the hardware or
13804                                  * device driver is being bogus.
13805                                  */
13806                                 bb_error_msg(_("unable to set superblock flags on %s\n"), ctx->device_name);
13807                                 bb_error_msg_and_die(0);
13808                         }
13809                         retval = e2fsck_run_ext3_journal(ctx);
13810                         if (retval) {
13811                                 bb_error_msg(_("while recovering ext3 journal of %s"),
13812                                         ctx->device_name);
13813                                 bb_error_msg_and_die(0);
13814                         }
13815                         ext2fs_close(ctx->fs);
13816                         ctx->fs = 0;
13817                         ctx->flags |= E2F_FLAG_RESTARTED;
13818                         goto restart;
13819                 }
13820         }
13821
13822         /*
13823          * Check for compatibility with the feature sets.  We need to
13824          * be more stringent than ext2fs_open().
13825          */
13826         if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13827             (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13828                 bb_error_msg("(%s)", ctx->device_name);
13829                 goto get_newer;
13830         }
13831         if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13832                 bb_error_msg("(%s)", ctx->device_name);
13833                 goto get_newer;
13834         }
13835 #ifdef ENABLE_COMPRESSION
13836         /* FIXME - do we support this at all? */
13837         if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13838                 bb_error_msg(_("Warning: compression support is experimental.\n"));
13839 #endif
13840 #ifndef ENABLE_HTREE
13841         if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13842                 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13843                           "but filesystem %s has HTREE directories.\n"),
13844                         ctx->device_name);
13845                 goto get_newer;
13846         }
13847 #endif
13848
13849         /*
13850          * If the user specified a specific superblock, presumably the
13851          * master superblock has been trashed.  So we mark the
13852          * superblock as dirty, so it can be written out.
13853          */
13854         if (ctx->superblock &&
13855             !(ctx->options & E2F_OPT_READONLY))
13856                 ext2fs_mark_super_dirty(fs);
13857
13858         /*
13859          * We only update the master superblock because (a) paranoia;
13860          * we don't want to corrupt the backup superblocks, and (b) we
13861          * don't need to update the mount count and last checked
13862          * fields in the backup superblock (the kernel doesn't
13863          * update the backup superblocks anyway).
13864          */
13865         fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13866
13867         ehandler_init(fs->io);
13868
13869         if (ctx->superblock)
13870                 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13871         ext2fs_mark_valid(fs);
13872         check_super_block(ctx);
13873         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13874                 bb_error_msg_and_die(0);
13875         check_if_skip(ctx);
13876         if (bad_blocks_file)
13877                 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
13878         else if (cflag)
13879                 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
13880         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13881                 bb_error_msg_and_die(0);
13882 #ifdef ENABLE_SWAPFS
13883
13884 #ifdef WORDS_BIGENDIAN
13885 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13886 #else
13887 #define NATIVE_FLAG 0
13888 #endif
13889
13890
13891         if (normalize_swapfs) {
13892                 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13893                         fprintf(stderr, _("%s: Filesystem byte order "
13894                                 "already normalized.\n"), ctx->device_name);
13895                         bb_error_msg_and_die(0);
13896                 }
13897         }
13898         if (swapfs) {
13899                 swap_filesys(ctx);
13900                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13901                         bb_error_msg_and_die(0);
13902         }
13903 #endif
13904
13905         /*
13906          * Mark the system as valid, 'til proven otherwise
13907          */
13908         ext2fs_mark_valid(fs);
13909
13910         retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13911         if (retval) {
13912                 bb_error_msg(_("while reading bad blocks inode"));
13913                 preenhalt(ctx);
13914                 printf(_("This doesn't bode well,"
13915                          " but we'll try to go on...\n"));
13916         }
13917
13918         run_result = e2fsck_run(ctx);
13919         e2fsck_clear_progbar(ctx);
13920         if (run_result == E2F_FLAG_RESTART) {
13921                 printf(_("Restarting e2fsck from the beginning...\n"));
13922                 retval = e2fsck_reset_context(ctx);
13923                 if (retval) {
13924                         bb_error_msg(_("while resetting context"));
13925                         bb_error_msg_and_die(0);
13926                 }
13927                 ext2fs_close(fs);
13928                 goto restart;
13929         }
13930         if (run_result & E2F_FLAG_CANCEL) {
13931                 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13932                        ctx->device_name : ctx->filesystem_name);
13933                 exit_value |= FSCK_CANCELED;
13934         }
13935         if (run_result & E2F_FLAG_ABORT)
13936                 bb_error_msg_and_die(_("aborted"));
13937
13938         /* Cleanup */
13939         if (ext2fs_test_changed(fs)) {
13940                 exit_value |= EXIT_NONDESTRUCT;
13941                 if (!(ctx->options & E2F_OPT_PREEN))
13942                     printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13943                                ctx->device_name);
13944                 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13945                         printf(_("%s: ***** REBOOT LINUX *****\n"),
13946                                ctx->device_name);
13947                         exit_value |= EXIT_DESTRUCT;
13948                 }
13949         }
13950         if (!ext2fs_test_valid(fs)) {
13951                 printf(_("\n%s: ********** WARNING: Filesystem still has "
13952                          "errors **********\n\n"), ctx->device_name);
13953                 exit_value |= EXIT_UNCORRECTED;
13954                 exit_value &= ~EXIT_NONDESTRUCT;
13955         }
13956         if (exit_value & FSCK_CANCELED)
13957                 exit_value &= ~EXIT_NONDESTRUCT;
13958         else {
13959                 show_stats(ctx);
13960                 if (!(ctx->options & E2F_OPT_READONLY)) {
13961                         if (ext2fs_test_valid(fs)) {
13962                                 if (!(sb->s_state & EXT2_VALID_FS))
13963                                         exit_value |= EXIT_NONDESTRUCT;
13964                                 sb->s_state = EXT2_VALID_FS;
13965                         } else
13966                                 sb->s_state &= ~EXT2_VALID_FS;
13967                         sb->s_mnt_count = 0;
13968                         sb->s_lastcheck = time(NULL);
13969                         ext2fs_mark_super_dirty(fs);
13970                 }
13971         }
13972
13973         e2fsck_write_bitmaps(ctx);
13974
13975         ext2fs_close(fs);
13976         ctx->fs = NULL;
13977         free(ctx->filesystem_name);
13978         free(ctx->journal_name);
13979         e2fsck_free_context(ctx);
13980
13981         return exit_value;
13982 }