Patch from Garrett Kajmowicz to move a lot of #defines into the
[oweals/busybox.git] / e2fsprogs / e2fsck.c
1 /*
2  * e2fsck
3  *
4  * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
5  * This file may be
6  * redistributed under the terms of the GNU Public License.
7  *
8  *
9  * Dictionary Abstract Data Type
10  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
11  * Free Software License:
12  * All rights are reserved by the author, with the following exceptions:
13  * Permission is granted to freely reproduce and distribute this software,
14  * possibly in exchange for a fee, provided that this copyright notice appears
15  * intact. Permission is also granted to adapt this software to produce
16  * derivative works, as long as the modified versions carry this copyright
17  * notice and additional notices stating that the work has been modified.
18  * This source code may be translated into executable form and incorporated
19  * into proprietary software; there is no requirement for such software to
20  * contain a copyright notice related to this source.
21  *
22  * linux/fs/recovery  and linux/fs/revoke
23  * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
24  *
25  * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
26  *
27  * This file is part of the Linux kernel and is made available under
28  * the terms of the GNU General Public License, version 2, or at your
29  * option, any later version, incorporated herein by reference.
30  *
31  * Journal recovery routines for the generic filesystem journaling code;
32  * part of the ext2fs journaling system.
33  */
34
35 #ifndef _GNU_SOURCE
36 #define _GNU_SOURCE 1 /* get strnlen() */
37 #endif
38
39 #include "e2fsck.h"     /*Put all of our defines here to clean things up*/
40
41 #ifdef __GNUC__
42 #define _INLINE_ __inline__
43 #define EXT2FS_ATTR(x) __attribute__(x)
44 #else
45 #define _INLINE_
46 #define EXT2FS_ATTR(x)
47 #endif
48
49 /*
50  * Procedure declarations
51  */
52
53 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
54
55 /* pass1.c */
56 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
57
58 /* pass2.c */
59 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
60                                     ext2_ino_t ino, char *buf);
61
62 /* pass3.c */
63 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
64 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
65                                          int num, int gauranteed_size);
66 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
67 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
68                                            int adj);
69
70 /* rehash.c */
71 static void e2fsck_rehash_directories(e2fsck_t ctx);
72
73 /* util.c */
74 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
75                                     const char *description);
76 static int ask(e2fsck_t ctx, const char * string, int def);
77 static void e2fsck_read_bitmaps(e2fsck_t ctx);
78 static void preenhalt(e2fsck_t ctx);
79 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
80                               struct ext2_inode * inode, const char * proc);
81 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
82                                struct ext2_inode * inode, const char * proc);
83 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
84                            const char *name, io_manager manager);
85
86 /* unix.c */
87 static void e2fsck_clear_progbar(e2fsck_t ctx);
88 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
89                                   float percent, unsigned int dpynum);
90
91
92 /*
93  * problem.h --- e2fsck problem error codes
94  */
95
96 typedef __u32 problem_t;
97
98 struct problem_context {
99         errcode_t       errcode;
100         ext2_ino_t ino, ino2, dir;
101         struct ext2_inode *inode;
102         struct ext2_dir_entry *dirent;
103         blk_t   blk, blk2;
104         e2_blkcnt_t     blkcount;
105         int             group;
106         __u64   num;
107         const char *str;
108 };
109
110
111
112 /*
113  * Function declarations
114  */
115 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
116 static int end_problem_latch(e2fsck_t ctx, int mask);
117 static int set_latch_flags(int mask, int setflags, int clearflags);
118 static void clear_problem_context(struct problem_context *ctx);
119
120 /*
121  * Dictionary Abstract Data Type
122  * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
123  *
124  * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
125  * kazlib_1_20
126  */
127
128 #ifndef DICT_H
129 #define DICT_H
130
131 /*
132  * Blurb for inclusion into C++ translation units
133  */
134
135 typedef unsigned long dictcount_t;
136 #define DICTCOUNT_T_MAX ULONG_MAX
137
138 /*
139  * The dictionary is implemented as a red-black tree
140  */
141
142 typedef enum { dnode_red, dnode_black } dnode_color_t;
143
144 typedef struct dnode_t {
145     struct dnode_t *dict_left;
146     struct dnode_t *dict_right;
147     struct dnode_t *dict_parent;
148     dnode_color_t dict_color;
149     const void *dict_key;
150     void *dict_data;
151 } dnode_t;
152
153 typedef int (*dict_comp_t)(const void *, const void *);
154 typedef void (*dnode_free_t)(dnode_t *);
155
156 typedef struct dict_t {
157     dnode_t dict_nilnode;
158     dictcount_t dict_nodecount;
159     dictcount_t dict_maxcount;
160     dict_comp_t dict_compare;
161     dnode_free_t dict_freenode;
162     int dict_dupes;
163 } dict_t;
164
165 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
166
167 typedef struct dict_load_t {
168     dict_t *dict_dictptr;
169     dnode_t dict_nilnode;
170 } dict_load_t;
171
172 #define dict_count(D) ((D)->dict_nodecount)
173 #define dnode_get(N) ((N)->dict_data)
174 #define dnode_getkey(N) ((N)->dict_key)
175
176 #endif
177
178 /*
179  * Compatibility header file for e2fsck which should be included
180  * instead of linux/jfs.h
181  *
182  * Copyright (C) 2000 Stephen C. Tweedie
183  */
184
185 /*
186  * Pull in the definition of the e2fsck context structure
187  */
188
189 struct buffer_head {
190         char            b_data[8192];
191         e2fsck_t        b_ctx;
192         io_channel      b_io;
193         int             b_size;
194         blk_t           b_blocknr;
195         int             b_dirty;
196         int             b_uptodate;
197         int             b_err;
198 };
199
200
201 #define K_DEV_FS        1
202 #define K_DEV_JOURNAL   2
203
204 #define lock_buffer(bh) do {} while(0)
205 #define unlock_buffer(bh) do {} while(0)
206 #define buffer_req(bh) 1
207 #define do_readahead(journal, start) do {} while(0)
208
209 static e2fsck_t e2fsck_global_ctx;  /* Try your very best not to use this! */
210
211 typedef struct {
212         int     object_length;
213 } kmem_cache_t;
214
215 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
216
217 /*
218  * We use the standard libext2fs portability tricks for inline
219  * functions.
220  */
221
222 static _INLINE_ kmem_cache_t * do_cache_create(int len)
223 {
224         kmem_cache_t *new_cache;
225
226         new_cache = malloc(sizeof(*new_cache));
227         if (new_cache)
228                 new_cache->object_length = len;
229         return new_cache;
230 }
231
232 static _INLINE_ void do_cache_destroy(kmem_cache_t *cache)
233 {
234         free(cache);
235 }
236
237 /*
238  * badblocks.c --- replace/append bad blocks to the bad block inode
239  */
240
241 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
242                                  void *priv_data);
243
244
245 static void invalid_block(ext2_filsys fs FSCK_ATTR((unused)), blk_t blk)
246 {
247         printf(_("Bad block %u out of range; ignored.\n"), blk);
248         return;
249 }
250
251 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
252                           int replace_bad_blocks)
253 {
254         ext2_filsys fs = ctx->fs;
255         errcode_t       retval;
256         badblocks_list  bb_list = 0;
257         FILE            *f;
258         char            buf[1024];
259
260         e2fsck_read_bitmaps(ctx);
261
262         /*
263          * Make sure the bad block inode is sane.  If there are any
264          * illegal blocks, clear them.
265          */
266         retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
267                                       check_bb_inode_blocks, 0);
268         if (retval) {
269                 com_err("ext2fs_block_iterate", retval,
270                         _("while sanity checking the bad blocks inode"));
271                 goto fatal;
272         }
273
274         /*
275          * If we're appending to the bad blocks inode, read in the
276          * current bad blocks.
277          */
278         if (!replace_bad_blocks) {
279                 retval = ext2fs_read_bb_inode(fs, &bb_list);
280                 if (retval) {
281                         com_err("ext2fs_read_bb_inode", retval,
282                                 _("while reading the bad blocks inode"));
283                         goto fatal;
284                 }
285         }
286
287         /*
288          * Now read in the bad blocks from the file; if
289          * bad_blocks_file is null, then try to run the badblocks
290          * command.
291          */
292         if (bad_blocks_file) {
293                 f = fopen(bad_blocks_file, "r");
294                 if (!f) {
295                         com_err("read_bad_blocks_file", errno,
296                                 _("while trying to open %s"), bad_blocks_file);
297                         goto fatal;
298                 }
299         } else {
300                 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
301                         (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
302                         (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
303                         fs->device_name, fs->super->s_blocks_count);
304                 f = popen(buf, "r");
305                 if (!f) {
306                         com_err("read_bad_blocks_file", errno,
307                                 _("while trying popen '%s'"), buf);
308                         goto fatal;
309                 }
310         }
311         retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
312         if (bad_blocks_file)
313                 fclose(f);
314         else
315                 pclose(f);
316         if (retval) {
317                 com_err("ext2fs_read_bb_FILE", retval,
318                         _("while reading in list of bad blocks from file"));
319                 goto fatal;
320         }
321
322         /*
323          * Finally, update the bad blocks from the bad_block_map
324          */
325         retval = ext2fs_update_bb_inode(fs, bb_list);
326         if (retval) {
327                 com_err("ext2fs_update_bb_inode", retval,
328                         _("while updating bad block inode"));
329                 goto fatal;
330         }
331
332         ext2fs_badblocks_list_free(bb_list);
333         return;
334
335 fatal:
336         ctx->flags |= E2F_FLAG_ABORT;
337         return;
338
339 }
340
341 static int check_bb_inode_blocks(ext2_filsys fs,
342                                  blk_t *block_nr,
343                                  int blockcnt FSCK_ATTR((unused)),
344                                  void *priv_data FSCK_ATTR((unused)))
345 {
346         if (!*block_nr)
347                 return 0;
348
349         /*
350          * If the block number is outrageous, clear it and ignore it.
351          */
352         if (*block_nr >= fs->super->s_blocks_count ||
353             *block_nr < fs->super->s_first_data_block) {
354                 printf(_("Warning illegal block %u found in bad block inode.  Cleared.\n"), *block_nr);
355                 *block_nr = 0;
356                 return BLOCK_CHANGED;
357         }
358
359         return 0;
360 }
361
362 /*
363  * Dictionary Abstract Data Type
364  */
365
366
367 /*
368  * These macros provide short convenient names for structure members,
369  * which are embellished with dict_ prefixes so that they are
370  * properly confined to the documented namespace. It's legal for a
371  * program which uses dict to define, for instance, a macro called ``parent''.
372  * Such a macro would interfere with the dnode_t struct definition.
373  * In general, highly portable and reusable C modules which expose their
374  * structures need to confine structure member names to well-defined spaces.
375  * The resulting identifiers aren't necessarily convenient to use, nor
376  * readable, in the implementation, however!
377  */
378
379 #define left dict_left
380 #define right dict_right
381 #define parent dict_parent
382 #define color dict_color
383 #define key dict_key
384 #define data dict_data
385
386 #define nilnode dict_nilnode
387 #define maxcount dict_maxcount
388 #define compare dict_compare
389 #define dupes dict_dupes
390
391 #define dict_root(D) ((D)->nilnode.left)
392 #define dict_nil(D) (&(D)->nilnode)
393 #define DICT_DEPTH_MAX 64
394
395 static void dnode_free(dnode_t *node);
396
397 /*
398  * Perform a ``left rotation'' adjustment on the tree.  The given node P and
399  * its right child C are rearranged so that the P instead becomes the left
400  * child of C.   The left subtree of C is inherited as the new right subtree
401  * for P.  The ordering of the keys within the tree is thus preserved.
402  */
403
404 static void rotate_left(dnode_t *upper)
405 {
406     dnode_t *lower, *lowleft, *upparent;
407
408     lower = upper->right;
409     upper->right = lowleft = lower->left;
410     lowleft->parent = upper;
411
412     lower->parent = upparent = upper->parent;
413
414     /* don't need to check for root node here because root->parent is
415        the sentinel nil node, and root->parent->left points back to root */
416
417     if (upper == upparent->left) {
418         upparent->left = lower;
419     } else {
420         assert (upper == upparent->right);
421         upparent->right = lower;
422     }
423
424     lower->left = upper;
425     upper->parent = lower;
426 }
427
428 /*
429  * This operation is the ``mirror'' image of rotate_left. It is
430  * the same procedure, but with left and right interchanged.
431  */
432
433 static void rotate_right(dnode_t *upper)
434 {
435     dnode_t *lower, *lowright, *upparent;
436
437     lower = upper->left;
438     upper->left = lowright = lower->right;
439     lowright->parent = upper;
440
441     lower->parent = upparent = upper->parent;
442
443     if (upper == upparent->right) {
444         upparent->right = lower;
445     } else {
446         assert (upper == upparent->left);
447         upparent->left = lower;
448     }
449
450     lower->right = upper;
451     upper->parent = lower;
452 }
453
454 /*
455  * Do a postorder traversal of the tree rooted at the specified
456  * node and free everything under it.  Used by dict_free().
457  */
458
459 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
460 {
461     if (node == nil)
462         return;
463     free_nodes(dict, node->left, nil);
464     free_nodes(dict, node->right, nil);
465     dict->dict_freenode(node);
466 }
467
468 /*
469  * Verify that the tree contains the given node. This is done by
470  * traversing all of the nodes and comparing their pointers to the
471  * given pointer. Returns 1 if the node is found, otherwise
472  * returns zero. It is intended for debugging purposes.
473  */
474
475 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
476 {
477     if (root != nil) {
478         return root == node
479                 || verify_dict_has_node(nil, root->left, node)
480                 || verify_dict_has_node(nil, root->right, node);
481     }
482     return 0;
483 }
484
485
486 /*
487  * Select a different set of node allocator routines.
488  */
489
490 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
491 {
492     assert (dict_count(dict) == 0);
493     dict->dict_freenode = fr;
494 }
495
496 /*
497  * Free all the nodes in the dictionary by using the dictionary's
498  * installed free routine. The dictionary is emptied.
499  */
500
501 static void dict_free_nodes(dict_t *dict)
502 {
503     dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
504     free_nodes(dict, root, nil);
505     dict->dict_nodecount = 0;
506     dict->nilnode.left = &dict->nilnode;
507     dict->nilnode.right = &dict->nilnode;
508 }
509
510 /*
511  * Initialize a user-supplied dictionary object.
512  */
513
514 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
515 {
516     dict->compare = comp;
517     dict->dict_freenode = dnode_free;
518     dict->dict_nodecount = 0;
519     dict->maxcount = maxcount;
520     dict->nilnode.left = &dict->nilnode;
521     dict->nilnode.right = &dict->nilnode;
522     dict->nilnode.parent = &dict->nilnode;
523     dict->nilnode.color = dnode_black;
524     dict->dupes = 0;
525     return dict;
526 }
527
528 /*
529  * Locate a node in the dictionary having the given key.
530  * If the node is not found, a null a pointer is returned (rather than
531  * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
532  * located node is returned.
533  */
534
535 static dnode_t *dict_lookup(dict_t *dict, const void *key)
536 {
537     dnode_t *root = dict_root(dict);
538     dnode_t *nil = dict_nil(dict);
539     dnode_t *saved;
540     int result;
541
542     /* simple binary search adapted for trees that contain duplicate keys */
543
544     while (root != nil) {
545         result = dict->compare(key, root->key);
546         if (result < 0)
547             root = root->left;
548         else if (result > 0)
549             root = root->right;
550         else {
551             if (!dict->dupes) { /* no duplicates, return match          */
552                 return root;
553             } else {            /* could be dupes, find leftmost one    */
554                 do {
555                     saved = root;
556                     root = root->left;
557                     while (root != nil && dict->compare(key, root->key))
558                         root = root->right;
559                 } while (root != nil);
560                 return saved;
561             }
562         }
563     }
564
565     return NULL;
566 }
567
568 /*
569  * Insert a node into the dictionary. The node should have been
570  * initialized with a data field. All other fields are ignored.
571  * The behavior is undefined if the user attempts to insert into
572  * a dictionary that is already full (for which the dict_isfull()
573  * function returns true).
574  */
575
576 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
577 {
578     dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
579     dnode_t *parent = nil, *uncle, *grandpa;
580     int result = -1;
581
582     node->key = key;
583
584     /* basic binary tree insert */
585
586     while (where != nil) {
587         parent = where;
588         result = dict->compare(key, where->key);
589         /* trap attempts at duplicate key insertion unless it's explicitly allowed */
590         assert (dict->dupes || result != 0);
591         if (result < 0)
592             where = where->left;
593         else
594             where = where->right;
595     }
596
597     assert (where == nil);
598
599     if (result < 0)
600         parent->left = node;
601     else
602         parent->right = node;
603
604     node->parent = parent;
605     node->left = nil;
606     node->right = nil;
607
608     dict->dict_nodecount++;
609
610     /* red black adjustments */
611
612     node->color = dnode_red;
613
614     while (parent->color == dnode_red) {
615         grandpa = parent->parent;
616         if (parent == grandpa->left) {
617             uncle = grandpa->right;
618             if (uncle->color == dnode_red) {    /* red parent, red uncle */
619                 parent->color = dnode_black;
620                 uncle->color = dnode_black;
621                 grandpa->color = dnode_red;
622                 node = grandpa;
623                 parent = grandpa->parent;
624             } else {                            /* red parent, black uncle */
625                 if (node == parent->right) {
626                     rotate_left(parent);
627                     parent = node;
628                     assert (grandpa == parent->parent);
629                     /* rotation between parent and child preserves grandpa */
630                 }
631                 parent->color = dnode_black;
632                 grandpa->color = dnode_red;
633                 rotate_right(grandpa);
634                 break;
635             }
636         } else {        /* symmetric cases: parent == parent->parent->right */
637             uncle = grandpa->left;
638             if (uncle->color == dnode_red) {
639                 parent->color = dnode_black;
640                 uncle->color = dnode_black;
641                 grandpa->color = dnode_red;
642                 node = grandpa;
643                 parent = grandpa->parent;
644             } else {
645                 if (node == parent->left) {
646                     rotate_right(parent);
647                     parent = node;
648                     assert (grandpa == parent->parent);
649                 }
650                 parent->color = dnode_black;
651                 grandpa->color = dnode_red;
652                 rotate_left(grandpa);
653                 break;
654             }
655         }
656     }
657
658     dict_root(dict)->color = dnode_black;
659
660 }
661
662 /*
663  * Allocate a node using the dictionary's allocator routine, give it
664  * the data item.
665  */
666
667 static dnode_t *dnode_init(dnode_t *dnode, void *data)
668 {
669     dnode->data = data;
670     dnode->parent = NULL;
671     dnode->left = NULL;
672     dnode->right = NULL;
673     return dnode;
674 }
675
676 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
677 {
678     dnode_t *node = malloc(sizeof(dnode_t));
679
680     if (node) {
681         dnode_init(node, data);
682         dict_insert(dict, node, key);
683         return 1;
684     }
685     return 0;
686 }
687
688 /*
689  * Return the node with the lowest (leftmost) key. If the dictionary is empty
690  * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
691  */
692
693 static dnode_t *dict_first(dict_t *dict)
694 {
695     dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
696
697     if (root != nil)
698         while ((left = root->left) != nil)
699             root = left;
700
701     return (root == nil) ? NULL : root;
702 }
703
704 /*
705  * Return the given node's successor node---the node which has the
706  * next key in the the left to right ordering. If the node has
707  * no successor, a null pointer is returned rather than a pointer to
708  * the nil node.
709  */
710
711 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
712 {
713     dnode_t *nil = dict_nil(dict), *parent, *left;
714
715     if (curr->right != nil) {
716         curr = curr->right;
717         while ((left = curr->left) != nil)
718             curr = left;
719         return curr;
720     }
721
722     parent = curr->parent;
723
724     while (parent != nil && curr == parent->right) {
725         curr = parent;
726         parent = curr->parent;
727     }
728
729     return (parent == nil) ? NULL : parent;
730 }
731
732
733 static void dnode_free(dnode_t *node)
734 {
735     free(node);
736 }
737
738
739 #undef left
740 #undef right
741 #undef parent
742 #undef color
743 #undef key
744 #undef data
745
746 #undef nilnode
747 #undef maxcount
748 #undef compare
749 #undef dupes
750
751
752 /*
753  * dirinfo.c --- maintains the directory information table for e2fsck.
754  */
755
756 /*
757  * This subroutine is called during pass1 to create a directory info
758  * entry.  During pass1, the passed-in parent is 0; it will get filled
759  * in during pass2.
760  */
761 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
762 {
763         struct dir_info *dir;
764         int             i, j;
765         ext2_ino_t      num_dirs;
766         errcode_t       retval;
767         unsigned long   old_size;
768
769         if (!ctx->dir_info) {
770                 ctx->dir_info_count = 0;
771                 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
772                 if (retval)
773                         num_dirs = 1024;        /* Guess */
774                 ctx->dir_info_size = num_dirs + 10;
775                 ctx->dir_info  = (struct dir_info *)
776                         e2fsck_allocate_memory(ctx, ctx->dir_info_size
777                                                * sizeof (struct dir_info),
778                                                "directory map");
779         }
780
781         if (ctx->dir_info_count >= ctx->dir_info_size) {
782                 old_size = ctx->dir_info_size * sizeof(struct dir_info);
783                 ctx->dir_info_size += 10;
784                 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
785                                            sizeof(struct dir_info),
786                                            &ctx->dir_info);
787                 if (retval) {
788                         ctx->dir_info_size -= 10;
789                         return;
790                 }
791         }
792
793         /*
794          * Normally, add_dir_info is called with each inode in
795          * sequential order; but once in a while (like when pass 3
796          * needs to recreate the root directory or lost+found
797          * directory) it is called out of order.  In those cases, we
798          * need to move the dir_info entries down to make room, since
799          * the dir_info array needs to be sorted by inode number for
800          * get_dir_info()'s sake.
801          */
802         if (ctx->dir_info_count &&
803             ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
804                 for (i = ctx->dir_info_count-1; i > 0; i--)
805                         if (ctx->dir_info[i-1].ino < ino)
806                                 break;
807                 dir = &ctx->dir_info[i];
808                 if (dir->ino != ino)
809                         for (j = ctx->dir_info_count++; j > i; j--)
810                                 ctx->dir_info[j] = ctx->dir_info[j-1];
811         } else
812                 dir = &ctx->dir_info[ctx->dir_info_count++];
813
814         dir->ino = ino;
815         dir->dotdot = parent;
816         dir->parent = parent;
817 }
818
819 /*
820  * get_dir_info() --- given an inode number, try to find the directory
821  * information entry for it.
822  */
823 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
824 {
825         int     low, high, mid;
826
827         low = 0;
828         high = ctx->dir_info_count-1;
829         if (!ctx->dir_info)
830                 return 0;
831         if (ino == ctx->dir_info[low].ino)
832                 return &ctx->dir_info[low];
833         if  (ino == ctx->dir_info[high].ino)
834                 return &ctx->dir_info[high];
835
836         while (low < high) {
837                 mid = (low+high)/2;
838                 if (mid == low || mid == high)
839                         break;
840                 if (ino == ctx->dir_info[mid].ino)
841                         return &ctx->dir_info[mid];
842                 if (ino < ctx->dir_info[mid].ino)
843                         high = mid;
844                 else
845                         low = mid;
846         }
847         return 0;
848 }
849
850 /*
851  * Free the dir_info structure when it isn't needed any more.
852  */
853 static void e2fsck_free_dir_info(e2fsck_t ctx)
854 {
855         ext2fs_free_mem(&ctx->dir_info);
856         ctx->dir_info_size = 0;
857         ctx->dir_info_count = 0;
858 }
859
860 /*
861  * Return the count of number of directories in the dir_info structure
862  */
863 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
864 {
865         return ctx->dir_info_count;
866 }
867
868 /*
869  * A simple interator function
870  */
871 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
872 {
873         if (*control >= ctx->dir_info_count)
874                 return 0;
875
876         return(ctx->dir_info + (*control)++);
877 }
878
879 /*
880  * dirinfo.c --- maintains the directory information table for e2fsck.
881  *
882  */
883
884 #ifdef ENABLE_HTREE
885
886 /*
887  * This subroutine is called during pass1 to create a directory info
888  * entry.  During pass1, the passed-in parent is 0; it will get filled
889  * in during pass2.
890  */
891 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
892 {
893         struct dx_dir_info *dir;
894         int             i, j;
895         errcode_t       retval;
896         unsigned long   old_size;
897
898         if (!ctx->dx_dir_info) {
899                 ctx->dx_dir_info_count = 0;
900                 ctx->dx_dir_info_size = 100; /* Guess */
901                 ctx->dx_dir_info  = (struct dx_dir_info *)
902                         e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
903                                                * sizeof (struct dx_dir_info),
904                                                "directory map");
905         }
906
907         if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
908                 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
909                 ctx->dx_dir_info_size += 10;
910                 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
911                                            sizeof(struct dx_dir_info),
912                                            &ctx->dx_dir_info);
913                 if (retval) {
914                         ctx->dx_dir_info_size -= 10;
915                         return;
916                 }
917         }
918
919         /*
920          * Normally, add_dx_dir_info is called with each inode in
921          * sequential order; but once in a while (like when pass 3
922          * needs to recreate the root directory or lost+found
923          * directory) it is called out of order.  In those cases, we
924          * need to move the dx_dir_info entries down to make room, since
925          * the dx_dir_info array needs to be sorted by inode number for
926          * get_dx_dir_info()'s sake.
927          */
928         if (ctx->dx_dir_info_count &&
929             ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
930                 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
931                         if (ctx->dx_dir_info[i-1].ino < ino)
932                                 break;
933                 dir = &ctx->dx_dir_info[i];
934                 if (dir->ino != ino)
935                         for (j = ctx->dx_dir_info_count++; j > i; j--)
936                                 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
937         } else
938                 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
939
940         dir->ino = ino;
941         dir->numblocks = num_blocks;
942         dir->hashversion = 0;
943         dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
944                                        * sizeof (struct dx_dirblock_info),
945                                        "dx_block info array");
946
947 }
948
949 /*
950  * get_dx_dir_info() --- given an inode number, try to find the directory
951  * information entry for it.
952  */
953 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
954 {
955         int     low, high, mid;
956
957         low = 0;
958         high = ctx->dx_dir_info_count-1;
959         if (!ctx->dx_dir_info)
960                 return 0;
961         if (ino == ctx->dx_dir_info[low].ino)
962                 return &ctx->dx_dir_info[low];
963         if  (ino == ctx->dx_dir_info[high].ino)
964                 return &ctx->dx_dir_info[high];
965
966         while (low < high) {
967                 mid = (low+high)/2;
968                 if (mid == low || mid == high)
969                         break;
970                 if (ino == ctx->dx_dir_info[mid].ino)
971                         return &ctx->dx_dir_info[mid];
972                 if (ino < ctx->dx_dir_info[mid].ino)
973                         high = mid;
974                 else
975                         low = mid;
976         }
977         return 0;
978 }
979
980 /*
981  * Free the dx_dir_info structure when it isn't needed any more.
982  */
983 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
984 {
985         int     i;
986         struct dx_dir_info *dir;
987
988         if (ctx->dx_dir_info) {
989                 dir = ctx->dx_dir_info;
990                 for (i=0; i < ctx->dx_dir_info_count; i++) {
991                         ext2fs_free_mem(&dir->dx_block);
992                 }
993                 ext2fs_free_mem(&ctx->dx_dir_info);
994         }
995         ctx->dx_dir_info_size = 0;
996         ctx->dx_dir_info_count = 0;
997 }
998
999 /*
1000  * A simple interator function
1001  */
1002 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
1003 {
1004         if (*control >= ctx->dx_dir_info_count)
1005                 return 0;
1006
1007         return(ctx->dx_dir_info + (*control)++);
1008 }
1009
1010 #endif /* ENABLE_HTREE */
1011 /*
1012  * e2fsck.c - a consistency checker for the new extended file system.
1013  *
1014  */
1015
1016 /*
1017  * This function allocates an e2fsck context
1018  */
1019 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
1020 {
1021         e2fsck_t        context;
1022         errcode_t       retval;
1023
1024         retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
1025         if (retval)
1026                 return retval;
1027
1028         memset(context, 0, sizeof(struct e2fsck_struct));
1029
1030         context->process_inode_size = 256;
1031         context->ext_attr_ver = 2;
1032
1033         *ret = context;
1034         return 0;
1035 }
1036
1037 struct ea_refcount_el {
1038         blk_t   ea_blk;
1039         int     ea_count;
1040 };
1041
1042 struct ea_refcount {
1043         blk_t           count;
1044         blk_t           size;
1045         blk_t           cursor;
1046         struct ea_refcount_el   *list;
1047 };
1048
1049 static void ea_refcount_free(ext2_refcount_t refcount)
1050 {
1051         if (!refcount)
1052                 return;
1053
1054         ext2fs_free_mem(&refcount->list);
1055         ext2fs_free_mem(&refcount);
1056 }
1057
1058 /*
1059  * This function resets an e2fsck context; it is called when e2fsck
1060  * needs to be restarted.
1061  */
1062 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
1063 {
1064         ctx->flags = 0;
1065         ctx->lost_and_found = 0;
1066         ctx->bad_lost_and_found = 0;
1067         ext2fs_free_inode_bitmap(ctx->inode_used_map);
1068         ctx->inode_used_map = 0;
1069         ext2fs_free_inode_bitmap(ctx->inode_dir_map);
1070         ctx->inode_dir_map = 0;
1071         ext2fs_free_inode_bitmap(ctx->inode_reg_map);
1072         ctx->inode_reg_map = 0;
1073         ext2fs_free_block_bitmap(ctx->block_found_map);
1074         ctx->block_found_map = 0;
1075         ext2fs_free_icount(ctx->inode_link_info);
1076         ctx->inode_link_info = 0;
1077         if (ctx->journal_io) {
1078                 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1079                         io_channel_close(ctx->journal_io);
1080                 ctx->journal_io = 0;
1081         }
1082         if (ctx->fs) {
1083                 ext2fs_free_dblist(ctx->fs->dblist);
1084                 ctx->fs->dblist = 0;
1085         }
1086         e2fsck_free_dir_info(ctx);
1087 #ifdef ENABLE_HTREE
1088         e2fsck_free_dx_dir_info(ctx);
1089 #endif
1090         ea_refcount_free(ctx->refcount);
1091         ctx->refcount = 0;
1092         ea_refcount_free(ctx->refcount_extra);
1093         ctx->refcount_extra = 0;
1094         ext2fs_free_block_bitmap(ctx->block_dup_map);
1095         ctx->block_dup_map = 0;
1096         ext2fs_free_block_bitmap(ctx->block_ea_map);
1097         ctx->block_ea_map = 0;
1098         ext2fs_free_inode_bitmap(ctx->inode_bb_map);
1099         ctx->inode_bb_map = 0;
1100         ext2fs_free_inode_bitmap(ctx->inode_bad_map);
1101         ctx->inode_bad_map = 0;
1102         ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
1103         ctx->inode_imagic_map = 0;
1104         ext2fs_u32_list_free(ctx->dirs_to_hash);
1105         ctx->dirs_to_hash = 0;
1106
1107         /*
1108          * Clear the array of invalid meta-data flags
1109          */
1110         ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
1111         ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
1112         ext2fs_free_mem(&ctx->invalid_inode_table_flag);
1113
1114         /* Clear statistic counters */
1115         ctx->fs_directory_count = 0;
1116         ctx->fs_regular_count = 0;
1117         ctx->fs_blockdev_count = 0;
1118         ctx->fs_chardev_count = 0;
1119         ctx->fs_links_count = 0;
1120         ctx->fs_symlinks_count = 0;
1121         ctx->fs_fast_symlinks_count = 0;
1122         ctx->fs_fifo_count = 0;
1123         ctx->fs_total_count = 0;
1124         ctx->fs_badblocks_count = 0;
1125         ctx->fs_sockets_count = 0;
1126         ctx->fs_ind_count = 0;
1127         ctx->fs_dind_count = 0;
1128         ctx->fs_tind_count = 0;
1129         ctx->fs_fragmented = 0;
1130         ctx->large_files = 0;
1131
1132         /* Reset the superblock to the user's requested value */
1133         ctx->superblock = ctx->use_superblock;
1134
1135         return 0;
1136 }
1137
1138 static void e2fsck_free_context(e2fsck_t ctx)
1139 {
1140         if (!ctx)
1141                 return;
1142
1143         e2fsck_reset_context(ctx);
1144         if (ctx->blkid)
1145                 blkid_put_cache(ctx->blkid);
1146
1147         ext2fs_free_mem(&ctx);
1148 }
1149
1150 /*
1151  * ea_refcount.c
1152  */
1153
1154 /*
1155  * The strategy we use for keeping track of EA refcounts is as
1156  * follows.  We keep a sorted array of first EA blocks and its
1157  * reference counts.  Once the refcount has dropped to zero, it is
1158  * removed from the array to save memory space.  Once the EA block is
1159  * checked, its bit is set in the block_ea_map bitmap.
1160  */
1161
1162
1163 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1164 {
1165         ext2_refcount_t refcount;
1166         errcode_t       retval;
1167         size_t          bytes;
1168
1169         retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1170         if (retval)
1171                 return retval;
1172         memset(refcount, 0, sizeof(struct ea_refcount));
1173
1174         if (!size)
1175                 size = 500;
1176         refcount->size = size;
1177         bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1178 #ifdef DEBUG
1179         printf("Refcount allocated %d entries, %d bytes.\n",
1180                refcount->size, bytes);
1181 #endif
1182         retval = ext2fs_get_mem(bytes, &refcount->list);
1183         if (retval)
1184                 goto errout;
1185         memset(refcount->list, 0, bytes);
1186
1187         refcount->count = 0;
1188         refcount->cursor = 0;
1189
1190         *ret = refcount;
1191         return 0;
1192
1193 errout:
1194         ea_refcount_free(refcount);
1195         return(retval);
1196 }
1197
1198 /*
1199  * collapse_refcount() --- go through the refcount array, and get rid
1200  * of any count == zero entries
1201  */
1202 static void refcount_collapse(ext2_refcount_t refcount)
1203 {
1204         unsigned int    i, j;
1205         struct ea_refcount_el   *list;
1206
1207         list = refcount->list;
1208         for (i = 0, j = 0; i < refcount->count; i++) {
1209                 if (list[i].ea_count) {
1210                         if (i != j)
1211                                 list[j] = list[i];
1212                         j++;
1213                 }
1214         }
1215 #if defined(DEBUG) || defined(TEST_PROGRAM)
1216         printf("Refcount_collapse: size was %d, now %d\n",
1217                refcount->count, j);
1218 #endif
1219         refcount->count = j;
1220 }
1221
1222
1223 /*
1224  * insert_refcount_el() --- Insert a new entry into the sorted list at a
1225  *      specified position.
1226  */
1227 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1228                                                  blk_t blk, int pos)
1229 {
1230         struct ea_refcount_el   *el;
1231         errcode_t               retval;
1232         blk_t                   new_size = 0;
1233         int                     num;
1234
1235         if (refcount->count >= refcount->size) {
1236                 new_size = refcount->size + 100;
1237 #ifdef DEBUG
1238                 printf("Reallocating refcount %d entries...\n", new_size);
1239 #endif
1240                 retval = ext2fs_resize_mem((size_t) refcount->size *
1241                                            sizeof(struct ea_refcount_el),
1242                                            (size_t) new_size *
1243                                            sizeof(struct ea_refcount_el),
1244                                            &refcount->list);
1245                 if (retval)
1246                         return 0;
1247                 refcount->size = new_size;
1248         }
1249         num = (int) refcount->count - pos;
1250         if (num < 0)
1251                 return 0;       /* should never happen */
1252         if (num) {
1253                 memmove(&refcount->list[pos+1], &refcount->list[pos],
1254                         sizeof(struct ea_refcount_el) * num);
1255         }
1256         refcount->count++;
1257         el = &refcount->list[pos];
1258         el->ea_count = 0;
1259         el->ea_blk = blk;
1260         return el;
1261 }
1262
1263
1264 /*
1265  * get_refcount_el() --- given an block number, try to find refcount
1266  *      information in the sorted list.  If the create flag is set,
1267  *      and we can't find an entry, create one in the sorted list.
1268  */
1269 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1270                                               blk_t blk, int create)
1271 {
1272         float   range;
1273         int     low, high, mid;
1274         blk_t   lowval, highval;
1275
1276         if (!refcount || !refcount->list)
1277                 return 0;
1278 retry:
1279         low = 0;
1280         high = (int) refcount->count-1;
1281         if (create && ((refcount->count == 0) ||
1282                        (blk > refcount->list[high].ea_blk))) {
1283                 if (refcount->count >= refcount->size)
1284                         refcount_collapse(refcount);
1285
1286                 return insert_refcount_el(refcount, blk,
1287                                           (unsigned) refcount->count);
1288         }
1289         if (refcount->count == 0)
1290                 return 0;
1291
1292         if (refcount->cursor >= refcount->count)
1293                 refcount->cursor = 0;
1294         if (blk == refcount->list[refcount->cursor].ea_blk)
1295                 return &refcount->list[refcount->cursor++];
1296 #ifdef DEBUG
1297         printf("Non-cursor get_refcount_el: %u\n", blk);
1298 #endif
1299         while (low <= high) {
1300                 if (low == high)
1301                         mid = low;
1302                 else {
1303                         /* Interpolate for efficiency */
1304                         lowval = refcount->list[low].ea_blk;
1305                         highval = refcount->list[high].ea_blk;
1306
1307                         if (blk < lowval)
1308                                 range = 0;
1309                         else if (blk > highval)
1310                                 range = 1;
1311                         else
1312                                 range = ((float) (blk - lowval)) /
1313                                         (highval - lowval);
1314                         mid = low + ((int) (range * (high-low)));
1315                 }
1316
1317                 if (blk == refcount->list[mid].ea_blk) {
1318                         refcount->cursor = mid+1;
1319                         return &refcount->list[mid];
1320                 }
1321                 if (blk < refcount->list[mid].ea_blk)
1322                         high = mid-1;
1323                 else
1324                         low = mid+1;
1325         }
1326         /*
1327          * If we need to create a new entry, it should be right at
1328          * low (where high will be left at low-1).
1329          */
1330         if (create) {
1331                 if (refcount->count >= refcount->size) {
1332                         refcount_collapse(refcount);
1333                         if (refcount->count < refcount->size)
1334                                 goto retry;
1335                 }
1336                 return insert_refcount_el(refcount, blk, low);
1337         }
1338         return 0;
1339 }
1340
1341 static errcode_t
1342 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1343 {
1344         struct ea_refcount_el   *el;
1345
1346         el = get_refcount_el(refcount, blk, 1);
1347         if (!el)
1348                 return EXT2_ET_NO_MEMORY;
1349         el->ea_count++;
1350
1351         if (ret)
1352                 *ret = el->ea_count;
1353         return 0;
1354 }
1355
1356 static errcode_t
1357 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1358 {
1359         struct ea_refcount_el   *el;
1360
1361         el = get_refcount_el(refcount, blk, 0);
1362         if (!el || el->ea_count == 0)
1363                 return EXT2_ET_INVALID_ARGUMENT;
1364
1365         el->ea_count--;
1366
1367         if (ret)
1368                 *ret = el->ea_count;
1369         return 0;
1370 }
1371
1372 static errcode_t
1373 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1374 {
1375         struct ea_refcount_el   *el;
1376
1377         /*
1378          * Get the refcount element
1379          */
1380         el = get_refcount_el(refcount, blk, count ? 1 : 0);
1381         if (!el)
1382                 return count ? EXT2_ET_NO_MEMORY : 0;
1383         el->ea_count = count;
1384         return 0;
1385 }
1386
1387 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1388 {
1389         refcount->cursor = 0;
1390 }
1391
1392
1393 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1394 {
1395         struct ea_refcount_el   *list;
1396
1397         while (1) {
1398                 if (refcount->cursor >= refcount->count)
1399                         return 0;
1400                 list = refcount->list;
1401                 if (list[refcount->cursor].ea_count) {
1402                         if (ret)
1403                                 *ret = list[refcount->cursor].ea_count;
1404                         return list[refcount->cursor++].ea_blk;
1405                 }
1406                 refcount->cursor++;
1407         }
1408 }
1409
1410
1411 /*
1412  * ehandler.c --- handle bad block errors which come up during the
1413  *      course of an e2fsck session.
1414  */
1415
1416
1417 static const char *operation;
1418
1419 static errcode_t
1420 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1421                          void *data, size_t size FSCK_ATTR((unused)),
1422                          int actual FSCK_ATTR((unused)), errcode_t error)
1423 {
1424         int     i;
1425         char    *p;
1426         ext2_filsys fs = (ext2_filsys) channel->app_data;
1427         e2fsck_t ctx;
1428
1429         ctx = (e2fsck_t) fs->priv_data;
1430
1431         /*
1432          * If more than one block was read, try reading each block
1433          * separately.  We could use the actual bytes read to figure
1434          * out where to start, but we don't bother.
1435          */
1436         if (count > 1) {
1437                 p = (char *) data;
1438                 for (i=0; i < count; i++, p += channel->block_size, block++) {
1439                         error = io_channel_read_blk(channel, block,
1440                                                     1, p);
1441                         if (error)
1442                                 return error;
1443                 }
1444                 return 0;
1445         }
1446         if (operation)
1447                 printf(_("Error reading block %lu (%s) while %s.  "), block,
1448                        error_message(error), operation);
1449         else
1450                 printf(_("Error reading block %lu (%s).  "), block,
1451                        error_message(error));
1452         preenhalt(ctx);
1453         if (ask(ctx, _("Ignore error"), 1)) {
1454                 if (ask(ctx, _("Force rewrite"), 1))
1455                         io_channel_write_blk(channel, block, 1, data);
1456                 return 0;
1457         }
1458
1459         return error;
1460 }
1461
1462 static errcode_t
1463 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1464                         const void *data, size_t size FSCK_ATTR((unused)),
1465                         int actual FSCK_ATTR((unused)), errcode_t error)
1466 {
1467         int             i;
1468         const char      *p;
1469         ext2_filsys fs = (ext2_filsys) channel->app_data;
1470         e2fsck_t ctx;
1471
1472         ctx = (e2fsck_t) fs->priv_data;
1473
1474         /*
1475          * If more than one block was written, try writing each block
1476          * separately.  We could use the actual bytes read to figure
1477          * out where to start, but we don't bother.
1478          */
1479         if (count > 1) {
1480                 p = (const char *) data;
1481                 for (i=0; i < count; i++, p += channel->block_size, block++) {
1482                         error = io_channel_write_blk(channel, block,
1483                                                      1, p);
1484                         if (error)
1485                                 return error;
1486                 }
1487                 return 0;
1488         }
1489
1490         if (operation)
1491                 printf(_("Error writing block %lu (%s) while %s.  "), block,
1492                        error_message(error), operation);
1493         else
1494                 printf(_("Error writing block %lu (%s).  "), block,
1495                        error_message(error));
1496         preenhalt(ctx);
1497         if (ask(ctx, _("Ignore error"), 1))
1498                 return 0;
1499
1500         return error;
1501 }
1502
1503 static inline const char *ehandler_operation(const char *op)
1504 {
1505         const char *ret = operation;
1506
1507         operation = op;
1508         return ret;
1509 }
1510
1511 static void ehandler_init(io_channel channel)
1512 {
1513         channel->read_error = e2fsck_handle_read_error;
1514         channel->write_error = e2fsck_handle_write_error;
1515 }
1516
1517 /*
1518  * journal.c --- code for handling the "ext3" journal
1519  *
1520  * Copyright (C) 2000 Andreas Dilger
1521  * Copyright (C) 2000 Theodore Ts'o
1522  *
1523  * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1524  * Copyright (C) 1999 Red Hat Software
1525  *
1526  * This file may be redistributed under the terms of the
1527  * GNU General Public License version 2 or at your discretion
1528  * any later version.
1529  */
1530
1531 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
1532
1533 /*
1534  * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1535  * This creates a larger static binary, and a smaller binary using
1536  * shared libraries.  It's also probably slightly less CPU-efficient,
1537  * which is why it's not on by default.  But, it's a good way of
1538  * testing the functions in inode_io.c and fileio.c.
1539  */
1540 #undef USE_INODE_IO
1541
1542 /* Kernel compatibility functions for handling the journal.  These allow us
1543  * to use the recovery.c file virtually unchanged from the kernel, so we
1544  * don't have to do much to keep kernel and user recovery in sync.
1545  */
1546 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1547 {
1548 #ifdef USE_INODE_IO
1549         *phys = block;
1550         return 0;
1551 #else
1552         struct inode    *inode = journal->j_inode;
1553         errcode_t       retval;
1554         blk_t           pblk;
1555
1556         if (!inode) {
1557                 *phys = block;
1558                 return 0;
1559         }
1560
1561         retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1562                             &inode->i_ext2, NULL, 0, block, &pblk);
1563         *phys = pblk;
1564         return (retval);
1565 #endif
1566 }
1567
1568 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1569 {
1570         struct buffer_head *bh;
1571
1572         bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1573         if (!bh)
1574                 return NULL;
1575
1576         bh->b_ctx = kdev->k_ctx;
1577         if (kdev->k_dev == K_DEV_FS)
1578                 bh->b_io = kdev->k_ctx->fs->io;
1579         else
1580                 bh->b_io = kdev->k_ctx->journal_io;
1581         bh->b_size = blocksize;
1582         bh->b_blocknr = blocknr;
1583
1584         return bh;
1585 }
1586
1587 static void sync_blockdev(kdev_t kdev)
1588 {
1589         io_channel      io;
1590
1591         if (kdev->k_dev == K_DEV_FS)
1592                 io = kdev->k_ctx->fs->io;
1593         else
1594                 io = kdev->k_ctx->journal_io;
1595
1596         io_channel_flush(io);
1597 }
1598
1599 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1600 {
1601         int retval;
1602         struct buffer_head *bh;
1603
1604         for (; nr > 0; --nr) {
1605                 bh = *bhp++;
1606                 if (rw == READ && !bh->b_uptodate) {
1607                         retval = io_channel_read_blk(bh->b_io,
1608                                                      bh->b_blocknr,
1609                                                      1, bh->b_data);
1610                         if (retval) {
1611                                 com_err(bh->b_ctx->device_name, retval,
1612                                         "while reading block %lu\n",
1613                                         (unsigned long) bh->b_blocknr);
1614                                 bh->b_err = retval;
1615                                 continue;
1616                         }
1617                         bh->b_uptodate = 1;
1618                 } else if (rw == WRITE && bh->b_dirty) {
1619                         retval = io_channel_write_blk(bh->b_io,
1620                                                       bh->b_blocknr,
1621                                                       1, bh->b_data);
1622                         if (retval) {
1623                                 com_err(bh->b_ctx->device_name, retval,
1624                                         "while writing block %lu\n",
1625                                         (unsigned long) bh->b_blocknr);
1626                                 bh->b_err = retval;
1627                                 continue;
1628                         }
1629                         bh->b_dirty = 0;
1630                         bh->b_uptodate = 1;
1631                 }
1632         }
1633 }
1634
1635 static inline void mark_buffer_dirty(struct buffer_head *bh)
1636 {
1637         bh->b_dirty = 1;
1638 }
1639
1640 static inline void mark_buffer_clean(struct buffer_head * bh)
1641 {
1642         bh->b_dirty = 0;
1643 }
1644
1645 static void brelse(struct buffer_head *bh)
1646 {
1647         if (bh->b_dirty)
1648                 ll_rw_block(WRITE, 1, &bh);
1649         ext2fs_free_mem(&bh);
1650 }
1651
1652 static inline int buffer_uptodate(struct buffer_head *bh)
1653 {
1654         return bh->b_uptodate;
1655 }
1656
1657 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1658 {
1659         bh->b_uptodate = val;
1660 }
1661
1662 static void wait_on_buffer(struct buffer_head *bh)
1663 {
1664         if (!bh->b_uptodate)
1665                 ll_rw_block(READ, 1, &bh);
1666 }
1667
1668
1669 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1670 {
1671         ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1672
1673         /* if we had an error doing journal recovery, we need a full fsck */
1674         if (error)
1675                 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1676         ext2fs_mark_super_dirty(ctx->fs);
1677 }
1678
1679 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1680 {
1681         struct ext2_super_block *sb = ctx->fs->super;
1682         struct ext2_super_block jsuper;
1683         struct problem_context  pctx;
1684         struct buffer_head      *bh;
1685         struct inode            *j_inode = NULL;
1686         struct kdev_s           *dev_fs = NULL, *dev_journal;
1687         const char              *journal_name = 0;
1688         journal_t               *journal = NULL;
1689         errcode_t               retval = 0;
1690         io_manager              io_ptr = 0;
1691         unsigned long           start = 0;
1692         blk_t                   blk;
1693         int                     ext_journal = 0;
1694         int                     tried_backup_jnl = 0;
1695         int                     i;
1696
1697         clear_problem_context(&pctx);
1698
1699         journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1700         if (!journal) {
1701                 return EXT2_ET_NO_MEMORY;
1702         }
1703
1704         dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1705         if (!dev_fs) {
1706                 retval = EXT2_ET_NO_MEMORY;
1707                 goto errout;
1708         }
1709         dev_journal = dev_fs+1;
1710
1711         dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1712         dev_fs->k_dev = K_DEV_FS;
1713         dev_journal->k_dev = K_DEV_JOURNAL;
1714
1715         journal->j_dev = dev_journal;
1716         journal->j_fs_dev = dev_fs;
1717         journal->j_inode = NULL;
1718         journal->j_blocksize = ctx->fs->blocksize;
1719
1720         if (uuid_is_null(sb->s_journal_uuid)) {
1721                 if (!sb->s_journal_inum)
1722                         return EXT2_ET_BAD_INODE_NUM;
1723                 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1724                                                  "journal inode");
1725                 if (!j_inode) {
1726                         retval = EXT2_ET_NO_MEMORY;
1727                         goto errout;
1728                 }
1729
1730                 j_inode->i_ctx = ctx;
1731                 j_inode->i_ino = sb->s_journal_inum;
1732
1733                 if ((retval = ext2fs_read_inode(ctx->fs,
1734                                                 sb->s_journal_inum,
1735                                                 &j_inode->i_ext2))) {
1736                 try_backup_journal:
1737                         if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1738                             tried_backup_jnl)
1739                                 goto errout;
1740                         memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1741                         memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1742                                EXT2_N_BLOCKS*4);
1743                         j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1744                         j_inode->i_ext2.i_links_count = 1;
1745                         j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1746                         tried_backup_jnl++;
1747                 }
1748                 if (!j_inode->i_ext2.i_links_count ||
1749                     !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1750                         retval = EXT2_ET_NO_JOURNAL;
1751                         goto try_backup_journal;
1752                 }
1753                 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1754                     JFS_MIN_JOURNAL_BLOCKS) {
1755                         retval = EXT2_ET_JOURNAL_TOO_SMALL;
1756                         goto try_backup_journal;
1757                 }
1758                 for (i=0; i < EXT2_N_BLOCKS; i++) {
1759                         blk = j_inode->i_ext2.i_block[i];
1760                         if (!blk) {
1761                                 if (i < EXT2_NDIR_BLOCKS) {
1762                                         retval = EXT2_ET_JOURNAL_TOO_SMALL;
1763                                         goto try_backup_journal;
1764                                 }
1765                                 continue;
1766                         }
1767                         if (blk < sb->s_first_data_block ||
1768                             blk >= sb->s_blocks_count) {
1769                                 retval = EXT2_ET_BAD_BLOCK_NUM;
1770                                 goto try_backup_journal;
1771                         }
1772                 }
1773                 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1774
1775 #ifdef USE_INODE_IO
1776                 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1777                                                  &j_inode->i_ext2,
1778                                                  &journal_name);
1779                 if (retval)
1780                         goto errout;
1781
1782                 io_ptr = inode_io_manager;
1783 #else
1784                 journal->j_inode = j_inode;
1785                 ctx->journal_io = ctx->fs->io;
1786                 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1787                         goto errout;
1788 #endif
1789         } else {
1790                 ext_journal = 1;
1791                 if (!ctx->journal_name) {
1792                         char uuid[37];
1793
1794                         uuid_unparse(sb->s_journal_uuid, uuid);
1795                         ctx->journal_name = blkid_get_devname(ctx->blkid,
1796                                                               "UUID", uuid);
1797                         if (!ctx->journal_name)
1798                                 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1799                 }
1800                 journal_name = ctx->journal_name;
1801
1802                 if (!journal_name) {
1803                         fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1804                         return EXT2_ET_LOAD_EXT_JOURNAL;
1805                 }
1806
1807                 io_ptr = unix_io_manager;
1808         }
1809
1810 #ifndef USE_INODE_IO
1811         if (ext_journal)
1812 #endif
1813                 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1814                                       &ctx->journal_io);
1815         if (retval)
1816                 goto errout;
1817
1818         io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1819
1820         if (ext_journal) {
1821                 if (ctx->fs->blocksize == 1024)
1822                         start = 1;
1823                 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1824                 if (!bh) {
1825                         retval = EXT2_ET_NO_MEMORY;
1826                         goto errout;
1827                 }
1828                 ll_rw_block(READ, 1, &bh);
1829                 if ((retval = bh->b_err) != 0)
1830                         goto errout;
1831                 memcpy(&jsuper, start ? bh->b_data :  bh->b_data + 1024,
1832                        sizeof(jsuper));
1833                 brelse(bh);
1834 #ifdef EXT2FS_ENABLE_SWAPFS
1835                 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1836                         ext2fs_swap_super(&jsuper);
1837 #endif
1838                 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1839                     !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1840                         fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1841                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
1842                         goto errout;
1843                 }
1844                 /* Make sure the journal UUID is correct */
1845                 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1846                            sizeof(jsuper.s_uuid))) {
1847                         fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1848                         retval = EXT2_ET_LOAD_EXT_JOURNAL;
1849                         goto errout;
1850                 }
1851
1852                 journal->j_maxlen = jsuper.s_blocks_count;
1853                 start++;
1854         }
1855
1856         if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1857                 retval = EXT2_ET_NO_MEMORY;
1858                 goto errout;
1859         }
1860
1861         journal->j_sb_buffer = bh;
1862         journal->j_superblock = (journal_superblock_t *)bh->b_data;
1863
1864 #ifdef USE_INODE_IO
1865         ext2fs_free_mem(&j_inode);
1866 #endif
1867
1868         *ret_journal = journal;
1869         return 0;
1870
1871 errout:
1872         ext2fs_free_mem(&dev_fs);
1873         ext2fs_free_mem(&j_inode);
1874         ext2fs_free_mem(&journal);
1875         return retval;
1876
1877 }
1878
1879 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1880                                               struct problem_context *pctx)
1881 {
1882         struct ext2_super_block *sb = ctx->fs->super;
1883         int recover = ctx->fs->super->s_feature_incompat &
1884                 EXT3_FEATURE_INCOMPAT_RECOVER;
1885         int has_journal = ctx->fs->super->s_feature_compat &
1886                 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1887
1888         if (has_journal || sb->s_journal_inum) {
1889                 /* The journal inode is bogus, remove and force full fsck */
1890                 pctx->ino = sb->s_journal_inum;
1891                 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1892                         if (has_journal && sb->s_journal_inum)
1893                                 printf("*** ext3 journal has been deleted - "
1894                                        "filesystem is now ext2 only ***\n\n");
1895                         sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1896                         sb->s_journal_inum = 0;
1897                         ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1898                         e2fsck_clear_recover(ctx, 1);
1899                         return 0;
1900                 }
1901                 return EXT2_ET_BAD_INODE_NUM;
1902         } else if (recover) {
1903                 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1904                         e2fsck_clear_recover(ctx, 1);
1905                         return 0;
1906                 }
1907                 return EXT2_ET_UNSUPP_FEATURE;
1908         }
1909         return 0;
1910 }
1911
1912 #define V1_SB_SIZE      0x0024
1913 static void clear_v2_journal_fields(journal_t *journal)
1914 {
1915         e2fsck_t ctx = journal->j_dev->k_ctx;
1916         struct problem_context pctx;
1917
1918         clear_problem_context(&pctx);
1919
1920         if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1921                 return;
1922
1923         memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1924                ctx->fs->blocksize-V1_SB_SIZE);
1925         mark_buffer_dirty(journal->j_sb_buffer);
1926 }
1927
1928
1929 static errcode_t e2fsck_journal_load(journal_t *journal)
1930 {
1931         e2fsck_t ctx = journal->j_dev->k_ctx;
1932         journal_superblock_t *jsb;
1933         struct buffer_head *jbh = journal->j_sb_buffer;
1934         struct problem_context pctx;
1935
1936         clear_problem_context(&pctx);
1937
1938         ll_rw_block(READ, 1, &jbh);
1939         if (jbh->b_err) {
1940                 com_err(ctx->device_name, jbh->b_err,
1941                         _("reading journal superblock\n"));
1942                 return jbh->b_err;
1943         }
1944
1945         jsb = journal->j_superblock;
1946         /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1947         if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1948                 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1949
1950         switch (ntohl(jsb->s_header.h_blocktype)) {
1951         case JFS_SUPERBLOCK_V1:
1952                 journal->j_format_version = 1;
1953                 if (jsb->s_feature_compat ||
1954                     jsb->s_feature_incompat ||
1955                     jsb->s_feature_ro_compat ||
1956                     jsb->s_nr_users)
1957                         clear_v2_journal_fields(journal);
1958                 break;
1959
1960         case JFS_SUPERBLOCK_V2:
1961                 journal->j_format_version = 2;
1962                 if (ntohl(jsb->s_nr_users) > 1 &&
1963                     uuid_is_null(ctx->fs->super->s_journal_uuid))
1964                         clear_v2_journal_fields(journal);
1965                 if (ntohl(jsb->s_nr_users) > 1) {
1966                         fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1967                         return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1968                 }
1969                 break;
1970
1971         /*
1972          * These should never appear in a journal super block, so if
1973          * they do, the journal is badly corrupted.
1974          */
1975         case JFS_DESCRIPTOR_BLOCK:
1976         case JFS_COMMIT_BLOCK:
1977         case JFS_REVOKE_BLOCK:
1978                 return EXT2_ET_CORRUPT_SUPERBLOCK;
1979
1980         /* If we don't understand the superblock major type, but there
1981          * is a magic number, then it is likely to be a new format we
1982          * just don't understand, so leave it alone. */
1983         default:
1984                 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1985         }
1986
1987         if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1988                 return EXT2_ET_UNSUPP_FEATURE;
1989
1990         if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1991                 return EXT2_ET_RO_UNSUPP_FEATURE;
1992
1993         /* We have now checked whether we know enough about the journal
1994          * format to be able to proceed safely, so any other checks that
1995          * fail we should attempt to recover from. */
1996         if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1997                 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
1998                         _("%s: no valid journal superblock found\n"),
1999                         ctx->device_name);
2000                 return EXT2_ET_CORRUPT_SUPERBLOCK;
2001         }
2002
2003         if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
2004                 journal->j_maxlen = ntohl(jsb->s_maxlen);
2005         else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
2006                 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
2007                         _("%s: journal too short\n"),
2008                         ctx->device_name);
2009                 return EXT2_ET_CORRUPT_SUPERBLOCK;
2010         }
2011
2012         journal->j_tail_sequence = ntohl(jsb->s_sequence);
2013         journal->j_transaction_sequence = journal->j_tail_sequence;
2014         journal->j_tail = ntohl(jsb->s_start);
2015         journal->j_first = ntohl(jsb->s_first);
2016         journal->j_last = ntohl(jsb->s_maxlen);
2017
2018         return 0;
2019 }
2020
2021 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
2022                                        journal_t *journal)
2023 {
2024         char *p;
2025         union {
2026                 uuid_t uuid;
2027                 __u32 val[4];
2028         } u;
2029         __u32 new_seq = 0;
2030         int i;
2031
2032         /* Leave a valid existing V1 superblock signature alone.
2033          * Anything unrecognisable we overwrite with a new V2
2034          * signature. */
2035
2036         if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
2037             jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
2038                 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
2039                 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
2040         }
2041
2042         /* Zero out everything else beyond the superblock header */
2043
2044         p = ((char *) jsb) + sizeof(journal_header_t);
2045         memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
2046
2047         jsb->s_blocksize = htonl(ctx->fs->blocksize);
2048         jsb->s_maxlen = htonl(journal->j_maxlen);
2049         jsb->s_first = htonl(1);
2050
2051         /* Initialize the journal sequence number so that there is "no"
2052          * chance we will find old "valid" transactions in the journal.
2053          * This avoids the need to zero the whole journal (slow to do,
2054          * and risky when we are just recovering the filesystem).
2055          */
2056         uuid_generate(u.uuid);
2057         for (i = 0; i < 4; i ++)
2058                 new_seq ^= u.val[i];
2059         jsb->s_sequence = htonl(new_seq);
2060
2061         mark_buffer_dirty(journal->j_sb_buffer);
2062         ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
2063 }
2064
2065 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
2066                                                   journal_t *journal,
2067                                                   struct problem_context *pctx)
2068 {
2069         struct ext2_super_block *sb = ctx->fs->super;
2070         int recover = ctx->fs->super->s_feature_incompat &
2071                 EXT3_FEATURE_INCOMPAT_RECOVER;
2072
2073         if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
2074                 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
2075                         e2fsck_journal_reset_super(ctx, journal->j_superblock,
2076                                                    journal);
2077                         journal->j_transaction_sequence = 1;
2078                         e2fsck_clear_recover(ctx, recover);
2079                         return 0;
2080                 }
2081                 return EXT2_ET_CORRUPT_SUPERBLOCK;
2082         } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
2083                 return EXT2_ET_CORRUPT_SUPERBLOCK;
2084
2085         return 0;
2086 }
2087
2088 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
2089                                    int reset, int drop)
2090 {
2091         journal_superblock_t *jsb;
2092
2093         if (drop)
2094                 mark_buffer_clean(journal->j_sb_buffer);
2095         else if (!(ctx->options & E2F_OPT_READONLY)) {
2096                 jsb = journal->j_superblock;
2097                 jsb->s_sequence = htonl(journal->j_transaction_sequence);
2098                 if (reset)
2099                         jsb->s_start = 0; /* this marks the journal as empty */
2100                 mark_buffer_dirty(journal->j_sb_buffer);
2101         }
2102         brelse(journal->j_sb_buffer);
2103
2104         if (ctx->journal_io) {
2105                 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2106                         io_channel_close(ctx->journal_io);
2107                 ctx->journal_io = 0;
2108         }
2109
2110 #ifndef USE_INODE_IO
2111         ext2fs_free_mem(&journal->j_inode);
2112 #endif
2113         ext2fs_free_mem(&journal->j_fs_dev);
2114         ext2fs_free_mem(&journal);
2115 }
2116
2117 /*
2118  * This function makes sure that the superblock fields regarding the
2119  * journal are consistent.
2120  */
2121 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
2122 {
2123         struct ext2_super_block *sb = ctx->fs->super;
2124         journal_t *journal;
2125         int recover = ctx->fs->super->s_feature_incompat &
2126                 EXT3_FEATURE_INCOMPAT_RECOVER;
2127         struct problem_context pctx;
2128         problem_t problem;
2129         int reset = 0, force_fsck = 0;
2130         int retval;
2131
2132         /* If we don't have any journal features, don't do anything more */
2133         if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
2134             !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
2135             uuid_is_null(sb->s_journal_uuid))
2136                 return 0;
2137
2138         clear_problem_context(&pctx);
2139         pctx.num = sb->s_journal_inum;
2140
2141         retval = e2fsck_get_journal(ctx, &journal);
2142         if (retval) {
2143                 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2144                     (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2145                     (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2146                     (retval == EXT2_ET_NO_JOURNAL))
2147                         return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2148                 return retval;
2149         }
2150
2151         retval = e2fsck_journal_load(journal);
2152         if (retval) {
2153                 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2154                     ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2155                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2156                                   &pctx))) ||
2157                     ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2158                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2159                                   &pctx))) ||
2160                     ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2161                     (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2162                         retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2163                                                                   &pctx);
2164                 e2fsck_journal_release(ctx, journal, 0, 1);
2165                 return retval;
2166         }
2167
2168         /*
2169          * We want to make the flags consistent here.  We will not leave with
2170          * needs_recovery set but has_journal clear.  We can't get in a loop
2171          * with -y, -n, or -p, only if a user isn't making up their mind.
2172          */
2173 no_has_journal:
2174         if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2175                 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2176                 pctx.str = "inode";
2177                 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2178                         if (recover &&
2179                             !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2180                                 goto no_has_journal;
2181                         /*
2182                          * Need a full fsck if we are releasing a
2183                          * journal stored on a reserved inode.
2184                          */
2185                         force_fsck = recover ||
2186                                 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2187                         /* Clear all of the journal fields */
2188                         sb->s_journal_inum = 0;
2189                         sb->s_journal_dev = 0;
2190                         memset(sb->s_journal_uuid, 0,
2191                                sizeof(sb->s_journal_uuid));
2192                         e2fsck_clear_recover(ctx, force_fsck);
2193                 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2194                         sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2195                         ext2fs_mark_super_dirty(ctx->fs);
2196                 }
2197         }
2198
2199         if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2200             !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2201             journal->j_superblock->s_start != 0) {
2202                 /* Print status information */
2203                 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2204                 if (ctx->superblock)
2205                         problem = PR_0_JOURNAL_RUN_DEFAULT;
2206                 else
2207                         problem = PR_0_JOURNAL_RUN;
2208                 if (fix_problem(ctx, problem, &pctx)) {
2209                         ctx->options |= E2F_OPT_FORCE;
2210                         sb->s_feature_incompat |=
2211                                 EXT3_FEATURE_INCOMPAT_RECOVER;
2212                         ext2fs_mark_super_dirty(ctx->fs);
2213                 } else if (fix_problem(ctx,
2214                                        PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2215                         reset = 1;
2216                         sb->s_state &= ~EXT2_VALID_FS;
2217                         ext2fs_mark_super_dirty(ctx->fs);
2218                 }
2219                 /*
2220                  * If the user answers no to the above question, we
2221                  * ignore the fact that journal apparently has data;
2222                  * accidentally replaying over valid data would be far
2223                  * worse than skipping a questionable recovery.
2224                  *
2225                  * XXX should we abort with a fatal error here?  What
2226                  * will the ext3 kernel code do if a filesystem with
2227                  * !NEEDS_RECOVERY but with a non-zero
2228                  * journal->j_superblock->s_start is mounted?
2229                  */
2230         }
2231
2232         e2fsck_journal_release(ctx, journal, reset, 0);
2233         return retval;
2234 }
2235
2236 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2237 {
2238         journal_t *journal;
2239         int retval;
2240
2241         journal_init_revoke_caches();
2242         retval = e2fsck_get_journal(ctx, &journal);
2243         if (retval)
2244                 return retval;
2245
2246         retval = e2fsck_journal_load(journal);
2247         if (retval)
2248                 goto errout;
2249
2250         retval = journal_init_revoke(journal, 1024);
2251         if (retval)
2252                 goto errout;
2253
2254         retval = -journal_recover(journal);
2255         if (retval)
2256                 goto errout;
2257
2258         if (journal->j_superblock->s_errno) {
2259                 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2260                 ext2fs_mark_super_dirty(ctx->fs);
2261                 journal->j_superblock->s_errno = 0;
2262                 mark_buffer_dirty(journal->j_sb_buffer);
2263         }
2264
2265 errout:
2266         journal_destroy_revoke(journal);
2267         journal_destroy_revoke_caches();
2268         e2fsck_journal_release(ctx, journal, 1, 0);
2269         return retval;
2270 }
2271
2272 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2273 {
2274         io_manager io_ptr = ctx->fs->io->manager;
2275         int blocksize = ctx->fs->blocksize;
2276         errcode_t       retval, recover_retval;
2277
2278         printf(_("%s: recovering journal\n"), ctx->device_name);
2279         if (ctx->options & E2F_OPT_READONLY) {
2280                 printf(_("%s: won't do journal recovery while read-only\n"),
2281                        ctx->device_name);
2282                 return EXT2_ET_FILE_RO;
2283         }
2284
2285         if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2286                 ext2fs_flush(ctx->fs);  /* Force out any modifications */
2287
2288         recover_retval = recover_ext3_journal(ctx);
2289
2290         /*
2291          * Reload the filesystem context to get up-to-date data from disk
2292          * because journal recovery will change the filesystem under us.
2293          */
2294         ext2fs_close(ctx->fs);
2295         retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2296                              ctx->superblock, blocksize, io_ptr,
2297                              &ctx->fs);
2298
2299         if (retval) {
2300                 com_err(ctx->program_name, retval,
2301                         _("while trying to re-open %s"),
2302                         ctx->device_name);
2303                 fatal_error(ctx, 0);
2304         }
2305         ctx->fs->priv_data = ctx;
2306
2307         /* Set the superblock flags */
2308         e2fsck_clear_recover(ctx, recover_retval);
2309         return recover_retval;
2310 }
2311
2312 /*
2313  * This function will move the journal inode from a visible file in
2314  * the filesystem directory hierarchy to the reserved inode if necessary.
2315  */
2316 static const char * const journal_names[] = {
2317         ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2318
2319 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2320 {
2321         struct ext2_super_block *sb = ctx->fs->super;
2322         struct problem_context  pctx;
2323         struct ext2_inode       inode;
2324         ext2_filsys             fs = ctx->fs;
2325         ext2_ino_t              ino;
2326         errcode_t               retval;
2327         const char * const *    cpp;
2328         int                     group, mount_flags;
2329
2330         clear_problem_context(&pctx);
2331
2332         /*
2333          * If the filesystem is opened read-only, or there is no
2334          * journal, then do nothing.
2335          */
2336         if ((ctx->options & E2F_OPT_READONLY) ||
2337             (sb->s_journal_inum == 0) ||
2338             !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2339                 return;
2340
2341         /*
2342          * Read in the journal inode
2343          */
2344         if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2345                 return;
2346
2347         /*
2348          * If it's necessary to backup the journal inode, do so.
2349          */
2350         if ((sb->s_jnl_backup_type == 0) ||
2351             ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2352              memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2353                 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2354                         memcpy(sb->s_jnl_blocks, inode.i_block,
2355                                EXT2_N_BLOCKS*4);
2356                         sb->s_jnl_blocks[16] = inode.i_size;
2357                         sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2358                         ext2fs_mark_super_dirty(fs);
2359                         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2360                 }
2361         }
2362
2363         /*
2364          * If the journal is already the hidden inode, then do nothing
2365          */
2366         if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2367                 return;
2368
2369         /*
2370          * The journal inode had better have only one link and not be readable.
2371          */
2372         if (inode.i_links_count != 1)
2373                 return;
2374
2375         /*
2376          * If the filesystem is mounted, or we can't tell whether
2377          * or not it's mounted, do nothing.
2378          */
2379         retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2380         if (retval || (mount_flags & EXT2_MF_MOUNTED))
2381                 return;
2382
2383         /*
2384          * If we can't find the name of the journal inode, then do
2385          * nothing.
2386          */
2387         for (cpp = journal_names; *cpp; cpp++) {
2388                 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2389                                        strlen(*cpp), 0, &ino);
2390                 if ((retval == 0) && (ino == sb->s_journal_inum))
2391                         break;
2392         }
2393         if (*cpp == 0)
2394                 return;
2395
2396         /* We need the inode bitmap to be loaded */
2397         retval = ext2fs_read_bitmaps(fs);
2398         if (retval)
2399                 return;
2400
2401         pctx.str = *cpp;
2402         if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2403                 return;
2404
2405         /*
2406          * OK, we've done all the checks, let's actually move the
2407          * journal inode.  Errors at this point mean we need to force
2408          * an ext2 filesystem check.
2409          */
2410         if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2411                 goto err_out;
2412         if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2413                 goto err_out;
2414         sb->s_journal_inum = EXT2_JOURNAL_INO;
2415         ext2fs_mark_super_dirty(fs);
2416         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2417         inode.i_links_count = 0;
2418         inode.i_dtime = time(0);
2419         if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2420                 goto err_out;
2421
2422         group = ext2fs_group_of_ino(fs, ino);
2423         ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2424         ext2fs_mark_ib_dirty(fs);
2425         fs->group_desc[group].bg_free_inodes_count++;
2426         fs->super->s_free_inodes_count++;
2427         return;
2428
2429 err_out:
2430         pctx.errcode = retval;
2431         fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2432         fs->super->s_state &= ~EXT2_VALID_FS;
2433         ext2fs_mark_super_dirty(fs);
2434         return;
2435 }
2436
2437 /*
2438  * message.c --- print e2fsck messages (with compression)
2439  *
2440  * print_e2fsck_message() prints a message to the user, using
2441  * compression techniques and expansions of abbreviations.
2442  *
2443  * The following % expansions are supported:
2444  *
2445  *      %b      <blk>                   block number
2446  *      %B      <blkcount>              integer
2447  *      %c      <blk2>                  block number
2448  *      %Di     <dirent>->ino           inode number
2449  *      %Dn     <dirent>->name          string
2450  *      %Dr     <dirent>->rec_len
2451  *      %Dl     <dirent>->name_len
2452  *      %Dt     <dirent>->filetype
2453  *      %d      <dir>                   inode number
2454  *      %g      <group>                 integer
2455  *      %i      <ino>                   inode number
2456  *      %Is     <inode> -> i_size
2457  *      %IS     <inode> -> i_extra_isize
2458  *      %Ib     <inode> -> i_blocks
2459  *      %Il     <inode> -> i_links_count
2460  *      %Im     <inode> -> i_mode
2461  *      %IM     <inode> -> i_mtime
2462  *      %IF     <inode> -> i_faddr
2463  *      %If     <inode> -> i_file_acl
2464  *      %Id     <inode> -> i_dir_acl
2465  *      %Iu     <inode> -> i_uid
2466  *      %Ig     <inode> -> i_gid
2467  *      %j      <ino2>                  inode number
2468  *      %m      <com_err error message>
2469  *      %N      <num>
2470  *      %p      ext2fs_get_pathname of directory <ino>
2471  *      %P      ext2fs_get_pathname of <dirent>->ino with <ino2> as
2472  *                      the containing directory.  (If dirent is NULL
2473  *                      then return the pathname of directory <ino2>)
2474  *      %q      ext2fs_get_pathname of directory <dir>
2475  *      %Q      ext2fs_get_pathname of directory <ino> with <dir> as
2476  *                      the containing directory.
2477  *      %s      <str>                   miscellaneous string
2478  *      %S      backup superblock
2479  *      %X      <num> hexadecimal format
2480  *
2481  * The following '@' expansions are supported:
2482  *
2483  *      @a      extended attribute
2484  *      @A      error allocating
2485  *      @b      block
2486  *      @B      bitmap
2487  *      @c      compress
2488  *      @C      conflicts with some other fs block
2489  *      @D      deleted
2490  *      @d      directory
2491  *      @e      entry
2492  *      @E      Entry '%Dn' in %p (%i)
2493  *      @f      filesystem
2494  *      @F      for @i %i (%Q) is
2495  *      @g      group
2496  *      @h      HTREE directory inode
2497  *      @i      inode
2498  *      @I      illegal
2499  *      @j      journal
2500  *      @l      lost+found
2501  *      @L      is a link
2502  *      @m      multiply-claimed
2503  *      @n      invalid
2504  *      @o      orphaned
2505  *      @p      problem in
2506  *      @r      root inode
2507  *      @s      should be
2508  *      @S      superblock
2509  *      @u      unattached
2510  *      @v      device
2511  *      @z      zero-length
2512  */
2513
2514
2515 /*
2516  * This structure defines the abbreviations used by the text strings
2517  * below.  The first character in the string is the index letter.  An
2518  * abbreviation of the form '@<i>' is expanded by looking up the index
2519  * letter <i> in the table below.
2520  */
2521 static const char * const abbrevs[] = {
2522         N_("aextended attribute"),
2523         N_("Aerror allocating"),
2524         N_("bblock"),
2525         N_("Bbitmap"),
2526         N_("ccompress"),
2527         N_("Cconflicts with some other fs @b"),
2528         N_("iinode"),
2529         N_("Iillegal"),
2530         N_("jjournal"),
2531         N_("Ddeleted"),
2532         N_("ddirectory"),
2533         N_("eentry"),
2534         N_("E@e '%Dn' in %p (%i)"),
2535         N_("ffilesystem"),
2536         N_("Ffor @i %i (%Q) is"),
2537         N_("ggroup"),
2538         N_("hHTREE @d @i"),
2539         N_("llost+found"),
2540         N_("Lis a link"),
2541     N_("mmultiply-claimed"),
2542     N_("ninvalid"),
2543         N_("oorphaned"),
2544         N_("pproblem in"),
2545         N_("rroot @i"),
2546         N_("sshould be"),
2547         N_("Ssuper@b"),
2548         N_("uunattached"),
2549         N_("vdevice"),
2550         N_("zzero-length"),
2551         "@@",
2552         0
2553         };
2554
2555 /*
2556  * Give more user friendly names to the "special" inodes.
2557  */
2558 #define num_special_inodes      11
2559 static const char * const special_inode_name[] =
2560 {
2561         N_("<The NULL inode>"),                 /* 0 */
2562         N_("<The bad blocks inode>"),           /* 1 */
2563         "/",                                    /* 2 */
2564         N_("<The ACL index inode>"),            /* 3 */
2565         N_("<The ACL data inode>"),             /* 4 */
2566         N_("<The boot loader inode>"),          /* 5 */
2567         N_("<The undelete directory inode>"),   /* 6 */
2568         N_("<The group descriptor inode>"),     /* 7 */
2569         N_("<The journal inode>"),              /* 8 */
2570         N_("<Reserved inode 9>"),               /* 9 */
2571         N_("<Reserved inode 10>"),              /* 10 */
2572 };
2573
2574 /*
2575  * This function does "safe" printing.  It will convert non-printable
2576  * ASCII characters using '^' and M- notation.
2577  */
2578 static void safe_print(const char *cp, int len)
2579 {
2580         unsigned char   ch;
2581
2582         if (len < 0)
2583                 len = strlen(cp);
2584
2585         while (len--) {
2586                 ch = *cp++;
2587                 if (ch > 128) {
2588                         fputs("M-", stdout);
2589                         ch -= 128;
2590                 }
2591                 if ((ch < 32) || (ch == 0x7f)) {
2592                         fputc('^', stdout);
2593                         ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2594                 }
2595                 fputc(ch, stdout);
2596         }
2597 }
2598
2599
2600 /*
2601  * This function prints a pathname, using the ext2fs_get_pathname
2602  * function
2603  */
2604 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2605 {
2606         errcode_t       retval;
2607         char            *path;
2608
2609         if (!dir && (ino < num_special_inodes)) {
2610                 fputs(_(special_inode_name[ino]), stdout);
2611                 return;
2612         }
2613
2614         retval = ext2fs_get_pathname(fs, dir, ino, &path);
2615         if (retval)
2616                 fputs("???", stdout);
2617         else {
2618                 safe_print(path, -1);
2619                 ext2fs_free_mem(&path);
2620         }
2621 }
2622
2623 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2624                           struct problem_context *pctx, int first);
2625 /*
2626  * This function handles the '@' expansion.  We allow recursive
2627  * expansion; an @ expression can contain further '@' and '%'
2628  * expressions.
2629  */
2630 static void expand_at_expression(e2fsck_t ctx, char ch,
2631                                           struct problem_context *pctx,
2632                                           int *first)
2633 {
2634         const char * const *cpp;
2635         const char *str;
2636
2637         /* Search for the abbreviation */
2638         for (cpp = abbrevs; *cpp; cpp++) {
2639                 if (ch == *cpp[0])
2640                         break;
2641         }
2642         if (*cpp) {
2643                 str = _(*cpp) + 1;
2644                 if (*first && islower(*str)) {
2645                         *first = 0;
2646                         fputc(toupper(*str++), stdout);
2647                 }
2648                 print_e2fsck_message(ctx, str, pctx, *first);
2649         } else
2650                 printf("@%c", ch);
2651 }
2652
2653 /*
2654  * This function expands '%IX' expressions
2655  */
2656 static void expand_inode_expression(char ch,
2657                                              struct problem_context *ctx)
2658 {
2659         struct ext2_inode       *inode;
2660         struct ext2_inode_large *large_inode;
2661         char *                  time_str;
2662         time_t                  t;
2663         int                     do_gmt = -1;
2664
2665         if (!ctx || !ctx->inode)
2666                 goto no_inode;
2667
2668         inode = ctx->inode;
2669         large_inode = (struct ext2_inode_large *) inode;
2670
2671         switch (ch) {
2672         case 's':
2673                 if (LINUX_S_ISDIR(inode->i_mode))
2674                         printf("%u", inode->i_size);
2675                 else {
2676 #ifdef EXT2_NO_64_TYPE
2677                         if (inode->i_size_high)
2678                                 printf("0x%x%08x", inode->i_size_high,
2679                                        inode->i_size);
2680                         else
2681                                 printf("%u", inode->i_size);
2682 #else
2683                         printf("%llu", (inode->i_size |
2684                                         ((__u64) inode->i_size_high << 32)));
2685 #endif
2686                 }
2687                 break;
2688         case 'S':
2689                 printf("%u", large_inode->i_extra_isize);
2690                 break;
2691         case 'b':
2692                 printf("%u", inode->i_blocks);
2693                 break;
2694         case 'l':
2695                 printf("%d", inode->i_links_count);
2696                 break;
2697         case 'm':
2698                 printf("0%o", inode->i_mode);
2699                 break;
2700         case 'M':
2701                 /* The diet libc doesn't respect the TZ environemnt variable */
2702                 if (do_gmt == -1) {
2703                         time_str = getenv("TZ");
2704                         if (!time_str)
2705                                 time_str = "";
2706                         do_gmt = !strcmp(time_str, "GMT");
2707                 }
2708                 t = inode->i_mtime;
2709                 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2710                 printf("%.24s", time_str);
2711                 break;
2712         case 'F':
2713                 printf("%u", inode->i_faddr);
2714                 break;
2715         case 'f':
2716                 printf("%u", inode->i_file_acl);
2717                 break;
2718         case 'd':
2719                 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2720                               inode->i_dir_acl : 0));
2721                 break;
2722         case 'u':
2723                 printf("%d", (inode->i_uid |
2724                               (inode->osd2.linux2.l_i_uid_high << 16)));
2725                 break;
2726         case 'g':
2727                 printf("%d", (inode->i_gid |
2728                               (inode->osd2.linux2.l_i_gid_high << 16)));
2729                 break;
2730         default:
2731         no_inode:
2732                 printf("%%I%c", ch);
2733                 break;
2734         }
2735 }
2736
2737 /*
2738  * This function expands '%dX' expressions
2739  */
2740 static _INLINE_ void expand_dirent_expression(char ch,
2741                                               struct problem_context *ctx)
2742 {
2743         struct ext2_dir_entry   *dirent;
2744         int     len;
2745
2746         if (!ctx || !ctx->dirent)
2747                 goto no_dirent;
2748
2749         dirent = ctx->dirent;
2750
2751         switch (ch) {
2752         case 'i':
2753                 printf("%u", dirent->inode);
2754                 break;
2755         case 'n':
2756                 len = dirent->name_len & 0xFF;
2757                 if (len > EXT2_NAME_LEN)
2758                         len = EXT2_NAME_LEN;
2759                 if (len > dirent->rec_len)
2760                         len = dirent->rec_len;
2761                 safe_print(dirent->name, len);
2762                 break;
2763         case 'r':
2764                 printf("%u", dirent->rec_len);
2765                 break;
2766         case 'l':
2767                 printf("%u", dirent->name_len & 0xFF);
2768                 break;
2769         case 't':
2770                 printf("%u", dirent->name_len >> 8);
2771                 break;
2772         default:
2773         no_dirent:
2774                 printf("%%D%c", ch);
2775                 break;
2776         }
2777 }
2778
2779 static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
2780                                                struct problem_context *ctx)
2781 {
2782         if (!ctx)
2783                 goto no_context;
2784
2785         switch (ch) {
2786         case '%':
2787                 fputc('%', stdout);
2788                 break;
2789         case 'b':
2790                 printf("%u", ctx->blk);
2791                 break;
2792         case 'B':
2793 #ifdef EXT2_NO_64_TYPE
2794                 printf("%d", ctx->blkcount);
2795 #else
2796                 printf("%lld", ctx->blkcount);
2797 #endif
2798                 break;
2799         case 'c':
2800                 printf("%u", ctx->blk2);
2801                 break;
2802         case 'd':
2803                 printf("%u", ctx->dir);
2804                 break;
2805         case 'g':
2806                 printf("%d", ctx->group);
2807                 break;
2808         case 'i':
2809                 printf("%u", ctx->ino);
2810                 break;
2811         case 'j':
2812                 printf("%u", ctx->ino2);
2813                 break;
2814         case 'm':
2815                 printf("%s", error_message(ctx->errcode));
2816                 break;
2817         case 'N':
2818 #ifdef EXT2_NO_64_TYPE
2819                 printf("%u", ctx->num);
2820 #else
2821                 printf("%llu", ctx->num);
2822 #endif
2823                 break;
2824         case 'p':
2825                 print_pathname(fs, ctx->ino, 0);
2826                 break;
2827         case 'P':
2828                 print_pathname(fs, ctx->ino2,
2829                                ctx->dirent ? ctx->dirent->inode : 0);
2830                 break;
2831         case 'q':
2832                 print_pathname(fs, ctx->dir, 0);
2833                 break;
2834         case 'Q':
2835                 print_pathname(fs, ctx->dir, ctx->ino);
2836                 break;
2837         case 'S':
2838                 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2839                 break;
2840         case 's':
2841                 printf("%s", ctx->str ? ctx->str : "NULL");
2842                 break;
2843         case 'X':
2844 #ifdef EXT2_NO_64_TYPE
2845                 printf("0x%x", ctx->num);
2846 #else
2847                 printf("0x%llx", ctx->num);
2848 #endif
2849                 break;
2850         default:
2851         no_context:
2852                 printf("%%%c", ch);
2853                 break;
2854         }
2855 }
2856
2857
2858 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2859                           struct problem_context *pctx, int first)
2860 {
2861         ext2_filsys fs = ctx->fs;
2862         const char *    cp;
2863         int             i;
2864
2865         e2fsck_clear_progbar(ctx);
2866         for (cp = msg; *cp; cp++) {
2867                 if (cp[0] == '@') {
2868                         cp++;
2869                         expand_at_expression(ctx, *cp, pctx, &first);
2870                 } else if (cp[0] == '%' && cp[1] == 'I') {
2871                         cp += 2;
2872                         expand_inode_expression(*cp, pctx);
2873                 } else if (cp[0] == '%' && cp[1] == 'D') {
2874                         cp += 2;
2875                         expand_dirent_expression(*cp, pctx);
2876                 } else if ((cp[0] == '%')) {
2877                         cp++;
2878                         expand_percent_expression(fs, *cp, pctx);
2879                 } else {
2880                         for (i=0; cp[i]; i++)
2881                                 if ((cp[i] == '@') || cp[i] == '%')
2882                                         break;
2883                         printf("%.*s", i, cp);
2884                         cp += i-1;
2885                 }
2886                 first = 0;
2887         }
2888 }
2889
2890
2891 /*
2892  * region.c --- code which manages allocations within a region.
2893  */
2894
2895 struct region_el {
2896         region_addr_t   start;
2897         region_addr_t   end;
2898         struct region_el *next;
2899 };
2900
2901 struct region_struct {
2902         region_addr_t   min;
2903         region_addr_t   max;
2904         struct region_el *allocated;
2905 };
2906
2907 static region_t region_create(region_addr_t min, region_addr_t max)
2908 {
2909         region_t        region;
2910
2911         region = malloc(sizeof(struct region_struct));
2912         if (!region)
2913                 return NULL;
2914         memset(region, 0, sizeof(struct region_struct));
2915         region->min = min;
2916         region->max = max;
2917         return region;
2918 }
2919
2920 static void region_free(region_t region)
2921 {
2922         struct region_el        *r, *next;
2923
2924         for (r = region->allocated; r; r = next) {
2925                 next = r->next;
2926                 free(r);
2927         }
2928         memset(region, 0, sizeof(struct region_struct));
2929         free(region);
2930 }
2931
2932 static int region_allocate(region_t region, region_addr_t start, int n)
2933 {
2934         struct region_el        *r, *new_region, *prev, *next;
2935         region_addr_t end;
2936
2937         end = start+n;
2938         if ((start < region->min) || (end > region->max))
2939                 return -1;
2940         if (n == 0)
2941                 return 1;
2942
2943         /*
2944          * Search through the linked list.  If we find that it
2945          * conflicts witih something that's already allocated, return
2946          * 1; if we can find an existing region which we can grow, do
2947          * so.  Otherwise, stop when we find the appropriate place
2948          * insert a new region element into the linked list.
2949          */
2950         for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2951                 if (((start >= r->start) && (start < r->end)) ||
2952                     ((end > r->start) && (end <= r->end)) ||
2953                     ((start <= r->start) && (end >= r->end)))
2954                         return 1;
2955                 if (end == r->start) {
2956                         r->start = start;
2957                         return 0;
2958                 }
2959                 if (start == r->end) {
2960                         if ((next = r->next)) {
2961                                 if (end > next->start)
2962                                         return 1;
2963                                 if (end == next->start) {
2964                                         r->end = next->end;
2965                                         r->next = next->next;
2966                                         free(next);
2967                                         return 0;
2968                                 }
2969                         }
2970                         r->end = end;
2971                         return 0;
2972                 }
2973                 if (start < r->start)
2974                         break;
2975         }
2976         /*
2977          * Insert a new region element structure into the linked list
2978          */
2979         new_region = malloc(sizeof(struct region_el));
2980         if (!new_region)
2981                 return -1;
2982         new_region->start = start;
2983         new_region->end = start + n;
2984         new_region->next = r;
2985         if (prev)
2986                 prev->next = new_region;
2987         else
2988                 region->allocated = new_region;
2989         return 0;
2990 }
2991
2992 /*
2993  * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2994  *
2995  * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2996  * and applies the following tests to each inode:
2997  *
2998  *      - The mode field of the inode must be legal.
2999  *      - The size and block count fields of the inode are correct.
3000  *      - A data block must not be used by another inode
3001  *
3002  * Pass 1 also gathers the collects the following information:
3003  *
3004  *      - A bitmap of which inodes are in use.          (inode_used_map)
3005  *      - A bitmap of which inodes are directories.     (inode_dir_map)
3006  *      - A bitmap of which inodes are regular files.   (inode_reg_map)
3007  *      - A bitmap of which inodes have bad fields.     (inode_bad_map)
3008  *      - A bitmap of which inodes are in bad blocks.   (inode_bb_map)
3009  *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
3010  *      - A bitmap of which blocks are in use.          (block_found_map)
3011  *      - A bitmap of which blocks are in use by two inodes     (block_dup_map)
3012  *      - The data blocks of the directory inodes.      (dir_map)
3013  *
3014  * Pass 1 is designed to stash away enough information so that the
3015  * other passes should not need to read in the inode information
3016  * during the normal course of a filesystem check.  (Althogh if an
3017  * inconsistency is detected, other passes may need to read in an
3018  * inode to fix it.)
3019  *
3020  * Note that pass 1B will be invoked if there are any duplicate blocks
3021  * found.
3022  */
3023
3024
3025 static int process_block(ext2_filsys fs, blk_t  *blocknr,
3026                          e2_blkcnt_t blockcnt, blk_t ref_blk,
3027                          int ref_offset, void *priv_data);
3028 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
3029                              e2_blkcnt_t blockcnt, blk_t ref_blk,
3030                              int ref_offset, void *priv_data);
3031 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3032                          char *block_buf);
3033 static void mark_table_blocks(e2fsck_t ctx);
3034 static void alloc_bb_map(e2fsck_t ctx);
3035 static void alloc_imagic_map(e2fsck_t ctx);
3036 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
3037 static void handle_fs_bad_blocks(e2fsck_t ctx);
3038 static void process_inodes(e2fsck_t ctx, char *block_buf);
3039 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
3040 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
3041                                   dgrp_t group, void * priv_data);
3042 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3043                                     char *block_buf, int adjust_sign);
3044 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
3045
3046 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
3047                                struct ext2_inode * inode, int bufsize,
3048                                const char *proc);
3049
3050 struct process_block_struct_1 {
3051         ext2_ino_t      ino;
3052         unsigned        is_dir:1, is_reg:1, clear:1, suppress:1,
3053                                 fragmented:1, compressed:1, bbcheck:1;
3054         blk_t           num_blocks;
3055         blk_t           max_blocks;
3056         e2_blkcnt_t     last_block;
3057         int             num_illegal_blocks;
3058         blk_t           previous_block;
3059         struct ext2_inode *inode;
3060         struct problem_context *pctx;
3061         ext2fs_block_bitmap fs_meta_blocks;
3062         e2fsck_t        ctx;
3063 };
3064
3065 struct process_inode_block {
3066         ext2_ino_t ino;
3067         struct ext2_inode inode;
3068 };
3069
3070 struct scan_callback_struct {
3071         e2fsck_t        ctx;
3072         char            *block_buf;
3073 };
3074
3075 /*
3076  * For the inodes to process list.
3077  */
3078 static struct process_inode_block *inodes_to_process;
3079 static int process_inode_count;
3080
3081 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
3082                             EXT2_MIN_BLOCK_LOG_SIZE + 1];
3083
3084 /*
3085  * Free all memory allocated by pass1 in preparation for restarting
3086  * things.
3087  */
3088 static void unwind_pass1(void)
3089 {
3090         ext2fs_free_mem(&inodes_to_process);
3091 }
3092
3093 /*
3094  * Check to make sure a device inode is real.  Returns 1 if the device
3095  * checks out, 0 if not.
3096  *
3097  * Note: this routine is now also used to check FIFO's and Sockets,
3098  * since they have the same requirement; the i_block fields should be
3099  * zero.
3100  */
3101 static int
3102 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
3103 {
3104         int     i;
3105
3106         /*
3107          * If i_blocks is non-zero, or the index flag is set, then
3108          * this is a bogus device/fifo/socket
3109          */
3110         if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
3111             (inode->i_flags & EXT2_INDEX_FL))
3112                 return 0;
3113
3114         /*
3115          * We should be able to do the test below all the time, but
3116          * because the kernel doesn't forcibly clear the device
3117          * inode's additional i_block fields, there are some rare
3118          * occasions when a legitimate device inode will have non-zero
3119          * additional i_block fields.  So for now, we only complain
3120          * when the immutable flag is set, which should never happen
3121          * for devices.  (And that's when the problem is caused, since
3122          * you can't set or clear immutable flags for devices.)  Once
3123          * the kernel has been fixed we can change this...
3124          */
3125         if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
3126                 for (i=4; i < EXT2_N_BLOCKS; i++)
3127                         if (inode->i_block[i])
3128                                 return 0;
3129         }
3130         return 1;
3131 }
3132
3133 /*
3134  * Check to make sure a symlink inode is real.  Returns 1 if the symlink
3135  * checks out, 0 if not.
3136  */
3137 static int
3138 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
3139 {
3140         unsigned int len;
3141         int i;
3142         blk_t   blocks;
3143
3144         if ((inode->i_size_high || inode->i_size == 0) ||
3145             (inode->i_flags & EXT2_INDEX_FL))
3146                 return 0;
3147
3148         blocks = ext2fs_inode_data_blocks(fs, inode);
3149         if (blocks) {
3150                 if ((inode->i_size >= fs->blocksize) ||
3151                     (blocks != fs->blocksize >> 9) ||
3152                     (inode->i_block[0] < fs->super->s_first_data_block) ||
3153                     (inode->i_block[0] >= fs->super->s_blocks_count))
3154                         return 0;
3155
3156                 for (i = 1; i < EXT2_N_BLOCKS; i++)
3157                         if (inode->i_block[i])
3158                                 return 0;
3159
3160                 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
3161                         return 0;
3162
3163                 len = strnlen(buf, fs->blocksize);
3164                 if (len == fs->blocksize)
3165                         return 0;
3166         } else {
3167                 if (inode->i_size >= sizeof(inode->i_block))
3168                         return 0;
3169
3170                 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3171                 if (len == sizeof(inode->i_block))
3172                         return 0;
3173         }
3174         if (len != inode->i_size)
3175                 return 0;
3176         return 1;
3177 }
3178
3179 /*
3180  * If the immutable (or append-only) flag is set on the inode, offer
3181  * to clear it.
3182  */
3183 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3184 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3185 {
3186         if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3187                 return;
3188
3189         if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3190                 return;
3191
3192         pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3193         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3194 }
3195
3196 /*
3197  * If device, fifo or socket, check size is zero -- if not offer to
3198  * clear it
3199  */
3200 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3201 {
3202         struct ext2_inode *inode = pctx->inode;
3203
3204         if ((inode->i_size == 0) && (inode->i_size_high == 0))
3205                 return;
3206
3207         if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3208                 return;
3209
3210         inode->i_size = 0;
3211         inode->i_size_high = 0;
3212         e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3213 }
3214
3215 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3216 {
3217         struct ext2_super_block *sb = ctx->fs->super;
3218         struct ext2_inode_large *inode;
3219         struct ext2_ext_attr_entry *entry;
3220         char *start, *end;
3221         int storage_size, remain, offs;
3222         int problem = 0;
3223
3224         inode = (struct ext2_inode_large *) pctx->inode;
3225         storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3226                 inode->i_extra_isize;
3227         start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3228                 inode->i_extra_isize + sizeof(__u32);
3229         end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3230         entry = (struct ext2_ext_attr_entry *) start;
3231
3232         /* scan all entry's headers first */
3233
3234         /* take finish entry 0UL into account */
3235         remain = storage_size - sizeof(__u32);
3236         offs = end - start;
3237
3238         while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3239
3240                 /* header eats this space */
3241                 remain -= sizeof(struct ext2_ext_attr_entry);
3242
3243                 /* is attribute name valid? */
3244                 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3245                         pctx->num = entry->e_name_len;
3246                         problem = PR_1_ATTR_NAME_LEN;
3247                         goto fix;
3248                 }
3249
3250                 /* attribute len eats this space */
3251                 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3252
3253                 /* check value size */
3254                 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3255                         pctx->num = entry->e_value_size;
3256                         problem = PR_1_ATTR_VALUE_SIZE;
3257                         goto fix;
3258                 }
3259
3260                 /* check value placement */
3261                 if (entry->e_value_offs +
3262                     EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3263                         printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3264                         pctx->num = entry->e_value_offs;
3265                         problem = PR_1_ATTR_VALUE_OFFSET;
3266                         goto fix;
3267                 }
3268
3269                 /* e_value_block must be 0 in inode's ea */
3270                 if (entry->e_value_block != 0) {
3271                         pctx->num = entry->e_value_block;
3272                         problem = PR_1_ATTR_VALUE_BLOCK;
3273                         goto fix;
3274                 }
3275
3276                 /* e_hash must be 0 in inode's ea */
3277                 if (entry->e_hash != 0) {
3278                         pctx->num = entry->e_hash;
3279                         problem = PR_1_ATTR_HASH;
3280                         goto fix;
3281                 }
3282
3283                 remain -= entry->e_value_size;
3284                 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3285
3286                 entry = EXT2_EXT_ATTR_NEXT(entry);
3287         }
3288 fix:
3289         /*
3290          * it seems like a corruption. it's very unlikely we could repair
3291          * EA(s) in automatic fashion -bzzz
3292          */
3293         if (problem == 0 || !fix_problem(ctx, problem, pctx))
3294                 return;
3295
3296         /* simple remove all possible EA(s) */
3297         *((__u32 *)start) = 0UL;
3298         e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3299                                 EXT2_INODE_SIZE(sb), "pass1");
3300 }
3301
3302 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3303 {
3304         struct ext2_super_block *sb = ctx->fs->super;
3305         struct ext2_inode_large *inode;
3306         __u32 *eamagic;
3307         int min, max;
3308
3309         inode = (struct ext2_inode_large *) pctx->inode;
3310         if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3311                 /* this isn't large inode. so, nothing to check */
3312                 return;
3313         }
3314
3315         /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3316         min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3317         max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3318         /*
3319          * For now we will allow i_extra_isize to be 0, but really
3320          * implementations should never allow i_extra_isize to be 0
3321          */
3322         if (inode->i_extra_isize &&
3323             (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3324                 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3325                         return;
3326                 inode->i_extra_isize = min;
3327                 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3328                                         EXT2_INODE_SIZE(sb), "pass1");
3329                 return;
3330         }
3331
3332         eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3333                         inode->i_extra_isize);
3334         if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3335                 /* it seems inode has an extended attribute(s) in body */
3336                 check_ea_in_inode(ctx, pctx);
3337         }
3338 }
3339
3340 static void e2fsck_pass1(e2fsck_t ctx)
3341 {
3342         int     i;
3343         __u64   max_sizes;
3344         ext2_filsys fs = ctx->fs;
3345         ext2_ino_t      ino;
3346         struct ext2_inode *inode;
3347         ext2_inode_scan scan;
3348         char            *block_buf;
3349         unsigned char   frag, fsize;
3350         struct          problem_context pctx;
3351         struct          scan_callback_struct scan_struct;
3352         struct ext2_super_block *sb = ctx->fs->super;
3353         int             imagic_fs;
3354         int             busted_fs_time = 0;
3355         int             inode_size;
3356
3357         clear_problem_context(&pctx);
3358
3359         if (!(ctx->options & E2F_OPT_PREEN))
3360                 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3361
3362         if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3363             !(ctx->options & E2F_OPT_NO)) {
3364                 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3365                         ctx->dirs_to_hash = 0;
3366         }
3367
3368         /* Pass 1 */
3369
3370 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3371
3372         for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3373                 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3374                 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3375                 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3376                 max_sizes = (max_sizes * (1UL << i)) - 1;
3377                 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3378         }
3379 #undef EXT2_BPP
3380
3381         imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3382
3383         /*
3384          * Allocate bitmaps structures
3385          */
3386         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3387                                               &ctx->inode_used_map);
3388         if (pctx.errcode) {
3389                 pctx.num = 1;
3390                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3391                 ctx->flags |= E2F_FLAG_ABORT;
3392                 return;
3393         }
3394         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3395                                 _("directory inode map"), &ctx->inode_dir_map);
3396         if (pctx.errcode) {
3397                 pctx.num = 2;
3398                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3399                 ctx->flags |= E2F_FLAG_ABORT;
3400                 return;
3401         }
3402         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3403                         _("regular file inode map"), &ctx->inode_reg_map);
3404         if (pctx.errcode) {
3405                 pctx.num = 6;
3406                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3407                 ctx->flags |= E2F_FLAG_ABORT;
3408                 return;
3409         }
3410         pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3411                                               &ctx->block_found_map);
3412         if (pctx.errcode) {
3413                 pctx.num = 1;
3414                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3415                 ctx->flags |= E2F_FLAG_ABORT;
3416                 return;
3417         }
3418         pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3419                                              &ctx->inode_link_info);
3420         if (pctx.errcode) {
3421                 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3422                 ctx->flags |= E2F_FLAG_ABORT;
3423                 return;
3424         }
3425         inode_size = EXT2_INODE_SIZE(fs->super);
3426         inode = (struct ext2_inode *)
3427                 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3428
3429         inodes_to_process = (struct process_inode_block *)
3430                 e2fsck_allocate_memory(ctx,
3431                                        (ctx->process_inode_size *
3432                                         sizeof(struct process_inode_block)),
3433                                        "array of inodes to process");
3434         process_inode_count = 0;
3435
3436         pctx.errcode = ext2fs_init_dblist(fs, 0);
3437         if (pctx.errcode) {
3438                 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3439                 ctx->flags |= E2F_FLAG_ABORT;
3440                 return;
3441         }
3442
3443         /*
3444          * If the last orphan field is set, clear it, since the pass1
3445          * processing will automatically find and clear the orphans.
3446          * In the future, we may want to try using the last_orphan
3447          * linked list ourselves, but for now, we clear it so that the
3448          * ext3 mount code won't get confused.
3449          */
3450         if (!(ctx->options & E2F_OPT_READONLY)) {
3451                 if (fs->super->s_last_orphan) {
3452                         fs->super->s_last_orphan = 0;
3453                         ext2fs_mark_super_dirty(fs);
3454                 }
3455         }
3456
3457         mark_table_blocks(ctx);
3458         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3459                                                     "block interate buffer");
3460         e2fsck_use_inode_shortcuts(ctx, 1);
3461         ehandler_operation(_("doing inode scan"));
3462         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3463                                               &scan);
3464         if (pctx.errcode) {
3465                 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3466                 ctx->flags |= E2F_FLAG_ABORT;
3467                 return;
3468         }
3469         ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3470         ctx->stashed_inode = inode;
3471         scan_struct.ctx = ctx;
3472         scan_struct.block_buf = block_buf;
3473         ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3474         if (ctx->progress)
3475                 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3476                         return;
3477         if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3478             (fs->super->s_mtime < fs->super->s_inodes_count))
3479                 busted_fs_time = 1;
3480
3481         while (1) {
3482                 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3483                                                           inode, inode_size);
3484                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3485                         return;
3486                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3487                         if (!ctx->inode_bb_map)
3488                                 alloc_bb_map(ctx);
3489                         ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
3490                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3491                         continue;
3492                 }
3493                 if (pctx.errcode) {
3494                         fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3495                         ctx->flags |= E2F_FLAG_ABORT;
3496                         return;
3497                 }
3498                 if (!ino)
3499                         break;
3500                 pctx.ino = ino;
3501                 pctx.inode = inode;
3502                 ctx->stashed_ino = ino;
3503                 if (inode->i_links_count) {
3504                         pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3505                                            ino, inode->i_links_count);
3506                         if (pctx.errcode) {
3507                                 pctx.num = inode->i_links_count;
3508                                 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3509                                 ctx->flags |= E2F_FLAG_ABORT;
3510                                 return;
3511                         }
3512                 }
3513                 if (ino == EXT2_BAD_INO) {
3514                         struct process_block_struct_1 pb;
3515
3516                         pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3517                                                           &pb.fs_meta_blocks);
3518                         if (pctx.errcode) {
3519                                 pctx.num = 4;
3520                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3521                                 ctx->flags |= E2F_FLAG_ABORT;
3522                                 return;
3523                         }
3524                         pb.ino = EXT2_BAD_INO;
3525                         pb.num_blocks = pb.last_block = 0;
3526                         pb.num_illegal_blocks = 0;
3527                         pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3528                         pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3529                         pb.inode = inode;
3530                         pb.pctx = &pctx;
3531                         pb.ctx = ctx;
3532                         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3533                                      block_buf, process_bad_block, &pb);
3534                         ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3535                         if (pctx.errcode) {
3536                                 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3537                                 ctx->flags |= E2F_FLAG_ABORT;
3538                                 return;
3539                         }
3540                         if (pb.bbcheck)
3541                                 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3542                                 ctx->flags |= E2F_FLAG_ABORT;
3543                                 return;
3544                         }
3545                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3546                         clear_problem_context(&pctx);
3547                         continue;
3548                 } else if (ino == EXT2_ROOT_INO) {
3549                         /*
3550                          * Make sure the root inode is a directory; if
3551                          * not, offer to clear it.  It will be
3552                          * regnerated in pass #3.
3553                          */
3554                         if (!LINUX_S_ISDIR(inode->i_mode)) {
3555                                 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3556                                         inode->i_dtime = time(0);
3557                                         inode->i_links_count = 0;
3558                                         ext2fs_icount_store(ctx->inode_link_info,
3559                                                             ino, 0);
3560                                         e2fsck_write_inode(ctx, ino, inode,
3561                                                            "pass1");
3562                                 }
3563
3564                         }
3565                         /*
3566                          * If dtime is set, offer to clear it.  mke2fs
3567                          * version 0.2b created filesystems with the
3568                          * dtime field set for the root and lost+found
3569                          * directories.  We won't worry about
3570                          * /lost+found, since that can be regenerated
3571                          * easily.  But we will fix the root directory
3572                          * as a special case.
3573                          */
3574                         if (inode->i_dtime && inode->i_links_count) {
3575                                 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3576                                         inode->i_dtime = 0;
3577                                         e2fsck_write_inode(ctx, ino, inode,
3578                                                            "pass1");
3579                                 }
3580                         }
3581                 } else if (ino == EXT2_JOURNAL_INO) {
3582                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3583                         if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3584                                 if (!LINUX_S_ISREG(inode->i_mode) &&
3585                                     fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3586                                                 &pctx)) {
3587                                         inode->i_mode = LINUX_S_IFREG;
3588                                         e2fsck_write_inode(ctx, ino, inode,
3589                                                            "pass1");
3590                                 }
3591                                 check_blocks(ctx, &pctx, block_buf);
3592                                 continue;
3593                         }
3594                         if ((inode->i_links_count || inode->i_blocks ||
3595                              inode->i_blocks || inode->i_block[0]) &&
3596                             fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3597                                         &pctx)) {
3598                                 memset(inode, 0, inode_size);
3599                                 ext2fs_icount_store(ctx->inode_link_info,
3600                                                     ino, 0);
3601                                 e2fsck_write_inode_full(ctx, ino, inode,
3602                                                         inode_size, "pass1");
3603                         }
3604                 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3605                         int     problem = 0;
3606
3607                         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3608                         if (ino == EXT2_BOOT_LOADER_INO) {
3609                                 if (LINUX_S_ISDIR(inode->i_mode))
3610                                         problem = PR_1_RESERVED_BAD_MODE;
3611                         } else if (ino == EXT2_RESIZE_INO) {
3612                                 if (inode->i_mode &&
3613                                     !LINUX_S_ISREG(inode->i_mode))
3614                                         problem = PR_1_RESERVED_BAD_MODE;
3615                         } else {
3616                                 if (inode->i_mode != 0)
3617                                         problem = PR_1_RESERVED_BAD_MODE;
3618                         }
3619                         if (problem) {
3620                                 if (fix_problem(ctx, problem, &pctx)) {
3621                                         inode->i_mode = 0;
3622                                         e2fsck_write_inode(ctx, ino, inode,
3623                                                            "pass1");
3624                                 }
3625                         }
3626                         check_blocks(ctx, &pctx, block_buf);
3627                         continue;
3628                 }
3629                 /*
3630                  * Check for inodes who might have been part of the
3631                  * orphaned list linked list.  They should have gotten
3632                  * dealt with by now, unless the list had somehow been
3633                  * corrupted.
3634                  *
3635                  * FIXME: In the future, inodes which are still in use
3636                  * (and which are therefore) pending truncation should
3637                  * be handled specially.  Right now we just clear the
3638                  * dtime field, and the normal e2fsck handling of
3639                  * inodes where i_size and the inode blocks are
3640                  * inconsistent is to fix i_size, instead of releasing
3641                  * the extra blocks.  This won't catch the inodes that
3642                  * was at the end of the orphan list, but it's better
3643                  * than nothing.  The right answer is that there
3644                  * shouldn't be any bugs in the orphan list handling.  :-)
3645                  */
3646                 if (inode->i_dtime && !busted_fs_time &&
3647                     inode->i_dtime < ctx->fs->super->s_inodes_count) {
3648                         if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3649                                 inode->i_dtime = inode->i_links_count ?
3650                                         0 : time(0);
3651                                 e2fsck_write_inode(ctx, ino, inode,
3652                                                    "pass1");
3653                         }
3654                 }
3655
3656                 /*
3657                  * This code assumes that deleted inodes have
3658                  * i_links_count set to 0.
3659                  */
3660                 if (!inode->i_links_count) {
3661                         if (!inode->i_dtime && inode->i_mode) {
3662                                 if (fix_problem(ctx,
3663                                             PR_1_ZERO_DTIME, &pctx)) {
3664                                         inode->i_dtime = time(0);
3665                                         e2fsck_write_inode(ctx, ino, inode,
3666                                                            "pass1");
3667                                 }
3668                         }
3669                         continue;
3670                 }
3671                 /*
3672                  * n.b.  0.3c ext2fs code didn't clear i_links_count for
3673                  * deleted files.  Oops.
3674                  *
3675                  * Since all new ext2 implementations get this right,
3676                  * we now assume that the case of non-zero
3677                  * i_links_count and non-zero dtime means that we
3678                  * should keep the file, not delete it.
3679                  *
3680                  */
3681                 if (inode->i_dtime) {
3682                         if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3683                                 inode->i_dtime = 0;
3684                                 e2fsck_write_inode(ctx, ino, inode, "pass1");
3685                         }
3686                 }
3687
3688                 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3689                 switch (fs->super->s_creator_os) {
3690                     case EXT2_OS_LINUX:
3691                         frag = inode->osd2.linux2.l_i_frag;
3692                         fsize = inode->osd2.linux2.l_i_fsize;
3693                         break;
3694                     case EXT2_OS_HURD:
3695                         frag = inode->osd2.hurd2.h_i_frag;
3696                         fsize = inode->osd2.hurd2.h_i_fsize;
3697                         break;
3698                     case EXT2_OS_MASIX:
3699                         frag = inode->osd2.masix2.m_i_frag;
3700                         fsize = inode->osd2.masix2.m_i_fsize;
3701                         break;
3702                     default:
3703                         frag = fsize = 0;
3704                 }
3705
3706                 if (inode->i_faddr || frag || fsize ||
3707                     (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3708                         mark_inode_bad(ctx, ino);
3709                 if (inode->i_flags & EXT2_IMAGIC_FL) {
3710                         if (imagic_fs) {
3711                                 if (!ctx->inode_imagic_map)
3712                                         alloc_imagic_map(ctx);
3713                                 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3714                                                          ino);
3715                         } else {
3716                                 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3717                                         inode->i_flags &= ~EXT2_IMAGIC_FL;
3718                                         e2fsck_write_inode(ctx, ino,
3719                                                            inode, "pass1");
3720                                 }
3721                         }
3722                 }
3723
3724                 check_inode_extra_space(ctx, &pctx);
3725
3726                 if (LINUX_S_ISDIR(inode->i_mode)) {
3727                         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3728                         e2fsck_add_dir_info(ctx, ino, 0);
3729                         ctx->fs_directory_count++;
3730                 } else if (LINUX_S_ISREG (inode->i_mode)) {
3731                         ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3732                         ctx->fs_regular_count++;
3733                 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3734                            e2fsck_pass1_check_device_inode(fs, inode)) {
3735                         check_immutable(ctx, &pctx);
3736                         check_size(ctx, &pctx);
3737                         ctx->fs_chardev_count++;
3738                 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3739                            e2fsck_pass1_check_device_inode(fs, inode)) {
3740                         check_immutable(ctx, &pctx);
3741                         check_size(ctx, &pctx);
3742                         ctx->fs_blockdev_count++;
3743                 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3744                            e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3745                         check_immutable(ctx, &pctx);
3746                         ctx->fs_symlinks_count++;
3747                         if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3748                                 ctx->fs_fast_symlinks_count++;
3749                                 check_blocks(ctx, &pctx, block_buf);
3750                                 continue;
3751                         }
3752                 }
3753                 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3754                          e2fsck_pass1_check_device_inode(fs, inode)) {
3755                         check_immutable(ctx, &pctx);
3756                         check_size(ctx, &pctx);
3757                         ctx->fs_fifo_count++;
3758                 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3759                            e2fsck_pass1_check_device_inode(fs, inode)) {
3760                         check_immutable(ctx, &pctx);
3761                         check_size(ctx, &pctx);
3762                         ctx->fs_sockets_count++;
3763                 } else
3764                         mark_inode_bad(ctx, ino);
3765                 if (inode->i_block[EXT2_IND_BLOCK])
3766                         ctx->fs_ind_count++;
3767                 if (inode->i_block[EXT2_DIND_BLOCK])
3768                         ctx->fs_dind_count++;
3769                 if (inode->i_block[EXT2_TIND_BLOCK])
3770                         ctx->fs_tind_count++;
3771                 if (inode->i_block[EXT2_IND_BLOCK] ||
3772                     inode->i_block[EXT2_DIND_BLOCK] ||
3773                     inode->i_block[EXT2_TIND_BLOCK] ||
3774                     inode->i_file_acl) {
3775                         inodes_to_process[process_inode_count].ino = ino;
3776                         inodes_to_process[process_inode_count].inode = *inode;
3777                         process_inode_count++;
3778                 } else
3779                         check_blocks(ctx, &pctx, block_buf);
3780
3781                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3782                         return;
3783
3784                 if (process_inode_count >= ctx->process_inode_size) {
3785                         process_inodes(ctx, block_buf);
3786
3787                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3788                                 return;
3789                 }
3790         }
3791         process_inodes(ctx, block_buf);
3792         ext2fs_close_inode_scan(scan);
3793         ehandler_operation(0);
3794
3795         /*
3796          * If any extended attribute blocks' reference counts need to
3797          * be adjusted, either up (ctx->refcount_extra), or down
3798          * (ctx->refcount), then fix them.
3799          */
3800         if (ctx->refcount) {
3801                 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3802                 ea_refcount_free(ctx->refcount);
3803                 ctx->refcount = 0;
3804         }
3805         if (ctx->refcount_extra) {
3806                 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3807                                         block_buf, +1);
3808                 ea_refcount_free(ctx->refcount_extra);
3809                 ctx->refcount_extra = 0;
3810         }
3811
3812         if (ctx->invalid_bitmaps)
3813                 handle_fs_bad_blocks(ctx);
3814
3815         /* We don't need the block_ea_map any more */
3816         ext2fs_free_block_bitmap(ctx->block_ea_map);
3817         ctx->block_ea_map = 0;
3818
3819         if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3820                 ext2fs_block_bitmap save_bmap;
3821
3822                 save_bmap = fs->block_map;
3823                 fs->block_map = ctx->block_found_map;
3824                 clear_problem_context(&pctx);
3825                 pctx.errcode = ext2fs_create_resize_inode(fs);
3826                 if (pctx.errcode) {
3827                         fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3828                         /* Should never get here */
3829                         ctx->flags |= E2F_FLAG_ABORT;
3830                         return;
3831                 }
3832                 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3833                                   "recreate inode");
3834                 inode->i_mtime = time(0);
3835                 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode, 
3836                                   "recreate inode");
3837                 fs->block_map = save_bmap;
3838                 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3839         }
3840
3841         if (ctx->flags & E2F_FLAG_RESTART) {
3842                 /*
3843                  * Only the master copy of the superblock and block
3844                  * group descriptors are going to be written during a
3845                  * restart, so set the superblock to be used to be the
3846                  * master superblock.
3847                  */
3848                 ctx->use_superblock = 0;
3849                 unwind_pass1();
3850                 goto endit;
3851         }
3852
3853         if (ctx->block_dup_map) {
3854                 if (ctx->options & E2F_OPT_PREEN) {
3855                         clear_problem_context(&pctx);
3856                         fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3857                 }
3858                 e2fsck_pass1_dupblocks(ctx, block_buf);
3859         }
3860         ext2fs_free_mem(&inodes_to_process);
3861 endit:
3862         e2fsck_use_inode_shortcuts(ctx, 0);
3863
3864         ext2fs_free_mem(&block_buf);
3865         ext2fs_free_mem(&inode);
3866
3867 }
3868
3869 /*
3870  * When the inode_scan routines call this callback at the end of the
3871  * glock group, call process_inodes.
3872  */
3873 static errcode_t scan_callback(ext2_filsys fs,
3874                                ext2_inode_scan scan FSCK_ATTR((unused)),
3875                                dgrp_t group, void * priv_data)
3876 {
3877         struct scan_callback_struct *scan_struct;
3878         e2fsck_t ctx;
3879
3880         scan_struct = (struct scan_callback_struct *) priv_data;
3881         ctx = scan_struct->ctx;
3882
3883         process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3884
3885         if (ctx->progress)
3886                 if ((ctx->progress)(ctx, 1, group+1,
3887                                     ctx->fs->group_desc_count))
3888                         return EXT2_ET_CANCEL_REQUESTED;
3889
3890         return 0;
3891 }
3892
3893 /*
3894  * Process the inodes in the "inodes to process" list.
3895  */
3896 static void process_inodes(e2fsck_t ctx, char *block_buf)
3897 {
3898         int                     i;
3899         struct ext2_inode       *old_stashed_inode;
3900         ext2_ino_t              old_stashed_ino;
3901         const char              *old_operation;
3902         char                    buf[80];
3903         struct problem_context  pctx;
3904
3905         /* begin process_inodes */
3906         if (process_inode_count == 0)
3907                 return;
3908         old_operation = ehandler_operation(0);
3909         old_stashed_inode = ctx->stashed_inode;
3910         old_stashed_ino = ctx->stashed_ino;
3911         qsort(inodes_to_process, process_inode_count,
3912                       sizeof(struct process_inode_block), process_inode_cmp);
3913         clear_problem_context(&pctx);
3914         for (i=0; i < process_inode_count; i++) {
3915                 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3916                 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3917                 sprintf(buf, _("reading indirect blocks of inode %u"),
3918                         pctx.ino);
3919                 ehandler_operation(buf);
3920                 check_blocks(ctx, &pctx, block_buf);
3921                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3922                         break;
3923         }
3924         ctx->stashed_inode = old_stashed_inode;
3925         ctx->stashed_ino = old_stashed_ino;
3926         process_inode_count = 0;
3927         /* end process inodes */
3928
3929         ehandler_operation(old_operation);
3930 }
3931
3932 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
3933 {
3934         const struct process_inode_block *ib_a =
3935                 (const struct process_inode_block *) a;
3936         const struct process_inode_block *ib_b =
3937                 (const struct process_inode_block *) b;
3938         int     ret;
3939
3940         ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3941                ib_b->inode.i_block[EXT2_IND_BLOCK]);
3942         if (ret == 0)
3943                 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3944         return ret;
3945 }
3946
3947 /*
3948  * Mark an inode as being bad in some what
3949  */
3950 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3951 {
3952         struct          problem_context pctx;
3953
3954         if (!ctx->inode_bad_map) {
3955                 clear_problem_context(&pctx);
3956
3957                 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3958                             _("bad inode map"), &ctx->inode_bad_map);
3959                 if (pctx.errcode) {
3960                         pctx.num = 3;
3961                         fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3962                         /* Should never get here */
3963                         ctx->flags |= E2F_FLAG_ABORT;
3964                         return;
3965                 }
3966         }
3967         ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3968 }
3969
3970
3971 /*
3972  * This procedure will allocate the inode "bb" (badblock) map table
3973  */
3974 static void alloc_bb_map(e2fsck_t ctx)
3975 {
3976         struct          problem_context pctx;
3977
3978         clear_problem_context(&pctx);
3979         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3980                                               _("inode in bad block map"),
3981                                               &ctx->inode_bb_map);
3982         if (pctx.errcode) {
3983                 pctx.num = 4;
3984                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3985                 /* Should never get here */
3986                 ctx->flags |= E2F_FLAG_ABORT;
3987                 return;
3988         }
3989 }
3990
3991 /*
3992  * This procedure will allocate the inode imagic table
3993  */
3994 static void alloc_imagic_map(e2fsck_t ctx)
3995 {
3996         struct          problem_context pctx;
3997
3998         clear_problem_context(&pctx);
3999         pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
4000                                               _("imagic inode map"),
4001                                               &ctx->inode_imagic_map);
4002         if (pctx.errcode) {
4003                 pctx.num = 5;
4004                 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4005                 /* Should never get here */
4006                 ctx->flags |= E2F_FLAG_ABORT;
4007                 return;
4008         }
4009 }
4010
4011 /*
4012  * Marks a block as in use, setting the dup_map if it's been set
4013  * already.  Called by process_block and process_bad_block.
4014  *
4015  * WARNING: Assumes checks have already been done to make sure block
4016  * is valid.  This is true in both process_block and process_bad_block.
4017  */
4018 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
4019 {
4020         struct          problem_context pctx;
4021
4022         clear_problem_context(&pctx);
4023
4024         if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
4025                 if (!ctx->block_dup_map) {
4026                         pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
4027                               _("multiply claimed block map"),
4028                               &ctx->block_dup_map);
4029                         if (pctx.errcode) {
4030                                 pctx.num = 3;
4031                                 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
4032                                             &pctx);
4033                                 /* Should never get here */
4034                                 ctx->flags |= E2F_FLAG_ABORT;
4035                                 return;
4036                         }
4037                 }
4038                 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
4039         } else {
4040                 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
4041         }
4042 }
4043
4044 /*
4045  * Adjust the extended attribute block's reference counts at the end
4046  * of pass 1, either by subtracting out references for EA blocks that
4047  * are still referenced in ctx->refcount, or by adding references for
4048  * EA blocks that had extra references as accounted for in
4049  * ctx->refcount_extra.
4050  */
4051 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4052                                     char *block_buf, int adjust_sign)
4053 {
4054         struct ext2_ext_attr_header     *header;
4055         struct problem_context          pctx;
4056         ext2_filsys                     fs = ctx->fs;
4057         blk_t                           blk;
4058         __u32                           should_be;
4059         int                             count;
4060
4061         clear_problem_context(&pctx);
4062
4063         ea_refcount_intr_begin(refcount);
4064         while (1) {
4065                 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
4066                         break;
4067                 pctx.blk = blk;
4068                 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4069                 if (pctx.errcode) {
4070                         fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
4071                         return;
4072                 }
4073                 header = (struct ext2_ext_attr_header *) block_buf;
4074                 pctx.blkcount = header->h_refcount;
4075                 should_be = header->h_refcount + adjust_sign * count;
4076                 pctx.num = should_be;
4077                 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
4078                         header->h_refcount = should_be;
4079                         pctx.errcode = ext2fs_write_ext_attr(fs, blk,
4080                                                              block_buf);
4081                         if (pctx.errcode) {
4082                                 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
4083                                 continue;
4084                         }
4085                 }
4086         }
4087 }
4088
4089 /*
4090  * Handle processing the extended attribute blocks
4091  */
4092 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
4093                            char *block_buf)
4094 {
4095         ext2_filsys fs = ctx->fs;
4096         ext2_ino_t      ino = pctx->ino;
4097         struct ext2_inode *inode = pctx->inode;
4098         blk_t           blk;
4099         char *          end;
4100         struct ext2_ext_attr_header *header;
4101         struct ext2_ext_attr_entry *entry;
4102         int             count;
4103         region_t        region;
4104
4105         blk = inode->i_file_acl;
4106         if (blk == 0)
4107                 return 0;
4108
4109         /*
4110          * If the Extended attribute flag isn't set, then a non-zero
4111          * file acl means that the inode is corrupted.
4112          *
4113          * Or if the extended attribute block is an invalid block,
4114          * then the inode is also corrupted.
4115          */
4116         if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
4117             (blk < fs->super->s_first_data_block) ||
4118             (blk >= fs->super->s_blocks_count)) {
4119                 mark_inode_bad(ctx, ino);
4120                 return 0;
4121         }
4122
4123         /* If ea bitmap hasn't been allocated, create it */
4124         if (!ctx->block_ea_map) {
4125                 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
4126                                                       _("ext attr block map"),
4127                                                       &ctx->block_ea_map);
4128                 if (pctx->errcode) {
4129                         pctx->num = 2;
4130                         fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
4131                         ctx->flags |= E2F_FLAG_ABORT;
4132                         return 0;
4133                 }
4134         }
4135
4136         /* Create the EA refcount structure if necessary */
4137         if (!ctx->refcount) {
4138                 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
4139                 if (pctx->errcode) {
4140                         pctx->num = 1;
4141                         fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4142                         ctx->flags |= E2F_FLAG_ABORT;
4143                         return 0;
4144                 }
4145         }
4146
4147         /* Have we seen this EA block before? */
4148         if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
4149                 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
4150                         return 1;
4151                 /* Ooops, this EA was referenced more than it stated */
4152                 if (!ctx->refcount_extra) {
4153                         pctx->errcode = ea_refcount_create(0,
4154                                            &ctx->refcount_extra);
4155                         if (pctx->errcode) {
4156                                 pctx->num = 2;
4157                                 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4158                                 ctx->flags |= E2F_FLAG_ABORT;
4159                                 return 0;
4160                         }
4161                 }
4162                 ea_refcount_increment(ctx->refcount_extra, blk, 0);
4163                 return 1;
4164         }
4165
4166         /*
4167          * OK, we haven't seen this EA block yet.  So we need to
4168          * validate it
4169          */
4170         pctx->blk = blk;
4171         pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4172         if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
4173                 goto clear_extattr;
4174         header = (struct ext2_ext_attr_header *) block_buf;
4175         pctx->blk = inode->i_file_acl;
4176         if (((ctx->ext_attr_ver == 1) &&
4177              (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
4178             ((ctx->ext_attr_ver == 2) &&
4179              (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
4180                 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
4181                         goto clear_extattr;
4182         }
4183
4184         if (header->h_blocks != 1) {
4185                 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
4186                         goto clear_extattr;
4187         }
4188
4189         region = region_create(0, fs->blocksize);
4190         if (!region) {
4191                 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
4192                 ctx->flags |= E2F_FLAG_ABORT;
4193                 return 0;
4194         }
4195         if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4196                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4197                         goto clear_extattr;
4198         }
4199
4200         entry = (struct ext2_ext_attr_entry *)(header+1);
4201         end = block_buf + fs->blocksize;
4202         while ((char *)entry < end && *(__u32 *)entry) {
4203                 if (region_allocate(region, (char *)entry - (char *)header,
4204                                    EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4205                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4206                                 goto clear_extattr;
4207                 }
4208                 if ((ctx->ext_attr_ver == 1 &&
4209                      (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4210                     (ctx->ext_attr_ver == 2 &&
4211                      entry->e_name_index == 0)) {
4212                         if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4213                                 goto clear_extattr;
4214                 }
4215                 if (entry->e_value_block != 0) {
4216                         if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4217                                 goto clear_extattr;
4218                 }
4219                 if (entry->e_value_size &&
4220                     region_allocate(region, entry->e_value_offs,
4221                                     EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4222                         if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4223                                 goto clear_extattr;
4224                 }
4225                 entry = EXT2_EXT_ATTR_NEXT(entry);
4226         }
4227         if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4228                 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4229                         goto clear_extattr;
4230         }
4231         region_free(region);
4232
4233         count = header->h_refcount - 1;
4234         if (count)
4235                 ea_refcount_store(ctx->refcount, blk, count);
4236         mark_block_used(ctx, blk);
4237         ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4238
4239         return 1;
4240
4241 clear_extattr:
4242         inode->i_file_acl = 0;
4243         e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4244         return 0;
4245 }
4246
4247 /* Returns 1 if bad htree, 0 if OK */
4248 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4249                         ext2_ino_t ino FSCK_ATTR((unused)),
4250                         struct ext2_inode *inode,
4251                         char *block_buf)
4252 {
4253         struct ext2_dx_root_info        *root;
4254         ext2_filsys                     fs = ctx->fs;
4255         errcode_t                       retval;
4256         blk_t                           blk;
4257
4258         if ((!LINUX_S_ISDIR(inode->i_mode) &&
4259              fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4260             (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4261              fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4262                 return 1;
4263
4264         blk = inode->i_block[0];
4265         if (((blk == 0) ||
4266              (blk < fs->super->s_first_data_block) ||
4267              (blk >= fs->super->s_blocks_count)) &&
4268             fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4269                 return 1;
4270
4271         retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4272         if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4273                 return 1;
4274
4275         /* XXX should check that beginning matches a directory */
4276         root = (struct ext2_dx_root_info *) (block_buf + 24);
4277
4278         if ((root->reserved_zero || root->info_length < 8) &&
4279             fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4280                 return 1;
4281
4282         pctx->num = root->hash_version;
4283         if ((root->hash_version != EXT2_HASH_LEGACY) &&
4284             (root->hash_version != EXT2_HASH_HALF_MD4) &&
4285             (root->hash_version != EXT2_HASH_TEA) &&
4286             fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4287                 return 1;
4288
4289         if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4290             fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4291                 return 1;
4292
4293         pctx->num = root->indirect_levels;
4294         if ((root->indirect_levels > 1) &&
4295             fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4296                 return 1;
4297
4298         return 0;
4299 }
4300
4301 /*
4302  * This subroutine is called on each inode to account for all of the
4303  * blocks used by that inode.
4304  */
4305 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4306                          char *block_buf)
4307 {
4308         ext2_filsys fs = ctx->fs;
4309         struct process_block_struct_1 pb;
4310         ext2_ino_t      ino = pctx->ino;
4311         struct ext2_inode *inode = pctx->inode;
4312         int             bad_size = 0;
4313         int             dirty_inode = 0;
4314         __u64           size;
4315
4316         pb.ino = ino;
4317         pb.num_blocks = 0;
4318         pb.last_block = -1;
4319         pb.num_illegal_blocks = 0;
4320         pb.suppress = 0; pb.clear = 0;
4321         pb.fragmented = 0;
4322         pb.compressed = 0;
4323         pb.previous_block = 0;
4324         pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4325         pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4326         pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4327         pb.inode = inode;
4328         pb.pctx = pctx;
4329         pb.ctx = ctx;
4330         pctx->ino = ino;
4331         pctx->errcode = 0;
4332
4333         if (inode->i_flags & EXT2_COMPRBLK_FL) {
4334                 if (fs->super->s_feature_incompat &
4335                     EXT2_FEATURE_INCOMPAT_COMPRESSION)
4336                         pb.compressed = 1;
4337                 else {
4338                         if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4339                                 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4340                                 dirty_inode++;
4341                         }
4342                 }
4343         }
4344
4345         if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4346                 pb.num_blocks++;
4347
4348         if (ext2fs_inode_has_valid_blocks(inode))
4349                 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4350                                        pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4351                                        block_buf, process_block, &pb);
4352         end_problem_latch(ctx, PR_LATCH_BLOCK);
4353         end_problem_latch(ctx, PR_LATCH_TOOBIG);
4354         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4355                 goto out;
4356         if (pctx->errcode)
4357                 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4358
4359         if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4360                 ctx->fs_fragmented++;
4361
4362         if (pb.clear) {
4363                 inode->i_links_count = 0;
4364                 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4365                 inode->i_dtime = time(0);
4366                 dirty_inode++;
4367                 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4368                 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4369                 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4370                 /*
4371                  * The inode was probably partially accounted for
4372                  * before processing was aborted, so we need to
4373                  * restart the pass 1 scan.
4374                  */
4375                 ctx->flags |= E2F_FLAG_RESTART;
4376                 goto out;
4377         }
4378
4379         if (inode->i_flags & EXT2_INDEX_FL) {
4380                 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4381                         inode->i_flags &= ~EXT2_INDEX_FL;
4382                         dirty_inode++;
4383                 } else {
4384 #ifdef ENABLE_HTREE
4385                         e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4386 #endif
4387                 }
4388         }
4389         if (ctx->dirs_to_hash && pb.is_dir &&
4390             !(inode->i_flags & EXT2_INDEX_FL) &&
4391             ((inode->i_size / fs->blocksize) >= 3))
4392                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4393
4394         if (!pb.num_blocks && pb.is_dir) {
4395                 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4396                         inode->i_links_count = 0;
4397                         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4398                         inode->i_dtime = time(0);
4399                         dirty_inode++;
4400                         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4401                         ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4402                         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4403                         ctx->fs_directory_count--;
4404                         goto out;
4405                 }
4406         }
4407
4408         pb.num_blocks *= (fs->blocksize / 512);
4409
4410         if (pb.is_dir) {
4411                 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4412                 if (nblock > (pb.last_block + 1))
4413                         bad_size = 1;
4414                 else if (nblock < (pb.last_block + 1)) {
4415                         if (((pb.last_block + 1) - nblock) >
4416                             fs->super->s_prealloc_dir_blocks)
4417                                 bad_size = 2;
4418                 }
4419         } else {
4420                 size = EXT2_I_SIZE(inode);
4421                 if ((pb.last_block >= 0) &&
4422                     (size < (__u64) pb.last_block * fs->blocksize))
4423                         bad_size = 3;
4424                 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4425                         bad_size = 4;
4426         }
4427         /* i_size for symlinks is checked elsewhere */
4428         if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4429                 pctx->num = (pb.last_block+1) * fs->blocksize;
4430                 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4431                         inode->i_size = pctx->num;
4432                         if (!LINUX_S_ISDIR(inode->i_mode))
4433                                 inode->i_size_high = pctx->num >> 32;
4434                         dirty_inode++;
4435                 }
4436                 pctx->num = 0;
4437         }
4438         if (LINUX_S_ISREG(inode->i_mode) &&
4439             (inode->i_size_high || inode->i_size & 0x80000000UL))
4440                 ctx->large_files++;
4441         if (pb.num_blocks != inode->i_blocks) {
4442                 pctx->num = pb.num_blocks;
4443                 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4444                         inode->i_blocks = pb.num_blocks;
4445                         dirty_inode++;
4446                 }
4447                 pctx->num = 0;
4448         }
4449 out:
4450         if (dirty_inode)
4451                 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4452 }
4453
4454
4455 /*
4456  * This is a helper function for check_blocks().
4457  */
4458 static int process_block(ext2_filsys fs,
4459                   blk_t *block_nr,
4460                   e2_blkcnt_t blockcnt,
4461                   blk_t ref_block FSCK_ATTR((unused)),
4462                   int ref_offset FSCK_ATTR((unused)),
4463                   void *priv_data)
4464 {
4465         struct process_block_struct_1 *p;
4466         struct problem_context *pctx;
4467         blk_t   blk = *block_nr;
4468         int     ret_code = 0;
4469         int     problem = 0;
4470         e2fsck_t        ctx;
4471
4472         p = (struct process_block_struct_1 *) priv_data;
4473         pctx = p->pctx;
4474         ctx = p->ctx;
4475
4476         if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4477                 /* todo: Check that the comprblk_fl is high, that the
4478                    blkaddr pattern looks right (all non-holes up to
4479                    first EXT2FS_COMPRESSED_BLKADDR, then all
4480                    EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4481                    that the feature_incompat bit is high, and that the
4482                    inode is a regular file.  If we're doing a "full
4483                    check" (a concept introduced to e2fsck by e2compr,
4484                    meaning that we look at data blocks as well as
4485                    metadata) then call some library routine that
4486                    checks the compressed data.  I'll have to think
4487                    about this, because one particularly important
4488                    problem to be able to fix is to recalculate the
4489                    cluster size if necessary.  I think that perhaps
4490                    we'd better do most/all e2compr-specific checks
4491                    separately, after the non-e2compr checks.  If not
4492                    doing a full check, it may be useful to test that
4493                    the personality is linux; e.g. if it isn't then
4494                    perhaps this really is just an illegal block. */
4495                 return 0;
4496         }
4497
4498         if (blk == 0) {
4499                 if (p->is_dir == 0) {
4500                         /*
4501                          * Should never happen, since only directories
4502                          * get called with BLOCK_FLAG_HOLE
4503                          */
4504 #if DEBUG_E2FSCK
4505                         printf("process_block() called with blk == 0, "
4506                                "blockcnt=%d, inode %lu???\n",
4507                                blockcnt, p->ino);
4508 #endif
4509                         return 0;
4510                 }
4511                 if (blockcnt < 0)
4512                         return 0;
4513                 if (blockcnt * fs->blocksize < p->inode->i_size) {
4514                         goto mark_dir;
4515                 }
4516                 return 0;
4517         }
4518
4519         /*
4520          * Simplistic fragmentation check.  We merely require that the
4521          * file be contiguous.  (Which can never be true for really
4522          * big files that are greater than a block group.)
4523          */
4524         if (!HOLE_BLKADDR(p->previous_block)) {
4525                 if (p->previous_block+1 != blk)
4526                         p->fragmented = 1;
4527         }
4528         p->previous_block = blk;
4529
4530         if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4531                 problem = PR_1_TOOBIG_DIR;
4532         if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4533                 problem = PR_1_TOOBIG_REG;
4534         if (!p->is_dir && !p->is_reg && blockcnt > 0)
4535                 problem = PR_1_TOOBIG_SYMLINK;
4536
4537         if (blk < fs->super->s_first_data_block ||
4538             blk >= fs->super->s_blocks_count)
4539                 problem = PR_1_ILLEGAL_BLOCK_NUM;
4540
4541         if (problem) {
4542                 p->num_illegal_blocks++;
4543                 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4544                         if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4545                                 p->clear = 1;
4546                                 return BLOCK_ABORT;
4547                         }
4548                         if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4549                                 p->suppress = 1;
4550                                 set_latch_flags(PR_LATCH_BLOCK,
4551                                                 PRL_SUPPRESS, 0);
4552                         }
4553                 }
4554                 pctx->blk = blk;
4555                 pctx->blkcount = blockcnt;
4556                 if (fix_problem(ctx, problem, pctx)) {
4557                         blk = *block_nr = 0;
4558                         ret_code = BLOCK_CHANGED;
4559                         goto mark_dir;
4560                 } else
4561                         return 0;
4562         }
4563
4564         if (p->ino == EXT2_RESIZE_INO) {
4565                 /*
4566                  * The resize inode has already be sanity checked
4567                  * during pass #0 (the superblock checks).  All we
4568                  * have to do is mark the double indirect block as
4569                  * being in use; all of the other blocks are handled
4570                  * by mark_table_blocks()).
4571                  */
4572                 if (blockcnt == BLOCK_COUNT_DIND)
4573                         mark_block_used(ctx, blk);
4574         } else
4575                 mark_block_used(ctx, blk);
4576         p->num_blocks++;
4577         if (blockcnt >= 0)
4578                 p->last_block = blockcnt;
4579 mark_dir:
4580         if (p->is_dir && (blockcnt >= 0)) {
4581                 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4582                                                     blk, blockcnt);
4583                 if (pctx->errcode) {
4584                         pctx->blk = blk;
4585                         pctx->num = blockcnt;
4586                         fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4587                         /* Should never get here */
4588                         ctx->flags |= E2F_FLAG_ABORT;
4589                         return BLOCK_ABORT;
4590                 }
4591         }
4592         return ret_code;
4593 }
4594
4595 static int process_bad_block(ext2_filsys fs,
4596                       blk_t *block_nr,
4597                       e2_blkcnt_t blockcnt,
4598                       blk_t ref_block FSCK_ATTR((unused)),
4599                       int ref_offset FSCK_ATTR((unused)),
4600                       void *priv_data)
4601 {
4602         struct process_block_struct_1 *p;
4603         blk_t           blk = *block_nr;
4604         blk_t           first_block;
4605         dgrp_t          i;
4606         struct problem_context *pctx;
4607         e2fsck_t        ctx;
4608
4609         /*
4610          * Note: This function processes blocks for the bad blocks
4611          * inode, which is never compressed.  So we don't use HOLE_BLKADDR().
4612          */
4613
4614         if (!blk)
4615                 return 0;
4616
4617         p = (struct process_block_struct_1 *) priv_data;
4618         ctx = p->ctx;
4619         pctx = p->pctx;
4620
4621         pctx->ino = EXT2_BAD_INO;
4622         pctx->blk = blk;
4623         pctx->blkcount = blockcnt;
4624
4625         if ((blk < fs->super->s_first_data_block) ||
4626             (blk >= fs->super->s_blocks_count)) {
4627                 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
4628                         *block_nr = 0;
4629                         return BLOCK_CHANGED;
4630                 } else
4631                         return 0;
4632         }
4633
4634         if (blockcnt < 0) {
4635                 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
4636                         p->bbcheck = 1;
4637                         if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
4638                                 *block_nr = 0;
4639                                 return BLOCK_CHANGED;
4640                         }
4641                 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
4642                                                     blk)) {
4643                         p->bbcheck = 1;
4644                         if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
4645                                         pctx)) {
4646                                 *block_nr = 0;
4647                                 return BLOCK_CHANGED;
4648                         }
4649                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4650                                 return BLOCK_ABORT;
4651                 } else
4652                         mark_block_used(ctx, blk);
4653                 return 0;
4654         }
4655
4656         ctx->fs_badblocks_count++;
4657         /*
4658          * If the block is not used, then mark it as used and return.
4659          * If it is already marked as found, this must mean that
4660          * there's an overlap between the filesystem table blocks
4661          * (bitmaps and inode table) and the bad block list.
4662          */
4663         if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
4664                 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
4665                 return 0;
4666         }
4667         /*
4668          * Try to find the where the filesystem block was used...
4669          */
4670         first_block = fs->super->s_first_data_block;
4671
4672         for (i = 0; i < fs->group_desc_count; i++ ) {
4673                 pctx->group = i;
4674                 pctx->blk = blk;
4675                 if (!ext2fs_bg_has_super(fs, i))
4676                         goto skip_super;
4677                 if (blk == first_block) {
4678                         if (i == 0) {
4679                                 if (fix_problem(ctx,
4680                                                 PR_1_BAD_PRIMARY_SUPERBLOCK,
4681                                                 pctx)) {
4682                                         *block_nr = 0;
4683                                         return BLOCK_CHANGED;
4684                                 }
4685                                 return 0;
4686                         }
4687                         fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
4688                         return 0;
4689                 }
4690                 if ((blk > first_block) &&
4691                     (blk <= first_block + fs->desc_blocks)) {
4692                         if (i == 0) {
4693                                 pctx->blk = *block_nr;
4694                                 if (fix_problem(ctx,
4695                         PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
4696                                         *block_nr = 0;
4697                                         return BLOCK_CHANGED;
4698                                 }
4699                                 return 0;
4700                         }
4701                         fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
4702                         return 0;
4703                 }
4704         skip_super:
4705                 if (blk == fs->group_desc[i].bg_block_bitmap) {
4706                         if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
4707                                 ctx->invalid_block_bitmap_flag[i]++;
4708                                 ctx->invalid_bitmaps++;
4709                         }
4710                         return 0;
4711                 }
4712                 if (blk == fs->group_desc[i].bg_inode_bitmap) {
4713                         if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
4714                                 ctx->invalid_inode_bitmap_flag[i]++;
4715                                 ctx->invalid_bitmaps++;
4716                         }
4717                         return 0;
4718                 }
4719                 if ((blk >= fs->group_desc[i].bg_inode_table) &&
4720                     (blk < (fs->group_desc[i].bg_inode_table +
4721                             fs->inode_blocks_per_group))) {
4722                         /*
4723                          * If there are bad blocks in the inode table,
4724                          * the inode scan code will try to do
4725                          * something reasonable automatically.
4726                          */
4727                         return 0;
4728                 }
4729                 first_block += fs->super->s_blocks_per_group;
4730         }
4731         /*
4732          * If we've gotten to this point, then the only
4733          * possibility is that the bad block inode meta data
4734          * is using a bad block.
4735          */
4736         if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
4737             (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
4738             (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
4739                 p->bbcheck = 1;
4740                 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
4741                         *block_nr = 0;
4742                         return BLOCK_CHANGED;
4743                 }
4744                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4745                         return BLOCK_ABORT;
4746                 return 0;
4747         }
4748
4749         pctx->group = -1;
4750
4751         /* Warn user that the block wasn't claimed */
4752         fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
4753
4754         return 0;
4755 }
4756
4757 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
4758                             const char *name, int num, blk_t *new_block)
4759 {
4760         ext2_filsys fs = ctx->fs;
4761         blk_t           old_block = *new_block;
4762         int             i;
4763         char            *buf;
4764         struct problem_context  pctx;
4765
4766         clear_problem_context(&pctx);
4767
4768         pctx.group = group;
4769         pctx.blk = old_block;
4770         pctx.str = name;
4771
4772         pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
4773                         first_block + fs->super->s_blocks_per_group,
4774                                         num, ctx->block_found_map, new_block);
4775         if (pctx.errcode) {
4776                 pctx.num = num;
4777                 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
4778                 ext2fs_unmark_valid(fs);
4779                 return;
4780         }
4781         pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
4782         if (pctx.errcode) {
4783                 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
4784                 ext2fs_unmark_valid(fs);
4785                 return;
4786         }
4787         ext2fs_mark_super_dirty(fs);
4788         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
4789         pctx.blk2 = *new_block;
4790         fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
4791                           PR_1_RELOC_TO), &pctx);
4792         pctx.blk2 = 0;
4793         for (i = 0; i < num; i++) {
4794                 pctx.blk = i;
4795                 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
4796                 if (old_block) {
4797                         pctx.errcode = io_channel_read_blk(fs->io,
4798                                    old_block + i, 1, buf);
4799                         if (pctx.errcode)
4800                                 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
4801                 } else
4802                         memset(buf, 0, fs->blocksize);
4803
4804                 pctx.blk = (*new_block) + i;
4805                 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
4806                                               1, buf);
4807                 if (pctx.errcode)
4808                         fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
4809         }
4810         ext2fs_free_mem(&buf);
4811 }
4812
4813 /*
4814  * This routine gets called at the end of pass 1 if bad blocks are
4815  * detected in the superblock, group descriptors, inode_bitmaps, or
4816  * block bitmaps.  At this point, all of the blocks have been mapped
4817  * out, so we can try to allocate new block(s) to replace the bad
4818  * blocks.
4819  */
4820 static void handle_fs_bad_blocks(e2fsck_t ctx)
4821 {
4822         ext2_filsys fs = ctx->fs;
4823         dgrp_t          i;
4824         int             first_block = fs->super->s_first_data_block;
4825
4826         for (i = 0; i < fs->group_desc_count; i++) {
4827                 if (ctx->invalid_block_bitmap_flag[i]) {
4828                         new_table_block(ctx, first_block, i, _("block bitmap"),
4829                                         1, &fs->group_desc[i].bg_block_bitmap);
4830                 }
4831                 if (ctx->invalid_inode_bitmap_flag[i]) {
4832                         new_table_block(ctx, first_block, i, _("inode bitmap"),
4833                                         1, &fs->group_desc[i].bg_inode_bitmap);
4834                 }
4835                 if (ctx->invalid_inode_table_flag[i]) {
4836                         new_table_block(ctx, first_block, i, _("inode table"),
4837                                         fs->inode_blocks_per_group,
4838                                         &fs->group_desc[i].bg_inode_table);
4839                         ctx->flags |= E2F_FLAG_RESTART;
4840                 }
4841                 first_block += fs->super->s_blocks_per_group;
4842         }
4843         ctx->invalid_bitmaps = 0;
4844 }
4845
4846 /*
4847  * This routine marks all blocks which are used by the superblock,
4848  * group descriptors, inode bitmaps, and block bitmaps.
4849  */
4850 static void mark_table_blocks(e2fsck_t ctx)
4851 {
4852         ext2_filsys fs = ctx->fs;
4853         blk_t   block, b;
4854         dgrp_t  i;
4855         int     j;
4856         struct problem_context pctx;
4857
4858         clear_problem_context(&pctx);
4859
4860         block = fs->super->s_first_data_block;
4861         for (i = 0; i < fs->group_desc_count; i++) {
4862                 pctx.group = i;
4863
4864                 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4865
4866                 /*
4867                  * Mark the blocks used for the inode table
4868                  */
4869                 if (fs->group_desc[i].bg_inode_table) {
4870                         for (j = 0, b = fs->group_desc[i].bg_inode_table;
4871                              j < fs->inode_blocks_per_group;
4872                              j++, b++) {
4873                                 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4874                                                              b)) {
4875                                         pctx.blk = b;
4876                                         if (fix_problem(ctx,
4877                                                 PR_1_ITABLE_CONFLICT, &pctx)) {
4878                                                 ctx->invalid_inode_table_flag[i]++;
4879                                                 ctx->invalid_bitmaps++;
4880                                         }
4881                                 } else {
4882                                     ext2fs_mark_block_bitmap(ctx->block_found_map,
4883                                                              b);
4884                                 }
4885                         }
4886                 }
4887
4888                 /*
4889                  * Mark block used for the block bitmap
4890                  */
4891                 if (fs->group_desc[i].bg_block_bitmap) {
4892                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
4893                                      fs->group_desc[i].bg_block_bitmap)) {
4894                                 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4895                                 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4896                                         ctx->invalid_block_bitmap_flag[i]++;
4897                                         ctx->invalid_bitmaps++;
4898                                 }
4899                         } else {
4900                             ext2fs_mark_block_bitmap(ctx->block_found_map,
4901                                      fs->group_desc[i].bg_block_bitmap);
4902                     }
4903
4904                 }
4905                 /*
4906                  * Mark block used for the inode bitmap
4907                  */
4908                 if (fs->group_desc[i].bg_inode_bitmap) {
4909                         if (ext2fs_test_block_bitmap(ctx->block_found_map,
4910                                      fs->group_desc[i].bg_inode_bitmap)) {
4911                                 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4912                                 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4913                                         ctx->invalid_inode_bitmap_flag[i]++;
4914                                         ctx->invalid_bitmaps++;
4915                                 }
4916                         } else {
4917                             ext2fs_mark_block_bitmap(ctx->block_found_map,
4918                                      fs->group_desc[i].bg_inode_bitmap);
4919                         }
4920                 }
4921                 block += fs->super->s_blocks_per_group;
4922         }
4923 }
4924
4925 /*
4926  * Thes subroutines short circuits ext2fs_get_blocks and
4927  * ext2fs_check_directory; we use them since we already have the inode
4928  * structure, so there's no point in letting the ext2fs library read
4929  * the inode again.
4930  */
4931 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4932                                   blk_t *blocks)
4933 {
4934         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4935         int     i;
4936
4937         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4938                 return EXT2_ET_CALLBACK_NOTHANDLED;
4939
4940         for (i=0; i < EXT2_N_BLOCKS; i++)
4941                 blocks[i] = ctx->stashed_inode->i_block[i];
4942         return 0;
4943 }
4944
4945 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4946                                   struct ext2_inode *inode)
4947 {
4948         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4949
4950         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4951                 return EXT2_ET_CALLBACK_NOTHANDLED;
4952         *inode = *ctx->stashed_inode;
4953         return 0;
4954 }
4955
4956 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4957                             struct ext2_inode *inode)
4958 {
4959         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4960
4961         if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4962                 *ctx->stashed_inode = *inode;
4963         return EXT2_ET_CALLBACK_NOTHANDLED;
4964 }
4965
4966 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4967 {
4968         e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4969
4970         if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4971                 return EXT2_ET_CALLBACK_NOTHANDLED;
4972
4973         if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4974                 return EXT2_ET_NO_DIRECTORY;
4975         return 0;
4976 }
4977
4978 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4979 {
4980         ext2_filsys fs = ctx->fs;
4981
4982         if (bool) {
4983                 fs->get_blocks = pass1_get_blocks;
4984                 fs->check_directory = pass1_check_directory;
4985                 fs->read_inode = pass1_read_inode;
4986                 fs->write_inode = pass1_write_inode;
4987                 ctx->stashed_ino = 0;
4988         } else {
4989                 fs->get_blocks = 0;
4990                 fs->check_directory = 0;
4991                 fs->read_inode = 0;
4992                 fs->write_inode = 0;
4993         }
4994 }
4995
4996 /*
4997  * pass1b.c --- Pass #1b of e2fsck
4998  *
4999  * This file contains pass1B, pass1C, and pass1D of e2fsck.  They are
5000  * only invoked if pass 1 discovered blocks which are in use by more
5001  * than one inode.
5002  *
5003  * Pass1B scans the data blocks of all the inodes again, generating a
5004  * complete list of duplicate blocks and which inodes have claimed
5005  * them.
5006  *
5007  * Pass1C does a tree-traversal of the filesystem, to determine the
5008  * parent directories of these inodes.  This step is necessary so that
5009  * e2fsck can print out the pathnames of affected inodes.
5010  *
5011  * Pass1D is a reconciliation pass.  For each inode with duplicate
5012  * blocks, the user is prompted if s/he would like to clone the file
5013  * (so that the file gets a fresh copy of the duplicated blocks) or
5014  * simply to delete the file.
5015  *
5016  */
5017
5018
5019 /* Needed for architectures where sizeof(int) != sizeof(void *) */
5020 #define INT_TO_VOIDPTR(val)  ((void *)(intptr_t)(val))
5021 #define VOIDPTR_TO_INT(ptr)  ((int)(intptr_t)(ptr))
5022
5023 /* Define an extension to the ext2 library's block count information */
5024 #define BLOCK_COUNT_EXTATTR     (-5)
5025
5026 struct block_el {
5027         blk_t   block;
5028         struct block_el *next;
5029 };
5030
5031 struct inode_el {
5032         ext2_ino_t      inode;
5033         struct inode_el *next;
5034 };
5035
5036 struct dup_block {
5037         int             num_bad;
5038         struct inode_el *inode_list;
5039 };
5040
5041 /*
5042  * This structure stores information about a particular inode which
5043  * is sharing blocks with other inodes.  This information is collected
5044  * to display to the user, so that the user knows what files he or she
5045  * is dealing with, when trying to decide how to resolve the conflict
5046  * of multiply-claimed blocks.
5047  */
5048 struct dup_inode {
5049         ext2_ino_t              dir;
5050         int                     num_dupblocks;
5051         struct ext2_inode       inode;
5052         struct block_el         *block_list;
5053 };
5054
5055 static int process_pass1b_block(ext2_filsys fs, blk_t   *blocknr,
5056                                 e2_blkcnt_t blockcnt, blk_t ref_blk,
5057                                 int ref_offset, void *priv_data);
5058 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5059                         struct dup_inode *dp, char *block_buf);
5060 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5061                       struct dup_inode *dp, char* block_buf);
5062 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
5063
5064 static void pass1b(e2fsck_t ctx, char *block_buf);
5065 static void pass1c(e2fsck_t ctx, char *block_buf);
5066 static void pass1d(e2fsck_t ctx, char *block_buf);
5067
5068 static int dup_inode_count = 0;
5069
5070 static dict_t blk_dict, ino_dict;
5071
5072 static ext2fs_inode_bitmap inode_dup_map;
5073
5074 static int dict_int_cmp(const void *a, const void *b)
5075 {
5076         intptr_t        ia, ib;
5077
5078         ia = (intptr_t)a;
5079         ib = (intptr_t)b;
5080
5081         return (ia-ib);
5082 }
5083
5084 /*
5085  * Add a duplicate block record
5086  */
5087 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
5088                      struct ext2_inode *inode)
5089 {
5090         dnode_t *n;
5091         struct dup_block        *db;
5092         struct dup_inode        *di;
5093         struct block_el         *blk_el;
5094         struct inode_el         *ino_el;
5095
5096         n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5097         if (n)
5098                 db = (struct dup_block *) dnode_get(n);
5099         else {
5100                 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
5101                          sizeof(struct dup_block), "duplicate block header");
5102                 db->num_bad = 0;
5103                 db->inode_list = 0;
5104                 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
5105         }
5106         ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
5107                          sizeof(struct inode_el), "inode element");
5108         ino_el->inode = ino;
5109         ino_el->next = db->inode_list;
5110         db->inode_list = ino_el;
5111         db->num_bad++;
5112
5113         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
5114         if (n)
5115                 di = (struct dup_inode *) dnode_get(n);
5116         else {
5117                 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
5118                          sizeof(struct dup_inode), "duplicate inode header");
5119                 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
5120                 di->num_dupblocks = 0;
5121                 di->block_list = 0;
5122                 di->inode = *inode;
5123                 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
5124         }
5125         blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
5126                          sizeof(struct block_el), "block element");
5127         blk_el->block = blk;
5128         blk_el->next = di->block_list;
5129         di->block_list = blk_el;
5130         di->num_dupblocks++;
5131 }
5132
5133 /*
5134  * Free a duplicate inode record
5135  */
5136 static void inode_dnode_free(dnode_t *node)
5137 {
5138         struct dup_inode        *di;
5139         struct block_el         *p, *next;
5140
5141         di = (struct dup_inode *) dnode_get(node);
5142         for (p = di->block_list; p; p = next) {
5143                 next = p->next;
5144                 free(p);
5145         }
5146         free(node);
5147 }
5148
5149 /*
5150  * Free a duplicate block record
5151  */
5152 static void block_dnode_free(dnode_t *node)
5153 {
5154         struct dup_block        *db;
5155         struct inode_el         *p, *next;
5156
5157         db = (struct dup_block *) dnode_get(node);
5158         for (p = db->inode_list; p; p = next) {
5159                 next = p->next;
5160                 free(p);
5161         }
5162         free(node);
5163 }
5164
5165
5166 /*
5167  * Main procedure for handling duplicate blocks
5168  */
5169 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
5170 {
5171         ext2_filsys             fs = ctx->fs;
5172         struct problem_context  pctx;
5173
5174         clear_problem_context(&pctx);
5175
5176         pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
5177                       _("multiply claimed inode map"), &inode_dup_map);
5178         if (pctx.errcode) {
5179                 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
5180                 ctx->flags |= E2F_FLAG_ABORT;
5181                 return;
5182         }
5183
5184         dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
5185         dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
5186         dict_set_allocator(&ino_dict, inode_dnode_free);
5187         dict_set_allocator(&blk_dict, block_dnode_free);
5188
5189         pass1b(ctx, block_buf);
5190         pass1c(ctx, block_buf);
5191         pass1d(ctx, block_buf);
5192
5193         /*
5194          * Time to free all of the accumulated data structures that we
5195          * don't need anymore.
5196          */
5197         dict_free_nodes(&ino_dict);
5198         dict_free_nodes(&blk_dict);
5199 }
5200
5201 /*
5202  * Scan the inodes looking for inodes that contain duplicate blocks.
5203  */
5204 struct process_block_struct_1b {
5205         e2fsck_t        ctx;
5206         ext2_ino_t      ino;
5207         int             dup_blocks;
5208         struct ext2_inode *inode;
5209         struct problem_context *pctx;
5210 };
5211
5212 static void pass1b(e2fsck_t ctx, char *block_buf)
5213 {
5214         ext2_filsys fs = ctx->fs;
5215         ext2_ino_t ino;
5216         struct ext2_inode inode;
5217         ext2_inode_scan scan;
5218         struct process_block_struct_1b pb;
5219         struct problem_context pctx;
5220
5221         clear_problem_context(&pctx);
5222
5223         if (!(ctx->options & E2F_OPT_PREEN))
5224                 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
5225         pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
5226                                               &scan);
5227         if (pctx.errcode) {
5228                 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
5229                 ctx->flags |= E2F_FLAG_ABORT;
5230                 return;
5231         }
5232         ctx->stashed_inode = &inode;
5233         pb.ctx = ctx;
5234         pb.pctx = &pctx;
5235         pctx.str = "pass1b";
5236         while (1) {
5237                 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
5238                 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
5239                         continue;
5240                 if (pctx.errcode) {
5241                         fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
5242                         ctx->flags |= E2F_FLAG_ABORT;
5243                         return;
5244                 }
5245                 if (!ino)
5246                         break;
5247                 pctx.ino = ctx->stashed_ino = ino;
5248                 if ((ino != EXT2_BAD_INO) &&
5249                     !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
5250                         continue;
5251
5252                 pb.ino = ino;
5253                 pb.dup_blocks = 0;
5254                 pb.inode = &inode;
5255
5256                 if (ext2fs_inode_has_valid_blocks(&inode) ||
5257                     (ino == EXT2_BAD_INO))
5258                         pctx.errcode = ext2fs_block_iterate2(fs, ino,
5259                                      0, block_buf, process_pass1b_block, &pb);
5260                 if (inode.i_file_acl)
5261                         process_pass1b_block(fs, &inode.i_file_acl,
5262                                              BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5263                 if (pb.dup_blocks) {
5264                         end_problem_latch(ctx, PR_LATCH_DBLOCK);
5265                         if (ino >= EXT2_FIRST_INODE(fs->super) ||
5266                             ino == EXT2_ROOT_INO)
5267                                 dup_inode_count++;
5268                 }
5269                 if (pctx.errcode)
5270                         fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5271         }
5272         ext2fs_close_inode_scan(scan);
5273         e2fsck_use_inode_shortcuts(ctx, 0);
5274 }
5275
5276 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
5277                                 blk_t   *block_nr,
5278                                 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5279                                 blk_t ref_blk FSCK_ATTR((unused)),
5280                                 int ref_offset FSCK_ATTR((unused)),
5281                                 void *priv_data)
5282 {
5283         struct process_block_struct_1b *p;
5284         e2fsck_t ctx;
5285
5286         if (HOLE_BLKADDR(*block_nr))
5287                 return 0;
5288         p = (struct process_block_struct_1b *) priv_data;
5289         ctx = p->ctx;
5290
5291         if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
5292                 return 0;
5293
5294         /* OK, this is a duplicate block */
5295         if (p->ino != EXT2_BAD_INO) {
5296                 p->pctx->blk = *block_nr;
5297                 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
5298         }
5299         p->dup_blocks++;
5300         ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
5301
5302         add_dupe(ctx, p->ino, *block_nr, p->inode);
5303
5304         return 0;
5305 }
5306
5307 /*
5308  * Pass 1c: Scan directories for inodes with duplicate blocks.  This
5309  * is used so that we can print pathnames when prompting the user for
5310  * what to do.
5311  */
5312 struct search_dir_struct {
5313         int             count;
5314         ext2_ino_t      first_inode;
5315         ext2_ino_t      max_inode;
5316 };
5317
5318 static int search_dirent_proc(ext2_ino_t dir, int entry,
5319                               struct ext2_dir_entry *dirent,
5320                               int offset FSCK_ATTR((unused)),
5321                               int blocksize FSCK_ATTR((unused)),
5322                               char *buf FSCK_ATTR((unused)),
5323                               void *priv_data)
5324 {
5325         struct search_dir_struct *sd;
5326         struct dup_inode        *p;
5327         dnode_t                 *n;
5328
5329         sd = (struct search_dir_struct *) priv_data;
5330
5331         if (dirent->inode > sd->max_inode)
5332                 /* Should abort this inode, but not everything */
5333                 return 0;
5334
5335         if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
5336             !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
5337                 return 0;
5338
5339         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
5340         if (!n)
5341                 return 0;
5342         p = (struct dup_inode *) dnode_get(n);
5343         p->dir = dir;
5344         sd->count--;
5345
5346         return(sd->count ? 0 : DIRENT_ABORT);
5347 }
5348
5349
5350 static void pass1c(e2fsck_t ctx, char *block_buf)
5351 {
5352         ext2_filsys fs = ctx->fs;
5353         struct search_dir_struct sd;
5354         struct problem_context pctx;
5355
5356         clear_problem_context(&pctx);
5357
5358         if (!(ctx->options & E2F_OPT_PREEN))
5359                 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
5360
5361         /*
5362          * Search through all directories to translate inodes to names
5363          * (by searching for the containing directory for that inode.)
5364          */
5365         sd.count = dup_inode_count;
5366         sd.first_inode = EXT2_FIRST_INODE(fs->super);
5367         sd.max_inode = fs->super->s_inodes_count;
5368         ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
5369                                   search_dirent_proc, &sd);
5370 }
5371
5372 static void pass1d(e2fsck_t ctx, char *block_buf)
5373 {
5374         ext2_filsys fs = ctx->fs;
5375         struct dup_inode        *p, *t;
5376         struct dup_block        *q;
5377         ext2_ino_t              *shared, ino;
5378         int     shared_len;
5379         int     i;
5380         int     file_ok;
5381         int     meta_data = 0;
5382         struct problem_context pctx;
5383         dnode_t *n, *m;
5384         struct block_el *s;
5385         struct inode_el *r;
5386
5387         clear_problem_context(&pctx);
5388
5389         if (!(ctx->options & E2F_OPT_PREEN))
5390                 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
5391         e2fsck_read_bitmaps(ctx);
5392
5393         pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
5394         fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
5395         shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
5396                                 sizeof(ext2_ino_t) * dict_count(&ino_dict),
5397                                 "Shared inode list");
5398         for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
5399                 p = (struct dup_inode *) dnode_get(n);
5400                 shared_len = 0;
5401                 file_ok = 1;
5402                 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
5403                 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
5404                         continue;
5405
5406                 /*
5407                  * Find all of the inodes which share blocks with this
5408                  * one.  First we find all of the duplicate blocks
5409                  * belonging to this inode, and then search each block
5410                  * get the list of inodes, and merge them together.
5411                  */
5412                 for (s = p->block_list; s; s = s->next) {
5413                         m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5414                         if (!m)
5415                                 continue; /* Should never happen... */
5416                         q = (struct dup_block *) dnode_get(m);
5417                         if (q->num_bad > 1)
5418                                 file_ok = 0;
5419                         if (check_if_fs_block(ctx, s->block)) {
5420                                 file_ok = 0;
5421                                 meta_data = 1;
5422                         }
5423
5424                         /*
5425                          * Add all inodes used by this block to the
5426                          * shared[] --- which is a unique list, so
5427                          * if an inode is already in shared[], don't
5428                          * add it again.
5429                          */
5430                         for (r = q->inode_list; r; r = r->next) {
5431                                 if (r->inode == ino)
5432                                         continue;
5433                                 for (i = 0; i < shared_len; i++)
5434                                         if (shared[i] == r->inode)
5435                                                 break;
5436                                 if (i == shared_len) {
5437                                         shared[shared_len++] = r->inode;
5438                                 }
5439                         }
5440                 }
5441
5442                 /*
5443                  * Report the inode that we are working on
5444                  */
5445                 pctx.inode = &p->inode;
5446                 pctx.ino = ino;
5447                 pctx.dir = p->dir;
5448                 pctx.blkcount = p->num_dupblocks;
5449                 pctx.num = meta_data ? shared_len+1 : shared_len;
5450                 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5451                 pctx.blkcount = 0;
5452                 pctx.num = 0;
5453
5454                 if (meta_data)
5455                         fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5456
5457                 for (i = 0; i < shared_len; i++) {
5458                         m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5459                         if (!m)
5460                                 continue; /* should never happen */
5461                         t = (struct dup_inode *) dnode_get(m);
5462                         /*
5463                          * Report the inode that we are sharing with
5464                          */
5465                         pctx.inode = &t->inode;
5466                         pctx.ino = shared[i];
5467                         pctx.dir = t->dir;
5468                         fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5469                 }
5470                 if (file_ok) {
5471                         fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5472                         continue;
5473                 }
5474                 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5475                         pctx.errcode = clone_file(ctx, ino, p, block_buf);
5476                         if (pctx.errcode)
5477                                 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5478                         else
5479                                 continue;
5480                 }
5481                 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5482                         delete_file(ctx, ino, p, block_buf);
5483                 else
5484                         ext2fs_unmark_valid(fs);
5485         }
5486         ext2fs_free_mem(&shared);
5487 }
5488
5489 /*
5490  * Drop the refcount on the dup_block structure, and clear the entry
5491  * in the block_dup_map if appropriate.
5492  */
5493 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5494 {
5495         p->num_bad--;
5496         if (p->num_bad <= 0 ||
5497             (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5498                 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5499 }
5500
5501 static int delete_file_block(ext2_filsys fs,
5502                              blk_t      *block_nr,
5503                              e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5504                              blk_t ref_block FSCK_ATTR((unused)),
5505                              int ref_offset FSCK_ATTR((unused)),
5506                              void *priv_data)
5507 {
5508         struct process_block_struct_1b *pb;
5509         struct dup_block *p;
5510         dnode_t *n;
5511         e2fsck_t ctx;
5512
5513         pb = (struct process_block_struct_1b *) priv_data;
5514         ctx = pb->ctx;
5515
5516         if (HOLE_BLKADDR(*block_nr))
5517                 return 0;
5518
5519         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5520                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5521                 if (n) {
5522                         p = (struct dup_block *) dnode_get(n);
5523                         decrement_badcount(ctx, *block_nr, p);
5524                 } else
5525                         com_err("delete_file_block", 0,
5526                             _("internal error; can't find dup_blk for %d\n"),
5527                                 *block_nr);
5528         } else {
5529                 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5530                 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5531         }
5532
5533         return 0;
5534 }
5535
5536 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5537                         struct dup_inode *dp, char* block_buf)
5538 {
5539         ext2_filsys fs = ctx->fs;
5540         struct process_block_struct_1b pb;
5541         struct ext2_inode       inode;
5542         struct problem_context  pctx;
5543         unsigned int            count;
5544
5545         clear_problem_context(&pctx);
5546         pctx.ino = pb.ino = ino;
5547         pb.dup_blocks = dp->num_dupblocks;
5548         pb.ctx = ctx;
5549         pctx.str = "delete_file";
5550
5551         e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5552         if (ext2fs_inode_has_valid_blocks(&inode))
5553                 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5554                                                      delete_file_block, &pb);
5555         if (pctx.errcode)
5556                 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5557         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5558         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5559         if (ctx->inode_bad_map)
5560                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5561         ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5562
5563         /* Inode may have changed by block_iterate, so reread it */
5564         e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5565         inode.i_links_count = 0;
5566         inode.i_dtime = time(0);
5567         if (inode.i_file_acl &&
5568             (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5569                 count = 1;
5570                 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5571                                                    block_buf, -1, &count);
5572                 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5573                         pctx.errcode = 0;
5574                         count = 1;
5575                 }
5576                 if (pctx.errcode) {
5577                         pctx.blk = inode.i_file_acl;
5578                         fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5579                 }
5580                 /*
5581                  * If the count is zero, then arrange to have the
5582                  * block deleted.  If the block is in the block_dup_map,
5583                  * also call delete_file_block since it will take care
5584                  * of keeping the accounting straight.
5585                  */
5586                 if ((count == 0) ||
5587                     ext2fs_test_block_bitmap(ctx->block_dup_map,
5588                                              inode.i_file_acl))
5589                         delete_file_block(fs, &inode.i_file_acl,
5590                                           BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5591         }
5592         e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5593 }
5594
5595 struct clone_struct {
5596         errcode_t       errcode;
5597         ext2_ino_t      dir;
5598         char    *buf;
5599         e2fsck_t ctx;
5600 };
5601
5602 static int clone_file_block(ext2_filsys fs,
5603                             blk_t       *block_nr,
5604                             e2_blkcnt_t blockcnt,
5605                             blk_t ref_block FSCK_ATTR((unused)),
5606                             int ref_offset FSCK_ATTR((unused)),
5607                             void *priv_data)
5608 {
5609         struct dup_block *p;
5610         blk_t   new_block;
5611         errcode_t       retval;
5612         struct clone_struct *cs = (struct clone_struct *) priv_data;
5613         dnode_t *n;
5614         e2fsck_t ctx;
5615
5616         ctx = cs->ctx;
5617
5618         if (HOLE_BLKADDR(*block_nr))
5619                 return 0;
5620
5621         if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5622                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5623                 if (n) {
5624                         p = (struct dup_block *) dnode_get(n);
5625                         retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5626                                                   &new_block);
5627                         if (retval) {
5628                                 cs->errcode = retval;
5629                                 return BLOCK_ABORT;
5630                         }
5631                         if (cs->dir && (blockcnt >= 0)) {
5632                                 retval = ext2fs_set_dir_block(fs->dblist,
5633                                       cs->dir, new_block, blockcnt);
5634                                 if (retval) {
5635                                         cs->errcode = retval;
5636                                         return BLOCK_ABORT;
5637                                 }
5638                         }
5639
5640                         retval = io_channel_read_blk(fs->io, *block_nr, 1,
5641                                                      cs->buf);
5642                         if (retval) {
5643                                 cs->errcode = retval;
5644                                 return BLOCK_ABORT;
5645                         }
5646                         retval = io_channel_write_blk(fs->io, new_block, 1,
5647                                                       cs->buf);
5648                         if (retval) {
5649                                 cs->errcode = retval;
5650                                 return BLOCK_ABORT;
5651                         }
5652                         decrement_badcount(ctx, *block_nr, p);
5653                         *block_nr = new_block;
5654                         ext2fs_mark_block_bitmap(ctx->block_found_map,
5655                                                  new_block);
5656                         ext2fs_mark_block_bitmap(fs->block_map, new_block);
5657                         return BLOCK_CHANGED;
5658                 } else
5659                         com_err("clone_file_block", 0,
5660                             _("internal error; can't find dup_blk for %d\n"),
5661                                 *block_nr);
5662         }
5663         return 0;
5664 }
5665
5666 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5667                       struct dup_inode *dp, char* block_buf)
5668 {
5669         ext2_filsys fs = ctx->fs;
5670         errcode_t       retval;
5671         struct clone_struct cs;
5672         struct problem_context  pctx;
5673         blk_t           blk;
5674         dnode_t         *n;
5675         struct inode_el *ino_el;
5676         struct dup_block        *db;
5677         struct dup_inode        *di;
5678
5679         clear_problem_context(&pctx);
5680         cs.errcode = 0;
5681         cs.dir = 0;
5682         cs.ctx = ctx;
5683         retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5684         if (retval)
5685                 return retval;
5686
5687         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5688                 cs.dir = ino;
5689
5690         pctx.ino = ino;
5691         pctx.str = "clone_file";
5692         if (ext2fs_inode_has_valid_blocks(&dp->inode))
5693                 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5694                                                      clone_file_block, &cs);
5695         ext2fs_mark_bb_dirty(fs);
5696         if (pctx.errcode) {
5697                 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5698                 retval = pctx.errcode;
5699                 goto errout;
5700         }
5701         if (cs.errcode) {
5702                 com_err("clone_file", cs.errcode,
5703                         _("returned from clone_file_block"));
5704                 retval = cs.errcode;
5705                 goto errout;
5706         }
5707         /* The inode may have changed on disk, so we have to re-read it */
5708         e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5709         blk = dp->inode.i_file_acl;
5710         if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5711                                      BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5712                     BLOCK_CHANGED)) {
5713                 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5714                 /*
5715                  * If we cloned the EA block, find all other inodes
5716                  * which refered to that EA block, and modify
5717                  * them to point to the new EA block.
5718                  */
5719                 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5720                 db = (struct dup_block *) dnode_get(n);
5721                 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5722                         if (ino_el->inode == ino)
5723                                 continue;
5724                         n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5725                         di = (struct dup_inode *) dnode_get(n);
5726                         if (di->inode.i_file_acl == blk) {
5727                                 di->inode.i_file_acl = dp->inode.i_file_acl;
5728                                 e2fsck_write_inode(ctx, ino_el->inode,
5729                                            &di->inode, "clone file EA");
5730                                 decrement_badcount(ctx, blk, db);
5731                         }
5732                 }
5733         }
5734         retval = 0;
5735 errout:
5736         ext2fs_free_mem(&cs.buf);
5737         return retval;
5738 }
5739
5740 /*
5741  * This routine returns 1 if a block overlaps with one of the superblocks,
5742  * group descriptors, inode bitmaps, or block bitmaps.
5743  */
5744 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5745 {
5746         ext2_filsys fs = ctx->fs;
5747         blk_t   block;
5748         dgrp_t  i;
5749
5750         block = fs->super->s_first_data_block;
5751         for (i = 0; i < fs->group_desc_count; i++) {
5752
5753                 /* Check superblocks/block group descriptros */
5754                 if (ext2fs_bg_has_super(fs, i)) {
5755                         if (test_block >= block &&
5756                             (test_block <= block + fs->desc_blocks))
5757                                 return 1;
5758                 }
5759
5760                 /* Check the inode table */
5761                 if ((fs->group_desc[i].bg_inode_table) &&
5762                     (test_block >= fs->group_desc[i].bg_inode_table) &&
5763                     (test_block < (fs->group_desc[i].bg_inode_table +
5764                                    fs->inode_blocks_per_group)))
5765                         return 1;
5766
5767                 /* Check the bitmap blocks */
5768                 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5769                     (test_block == fs->group_desc[i].bg_inode_bitmap))
5770                         return 1;
5771
5772                 block += fs->super->s_blocks_per_group;
5773         }
5774         return 0;
5775 }
5776 /*
5777  * pass2.c --- check directory structure
5778  *
5779  * Pass 2 of e2fsck iterates through all active directory inodes, and
5780  * applies to following tests to each directory entry in the directory
5781  * blocks in the inodes:
5782  *
5783  *      - The length of the directory entry (rec_len) should be at
5784  *              least 8 bytes, and no more than the remaining space
5785  *              left in the directory block.
5786  *      - The length of the name in the directory entry (name_len)
5787  *              should be less than (rec_len - 8).
5788  *      - The inode number in the directory entry should be within
5789  *              legal bounds.
5790  *      - The inode number should refer to a in-use inode.
5791  *      - The first entry should be '.', and its inode should be
5792  *              the inode of the directory.
5793  *      - The second entry should be '..'.
5794  *
5795  * To minimize disk seek time, the directory blocks are processed in
5796  * sorted order of block numbers.
5797  *
5798  * Pass 2 also collects the following information:
5799  *      - The inode numbers of the subdirectories for each directory.
5800  *
5801  * Pass 2 relies on the following information from previous passes:
5802  *      - The directory information collected in pass 1.
5803  *      - The inode_used_map bitmap
5804  *      - The inode_bad_map bitmap
5805  *      - The inode_dir_map bitmap
5806  *
5807  * Pass 2 frees the following data structures
5808  *      - The inode_bad_map bitmap
5809  *      - The inode_reg_map bitmap
5810  */
5811
5812 /*
5813  * Keeps track of how many times an inode is referenced.
5814  */
5815 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5816 static int check_dir_block(ext2_filsys fs,
5817                            struct ext2_db_entry *dir_blocks_info,
5818                            void *priv_data);
5819 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5820                               struct problem_context *pctx);
5821 static int update_dir_block(ext2_filsys fs,
5822                             blk_t       *block_nr,
5823                             e2_blkcnt_t blockcnt,
5824                             blk_t       ref_block,
5825                             int         ref_offset,
5826                             void        *priv_data);
5827 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5828 static int htree_depth(struct dx_dir_info *dx_dir,
5829                        struct dx_dirblock_info *dx_db);
5830 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
5831
5832 struct check_dir_struct {
5833         char *buf;
5834         struct problem_context  pctx;
5835         int     count, max;
5836         e2fsck_t ctx;
5837 };
5838
5839 static void e2fsck_pass2(e2fsck_t ctx)
5840 {
5841         struct ext2_super_block *sb = ctx->fs->super;
5842         struct problem_context  pctx;
5843         ext2_filsys             fs = ctx->fs;
5844         char                    *buf;
5845         struct dir_info         *dir;
5846         struct check_dir_struct cd;
5847         struct dx_dir_info      *dx_dir;
5848         struct dx_dirblock_info *dx_db, *dx_parent;
5849         int                     b;
5850         int                     i, depth;
5851         problem_t               code;
5852         int                     bad_dir;
5853
5854         clear_problem_context(&cd.pctx);
5855
5856         /* Pass 2 */
5857
5858         if (!(ctx->options & E2F_OPT_PREEN))
5859                 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5860
5861         cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5862                                                 0, ctx->inode_link_info,
5863                                                 &ctx->inode_count);
5864         if (cd.pctx.errcode) {
5865                 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5866                 ctx->flags |= E2F_FLAG_ABORT;
5867                 return;
5868         }
5869         buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5870                                               "directory scan buffer");
5871
5872         /*
5873          * Set up the parent pointer for the root directory, if
5874          * present.  (If the root directory is not present, we will
5875          * create it in pass 3.)
5876          */
5877         dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5878         if (dir)
5879                 dir->parent = EXT2_ROOT_INO;
5880
5881         cd.buf = buf;
5882         cd.ctx = ctx;
5883         cd.count = 1;
5884         cd.max = ext2fs_dblist_count(fs->dblist);
5885
5886         if (ctx->progress)
5887                 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5888
5889         if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5890                 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5891
5892         cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5893                                                 &cd);
5894         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5895                 return;
5896         if (cd.pctx.errcode) {
5897                 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5898                 ctx->flags |= E2F_FLAG_ABORT;
5899                 return;
5900         }
5901
5902 #ifdef ENABLE_HTREE
5903         for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5904                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5905                         return;
5906                 if (dx_dir->numblocks == 0)
5907                         continue;
5908                 clear_problem_context(&pctx);
5909                 bad_dir = 0;
5910                 pctx.dir = dx_dir->ino;
5911                 dx_db = dx_dir->dx_block;
5912                 if (dx_db->flags & DX_FLAG_REFERENCED)
5913                         dx_db->flags |= DX_FLAG_DUP_REF;
5914                 else
5915                         dx_db->flags |= DX_FLAG_REFERENCED;
5916                 /*
5917                  * Find all of the first and last leaf blocks, and
5918                  * update their parent's min and max hash values
5919                  */
5920                 for (b=0, dx_db = dx_dir->dx_block;
5921                      b < dx_dir->numblocks;
5922                      b++, dx_db++) {
5923                         if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5924                             !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5925                                 continue;
5926                         dx_parent = &dx_dir->dx_block[dx_db->parent];
5927                         /*
5928                          * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5929                          */
5930                         if (dx_db->flags & DX_FLAG_FIRST)
5931                                 dx_parent->min_hash = dx_db->min_hash;
5932                         /*
5933                          * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5934                          */
5935                         if (dx_db->flags & DX_FLAG_LAST)
5936                                 dx_parent->max_hash = dx_db->max_hash;
5937                 }
5938
5939                 for (b=0, dx_db = dx_dir->dx_block;
5940                      b < dx_dir->numblocks;
5941                      b++, dx_db++) {
5942                         pctx.blkcount = b;
5943                         pctx.group = dx_db->parent;
5944                         code = 0;
5945                         if (!(dx_db->flags & DX_FLAG_FIRST) &&
5946                             (dx_db->min_hash < dx_db->node_min_hash)) {
5947                                 pctx.blk = dx_db->min_hash;
5948                                 pctx.blk2 = dx_db->node_min_hash;
5949                                 code = PR_2_HTREE_MIN_HASH;
5950                                 fix_problem(ctx, code, &pctx);
5951                                 bad_dir++;
5952                         }
5953                         if (dx_db->type == DX_DIRBLOCK_LEAF) {
5954                                 depth = htree_depth(dx_dir, dx_db);
5955                                 if (depth != dx_dir->depth) {
5956                                         code = PR_2_HTREE_BAD_DEPTH;
5957                                         fix_problem(ctx, code, &pctx);
5958                                         bad_dir++;
5959                                 }
5960                         }
5961                         /*
5962                          * This test doesn't apply for the root block
5963                          * at block #0
5964                          */
5965                         if (b &&
5966                             (dx_db->max_hash > dx_db->node_max_hash)) {
5967                                 pctx.blk = dx_db->max_hash;
5968                                 pctx.blk2 = dx_db->node_max_hash;
5969                                 code = PR_2_HTREE_MAX_HASH;
5970                                 fix_problem(ctx, code, &pctx);
5971                                 bad_dir++;
5972                         }
5973                         if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5974                                 code = PR_2_HTREE_NOTREF;
5975                                 fix_problem(ctx, code, &pctx);
5976                                 bad_dir++;
5977                         } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5978                                 code = PR_2_HTREE_DUPREF;
5979                                 fix_problem(ctx, code, &pctx);
5980                                 bad_dir++;
5981                         }
5982                         if (code == 0)
5983                                 continue;
5984                 }
5985                 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5986                         clear_htree(ctx, dx_dir->ino);
5987                         dx_dir->numblocks = 0;
5988                 }
5989         }
5990 #endif
5991         ext2fs_free_mem(&buf);
5992         ext2fs_free_dblist(fs->dblist);
5993
5994         ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5995         ctx->inode_bad_map = 0;
5996         ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5997         ctx->inode_reg_map = 0;
5998
5999         clear_problem_context(&pctx);
6000         if (ctx->large_files) {
6001                 if (!(sb->s_feature_ro_compat &
6002                       EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
6003                     fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
6004                         sb->s_feature_ro_compat |=
6005                                 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
6006                         ext2fs_mark_super_dirty(fs);
6007                 }
6008                 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
6009                     fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
6010                         ext2fs_update_dynamic_rev(fs);
6011                         ext2fs_mark_super_dirty(fs);
6012                 }
6013         } else if (!ctx->large_files &&
6014             (sb->s_feature_ro_compat &
6015               EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
6016                 if (fs->flags & EXT2_FLAG_RW) {
6017                         sb->s_feature_ro_compat &=
6018                                 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
6019                         ext2fs_mark_super_dirty(fs);
6020                 }
6021         }
6022
6023 }
6024
6025 #define MAX_DEPTH 32000
6026 static int htree_depth(struct dx_dir_info *dx_dir,
6027                        struct dx_dirblock_info *dx_db)
6028 {
6029         int     depth = 0;
6030
6031         while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
6032                 dx_db = &dx_dir->dx_block[dx_db->parent];
6033                 depth++;
6034         }
6035         return depth;
6036 }
6037
6038 static int dict_de_cmp(const void *a, const void *b)
6039 {
6040         const struct ext2_dir_entry *de_a, *de_b;
6041         int     a_len, b_len;
6042
6043         de_a = (const struct ext2_dir_entry *) a;
6044         a_len = de_a->name_len & 0xFF;
6045         de_b = (const struct ext2_dir_entry *) b;
6046         b_len = de_b->name_len & 0xFF;
6047
6048         if (a_len != b_len)
6049                 return (a_len - b_len);
6050
6051         return strncmp(de_a->name, de_b->name, a_len);
6052 }
6053
6054 /*
6055  * This is special sort function that makes sure that directory blocks
6056  * with a dirblock of zero are sorted to the beginning of the list.
6057  * This guarantees that the root node of the htree directories are
6058  * processed first, so we know what hash version to use.
6059  */
6060 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b)
6061 {
6062         const struct ext2_db_entry *db_a =
6063                 (const struct ext2_db_entry *) a;
6064         const struct ext2_db_entry *db_b =
6065                 (const struct ext2_db_entry *) b;
6066
6067         if (db_a->blockcnt && !db_b->blockcnt)
6068                 return 1;
6069
6070         if (!db_a->blockcnt && db_b->blockcnt)
6071                 return -1;
6072
6073         if (db_a->blk != db_b->blk)
6074                 return (int) (db_a->blk - db_b->blk);
6075
6076         if (db_a->ino != db_b->ino)
6077                 return (int) (db_a->ino - db_b->ino);
6078
6079         return (int) (db_a->blockcnt - db_b->blockcnt);
6080 }
6081
6082
6083 /*
6084  * Make sure the first entry in the directory is '.', and that the
6085  * directory entry is sane.
6086  */
6087 static int check_dot(e2fsck_t ctx,
6088                      struct ext2_dir_entry *dirent,
6089                      ext2_ino_t ino, struct problem_context *pctx)
6090 {
6091         struct ext2_dir_entry *nextdir;
6092         int     status = 0;
6093         int     created = 0;
6094         int     new_len;
6095         int     problem = 0;
6096
6097         if (!dirent->inode)
6098                 problem = PR_2_MISSING_DOT;
6099         else if (((dirent->name_len & 0xFF) != 1) ||
6100                  (dirent->name[0] != '.'))
6101                 problem = PR_2_1ST_NOT_DOT;
6102         else if (dirent->name[1] != '\0')
6103                 problem = PR_2_DOT_NULL_TERM;
6104
6105         if (problem) {
6106                 if (fix_problem(ctx, problem, pctx)) {
6107                         if (dirent->rec_len < 12)
6108                                 dirent->rec_len = 12;
6109                         dirent->inode = ino;
6110                         dirent->name_len = 1;
6111                         dirent->name[0] = '.';
6112                         dirent->name[1] = '\0';
6113                         status = 1;
6114                         created = 1;
6115                 }
6116         }
6117         if (dirent->inode != ino) {
6118                 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
6119                         dirent->inode = ino;
6120                         status = 1;
6121                 }
6122         }
6123         if (dirent->rec_len > 12) {
6124                 new_len = dirent->rec_len - 12;
6125                 if (new_len > 12) {
6126                         if (created ||
6127                             fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
6128                                 nextdir = (struct ext2_dir_entry *)
6129                                         ((char *) dirent + 12);
6130                                 dirent->rec_len = 12;
6131                                 nextdir->rec_len = new_len;
6132                                 nextdir->inode = 0;
6133                                 nextdir->name_len = 0;
6134                                 status = 1;
6135                         }
6136                 }
6137         }
6138         return status;
6139 }
6140
6141 /*
6142  * Make sure the second entry in the directory is '..', and that the
6143  * directory entry is sane.  We do not check the inode number of '..'
6144  * here; this gets done in pass 3.
6145  */
6146 static int check_dotdot(e2fsck_t ctx,
6147                         struct ext2_dir_entry *dirent,
6148                         struct dir_info *dir, struct problem_context *pctx)
6149 {
6150         int             problem = 0;
6151
6152         if (!dirent->inode)
6153                 problem = PR_2_MISSING_DOT_DOT;
6154         else if (((dirent->name_len & 0xFF) != 2) ||
6155                  (dirent->name[0] != '.') ||
6156                  (dirent->name[1] != '.'))
6157                 problem = PR_2_2ND_NOT_DOT_DOT;
6158         else if (dirent->name[2] != '\0')
6159                 problem = PR_2_DOT_DOT_NULL_TERM;
6160
6161         if (problem) {
6162                 if (fix_problem(ctx, problem, pctx)) {
6163                         if (dirent->rec_len < 12)
6164                                 dirent->rec_len = 12;
6165                         /*
6166                          * Note: we don't have the parent inode just
6167                          * yet, so we will fill it in with the root
6168                          * inode.  This will get fixed in pass 3.
6169                          */
6170                         dirent->inode = EXT2_ROOT_INO;
6171                         dirent->name_len = 2;
6172                         dirent->name[0] = '.';
6173                         dirent->name[1] = '.';
6174                         dirent->name[2] = '\0';
6175                         return 1;
6176                 }
6177                 return 0;
6178         }
6179         dir->dotdot = dirent->inode;
6180         return 0;
6181 }
6182
6183 /*
6184  * Check to make sure a directory entry doesn't contain any illegal
6185  * characters.
6186  */
6187 static int check_name(e2fsck_t ctx,
6188                       struct ext2_dir_entry *dirent,
6189                       struct problem_context *pctx)
6190 {
6191         int     i;
6192         int     fixup = -1;
6193         int     ret = 0;
6194
6195         for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
6196                 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
6197                         if (fixup < 0) {
6198                                 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
6199                         }
6200                         if (fixup) {
6201                                 dirent->name[i] = '.';
6202                                 ret = 1;
6203                         }
6204                 }
6205         }
6206         return ret;
6207 }
6208
6209 /*
6210  * Check the directory filetype (if present)
6211  */
6212
6213 /*
6214  * Given a mode, return the ext2 file type
6215  */
6216 static int ext2_file_type(unsigned int mode)
6217 {
6218         if (LINUX_S_ISREG(mode))
6219                 return EXT2_FT_REG_FILE;
6220
6221         if (LINUX_S_ISDIR(mode))
6222                 return EXT2_FT_DIR;
6223
6224         if (LINUX_S_ISCHR(mode))
6225                 return EXT2_FT_CHRDEV;
6226
6227         if (LINUX_S_ISBLK(mode))
6228                 return EXT2_FT_BLKDEV;
6229
6230         if (LINUX_S_ISLNK(mode))
6231                 return EXT2_FT_SYMLINK;
6232
6233         if (LINUX_S_ISFIFO(mode))
6234                 return EXT2_FT_FIFO;
6235
6236         if (LINUX_S_ISSOCK(mode))
6237                 return EXT2_FT_SOCK;
6238
6239         return 0;
6240 }
6241
6242 static _INLINE_ int check_filetype(e2fsck_t ctx,
6243                                    struct ext2_dir_entry *dirent,
6244                                    struct problem_context *pctx)
6245 {
6246         int     filetype = dirent->name_len >> 8;
6247         int     should_be = EXT2_FT_UNKNOWN;
6248         struct ext2_inode       inode;
6249
6250         if (!(ctx->fs->super->s_feature_incompat &
6251               EXT2_FEATURE_INCOMPAT_FILETYPE)) {
6252                 if (filetype == 0 ||
6253                     !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
6254                         return 0;
6255                 dirent->name_len = dirent->name_len & 0xFF;
6256                 return 1;
6257         }
6258
6259         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
6260                 should_be = EXT2_FT_DIR;
6261         } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
6262                                             dirent->inode)) {
6263                 should_be = EXT2_FT_REG_FILE;
6264         } else if (ctx->inode_bad_map &&
6265                    ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6266                                             dirent->inode))
6267                 should_be = 0;
6268         else {
6269                 e2fsck_read_inode(ctx, dirent->inode, &inode,
6270                                   "check_filetype");
6271                 should_be = ext2_file_type(inode.i_mode);
6272         }
6273         if (filetype == should_be)
6274                 return 0;
6275         pctx->num = should_be;
6276
6277         if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
6278                         pctx) == 0)
6279                 return 0;
6280
6281         dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
6282         return 1;
6283 }
6284
6285 #ifdef ENABLE_HTREE
6286 static void parse_int_node(ext2_filsys fs,
6287                            struct ext2_db_entry *db,
6288                            struct check_dir_struct *cd,
6289                            struct dx_dir_info   *dx_dir,
6290                            char *block_buf)
6291 {
6292         struct          ext2_dx_root_info  *root;
6293         struct          ext2_dx_entry *ent;
6294         struct          ext2_dx_countlimit *limit;
6295         struct dx_dirblock_info *dx_db;
6296         int             i, expect_limit, count;
6297         blk_t           blk;
6298         ext2_dirhash_t  min_hash = 0xffffffff;
6299         ext2_dirhash_t  max_hash = 0;
6300         ext2_dirhash_t  hash = 0, prev_hash;
6301
6302         if (db->blockcnt == 0) {
6303                 root = (struct ext2_dx_root_info *) (block_buf + 24);
6304                 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
6305         } else {
6306                 ent = (struct ext2_dx_entry *) (block_buf+8);
6307         }
6308         limit = (struct ext2_dx_countlimit *) ent;
6309
6310         count = ext2fs_le16_to_cpu(limit->count);
6311         expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
6312                 sizeof(struct ext2_dx_entry);
6313         if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
6314                 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
6315                 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
6316                         goto clear_and_exit;
6317         }
6318         if (count > expect_limit) {
6319                 cd->pctx.num = count;
6320                 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
6321                         goto clear_and_exit;
6322                 count = expect_limit;
6323         }
6324
6325         for (i=0; i < count; i++) {
6326                 prev_hash = hash;
6327                 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
6328                 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
6329                 /* Check to make sure the block is valid */
6330                 if (blk > (blk_t) dx_dir->numblocks) {
6331                         cd->pctx.blk = blk;
6332                         if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
6333                                         &cd->pctx))
6334                                 goto clear_and_exit;
6335                 }
6336                 if (hash < prev_hash &&
6337                     fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
6338                         goto clear_and_exit;
6339                 dx_db = &dx_dir->dx_block[blk];
6340                 if (dx_db->flags & DX_FLAG_REFERENCED) {
6341                         dx_db->flags |= DX_FLAG_DUP_REF;
6342                 } else {
6343                         dx_db->flags |= DX_FLAG_REFERENCED;
6344                         dx_db->parent = db->blockcnt;
6345                 }
6346                 if (hash < min_hash)
6347                         min_hash = hash;
6348                 if (hash > max_hash)
6349                         max_hash = hash;
6350                 dx_db->node_min_hash = hash;
6351                 if ((i+1) < count)
6352                         dx_db->node_max_hash =
6353                           ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
6354                 else {
6355                         dx_db->node_max_hash = 0xfffffffe;
6356                         dx_db->flags |= DX_FLAG_LAST;
6357                 }
6358                 if (i == 0)
6359                         dx_db->flags |= DX_FLAG_FIRST;
6360         }
6361         dx_db = &dx_dir->dx_block[db->blockcnt];
6362         dx_db->min_hash = min_hash;
6363         dx_db->max_hash = max_hash;
6364         return;
6365
6366 clear_and_exit:
6367         clear_htree(cd->ctx, cd->pctx.ino);
6368         dx_dir->numblocks = 0;
6369 }
6370 #endif /* ENABLE_HTREE */
6371
6372 /*
6373  * Given a busted directory, try to salvage it somehow.
6374  *
6375  */
6376 static void salvage_directory(ext2_filsys fs,
6377                               struct ext2_dir_entry *dirent,
6378                               struct ext2_dir_entry *prev,
6379                               unsigned int *offset)
6380 {
6381         char    *cp = (char *) dirent;
6382         int left = fs->blocksize - *offset - dirent->rec_len;
6383         int name_len = dirent->name_len & 0xFF;
6384
6385         /*
6386          * Special case of directory entry of size 8: copy what's left
6387          * of the directory block up to cover up the invalid hole.
6388          */
6389         if ((left >= 12) && (dirent->rec_len == 8)) {
6390                 memmove(cp, cp+8, left);
6391                 memset(cp + left, 0, 8);
6392                 return;
6393         }
6394         /*
6395          * If the directory entry overruns the end of the directory
6396          * block, and the name is small enough to fit, then adjust the
6397          * record length.
6398          */
6399         if ((left < 0) &&
6400             (name_len + 8 <= dirent->rec_len + left) &&
6401             dirent->inode <= fs->super->s_inodes_count &&
6402             strnlen(dirent->name, name_len) == name_len) {
6403                 dirent->rec_len += left;
6404                 return;
6405         }
6406         /*
6407          * If the directory entry is a multiple of four, so it is
6408          * valid, let the previous directory entry absorb the invalid
6409          * one.
6410          */
6411         if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
6412                 prev->rec_len += dirent->rec_len;
6413                 *offset += dirent->rec_len;
6414                 return;
6415         }
6416         /*
6417          * Default salvage method --- kill all of the directory
6418          * entries for the rest of the block.  We will either try to
6419          * absorb it into the previous directory entry, or create a
6420          * new empty directory entry the rest of the directory block.
6421          */
6422         if (prev) {
6423                 prev->rec_len += fs->blocksize - *offset;
6424                 *offset = fs->blocksize;
6425         } else {
6426                 dirent->rec_len = fs->blocksize - *offset;
6427                 dirent->name_len = 0;
6428                 dirent->inode = 0;
6429         }
6430 }
6431
6432 static int check_dir_block(ext2_filsys fs,
6433                            struct ext2_db_entry *db,
6434                            void *priv_data)
6435 {
6436         struct dir_info         *subdir, *dir;
6437         struct dx_dir_info      *dx_dir;
6438 #ifdef ENABLE_HTREE
6439         struct dx_dirblock_info *dx_db = 0;
6440 #endif /* ENABLE_HTREE */
6441         struct ext2_dir_entry   *dirent, *prev;
6442         ext2_dirhash_t          hash;
6443         unsigned int            offset = 0;
6444         int                     dir_modified = 0;
6445         int                     dot_state;
6446         blk_t                   block_nr = db->blk;
6447         ext2_ino_t              ino = db->ino;
6448         __u16                   links;
6449         struct check_dir_struct *cd;
6450         char                    *buf;
6451         e2fsck_t                ctx;
6452         int                     problem;
6453         struct ext2_dx_root_info *root;
6454         struct ext2_dx_countlimit *limit;
6455         static dict_t de_dict;
6456         struct problem_context  pctx;
6457         int     dups_found = 0;
6458
6459         cd = (struct check_dir_struct *) priv_data;
6460         buf = cd->buf;
6461         ctx = cd->ctx;
6462
6463         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6464                 return DIRENT_ABORT;
6465
6466         if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6467                 return DIRENT_ABORT;
6468
6469         /*
6470          * Make sure the inode is still in use (could have been
6471          * deleted in the duplicate/bad blocks pass.
6472          */
6473         if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6474                 return 0;
6475
6476         cd->pctx.ino = ino;
6477         cd->pctx.blk = block_nr;
6478         cd->pctx.blkcount = db->blockcnt;
6479         cd->pctx.ino2 = 0;
6480         cd->pctx.dirent = 0;
6481         cd->pctx.num = 0;
6482
6483         if (db->blk == 0) {
6484                 if (allocate_dir_block(ctx, db, &cd->pctx))
6485                         return 0;
6486                 block_nr = db->blk;
6487         }
6488
6489         if (db->blockcnt)
6490                 dot_state = 2;
6491         else
6492                 dot_state = 0;
6493
6494         if (ctx->dirs_to_hash &&
6495             ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6496                 dups_found++;
6497
6498         cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6499         if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6500                 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6501         if (cd->pctx.errcode) {
6502                 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6503                         ctx->flags |= E2F_FLAG_ABORT;
6504                         return DIRENT_ABORT;
6505                 }
6506                 memset(buf, 0, fs->blocksize);
6507         }
6508 #ifdef ENABLE_HTREE
6509         dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6510         if (dx_dir && dx_dir->numblocks) {
6511                 if (db->blockcnt >= dx_dir->numblocks) {
6512                         printf("XXX should never happen!!!\n");
6513                         abort();
6514                 }
6515                 dx_db = &dx_dir->dx_block[db->blockcnt];
6516                 dx_db->type = DX_DIRBLOCK_LEAF;
6517                 dx_db->phys = block_nr;
6518                 dx_db->min_hash = ~0;
6519                 dx_db->max_hash = 0;
6520
6521                 dirent = (struct ext2_dir_entry *) buf;
6522                 limit = (struct ext2_dx_countlimit *) (buf+8);
6523                 if (db->blockcnt == 0) {
6524                         root = (struct ext2_dx_root_info *) (buf + 24);
6525                         dx_db->type = DX_DIRBLOCK_ROOT;
6526                         dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6527                         if ((root->reserved_zero ||
6528                              root->info_length < 8 ||
6529                              root->indirect_levels > 1) &&
6530                             fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6531                                 clear_htree(ctx, ino);
6532                                 dx_dir->numblocks = 0;
6533                                 dx_db = 0;
6534                         }
6535                         dx_dir->hashversion = root->hash_version;
6536                         dx_dir->depth = root->indirect_levels + 1;
6537                 } else if ((dirent->inode == 0) &&
6538                            (dirent->rec_len == fs->blocksize) &&
6539                            (dirent->name_len == 0) &&
6540                            (ext2fs_le16_to_cpu(limit->limit) ==
6541                             ((fs->blocksize-8) /
6542                              sizeof(struct ext2_dx_entry))))
6543                         dx_db->type = DX_DIRBLOCK_NODE;
6544         }
6545 #endif /* ENABLE_HTREE */
6546
6547         dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6548         prev = 0;
6549         do {
6550                 problem = 0;
6551                 dirent = (struct ext2_dir_entry *) (buf + offset);
6552                 cd->pctx.dirent = dirent;
6553                 cd->pctx.num = offset;
6554                 if (((offset + dirent->rec_len) > fs->blocksize) ||
6555                     (dirent->rec_len < 12) ||
6556                     ((dirent->rec_len % 4) != 0) ||
6557                     (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6558                         if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6559                                 salvage_directory(fs, dirent, prev, &offset);
6560                                 dir_modified++;
6561                                 continue;
6562                         } else
6563                                 goto abort_free_dict;
6564                 }
6565                 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6566                         if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6567                                 dirent->name_len = EXT2_NAME_LEN;
6568                                 dir_modified++;
6569                         }
6570                 }
6571
6572                 if (dot_state == 0) {
6573                         if (check_dot(ctx, dirent, ino, &cd->pctx))
6574                                 dir_modified++;
6575                 } else if (dot_state == 1) {
6576                         dir = e2fsck_get_dir_info(ctx, ino);
6577                         if (!dir) {
6578                                 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6579                                 goto abort_free_dict;
6580                         }
6581                         if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6582                                 dir_modified++;
6583                 } else if (dirent->inode == ino) {
6584                         problem = PR_2_LINK_DOT;
6585                         if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6586                                 dirent->inode = 0;
6587                                 dir_modified++;
6588                                 goto next;
6589                         }
6590                 }
6591                 if (!dirent->inode)
6592                         goto next;
6593
6594                 /*
6595                  * Make sure the inode listed is a legal one.
6596                  */
6597                 if (((dirent->inode != EXT2_ROOT_INO) &&
6598                      (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6599                     (dirent->inode > fs->super->s_inodes_count)) {
6600                         problem = PR_2_BAD_INO;
6601                 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6602                                                dirent->inode))) {
6603                         /*
6604                          * If the inode is unused, offer to clear it.
6605                          */
6606                         problem = PR_2_UNUSED_INODE;
6607                 } else if (ctx->inode_bb_map &&
6608                            (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
6609                                                      dirent->inode))) {
6610                         /*
6611                          * If the inode is in a bad block, offer to
6612                          * clear it.
6613                          */
6614                         problem = PR_2_BB_INODE;
6615                 } else if ((dot_state > 1) &&
6616                            ((dirent->name_len & 0xFF) == 1) &&
6617                            (dirent->name[0] == '.')) {
6618                         /*
6619                          * If there's a '.' entry in anything other
6620                          * than the first directory entry, it's a
6621                          * duplicate entry that should be removed.
6622                          */
6623                         problem = PR_2_DUP_DOT;
6624                 } else if ((dot_state > 1) &&
6625                            ((dirent->name_len & 0xFF) == 2) &&
6626                            (dirent->name[0] == '.') &&
6627                            (dirent->name[1] == '.')) {
6628                         /*
6629                          * If there's a '..' entry in anything other
6630                          * than the second directory entry, it's a
6631                          * duplicate entry that should be removed.
6632                          */
6633                         problem = PR_2_DUP_DOT_DOT;
6634                 } else if ((dot_state > 1) &&
6635                            (dirent->inode == EXT2_ROOT_INO)) {
6636                         /*
6637                          * Don't allow links to the root directory.
6638                          * We check this specially to make sure we
6639                          * catch this error case even if the root
6640                          * directory hasn't been created yet.
6641                          */
6642                         problem = PR_2_LINK_ROOT;
6643                 } else if ((dot_state > 1) &&
6644                            (dirent->name_len & 0xFF) == 0) {
6645                         /*
6646                          * Don't allow zero-length directory names.
6647                          */
6648                         problem = PR_2_NULL_NAME;
6649                 }
6650
6651                 if (problem) {
6652                         if (fix_problem(ctx, problem, &cd->pctx)) {
6653                                 dirent->inode = 0;
6654                                 dir_modified++;
6655                                 goto next;
6656                         } else {
6657                                 ext2fs_unmark_valid(fs);
6658                                 if (problem == PR_2_BAD_INO)
6659                                         goto next;
6660                         }
6661                 }
6662
6663                 /*
6664                  * If the inode was marked as having bad fields in
6665                  * pass1, process it and offer to fix/clear it.
6666                  * (We wait until now so that we can display the
6667                  * pathname to the user.)
6668                  */
6669                 if (ctx->inode_bad_map &&
6670                     ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6671                                              dirent->inode)) {
6672                         if (e2fsck_process_bad_inode(ctx, ino,
6673                                                      dirent->inode,
6674                                                      buf + fs->blocksize)) {
6675                                 dirent->inode = 0;
6676                                 dir_modified++;
6677                                 goto next;
6678                         }
6679                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6680                                 return DIRENT_ABORT;
6681                 }
6682
6683                 if (check_name(ctx, dirent, &cd->pctx))
6684                         dir_modified++;
6685
6686                 if (check_filetype(ctx, dirent, &cd->pctx))
6687                         dir_modified++;
6688
6689 #ifdef ENABLE_HTREE
6690                 if (dx_db) {
6691                         ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6692                                        (dirent->name_len & 0xFF),
6693                                        fs->super->s_hash_seed, &hash, 0);
6694                         if (hash < dx_db->min_hash)
6695                                 dx_db->min_hash = hash;
6696                         if (hash > dx_db->max_hash)
6697                                 dx_db->max_hash = hash;
6698                 }
6699 #endif
6700
6701                 /*
6702                  * If this is a directory, then mark its parent in its
6703                  * dir_info structure.  If the parent field is already
6704                  * filled in, then this directory has more than one
6705                  * hard link.  We assume the first link is correct,
6706                  * and ask the user if he/she wants to clear this one.
6707                  */
6708                 if ((dot_state > 1) &&
6709                     (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6710                                               dirent->inode))) {
6711                         subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6712                         if (!subdir) {
6713                                 cd->pctx.ino = dirent->inode;
6714                                 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6715                                 goto abort_free_dict;
6716                         }
6717                         if (subdir->parent) {
6718                                 cd->pctx.ino2 = subdir->parent;
6719                                 if (fix_problem(ctx, PR_2_LINK_DIR,
6720                                                 &cd->pctx)) {
6721                                         dirent->inode = 0;
6722                                         dir_modified++;
6723                                         goto next;
6724                                 }
6725                                 cd->pctx.ino2 = 0;
6726                         } else
6727                                 subdir->parent = ino;
6728                 }
6729
6730                 if (dups_found) {
6731                         ;
6732                 } else if (dict_lookup(&de_dict, dirent)) {
6733                         clear_problem_context(&pctx);
6734                         pctx.ino = ino;
6735                         pctx.dirent = dirent;
6736                         fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6737                         if (!ctx->dirs_to_hash)
6738                                 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6739                         if (ctx->dirs_to_hash)
6740                                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6741                         dups_found++;
6742                 } else
6743                         dict_alloc_insert(&de_dict, dirent, dirent);
6744
6745                 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6746                                         &links);
6747                 if (links > 1)
6748                         ctx->fs_links_count++;
6749                 ctx->fs_total_count++;
6750         next:
6751                 prev = dirent;
6752                 offset += dirent->rec_len;
6753                 dot_state++;
6754         } while (offset < fs->blocksize);
6755 #ifdef ENABLE_HTREE
6756         if (dx_db) {
6757                 cd->pctx.dir = cd->pctx.ino;
6758                 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6759                     (dx_db->type == DX_DIRBLOCK_NODE))
6760                         parse_int_node(fs, db, cd, dx_dir, buf);
6761         }
6762 #endif /* ENABLE_HTREE */
6763         if (offset != fs->blocksize) {
6764                 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6765                 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6766                         dirent->rec_len = cd->pctx.num;
6767                         dir_modified++;
6768                 }
6769         }
6770         if (dir_modified) {
6771                 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6772                 if (cd->pctx.errcode) {
6773                         if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6774                                          &cd->pctx))
6775                                 goto abort_free_dict;
6776                 }
6777                 ext2fs_mark_changed(fs);
6778         }
6779         dict_free_nodes(&de_dict);
6780         return 0;
6781 abort_free_dict:
6782         dict_free_nodes(&de_dict);
6783         ctx->flags |= E2F_FLAG_ABORT;
6784         return DIRENT_ABORT;
6785 }
6786
6787 /*
6788  * This function is called to deallocate a block, and is an interator
6789  * functioned called by deallocate inode via ext2fs_iterate_block().
6790  */
6791 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6792                                   e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6793                                   blk_t ref_block FSCK_ATTR((unused)),
6794                                   int ref_offset FSCK_ATTR((unused)),
6795                                   void *priv_data)
6796 {
6797         e2fsck_t        ctx = (e2fsck_t) priv_data;
6798
6799         if (HOLE_BLKADDR(*block_nr))
6800                 return 0;
6801         if ((*block_nr < fs->super->s_first_data_block) ||
6802             (*block_nr >= fs->super->s_blocks_count))
6803                 return 0;
6804         ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6805         ext2fs_block_alloc_stats(fs, *block_nr, -1);
6806         return 0;
6807 }
6808
6809 /*
6810  * This fuction deallocates an inode
6811  */
6812 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6813 {
6814         ext2_filsys fs = ctx->fs;
6815         struct ext2_inode       inode;
6816         struct problem_context  pctx;
6817         __u32                   count;
6818
6819         ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6820         e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6821         inode.i_links_count = 0;
6822         inode.i_dtime = time(0);
6823         e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6824         clear_problem_context(&pctx);
6825         pctx.ino = ino;
6826
6827         /*
6828          * Fix up the bitmaps...
6829          */
6830         e2fsck_read_bitmaps(ctx);
6831         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6832         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6833         if (ctx->inode_bad_map)
6834                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6835         ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6836
6837         if (inode.i_file_acl &&
6838             (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6839                 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6840                                                    block_buf, -1, &count);
6841                 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6842                         pctx.errcode = 0;
6843                         count = 1;
6844                 }
6845                 if (pctx.errcode) {
6846                         pctx.blk = inode.i_file_acl;
6847                         fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6848                         ctx->flags |= E2F_FLAG_ABORT;
6849                         return;
6850                 }
6851                 if (count == 0) {
6852                         ext2fs_unmark_block_bitmap(ctx->block_found_map,
6853                                                    inode.i_file_acl);
6854                         ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6855                 }
6856                 inode.i_file_acl = 0;
6857         }
6858
6859         if (!ext2fs_inode_has_valid_blocks(&inode))
6860                 return;
6861
6862         if (LINUX_S_ISREG(inode.i_mode) &&
6863             (inode.i_size_high || inode.i_size & 0x80000000UL))
6864                 ctx->large_files--;
6865
6866         pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6867                                             deallocate_inode_block, ctx);
6868         if (pctx.errcode) {
6869                 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6870                 ctx->flags |= E2F_FLAG_ABORT;
6871                 return;
6872         }
6873 }
6874
6875 /*
6876  * This fuction clears the htree flag on an inode
6877  */
6878 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6879 {
6880         struct ext2_inode       inode;
6881
6882         e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6883         inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6884         e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6885         if (ctx->dirs_to_hash)
6886                 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6887 }
6888
6889
6890 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6891                                     ext2_ino_t ino, char *buf)
6892 {
6893         ext2_filsys fs = ctx->fs;
6894         struct ext2_inode       inode;
6895         int                     inode_modified = 0;
6896         int                     not_fixed = 0;
6897         unsigned char           *frag, *fsize;
6898         struct problem_context  pctx;
6899         int     problem = 0;
6900
6901         e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6902
6903         clear_problem_context(&pctx);
6904         pctx.ino = ino;
6905         pctx.dir = dir;
6906         pctx.inode = &inode;
6907
6908         if (inode.i_file_acl &&
6909             !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6910             fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6911                 inode.i_file_acl = 0;
6912 #ifdef EXT2FS_ENABLE_SWAPFS
6913                 /*
6914                  * This is a special kludge to deal with long symlinks
6915                  * on big endian systems.  i_blocks had already been
6916                  * decremented earlier in pass 1, but since i_file_acl
6917                  * hadn't yet been cleared, ext2fs_read_inode()
6918                  * assumed that the file was short symlink and would
6919                  * not have byte swapped i_block[0].  Hence, we have
6920                  * to byte-swap it here.
6921                  */
6922                 if (LINUX_S_ISLNK(inode.i_mode) &&
6923                     (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6924                     (inode.i_blocks == fs->blocksize >> 9))
6925                         inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6926 #endif
6927                 inode_modified++;
6928         } else
6929                 not_fixed++;
6930
6931         if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6932             !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6933             !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6934             !(LINUX_S_ISSOCK(inode.i_mode)))
6935                 problem = PR_2_BAD_MODE;
6936         else if (LINUX_S_ISCHR(inode.i_mode)
6937                  && !e2fsck_pass1_check_device_inode(fs, &inode))
6938                 problem = PR_2_BAD_CHAR_DEV;
6939         else if (LINUX_S_ISBLK(inode.i_mode)
6940                  && !e2fsck_pass1_check_device_inode(fs, &inode))
6941                 problem = PR_2_BAD_BLOCK_DEV;
6942         else if (LINUX_S_ISFIFO(inode.i_mode)
6943                  && !e2fsck_pass1_check_device_inode(fs, &inode))
6944                 problem = PR_2_BAD_FIFO;
6945         else if (LINUX_S_ISSOCK(inode.i_mode)
6946                  && !e2fsck_pass1_check_device_inode(fs, &inode))
6947                 problem = PR_2_BAD_SOCKET;
6948         else if (LINUX_S_ISLNK(inode.i_mode)
6949                  && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6950                 problem = PR_2_INVALID_SYMLINK;
6951         }
6952
6953         if (problem) {
6954                 if (fix_problem(ctx, problem, &pctx)) {
6955                         deallocate_inode(ctx, ino, 0);
6956                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6957                                 return 0;
6958                         return 1;
6959                 } else
6960                         not_fixed++;
6961                 problem = 0;
6962         }
6963
6964         if (inode.i_faddr) {
6965                 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6966                         inode.i_faddr = 0;
6967                         inode_modified++;
6968                 } else
6969                         not_fixed++;
6970         }
6971
6972         switch (fs->super->s_creator_os) {
6973             case EXT2_OS_LINUX:
6974                 frag = &inode.osd2.linux2.l_i_frag;
6975                 fsize = &inode.osd2.linux2.l_i_fsize;
6976                 break;
6977             case EXT2_OS_HURD:
6978                 frag = &inode.osd2.hurd2.h_i_frag;
6979                 fsize = &inode.osd2.hurd2.h_i_fsize;
6980                 break;
6981             case EXT2_OS_MASIX:
6982                 frag = &inode.osd2.masix2.m_i_frag;
6983                 fsize = &inode.osd2.masix2.m_i_fsize;
6984                 break;
6985             default:
6986                 frag = fsize = 0;
6987         }
6988         if (frag && *frag) {
6989                 pctx.num = *frag;
6990                 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6991                         *frag = 0;
6992                         inode_modified++;
6993                 } else
6994                         not_fixed++;
6995                 pctx.num = 0;
6996         }
6997         if (fsize && *fsize) {
6998                 pctx.num = *fsize;
6999                 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
7000                         *fsize = 0;
7001                         inode_modified++;
7002                 } else
7003                         not_fixed++;
7004                 pctx.num = 0;
7005         }
7006
7007         if (inode.i_file_acl &&
7008             ((inode.i_file_acl < fs->super->s_first_data_block) ||
7009              (inode.i_file_acl >= fs->super->s_blocks_count))) {
7010                 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
7011                         inode.i_file_acl = 0;
7012                         inode_modified++;
7013                 } else
7014                         not_fixed++;
7015         }
7016         if (inode.i_dir_acl &&
7017             LINUX_S_ISDIR(inode.i_mode)) {
7018                 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
7019                         inode.i_dir_acl = 0;
7020                         inode_modified++;
7021                 } else
7022                         not_fixed++;
7023         }
7024
7025         if (inode_modified)
7026                 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
7027         if (!not_fixed)
7028                 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7029         return 0;
7030 }
7031
7032
7033 /*
7034  * allocate_dir_block --- this function allocates a new directory
7035  *      block for a particular inode; this is done if a directory has
7036  *      a "hole" in it, or if a directory has a illegal block number
7037  *      that was zeroed out and now needs to be replaced.
7038  */
7039 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
7040                               struct problem_context *pctx)
7041 {
7042         ext2_filsys fs = ctx->fs;
7043         blk_t                   blk;
7044         char                    *block;
7045         struct ext2_inode       inode;
7046
7047         if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
7048                 return 1;
7049
7050         /*
7051          * Read the inode and block bitmaps in; we'll be messing with
7052          * them.
7053          */
7054         e2fsck_read_bitmaps(ctx);
7055
7056         /*
7057          * First, find a free block
7058          */
7059         pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7060         if (pctx->errcode) {
7061                 pctx->str = "ext2fs_new_block";
7062                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7063                 return 1;
7064         }
7065         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7066         ext2fs_mark_block_bitmap(fs->block_map, blk);
7067         ext2fs_mark_bb_dirty(fs);
7068
7069         /*
7070          * Now let's create the actual data block for the inode
7071          */
7072         if (db->blockcnt)
7073                 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
7074         else
7075                 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
7076                                                      EXT2_ROOT_INO, &block);
7077
7078         if (pctx->errcode) {
7079                 pctx->str = "ext2fs_new_dir_block";
7080                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7081                 return 1;
7082         }
7083
7084         pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
7085         ext2fs_free_mem(&block);
7086         if (pctx->errcode) {
7087                 pctx->str = "ext2fs_write_dir_block";
7088                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7089                 return 1;
7090         }
7091
7092         /*
7093          * Update the inode block count
7094          */
7095         e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
7096         inode.i_blocks += fs->blocksize / 512;
7097         if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
7098                 inode.i_size = (db->blockcnt+1) * fs->blocksize;
7099         e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
7100
7101         /*
7102          * Finally, update the block pointers for the inode
7103          */
7104         db->blk = blk;
7105         pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
7106                                       0, update_dir_block, db);
7107         if (pctx->errcode) {
7108                 pctx->str = "ext2fs_block_iterate";
7109                 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7110                 return 1;
7111         }
7112
7113         return 0;
7114 }
7115
7116 /*
7117  * This is a helper function for allocate_dir_block().
7118  */
7119 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
7120                             blk_t       *block_nr,
7121                             e2_blkcnt_t blockcnt,
7122                             blk_t ref_block FSCK_ATTR((unused)),
7123                             int ref_offset FSCK_ATTR((unused)),
7124                             void *priv_data)
7125 {
7126         struct ext2_db_entry *db;
7127
7128         db = (struct ext2_db_entry *) priv_data;
7129         if (db->blockcnt == (int) blockcnt) {
7130                 *block_nr = db->blk;
7131                 return BLOCK_CHANGED;
7132         }
7133         return 0;
7134 }
7135
7136 /*
7137  * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
7138  *
7139  * Pass #3 assures that all directories are connected to the
7140  * filesystem tree, using the following algorithm:
7141  *
7142  * First, the root directory is checked to make sure it exists; if
7143  * not, e2fsck will offer to create a new one.  It is then marked as
7144  * "done".
7145  *
7146  * Then, pass3 interates over all directory inodes; for each directory
7147  * it attempts to trace up the filesystem tree, using dirinfo.parent
7148  * until it reaches a directory which has been marked "done".  If it
7149  * can not do so, then the directory must be disconnected, and e2fsck
7150  * will offer to reconnect it to /lost+found.  While it is chasing
7151  * parent pointers up the filesystem tree, if pass3 sees a directory
7152  * twice, then it has detected a filesystem loop, and it will again
7153  * offer to reconnect the directory to /lost+found in to break the
7154  * filesystem loop.
7155  *
7156  * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
7157  * reconnect inodes to /lost+found; this subroutine is also used by
7158  * pass 4.  e2fsck_reconnect_file() calls get_lost_and_found(), which
7159  * is responsible for creating /lost+found if it does not exist.
7160  *
7161  * Pass 3 frees the following data structures:
7162  *      - The dirinfo directory information cache.
7163  */
7164
7165 static void check_root(e2fsck_t ctx);
7166 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
7167                            struct problem_context *pctx);
7168 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
7169
7170 static ext2fs_inode_bitmap inode_loop_detect;
7171 static ext2fs_inode_bitmap inode_done_map;
7172
7173 static void e2fsck_pass3(e2fsck_t ctx)
7174 {
7175         ext2_filsys fs = ctx->fs;
7176         int             i;
7177         struct problem_context  pctx;
7178         struct dir_info *dir;
7179         unsigned long maxdirs, count;
7180
7181         clear_problem_context(&pctx);
7182
7183         /* Pass 3 */
7184
7185         if (!(ctx->options & E2F_OPT_PREEN))
7186                 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
7187
7188         /*
7189          * Allocate some bitmaps to do loop detection.
7190          */
7191         pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
7192                                                     &inode_done_map);
7193         if (pctx.errcode) {
7194                 pctx.num = 2;
7195                 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
7196                 ctx->flags |= E2F_FLAG_ABORT;
7197                 goto abort_exit;
7198         }
7199         check_root(ctx);
7200         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7201                 goto abort_exit;
7202
7203         ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
7204
7205         maxdirs = e2fsck_get_num_dirinfo(ctx);
7206         count = 1;
7207
7208         if (ctx->progress)
7209                 if ((ctx->progress)(ctx, 3, 0, maxdirs))
7210                         goto abort_exit;
7211
7212         for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
7213                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7214                         goto abort_exit;
7215                 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
7216                         goto abort_exit;
7217                 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
7218                         if (check_directory(ctx, dir, &pctx))
7219                                 goto abort_exit;
7220         }
7221
7222         /*
7223          * Force the creation of /lost+found if not present
7224          */
7225         if ((ctx->flags & E2F_OPT_READONLY) == 0)
7226                 e2fsck_get_lost_and_found(ctx, 1);
7227
7228         /*
7229          * If there are any directories that need to be indexed or
7230          * optimized, do it here.
7231          */
7232         e2fsck_rehash_directories(ctx);
7233
7234 abort_exit:
7235         e2fsck_free_dir_info(ctx);
7236         ext2fs_free_inode_bitmap(inode_loop_detect);
7237         inode_loop_detect = 0;
7238         ext2fs_free_inode_bitmap(inode_done_map);
7239         inode_done_map = 0;
7240 }
7241
7242 /*
7243  * This makes sure the root inode is present; if not, we ask if the
7244  * user wants us to create it.  Not creating it is a fatal error.
7245  */
7246 static void check_root(e2fsck_t ctx)
7247 {
7248         ext2_filsys fs = ctx->fs;
7249         blk_t                   blk;
7250         struct ext2_inode       inode;
7251         char *                  block;
7252         struct problem_context  pctx;
7253
7254         clear_problem_context(&pctx);
7255
7256         if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
7257                 /*
7258                  * If the root inode is not a directory, die here.  The
7259                  * user must have answered 'no' in pass1 when we
7260                  * offered to clear it.
7261                  */
7262                 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
7263                                                EXT2_ROOT_INO))) {
7264                         fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
7265                         ctx->flags |= E2F_FLAG_ABORT;
7266                 }
7267                 return;
7268         }
7269
7270         if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
7271                 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
7272                 ctx->flags |= E2F_FLAG_ABORT;
7273                 return;
7274         }
7275
7276         e2fsck_read_bitmaps(ctx);
7277
7278         /*
7279          * First, find a free block
7280          */
7281         pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7282         if (pctx.errcode) {
7283                 pctx.str = "ext2fs_new_block";
7284                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7285                 ctx->flags |= E2F_FLAG_ABORT;
7286                 return;
7287         }
7288         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7289         ext2fs_mark_block_bitmap(fs->block_map, blk);
7290         ext2fs_mark_bb_dirty(fs);
7291
7292         /*
7293          * Now let's create the actual data block for the inode
7294          */
7295         pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
7296                                             &block);
7297         if (pctx.errcode) {
7298                 pctx.str = "ext2fs_new_dir_block";
7299                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7300                 ctx->flags |= E2F_FLAG_ABORT;
7301                 return;
7302         }
7303
7304         pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
7305         if (pctx.errcode) {
7306                 pctx.str = "ext2fs_write_dir_block";
7307                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7308                 ctx->flags |= E2F_FLAG_ABORT;
7309                 return;
7310         }
7311         ext2fs_free_mem(&block);
7312
7313         /*
7314          * Set up the inode structure
7315          */
7316         memset(&inode, 0, sizeof(inode));
7317         inode.i_mode = 040755;
7318         inode.i_size = fs->blocksize;
7319         inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7320         inode.i_links_count = 2;
7321         inode.i_blocks = fs->blocksize / 512;
7322         inode.i_block[0] = blk;
7323
7324         /*
7325          * Write out the inode.
7326          */
7327         pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
7328         if (pctx.errcode) {
7329                 pctx.str = "ext2fs_write_inode";
7330                 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7331                 ctx->flags |= E2F_FLAG_ABORT;
7332                 return;
7333         }
7334
7335         /*
7336          * Miscellaneous bookkeeping...
7337          */
7338         e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
7339         ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
7340         ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
7341
7342         ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
7343         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
7344         ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
7345         ext2fs_mark_ib_dirty(fs);
7346 }
7347
7348 /*
7349  * This subroutine is responsible for making sure that a particular
7350  * directory is connected to the root; if it isn't we trace it up as
7351  * far as we can go, and then offer to connect the resulting parent to
7352  * the lost+found.  We have to do loop detection; if we ever discover
7353  * a loop, we treat that as a disconnected directory and offer to
7354  * reparent it to lost+found.
7355  *
7356  * However, loop detection is expensive, because for very large
7357  * filesystems, the inode_loop_detect bitmap is huge, and clearing it
7358  * is non-trivial.  Loops in filesystems are also a rare error case,
7359  * and we shouldn't optimize for error cases.  So we try two passes of
7360  * the algorithm.  The first time, we ignore loop detection and merely
7361  * increment a counter; if the counter exceeds some extreme threshold,
7362  * then we try again with the loop detection bitmap enabled.
7363  */
7364 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
7365                            struct problem_context *pctx)
7366 {
7367         ext2_filsys     fs = ctx->fs;
7368         struct dir_info *p = dir;
7369         int             loop_pass = 0, parent_count = 0;
7370
7371         if (!p)
7372                 return 0;
7373
7374         while (1) {
7375                 /*
7376                  * Mark this inode as being "done"; by the time we
7377                  * return from this function, the inode we either be
7378                  * verified as being connected to the directory tree,
7379                  * or we will have offered to reconnect this to
7380                  * lost+found.
7381                  *
7382                  * If it was marked done already, then we've reached a
7383                  * parent we've already checked.
7384                  */
7385                 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
7386                         break;
7387
7388                 /*
7389                  * If this directory doesn't have a parent, or we've
7390                  * seen the parent once already, then offer to
7391                  * reparent it to lost+found
7392                  */
7393                 if (!p->parent ||
7394                     (loop_pass &&
7395                      (ext2fs_test_inode_bitmap(inode_loop_detect,
7396                                               p->parent)))) {
7397                         pctx->ino = p->ino;
7398                         if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
7399                                 if (e2fsck_reconnect_file(ctx, pctx->ino))
7400                                         ext2fs_unmark_valid(fs);
7401                                 else {
7402                                         p = e2fsck_get_dir_info(ctx, pctx->ino);
7403                                         p->parent = ctx->lost_and_found;
7404                                         fix_dotdot(ctx, p, ctx->lost_and_found);
7405                                 }
7406                         }
7407                         break;
7408                 }
7409                 p = e2fsck_get_dir_info(ctx, p->parent);
7410                 if (!p) {
7411                         fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
7412                         return 0;
7413                 }
7414                 if (loop_pass) {
7415                         ext2fs_mark_inode_bitmap(inode_loop_detect,
7416                                                  p->ino);
7417                 } else if (parent_count++ > 2048) {
7418                         /*
7419                          * If we've run into a path depth that's
7420                          * greater than 2048, try again with the inode
7421                          * loop bitmap turned on and start from the
7422                          * top.
7423                          */
7424                         loop_pass = 1;
7425                         if (inode_loop_detect)
7426                                 ext2fs_clear_inode_bitmap(inode_loop_detect);
7427                         else {
7428                                 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7429                                 if (pctx->errcode) {
7430                                         pctx->num = 1;
7431                                         fix_problem(ctx,
7432                                     PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7433                                         ctx->flags |= E2F_FLAG_ABORT;
7434                                         return -1;
7435                                 }
7436                         }
7437                         p = dir;
7438                 }
7439         }
7440
7441         /*
7442          * Make sure that .. and the parent directory are the same;
7443          * offer to fix it if not.
7444          */
7445         if (dir->parent != dir->dotdot) {
7446                 pctx->ino = dir->ino;
7447                 pctx->ino2 = dir->dotdot;
7448                 pctx->dir = dir->parent;
7449                 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7450                         fix_dotdot(ctx, dir, dir->parent);
7451         }
7452         return 0;
7453 }
7454
7455 /*
7456  * This routine gets the lost_and_found inode, making it a directory
7457  * if necessary
7458  */
7459 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7460 {
7461         ext2_filsys fs = ctx->fs;
7462         ext2_ino_t                      ino;
7463         blk_t                   blk;
7464         errcode_t               retval;
7465         struct ext2_inode       inode;
7466         char *                  block;
7467         static const char       name[] = "lost+found";
7468         struct  problem_context pctx;
7469         struct dir_info         *dirinfo;
7470
7471         if (ctx->lost_and_found)
7472                 return ctx->lost_and_found;
7473
7474         clear_problem_context(&pctx);
7475
7476         retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7477                                sizeof(name)-1, 0, &ino);
7478         if (retval && !fix)
7479                 return 0;
7480         if (!retval) {
7481                 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7482                         ctx->lost_and_found = ino;
7483                         return ino;
7484                 }
7485
7486                 /* Lost+found isn't a directory! */
7487                 if (!fix)
7488                         return 0;
7489                 pctx.ino = ino;
7490                 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7491                         return 0;
7492
7493                 /* OK, unlink the old /lost+found file. */
7494                 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7495                 if (pctx.errcode) {
7496                         pctx.str = "ext2fs_unlink";
7497                         fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7498                         return 0;
7499                 }
7500                 dirinfo = e2fsck_get_dir_info(ctx, ino);
7501                 if (dirinfo)
7502                         dirinfo->parent = 0;
7503                 e2fsck_adjust_inode_count(ctx, ino, -1);
7504         } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7505                 pctx.errcode = retval;
7506                 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7507         }
7508         if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7509                 return 0;
7510
7511         /*
7512          * Read the inode and block bitmaps in; we'll be messing with
7513          * them.
7514          */
7515         e2fsck_read_bitmaps(ctx);
7516
7517         /*
7518          * First, find a free block
7519          */
7520         retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7521         if (retval) {
7522                 pctx.errcode = retval;
7523                 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7524                 return 0;
7525         }
7526         ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7527         ext2fs_block_alloc_stats(fs, blk, +1);
7528
7529         /*
7530          * Next find a free inode.
7531          */
7532         retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7533                                   ctx->inode_used_map, &ino);
7534         if (retval) {
7535                 pctx.errcode = retval;
7536                 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7537                 return 0;
7538         }
7539         ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7540         ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7541         ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7542
7543         /*
7544          * Now let's create the actual data block for the inode
7545          */
7546         retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7547         if (retval) {
7548                 pctx.errcode = retval;
7549                 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7550                 return 0;
7551         }
7552
7553         retval = ext2fs_write_dir_block(fs, blk, block);
7554         ext2fs_free_mem(&block);
7555         if (retval) {
7556                 pctx.errcode = retval;
7557                 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7558                 return 0;
7559         }
7560
7561         /*
7562          * Set up the inode structure
7563          */
7564         memset(&inode, 0, sizeof(inode));
7565         inode.i_mode = 040700;
7566         inode.i_size = fs->blocksize;
7567         inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7568         inode.i_links_count = 2;
7569         inode.i_blocks = fs->blocksize / 512;
7570         inode.i_block[0] = blk;
7571
7572         /*
7573          * Next, write out the inode.
7574          */
7575         pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7576         if (pctx.errcode) {
7577                 pctx.str = "ext2fs_write_inode";
7578                 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7579                 return 0;
7580         }
7581         /*
7582          * Finally, create the directory link
7583          */
7584         pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7585         if (pctx.errcode) {
7586                 pctx.str = "ext2fs_link";
7587                 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7588                 return 0;
7589         }
7590
7591         /*
7592          * Miscellaneous bookkeeping that needs to be kept straight.
7593          */
7594         e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7595         e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7596         ext2fs_icount_store(ctx->inode_count, ino, 2);
7597         ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7598         ctx->lost_and_found = ino;
7599         return ino;
7600 }
7601
7602 /*
7603  * This routine will connect a file to lost+found
7604  */
7605 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7606 {
7607         ext2_filsys fs = ctx->fs;
7608         errcode_t       retval;
7609         char            name[80];
7610         struct problem_context  pctx;
7611         struct ext2_inode       inode;
7612         int             file_type = 0;
7613
7614         clear_problem_context(&pctx);
7615         pctx.ino = ino;
7616
7617         if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7618                 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7619                         ctx->bad_lost_and_found++;
7620         }
7621         if (ctx->bad_lost_and_found) {
7622                 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7623                 return 1;
7624         }
7625
7626         sprintf(name, "#%u", ino);
7627         if (ext2fs_read_inode(fs, ino, &inode) == 0)
7628                 file_type = ext2_file_type(inode.i_mode);
7629         retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7630         if (retval == EXT2_ET_DIR_NO_SPACE) {
7631                 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7632                         return 1;
7633                 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7634                                                  1, 0);
7635                 if (retval) {
7636                         pctx.errcode = retval;
7637                         fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7638                         return 1;
7639                 }
7640                 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7641                                      ino, file_type);
7642         }
7643         if (retval) {
7644                 pctx.errcode = retval;
7645                 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7646                 return 1;
7647         }
7648         e2fsck_adjust_inode_count(ctx, ino, 1);
7649
7650         return 0;
7651 }
7652
7653 /*
7654  * Utility routine to adjust the inode counts on an inode.
7655  */
7656 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7657 {
7658         ext2_filsys fs = ctx->fs;
7659         errcode_t               retval;
7660         struct ext2_inode       inode;
7661
7662         if (!ino)
7663                 return 0;
7664
7665         retval = ext2fs_read_inode(fs, ino, &inode);
7666         if (retval)
7667                 return retval;
7668
7669         if (adj == 1) {
7670                 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7671                 if (inode.i_links_count == (__u16) ~0)
7672                         return 0;
7673                 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7674                 inode.i_links_count++;
7675         } else if (adj == -1) {
7676                 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7677                 if (inode.i_links_count == 0)
7678                         return 0;
7679                 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7680                 inode.i_links_count--;
7681         }
7682
7683         retval = ext2fs_write_inode(fs, ino, &inode);
7684         if (retval)
7685                 return retval;
7686
7687         return 0;
7688 }
7689
7690 /*
7691  * Fix parent --- this routine fixes up the parent of a directory.
7692  */
7693 struct fix_dotdot_struct {
7694         ext2_filsys     fs;
7695         ext2_ino_t      parent;
7696         int             done;
7697         e2fsck_t        ctx;
7698 };
7699
7700 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7701                            int  offset FSCK_ATTR((unused)),
7702                            int  blocksize FSCK_ATTR((unused)),
7703                            char *buf FSCK_ATTR((unused)),
7704                            void *priv_data)
7705 {
7706         struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7707         errcode_t       retval;
7708         struct problem_context pctx;
7709
7710         if ((dirent->name_len & 0xFF) != 2)
7711                 return 0;
7712         if (strncmp(dirent->name, "..", 2))
7713                 return 0;
7714
7715         clear_problem_context(&pctx);
7716
7717         retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7718         if (retval) {
7719                 pctx.errcode = retval;
7720                 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7721         }
7722         retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7723         if (retval) {
7724                 pctx.errcode = retval;
7725                 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7726         }
7727         dirent->inode = fp->parent;
7728
7729         fp->done++;
7730         return DIRENT_ABORT | DIRENT_CHANGED;
7731 }
7732
7733 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7734 {
7735         ext2_filsys fs = ctx->fs;
7736         errcode_t       retval;
7737         struct fix_dotdot_struct fp;
7738         struct problem_context pctx;
7739
7740         fp.fs = fs;
7741         fp.parent = parent;
7742         fp.done = 0;
7743         fp.ctx = ctx;
7744
7745         retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7746                                     0, fix_dotdot_proc, &fp);
7747         if (retval || !fp.done) {
7748                 clear_problem_context(&pctx);
7749                 pctx.ino = dir->ino;
7750                 pctx.errcode = retval;
7751                 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7752                             PR_3_FIX_PARENT_NOFIND, &pctx);
7753                 ext2fs_unmark_valid(fs);
7754         }
7755         dir->dotdot = parent;
7756
7757         return;
7758 }
7759
7760 /*
7761  * These routines are responsible for expanding a /lost+found if it is
7762  * too small.
7763  */
7764
7765 struct expand_dir_struct {
7766         int                     num;
7767         int                     guaranteed_size;
7768         int                     newblocks;
7769         int                     last_block;
7770         errcode_t               err;
7771         e2fsck_t                ctx;
7772 };
7773
7774 static int expand_dir_proc(ext2_filsys fs,
7775                            blk_t        *blocknr,
7776                            e2_blkcnt_t  blockcnt,
7777                            blk_t ref_block FSCK_ATTR((unused)),
7778                            int ref_offset FSCK_ATTR((unused)),
7779                            void *priv_data)
7780 {
7781         struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7782         blk_t   new_blk;
7783         static blk_t    last_blk = 0;
7784         char            *block;
7785         errcode_t       retval;
7786         e2fsck_t        ctx;
7787
7788         ctx = es->ctx;
7789
7790         if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7791                 return BLOCK_ABORT;
7792
7793         if (blockcnt > 0)
7794                 es->last_block = blockcnt;
7795         if (*blocknr) {
7796                 last_blk = *blocknr;
7797                 return 0;
7798         }
7799         retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7800                                   &new_blk);
7801         if (retval) {
7802                 es->err = retval;
7803                 return BLOCK_ABORT;
7804         }
7805         if (blockcnt > 0) {
7806                 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7807                 if (retval) {
7808                         es->err = retval;
7809                         return BLOCK_ABORT;
7810                 }
7811                 es->num--;
7812                 retval = ext2fs_write_dir_block(fs, new_blk, block);
7813         } else {
7814                 retval = ext2fs_get_mem(fs->blocksize, &block);
7815                 if (retval) {
7816                         es->err = retval;
7817                         return BLOCK_ABORT;
7818                 }
7819                 memset(block, 0, fs->blocksize);
7820                 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7821         }
7822         if (retval) {
7823                 es->err = retval;
7824                 return BLOCK_ABORT;
7825         }
7826         ext2fs_free_mem(&block);
7827         *blocknr = new_blk;
7828         ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7829         ext2fs_block_alloc_stats(fs, new_blk, +1);
7830         es->newblocks++;
7831
7832         if (es->num == 0)
7833                 return (BLOCK_CHANGED | BLOCK_ABORT);
7834         else
7835                 return BLOCK_CHANGED;
7836 }
7837
7838 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7839                                   int num, int guaranteed_size)
7840 {
7841         ext2_filsys fs = ctx->fs;
7842         errcode_t       retval;
7843         struct expand_dir_struct es;
7844         struct ext2_inode       inode;
7845
7846         if (!(fs->flags & EXT2_FLAG_RW))
7847                 return EXT2_ET_RO_FILSYS;
7848
7849         /*
7850          * Read the inode and block bitmaps in; we'll be messing with
7851          * them.
7852          */
7853         e2fsck_read_bitmaps(ctx);
7854
7855         retval = ext2fs_check_directory(fs, dir);
7856         if (retval)
7857                 return retval;
7858
7859         es.num = num;
7860         es.guaranteed_size = guaranteed_size;
7861         es.last_block = 0;
7862         es.err = 0;
7863         es.newblocks = 0;
7864         es.ctx = ctx;
7865
7866         retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7867                                        0, expand_dir_proc, &es);
7868
7869         if (es.err)
7870                 return es.err;
7871
7872         /*
7873          * Update the size and block count fields in the inode.
7874          */
7875         retval = ext2fs_read_inode(fs, dir, &inode);
7876         if (retval)
7877                 return retval;
7878
7879         inode.i_size = (es.last_block + 1) * fs->blocksize;
7880         inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7881
7882         e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7883
7884         return 0;
7885 }
7886
7887 /*
7888  * pass4.c -- pass #4 of e2fsck: Check reference counts
7889  *
7890  * Pass 4 frees the following data structures:
7891  *      - A bitmap of which inodes are in bad blocks.   (inode_bb_map)
7892  *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
7893  */
7894
7895 /*
7896  * This routine is called when an inode is not connected to the
7897  * directory tree.
7898  *
7899  * This subroutine returns 1 then the caller shouldn't bother with the
7900  * rest of the pass 4 tests.
7901  */
7902 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7903 {
7904         ext2_filsys fs = ctx->fs;
7905         struct ext2_inode       inode;
7906         struct problem_context  pctx;
7907
7908         e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7909         clear_problem_context(&pctx);
7910         pctx.ino = i;
7911         pctx.inode = &inode;
7912
7913         /*
7914          * Offer to delete any zero-length files that does not have
7915          * blocks.  If there is an EA block, it might have useful
7916          * information, so we won't prompt to delete it, but let it be
7917          * reconnected to lost+found.
7918          */
7919         if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7920                                 LINUX_S_ISDIR(inode.i_mode))) {
7921                 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7922                         ext2fs_icount_store(ctx->inode_link_info, i, 0);
7923                         inode.i_links_count = 0;
7924                         inode.i_dtime = time(0);
7925                         e2fsck_write_inode(ctx, i, &inode,
7926                                            "disconnect_inode");
7927                         /*
7928                          * Fix up the bitmaps...
7929                          */
7930                         e2fsck_read_bitmaps(ctx);
7931                         ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7932                         ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7933                         ext2fs_inode_alloc_stats2(fs, i, -1,
7934                                                   LINUX_S_ISDIR(inode.i_mode));
7935                         return 0;
7936                 }
7937         }
7938
7939         /*
7940          * Prompt to reconnect.
7941          */
7942         if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7943                 if (e2fsck_reconnect_file(ctx, i))
7944                         ext2fs_unmark_valid(fs);
7945         } else {
7946                 /*
7947                  * If we don't attach the inode, then skip the
7948                  * i_links_test since there's no point in trying to
7949                  * force i_links_count to zero.
7950                  */
7951                 ext2fs_unmark_valid(fs);
7952                 return 1;
7953         }
7954         return 0;
7955 }
7956
7957
7958 static void e2fsck_pass4(e2fsck_t ctx)
7959 {
7960         ext2_filsys fs = ctx->fs;
7961         ext2_ino_t      i;
7962         struct ext2_inode       inode;
7963         struct problem_context  pctx;
7964         __u16   link_count, link_counted;
7965         char    *buf = 0;
7966         int     group, maxgroup;
7967
7968         /* Pass 4 */
7969
7970         clear_problem_context(&pctx);
7971
7972         if (!(ctx->options & E2F_OPT_PREEN))
7973                 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7974
7975         group = 0;
7976         maxgroup = fs->group_desc_count;
7977         if (ctx->progress)
7978                 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7979                         return;
7980
7981         for (i=1; i <= fs->super->s_inodes_count; i++) {
7982                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7983                         return;
7984                 if ((i % fs->super->s_inodes_per_group) == 0) {
7985                         group++;
7986                         if (ctx->progress)
7987                                 if ((ctx->progress)(ctx, 4, group, maxgroup))
7988                                         return;
7989                 }
7990                 if (i == EXT2_BAD_INO ||
7991                     (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7992                         continue;
7993                 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7994                     (ctx->inode_imagic_map &&
7995                      ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
7996                     (ctx->inode_bb_map &&
7997                      ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
7998                         continue;
7999                 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
8000                 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
8001                 if (link_counted == 0) {
8002                         if (!buf)
8003                                 buf = e2fsck_allocate_memory(ctx,
8004                                      fs->blocksize, "bad_inode buffer");
8005                         if (e2fsck_process_bad_inode(ctx, 0, i, buf))
8006                                 continue;
8007                         if (disconnect_inode(ctx, i))
8008                                 continue;
8009                         ext2fs_icount_fetch(ctx->inode_link_info, i,
8010                                             &link_count);
8011                         ext2fs_icount_fetch(ctx->inode_count, i,
8012                                             &link_counted);
8013                 }
8014                 if (link_counted != link_count) {
8015                         e2fsck_read_inode(ctx, i, &inode, "pass4");
8016                         pctx.ino = i;
8017                         pctx.inode = &inode;
8018                         if (link_count != inode.i_links_count) {
8019                                 pctx.num = link_count;
8020                                 fix_problem(ctx,
8021                                             PR_4_INCONSISTENT_COUNT, &pctx);
8022                         }
8023                         pctx.num = link_counted;
8024                         if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
8025                                 inode.i_links_count = link_counted;
8026                                 e2fsck_write_inode(ctx, i, &inode, "pass4");
8027                         }
8028                 }
8029         }
8030         ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
8031         ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
8032         ext2fs_free_inode_bitmap(ctx->inode_bb_map);
8033         ctx->inode_bb_map = 0;
8034         ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
8035         ctx->inode_imagic_map = 0;
8036         ext2fs_free_mem(&buf);
8037 }
8038
8039 /*
8040  * pass5.c --- check block and inode bitmaps against on-disk bitmaps
8041  */
8042
8043 #define NO_BLK ((blk_t) -1)
8044
8045 static void print_bitmap_problem(e2fsck_t ctx, int problem,
8046                             struct problem_context *pctx)
8047 {
8048         switch (problem) {
8049         case PR_5_BLOCK_UNUSED:
8050                 if (pctx->blk == pctx->blk2)
8051                         pctx->blk2 = 0;
8052                 else
8053                         problem = PR_5_BLOCK_RANGE_UNUSED;
8054                 break;
8055         case PR_5_BLOCK_USED:
8056                 if (pctx->blk == pctx->blk2)
8057                         pctx->blk2 = 0;
8058                 else
8059                         problem = PR_5_BLOCK_RANGE_USED;
8060                 break;
8061         case PR_5_INODE_UNUSED:
8062                 if (pctx->ino == pctx->ino2)
8063                         pctx->ino2 = 0;
8064                 else
8065                         problem = PR_5_INODE_RANGE_UNUSED;
8066                 break;
8067         case PR_5_INODE_USED:
8068                 if (pctx->ino == pctx->ino2)
8069                         pctx->ino2 = 0;
8070                 else
8071                         problem = PR_5_INODE_RANGE_USED;
8072                 break;
8073         }
8074         fix_problem(ctx, problem, pctx);
8075         pctx->blk = pctx->blk2 = NO_BLK;
8076         pctx->ino = pctx->ino2 = 0;
8077 }
8078
8079 static void check_block_bitmaps(e2fsck_t ctx)
8080 {
8081         ext2_filsys fs = ctx->fs;
8082         blk_t   i;
8083         int     *free_array;
8084         int     group = 0;
8085         unsigned int    blocks = 0;
8086         unsigned int    free_blocks = 0;
8087         int     group_free = 0;
8088         int     actual, bitmap;
8089         struct problem_context  pctx;
8090         int     problem, save_problem, fixit, had_problem;
8091         errcode_t       retval;
8092
8093         clear_problem_context(&pctx);
8094         free_array = (int *) e2fsck_allocate_memory(ctx,
8095             fs->group_desc_count * sizeof(int), "free block count array");
8096
8097         if ((fs->super->s_first_data_block <
8098              ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
8099             (fs->super->s_blocks_count-1 >
8100              ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
8101                 pctx.num = 1;
8102                 pctx.blk = fs->super->s_first_data_block;
8103                 pctx.blk2 = fs->super->s_blocks_count -1;
8104                 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
8105                 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
8106                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8107
8108                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8109                 return;
8110         }
8111
8112         if ((fs->super->s_first_data_block <
8113              ext2fs_get_block_bitmap_start(fs->block_map)) ||
8114             (fs->super->s_blocks_count-1 >
8115              ext2fs_get_block_bitmap_end(fs->block_map))) {
8116                 pctx.num = 2;
8117                 pctx.blk = fs->super->s_first_data_block;
8118                 pctx.blk2 = fs->super->s_blocks_count -1;
8119                 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
8120                 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
8121                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8122
8123                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8124                 return;
8125         }
8126
8127 redo_counts:
8128         had_problem = 0;
8129         save_problem = 0;
8130         pctx.blk = pctx.blk2 = NO_BLK;
8131         for (i = fs->super->s_first_data_block;
8132              i < fs->super->s_blocks_count;
8133              i++) {
8134                 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
8135                 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
8136
8137                 if (actual == bitmap)
8138                         goto do_counts;
8139
8140                 if (!actual && bitmap) {
8141                         /*
8142                          * Block not used, but marked in use in the bitmap.
8143                          */
8144                         problem = PR_5_BLOCK_UNUSED;
8145                 } else {
8146                         /*
8147                          * Block used, but not marked in use in the bitmap.
8148                          */
8149                         problem = PR_5_BLOCK_USED;
8150                 }
8151                 if (pctx.blk == NO_BLK) {
8152                         pctx.blk = pctx.blk2 = i;
8153                         save_problem = problem;
8154                 } else {
8155                         if ((problem == save_problem) &&
8156                             (pctx.blk2 == i-1))
8157                                 pctx.blk2++;
8158                         else {
8159                                 print_bitmap_problem(ctx, save_problem, &pctx);
8160                                 pctx.blk = pctx.blk2 = i;
8161                                 save_problem = problem;
8162                         }
8163                 }
8164                 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
8165                 had_problem++;
8166
8167         do_counts:
8168                 if (!bitmap) {
8169                         group_free++;
8170                         free_blocks++;
8171                 }
8172                 blocks ++;
8173                 if ((blocks == fs->super->s_blocks_per_group) ||
8174                     (i == fs->super->s_blocks_count-1)) {
8175                         free_array[group] = group_free;
8176                         group ++;
8177                         blocks = 0;
8178                         group_free = 0;
8179                         if (ctx->progress)
8180                                 if ((ctx->progress)(ctx, 5, group,
8181                                                     fs->group_desc_count*2))
8182                                         return;
8183                 }
8184         }
8185         if (pctx.blk != NO_BLK)
8186                 print_bitmap_problem(ctx, save_problem, &pctx);
8187         if (had_problem)
8188                 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
8189         else
8190                 fixit = -1;
8191         ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
8192
8193         if (fixit == 1) {
8194                 ext2fs_free_block_bitmap(fs->block_map);
8195                 retval = ext2fs_copy_bitmap(ctx->block_found_map,
8196                                                   &fs->block_map);
8197                 if (retval) {
8198                         clear_problem_context(&pctx);
8199                         fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
8200                         ctx->flags |= E2F_FLAG_ABORT;
8201                         return;
8202                 }
8203                 ext2fs_set_bitmap_padding(fs->block_map);
8204                 ext2fs_mark_bb_dirty(fs);
8205
8206                 /* Redo the counts */
8207                 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
8208                 memset(free_array, 0, fs->group_desc_count * sizeof(int));
8209                 goto redo_counts;
8210         } else if (fixit == 0)
8211                 ext2fs_unmark_valid(fs);
8212
8213         for (i = 0; i < fs->group_desc_count; i++) {
8214                 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
8215                         pctx.group = i;
8216                         pctx.blk = fs->group_desc[i].bg_free_blocks_count;
8217                         pctx.blk2 = free_array[i];
8218
8219                         if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
8220                                         &pctx)) {
8221                                 fs->group_desc[i].bg_free_blocks_count =
8222                                         free_array[i];
8223                                 ext2fs_mark_super_dirty(fs);
8224                         } else
8225                                 ext2fs_unmark_valid(fs);
8226                 }
8227         }
8228         if (free_blocks != fs->super->s_free_blocks_count) {
8229                 pctx.group = 0;
8230                 pctx.blk = fs->super->s_free_blocks_count;
8231                 pctx.blk2 = free_blocks;
8232
8233                 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
8234                         fs->super->s_free_blocks_count = free_blocks;
8235                         ext2fs_mark_super_dirty(fs);
8236                 } else
8237                         ext2fs_unmark_valid(fs);
8238         }
8239         ext2fs_free_mem(&free_array);
8240 }
8241
8242 static void check_inode_bitmaps(e2fsck_t ctx)
8243 {
8244         ext2_filsys fs = ctx->fs;
8245         ext2_ino_t      i;
8246         unsigned int    free_inodes = 0;
8247         int             group_free = 0;
8248         int             dirs_count = 0;
8249         int             group = 0;
8250         unsigned int    inodes = 0;
8251         int             *free_array;
8252         int             *dir_array;
8253         int             actual, bitmap;
8254         errcode_t       retval;
8255         struct problem_context  pctx;
8256         int             problem, save_problem, fixit, had_problem;
8257
8258         clear_problem_context(&pctx);
8259         free_array = (int *) e2fsck_allocate_memory(ctx,
8260             fs->group_desc_count * sizeof(int), "free inode count array");
8261
8262         dir_array = (int *) e2fsck_allocate_memory(ctx,
8263            fs->group_desc_count * sizeof(int), "directory count array");
8264
8265         if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
8266             (fs->super->s_inodes_count >
8267              ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
8268                 pctx.num = 3;
8269                 pctx.blk = 1;
8270                 pctx.blk2 = fs->super->s_inodes_count;
8271                 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
8272                 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
8273                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8274
8275                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8276                 return;
8277         }
8278         if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
8279             (fs->super->s_inodes_count >
8280              ext2fs_get_inode_bitmap_end(fs->inode_map))) {
8281                 pctx.num = 4;
8282                 pctx.blk = 1;
8283                 pctx.blk2 = fs->super->s_inodes_count;
8284                 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
8285                 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
8286                 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8287
8288                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8289                 return;
8290         }
8291
8292 redo_counts:
8293         had_problem = 0;
8294         save_problem = 0;
8295         pctx.ino = pctx.ino2 = 0;
8296         for (i = 1; i <= fs->super->s_inodes_count; i++) {
8297                 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
8298                 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
8299
8300                 if (actual == bitmap)
8301                         goto do_counts;
8302
8303                 if (!actual && bitmap) {
8304                         /*
8305                          * Inode wasn't used, but marked in bitmap
8306                          */
8307                         problem = PR_5_INODE_UNUSED;
8308                 } else /* if (actual && !bitmap) */ {
8309                         /*
8310                          * Inode used, but not in bitmap
8311                          */
8312                         problem = PR_5_INODE_USED;
8313                 }
8314                 if (pctx.ino == 0) {
8315                         pctx.ino = pctx.ino2 = i;
8316                         save_problem = problem;
8317                 } else {
8318                         if ((problem == save_problem) &&
8319                             (pctx.ino2 == i-1))
8320                                 pctx.ino2++;
8321                         else {
8322                                 print_bitmap_problem(ctx, save_problem, &pctx);
8323                                 pctx.ino = pctx.ino2 = i;
8324                                 save_problem = problem;
8325                         }
8326                 }
8327                 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
8328                 had_problem++;
8329
8330 do_counts:
8331                 if (!bitmap) {
8332                         group_free++;
8333                         free_inodes++;
8334                 } else {
8335                         if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
8336                                 dirs_count++;
8337                 }
8338                 inodes++;
8339                 if ((inodes == fs->super->s_inodes_per_group) ||
8340                     (i == fs->super->s_inodes_count)) {
8341                         free_array[group] = group_free;
8342                         dir_array[group] = dirs_count;
8343                         group ++;
8344                         inodes = 0;
8345                         group_free = 0;
8346                         dirs_count = 0;
8347                         if (ctx->progress)
8348                                 if ((ctx->progress)(ctx, 5,
8349                                             group + fs->group_desc_count,
8350                                             fs->group_desc_count*2))
8351                                         return;
8352                 }
8353         }
8354         if (pctx.ino)
8355                 print_bitmap_problem(ctx, save_problem, &pctx);
8356
8357         if (had_problem)
8358                 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
8359         else
8360                 fixit = -1;
8361         ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
8362
8363         if (fixit == 1) {
8364                 ext2fs_free_inode_bitmap(fs->inode_map);
8365                 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
8366                                                   &fs->inode_map);
8367                 if (retval) {
8368                         clear_problem_context(&pctx);
8369                         fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
8370                         ctx->flags |= E2F_FLAG_ABORT;
8371                         return;
8372                 }
8373                 ext2fs_set_bitmap_padding(fs->inode_map);
8374                 ext2fs_mark_ib_dirty(fs);
8375
8376                 /* redo counts */
8377                 inodes = 0; free_inodes = 0; group_free = 0;
8378                 dirs_count = 0; group = 0;
8379                 memset(free_array, 0, fs->group_desc_count * sizeof(int));
8380                 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
8381                 goto redo_counts;
8382         } else if (fixit == 0)
8383                 ext2fs_unmark_valid(fs);
8384
8385         for (i = 0; i < fs->group_desc_count; i++) {
8386                 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
8387                         pctx.group = i;
8388                         pctx.ino = fs->group_desc[i].bg_free_inodes_count;
8389                         pctx.ino2 = free_array[i];
8390                         if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
8391                                         &pctx)) {
8392                                 fs->group_desc[i].bg_free_inodes_count =
8393                                         free_array[i];
8394                                 ext2fs_mark_super_dirty(fs);
8395                         } else
8396                                 ext2fs_unmark_valid(fs);
8397                 }
8398                 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
8399                         pctx.group = i;
8400                         pctx.ino = fs->group_desc[i].bg_used_dirs_count;
8401                         pctx.ino2 = dir_array[i];
8402
8403                         if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
8404                                         &pctx)) {
8405                                 fs->group_desc[i].bg_used_dirs_count =
8406                                         dir_array[i];
8407                                 ext2fs_mark_super_dirty(fs);
8408                         } else
8409                                 ext2fs_unmark_valid(fs);
8410                 }
8411         }
8412         if (free_inodes != fs->super->s_free_inodes_count) {
8413                 pctx.group = -1;
8414                 pctx.ino = fs->super->s_free_inodes_count;
8415                 pctx.ino2 = free_inodes;
8416
8417                 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
8418                         fs->super->s_free_inodes_count = free_inodes;
8419                         ext2fs_mark_super_dirty(fs);
8420                 } else
8421                         ext2fs_unmark_valid(fs);
8422         }
8423         ext2fs_free_mem(&free_array);
8424         ext2fs_free_mem(&dir_array);
8425 }
8426
8427 static void check_inode_end(e2fsck_t ctx)
8428 {
8429         ext2_filsys fs = ctx->fs;
8430         ext2_ino_t      end, save_inodes_count, i;
8431         struct problem_context  pctx;
8432
8433         clear_problem_context(&pctx);
8434
8435         end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8436         pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8437                                                      &save_inodes_count);
8438         if (pctx.errcode) {
8439                 pctx.num = 1;
8440                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8441                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8442                 return;
8443         }
8444         if (save_inodes_count == end)
8445                 return;
8446
8447         for (i = save_inodes_count + 1; i <= end; i++) {
8448                 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8449                         if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8450                                 for (i = save_inodes_count + 1; i <= end; i++)
8451                                         ext2fs_mark_inode_bitmap(fs->inode_map,
8452                                                                  i);
8453                                 ext2fs_mark_ib_dirty(fs);
8454                         } else
8455                                 ext2fs_unmark_valid(fs);
8456                         break;
8457                 }
8458         }
8459
8460         pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8461                                                      save_inodes_count, 0);
8462         if (pctx.errcode) {
8463                 pctx.num = 2;
8464                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8465                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8466                 return;
8467         }
8468 }
8469
8470 static void check_block_end(e2fsck_t ctx)
8471 {
8472         ext2_filsys fs = ctx->fs;
8473         blk_t   end, save_blocks_count, i;
8474         struct problem_context  pctx;
8475
8476         clear_problem_context(&pctx);
8477
8478         end = fs->block_map->start +
8479                 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8480         pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8481                                                      &save_blocks_count);
8482         if (pctx.errcode) {
8483                 pctx.num = 3;
8484                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8485                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8486                 return;
8487         }
8488         if (save_blocks_count == end)
8489                 return;
8490
8491         for (i = save_blocks_count + 1; i <= end; i++) {
8492                 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8493                         if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8494                                 for (i = save_blocks_count + 1; i <= end; i++)
8495                                         ext2fs_mark_block_bitmap(fs->block_map,
8496                                                                  i);
8497                                 ext2fs_mark_bb_dirty(fs);
8498                         } else
8499                                 ext2fs_unmark_valid(fs);
8500                         break;
8501                 }
8502         }
8503
8504         pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8505                                                      save_blocks_count, 0);
8506         if (pctx.errcode) {
8507                 pctx.num = 4;
8508                 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8509                 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8510                 return;
8511         }
8512 }
8513
8514 static void e2fsck_pass5(e2fsck_t ctx)
8515 {
8516         struct problem_context  pctx;
8517
8518         /* Pass 5 */
8519
8520         clear_problem_context(&pctx);
8521
8522         if (!(ctx->options & E2F_OPT_PREEN))
8523                 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8524
8525         if (ctx->progress)
8526                 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8527                         return;
8528
8529         e2fsck_read_bitmaps(ctx);
8530
8531         check_block_bitmaps(ctx);
8532         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8533                 return;
8534         check_inode_bitmaps(ctx);
8535         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8536                 return;
8537         check_inode_end(ctx);
8538         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8539                 return;
8540         check_block_end(ctx);
8541         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8542                 return;
8543
8544         ext2fs_free_inode_bitmap(ctx->inode_used_map);
8545         ctx->inode_used_map = 0;
8546         ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8547         ctx->inode_dir_map = 0;
8548         ext2fs_free_block_bitmap(ctx->block_found_map);
8549         ctx->block_found_map = 0;
8550 }
8551
8552 /*
8553  * problem.c --- report filesystem problems to the user
8554  */
8555
8556 #define PR_PREEN_OK     0x000001 /* Don't need to do preenhalt */
8557 #define PR_NO_OK        0x000002 /* If user answers no, don't make fs invalid */
8558 #define PR_NO_DEFAULT   0x000004 /* Default to no */
8559 #define PR_MSG_ONLY     0x000008 /* Print message only */
8560
8561 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8562
8563 #define PR_FATAL        0x001000 /* Fatal error */
8564 #define PR_AFTER_CODE   0x002000 /* After asking the first question, */
8565                                  /* ask another */
8566 #define PR_PREEN_NOMSG  0x004000 /* Don't print a message if we're preening */
8567 #define PR_NOCOLLATE    0x008000 /* Don't collate answers for this latch */
8568 #define PR_NO_NOMSG     0x010000 /* Don't print a message if e2fsck -n */
8569 #define PR_PREEN_NO     0x020000 /* Use No as an answer if preening */
8570 #define PR_PREEN_NOHDR  0x040000 /* Don't print the preen header */
8571
8572
8573 #define PROMPT_NONE     0
8574 #define PROMPT_FIX      1
8575 #define PROMPT_CLEAR    2
8576 #define PROMPT_RELOCATE 3
8577 #define PROMPT_ALLOCATE 4
8578 #define PROMPT_EXPAND   5
8579 #define PROMPT_CONNECT  6
8580 #define PROMPT_CREATE   7
8581 #define PROMPT_SALVAGE  8
8582 #define PROMPT_TRUNCATE 9
8583 #define PROMPT_CLEAR_INODE 10
8584 #define PROMPT_ABORT    11
8585 #define PROMPT_SPLIT    12
8586 #define PROMPT_CONTINUE 13
8587 #define PROMPT_CLONE    14
8588 #define PROMPT_DELETE   15
8589 #define PROMPT_SUPPRESS 16
8590 #define PROMPT_UNLINK   17
8591 #define PROMPT_CLEAR_HTREE 18
8592 #define PROMPT_RECREATE 19
8593 #define PROMPT_NULL     20
8594
8595 struct e2fsck_problem {
8596         problem_t       e2p_code;
8597         const char *    e2p_description;
8598         char            prompt;
8599         int             flags;
8600         problem_t       second_code;
8601 };
8602
8603 struct latch_descr {
8604         int             latch_code;
8605         problem_t       question;
8606         problem_t       end_message;
8607         int             flags;
8608 };
8609
8610 /*
8611  * These are the prompts which are used to ask the user if they want
8612  * to fix a problem.
8613  */
8614 static const char * const prompt[] = {
8615         N_("(no prompt)"),      /* 0 */
8616         N_("Fix"),              /* 1 */
8617         N_("Clear"),            /* 2 */
8618         N_("Relocate"),         /* 3 */
8619         N_("Allocate"),         /* 4 */
8620         N_("Expand"),           /* 5 */
8621         N_("Connect to /lost+found"), /* 6 */
8622         N_("Create"),           /* 7 */
8623         N_("Salvage"),          /* 8 */
8624         N_("Truncate"),         /* 9 */
8625         N_("Clear inode"),      /* 10 */
8626         N_("Abort"),            /* 11 */
8627         N_("Split"),            /* 12 */
8628         N_("Continue"),         /* 13 */
8629         N_("Clone multiply-claimed blocks"), /* 14 */
8630         N_("Delete file"),      /* 15 */
8631         N_("Suppress messages"),/* 16 */
8632         N_("Unlink"),           /* 17 */
8633         N_("Clear HTree index"),/* 18 */
8634         N_("Recreate"),         /* 19 */
8635         "",                     /* 20 */
8636 };
8637
8638 /*
8639  * These messages are printed when we are preen mode and we will be
8640  * automatically fixing the problem.
8641  */
8642 static const char * const preen_msg[] = {
8643         N_("(NONE)"),           /* 0 */
8644         N_("FIXED"),            /* 1 */
8645         N_("CLEARED"),          /* 2 */
8646         N_("RELOCATED"),        /* 3 */
8647         N_("ALLOCATED"),        /* 4 */
8648         N_("EXPANDED"),         /* 5 */
8649         N_("RECONNECTED"),      /* 6 */
8650         N_("CREATED"),          /* 7 */
8651         N_("SALVAGED"),         /* 8 */
8652         N_("TRUNCATED"),        /* 9 */
8653         N_("INODE CLEARED"),    /* 10 */
8654         N_("ABORTED"),          /* 11 */
8655         N_("SPLIT"),            /* 12 */
8656         N_("CONTINUING"),       /* 13 */
8657         N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8658         N_("FILE DELETED"),     /* 15 */
8659         N_("SUPPRESSED"),       /* 16 */
8660         N_("UNLINKED"),         /* 17 */
8661         N_("HTREE INDEX CLEARED"),/* 18 */
8662         N_("WILL RECREATE"),    /* 19 */
8663         "",                     /* 20 */
8664 };
8665
8666 static const struct e2fsck_problem problem_table[] = {
8667
8668         /* Pre-Pass 1 errors */
8669
8670         /* Block bitmap not in group */
8671         { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g.  (@b %b)\n"),
8672           PROMPT_RELOCATE, PR_LATCH_RELOC },
8673
8674         /* Inode bitmap not in group */
8675         { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g.  (@b %b)\n"),
8676           PROMPT_RELOCATE, PR_LATCH_RELOC },
8677
8678         /* Inode table not in group */
8679         { PR_0_ITABLE_NOT_GROUP,
8680           N_("@i table for @g %g is not in @g.  (@b %b)\n"
8681           "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8682           PROMPT_RELOCATE, PR_LATCH_RELOC },
8683
8684         /* Superblock corrupt */
8685         { PR_0_SB_CORRUPT,
8686           N_("\nThe @S could not be read or does not describe a correct ext2\n"
8687           "@f.  If the @v is valid and it really contains an ext2\n"
8688           "@f (and not swap or ufs or something else), then the @S\n"
8689           "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8690           "    e2fsck -b %S <@v>\n\n"),
8691           PROMPT_NONE, PR_FATAL },
8692
8693         /* Filesystem size is wrong */
8694         { PR_0_FS_SIZE_WRONG,
8695           N_("The @f size (according to the @S) is %b @bs\n"
8696           "The physical size of the @v is %c @bs\n"
8697           "Either the @S or the partition table is likely to be corrupt!\n"),
8698           PROMPT_ABORT, 0 },
8699
8700         /* Fragments not supported */
8701         { PR_0_NO_FRAGMENTS,
8702           N_("@S @b_size = %b, fragsize = %c.\n"
8703           "This version of e2fsck does not support fragment sizes different\n"
8704           "from the @b size.\n"),
8705           PROMPT_NONE, PR_FATAL },
8706
8707           /* Bad blocks_per_group */
8708         { PR_0_BLOCKS_PER_GROUP,
8709           N_("@S @bs_per_group = %b, should have been %c\n"),
8710           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8711
8712         /* Bad first_data_block */
8713         { PR_0_FIRST_DATA_BLOCK,
8714           N_("@S first_data_@b = %b, should have been %c\n"),
8715           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8716
8717         /* Adding UUID to filesystem */
8718         { PR_0_ADD_UUID,
8719           N_("@f did not have a UUID; generating one.\n\n"),
8720           PROMPT_NONE, 0 },
8721
8722         /* Relocate hint */
8723         { PR_0_RELOCATE_HINT,
8724           N_("Note: if several inode or block bitmap blocks or part\n"
8725           "of the inode table require relocation, you may wish to try\n"
8726           "running e2fsck with the '-b %S' option first.  The problem\n"
8727           "may lie only with the primary block group descriptors, and\n"
8728           "the backup block group descriptors may be OK.\n\n"),
8729           PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8730
8731         /* Miscellaneous superblock corruption */
8732         { PR_0_MISC_CORRUPT_SUPER,
8733           N_("Corruption found in @S.  (%s = %N).\n"),
8734           PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8735
8736         /* Error determing physical device size of filesystem */
8737         { PR_0_GETSIZE_ERROR,
8738           N_("Error determining size of the physical @v: %m\n"),
8739           PROMPT_NONE, PR_FATAL },
8740
8741         /* Inode count in superblock is incorrect */
8742         { PR_0_INODE_COUNT_WRONG,
8743           N_("@i count in @S is %i, @s %j.\n"),
8744           PROMPT_FIX, 0 },
8745
8746         { PR_0_HURD_CLEAR_FILETYPE,
8747           N_("The Hurd does not support the filetype feature.\n"),
8748           PROMPT_CLEAR, 0 },
8749
8750         /* Journal inode is invalid */
8751         { PR_0_JOURNAL_BAD_INODE,
8752           N_("@S has an @n ext3 @j (@i %i).\n"),
8753           PROMPT_CLEAR, PR_PREEN_OK },
8754
8755         /* The external journal has (unsupported) multiple filesystems */
8756         { PR_0_JOURNAL_UNSUPP_MULTIFS,
8757           N_("External @j has multiple @f users (unsupported).\n"),
8758           PROMPT_NONE, PR_FATAL },
8759
8760         /* Can't find external journal */
8761         { PR_0_CANT_FIND_JOURNAL,
8762           N_("Can't find external @j\n"),
8763           PROMPT_NONE, PR_FATAL },
8764
8765         /* External journal has bad superblock */
8766         { PR_0_EXT_JOURNAL_BAD_SUPER,
8767           N_("External @j has bad @S\n"),
8768           PROMPT_NONE, PR_FATAL },
8769
8770         /* Superblock has a bad journal UUID */
8771         { PR_0_JOURNAL_BAD_UUID,
8772           N_("External @j does not support this @f\n"),
8773           PROMPT_NONE, PR_FATAL },
8774
8775         /* Journal has an unknown superblock type */
8776         { PR_0_JOURNAL_UNSUPP_SUPER,
8777           N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8778              "It is likely that your copy of e2fsck is old and/or doesn't "
8779              "support this @j format.\n"
8780              "It is also possible the @j @S is corrupt.\n"),
8781           PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8782
8783         /* Journal superblock is corrupt */
8784         { PR_0_JOURNAL_BAD_SUPER,
8785           N_("Ext3 @j @S is corrupt.\n"),
8786           PROMPT_FIX, PR_PREEN_OK },
8787
8788         /* Superblock flag should be cleared */
8789         { PR_0_JOURNAL_HAS_JOURNAL,
8790           N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8791           PROMPT_CLEAR, PR_PREEN_OK },
8792
8793         /* Superblock flag is incorrect */
8794         { PR_0_JOURNAL_RECOVER_SET,
8795           N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8796           PROMPT_CLEAR, PR_PREEN_OK },
8797
8798         /* Journal has data, but recovery flag is clear */
8799         { PR_0_JOURNAL_RECOVERY_CLEAR,
8800           N_("ext3 recovery flag is clear, but @j has data.\n"),
8801           PROMPT_NONE, 0 },
8802
8803         /* Ask if we should clear the journal */
8804         { PR_0_JOURNAL_RESET_JOURNAL,
8805           N_("Clear @j"),
8806           PROMPT_NULL, PR_PREEN_NOMSG },
8807
8808         /* Ask if we should run the journal anyway */
8809         { PR_0_JOURNAL_RUN,
8810           N_("Run @j anyway"),
8811           PROMPT_NULL, 0 },
8812
8813         /* Run the journal by default */
8814         { PR_0_JOURNAL_RUN_DEFAULT,
8815           N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8816           PROMPT_NONE, 0 },
8817
8818         /* Clearing orphan inode */
8819         { PR_0_ORPHAN_CLEAR_INODE,
8820           N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8821           PROMPT_NONE, 0 },
8822
8823         /* Illegal block found in orphaned inode */
8824         { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8825            N_("@I @b #%B (%b) found in @o @i %i.\n"),
8826           PROMPT_NONE, 0 },
8827
8828         /* Already cleared block found in orphaned inode */
8829         { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8830            N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8831           PROMPT_NONE, 0 },
8832
8833         /* Illegal orphan inode in superblock */
8834         { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8835           N_("@I @o @i %i in @S.\n"),
8836           PROMPT_NONE, 0 },
8837
8838         /* Illegal inode in orphaned inode list */
8839         { PR_0_ORPHAN_ILLEGAL_INODE,
8840           N_("@I @i %i in @o @i list.\n"),
8841           PROMPT_NONE, 0 },
8842
8843         /* Filesystem revision is 0, but feature flags are set */
8844         { PR_0_FS_REV_LEVEL,
8845           N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
8846           PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8847
8848         /* Journal superblock has an unknown read-only feature flag set */
8849         { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8850           N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8851           PROMPT_ABORT, 0 },
8852
8853         /* Journal superblock has an unknown incompatible feature flag set */
8854         { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8855           N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8856           PROMPT_ABORT, 0 },
8857
8858         /* Journal has unsupported version number */
8859         { PR_0_JOURNAL_UNSUPP_VERSION,
8860           N_("@j version not supported by this e2fsck.\n"),
8861           PROMPT_ABORT, 0 },
8862
8863         /* Moving journal to hidden file */
8864         { PR_0_MOVE_JOURNAL,
8865           N_("Moving @j from /%s to hidden @i.\n\n"),
8866           PROMPT_NONE, 0 },
8867
8868         /* Error moving journal to hidden file */
8869         { PR_0_ERR_MOVE_JOURNAL,
8870           N_("Error moving @j: %m\n\n"),
8871           PROMPT_NONE, 0 },
8872
8873         /* Clearing V2 journal superblock */
8874         { PR_0_CLEAR_V2_JOURNAL,
8875           N_("Found @n V2 @j @S fields (from V1 @j).\n"
8876              "Clearing fields beyond the V1 @j @S...\n\n"),
8877           PROMPT_NONE, 0 },
8878
8879         /* Backup journal inode blocks */
8880         { PR_0_BACKUP_JNL,
8881           N_("Backing up @j @i @b information.\n\n"),
8882           PROMPT_NONE, 0 },
8883
8884         /* Reserved blocks w/o resize_inode */
8885         { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8886           N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8887              "is %N; @s zero.  "),
8888           PROMPT_FIX, 0 },
8889
8890         /* Resize_inode not enabled, but resize inode is non-zero */
8891         { PR_0_CLEAR_RESIZE_INODE,
8892           N_("Resize_@i not enabled, but the resize @i is non-zero.  "),
8893           PROMPT_CLEAR, 0 },
8894
8895         /* Resize inode invalid */
8896         { PR_0_RESIZE_INODE_INVALID,
8897           N_("Resize @i not valid.  "),
8898           PROMPT_RECREATE, 0 },
8899
8900         /* Pass 1 errors */
8901
8902         /* Pass 1: Checking inodes, blocks, and sizes */
8903         { PR_1_PASS_HEADER,
8904           N_("Pass 1: Checking @is, @bs, and sizes\n"),
8905           PROMPT_NONE, 0 },
8906
8907         /* Root directory is not an inode */
8908         { PR_1_ROOT_NO_DIR, N_("@r is not a @d.  "),
8909           PROMPT_CLEAR, 0 },
8910
8911         /* Root directory has dtime set */
8912         { PR_1_ROOT_DTIME,
8913           N_("@r has dtime set (probably due to old mke2fs).  "),
8914           PROMPT_FIX, PR_PREEN_OK },
8915
8916         /* Reserved inode has bad mode */
8917         { PR_1_RESERVED_BAD_MODE,
8918           N_("Reserved @i %i (%Q) has @n mode.  "),
8919           PROMPT_CLEAR, PR_PREEN_OK },
8920
8921         /* Deleted inode has zero dtime */
8922         { PR_1_ZERO_DTIME,
8923           N_("@D @i %i has zero dtime.  "),
8924           PROMPT_FIX, PR_PREEN_OK },
8925
8926         /* Inode in use, but dtime set */
8927         { PR_1_SET_DTIME,
8928           N_("@i %i is in use, but has dtime set.  "),
8929           PROMPT_FIX, PR_PREEN_OK },
8930
8931         /* Zero-length directory */
8932         { PR_1_ZERO_LENGTH_DIR,
8933           N_("@i %i is a @z @d.  "),
8934           PROMPT_CLEAR, PR_PREEN_OK },
8935
8936         /* Block bitmap conflicts with some other fs block */
8937         { PR_1_BB_CONFLICT,
8938           N_("@g %g's @b @B at %b @C.\n"),
8939           PROMPT_RELOCATE, 0 },
8940
8941         /* Inode bitmap conflicts with some other fs block */
8942         { PR_1_IB_CONFLICT,
8943           N_("@g %g's @i @B at %b @C.\n"),
8944           PROMPT_RELOCATE, 0 },
8945
8946         /* Inode table conflicts with some other fs block */
8947         { PR_1_ITABLE_CONFLICT,
8948           N_("@g %g's @i table at %b @C.\n"),
8949           PROMPT_RELOCATE, 0 },
8950
8951         /* Block bitmap is on a bad block */
8952         { PR_1_BB_BAD_BLOCK,
8953           N_("@g %g's @b @B (%b) is bad.  "),
8954           PROMPT_RELOCATE, 0 },
8955
8956         /* Inode bitmap is on a bad block */
8957         { PR_1_IB_BAD_BLOCK,
8958           N_("@g %g's @i @B (%b) is bad.  "),
8959           PROMPT_RELOCATE, 0 },
8960
8961         /* Inode has incorrect i_size */
8962         { PR_1_BAD_I_SIZE,
8963           N_("@i %i, i_size is %Is, @s %N.  "),
8964           PROMPT_FIX, PR_PREEN_OK },
8965
8966         /* Inode has incorrect i_blocks */
8967         { PR_1_BAD_I_BLOCKS,
8968           N_("@i %i, i_@bs is %Ib, @s %N.  "),
8969           PROMPT_FIX, PR_PREEN_OK },
8970
8971         /* Illegal blocknumber in inode */
8972         { PR_1_ILLEGAL_BLOCK_NUM,
8973           N_("@I @b #%B (%b) in @i %i.  "),
8974           PROMPT_CLEAR, PR_LATCH_BLOCK },
8975
8976         /* Block number overlaps fs metadata */
8977         { PR_1_BLOCK_OVERLAPS_METADATA,
8978           N_("@b #%B (%b) overlaps @f metadata in @i %i.  "),
8979           PROMPT_CLEAR, PR_LATCH_BLOCK },
8980
8981         /* Inode has illegal blocks (latch question) */
8982         { PR_1_INODE_BLOCK_LATCH,
8983           N_("@i %i has illegal @b(s).  "),
8984           PROMPT_CLEAR, 0 },
8985
8986         /* Too many bad blocks in inode */
8987         { PR_1_TOO_MANY_BAD_BLOCKS,
8988           N_("Too many illegal @bs in @i %i.\n"),
8989           PROMPT_CLEAR_INODE, PR_NO_OK },
8990
8991         /* Illegal block number in bad block inode */
8992         { PR_1_BB_ILLEGAL_BLOCK_NUM,
8993           N_("@I @b #%B (%b) in bad @b @i.  "),
8994           PROMPT_CLEAR, PR_LATCH_BBLOCK },
8995
8996         /* Bad block inode has illegal blocks (latch question) */
8997         { PR_1_INODE_BBLOCK_LATCH,
8998           N_("Bad @b @i has illegal @b(s).  "),
8999           PROMPT_CLEAR, 0 },
9000
9001         /* Duplicate or bad blocks in use! */
9002         { PR_1_DUP_BLOCKS_PREENSTOP,
9003           N_("Duplicate or bad @b in use!\n"),
9004           PROMPT_NONE, 0 },
9005
9006         /* Bad block used as bad block indirect block */
9007         { PR_1_BBINODE_BAD_METABLOCK,
9008           N_("Bad @b %b used as bad @b @i indirect @b.  "),
9009           PROMPT_CLEAR, PR_LATCH_BBLOCK },
9010
9011         /* Inconsistency can't be fixed prompt */
9012         { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
9013           N_("\nThe bad @b @i has probably been corrupted.  You probably\n"
9014              "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
9015              "in the @f.\n"),
9016           PROMPT_CONTINUE, PR_PREEN_NOMSG },
9017
9018         /* Bad primary block */
9019         { PR_1_BAD_PRIMARY_BLOCK,
9020           N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
9021           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
9022
9023         /* Bad primary block prompt */
9024         { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
9025           N_("You can remove this @b from the bad @b list and hope\n"
9026              "that the @b is really OK.  But there are no guarantees.\n\n"),
9027           PROMPT_CLEAR, PR_PREEN_NOMSG },
9028
9029         /* Bad primary superblock */
9030         { PR_1_BAD_PRIMARY_SUPERBLOCK,
9031           N_("The primary @S (%b) is on the bad @b list.\n"),
9032           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9033
9034         /* Bad primary block group descriptors */
9035         { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
9036           N_("Block %b in the primary @g descriptors "
9037           "is on the bad @b list\n"),
9038           PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9039
9040         /* Bad superblock in group */
9041         { PR_1_BAD_SUPERBLOCK,
9042           N_("Warning: Group %g's @S (%b) is bad.\n"),
9043           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9044
9045         /* Bad block group descriptors in group */
9046         { PR_1_BAD_GROUP_DESCRIPTORS,
9047           N_("Warning: Group %g's copy of the @g descriptors has a bad "
9048           "@b (%b).\n"),
9049           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9050
9051         /* Block claimed for no reason */
9052         { PR_1_PROGERR_CLAIMED_BLOCK,
9053           N_("Programming error?  @b #%b claimed for no reason in "
9054           "process_bad_@b.\n"),
9055           PROMPT_NONE, PR_PREEN_OK },
9056
9057         /* Error allocating blocks for relocating metadata */
9058         { PR_1_RELOC_BLOCK_ALLOCATE,
9059           N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
9060           PROMPT_NONE, PR_PREEN_OK },
9061
9062         /* Error allocating block buffer during relocation process */
9063         { PR_1_RELOC_MEMORY_ALLOCATE,
9064           N_("@A @b buffer for relocating %s\n"),
9065           PROMPT_NONE, PR_PREEN_OK },
9066
9067         /* Relocating metadata group information from X to Y */
9068         { PR_1_RELOC_FROM_TO,
9069           N_("Relocating @g %g's %s from %b to %c...\n"),
9070           PROMPT_NONE, PR_PREEN_OK },
9071
9072         /* Relocating metatdata group information to X */
9073         { PR_1_RELOC_TO,
9074           N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
9075           PROMPT_NONE, PR_PREEN_OK },
9076
9077         /* Block read error during relocation process */
9078         { PR_1_RELOC_READ_ERR,
9079           N_("Warning: could not read @b %b of %s: %m\n"),
9080           PROMPT_NONE, PR_PREEN_OK },
9081
9082         /* Block write error during relocation process */
9083         { PR_1_RELOC_WRITE_ERR,
9084           N_("Warning: could not write @b %b for %s: %m\n"),
9085           PROMPT_NONE, PR_PREEN_OK },
9086
9087         /* Error allocating inode bitmap */
9088         { PR_1_ALLOCATE_IBITMAP_ERROR,
9089           N_("@A @i @B (%N): %m\n"),
9090           PROMPT_NONE, PR_FATAL },
9091
9092         /* Error allocating block bitmap */
9093         { PR_1_ALLOCATE_BBITMAP_ERROR,
9094           N_("@A @b @B (%N): %m\n"),
9095           PROMPT_NONE, PR_FATAL },
9096
9097         /* Error allocating icount structure */
9098         { PR_1_ALLOCATE_ICOUNT,
9099           N_("@A icount link information: %m\n"),
9100           PROMPT_NONE, PR_FATAL },
9101
9102         /* Error allocating dbcount */
9103         { PR_1_ALLOCATE_DBCOUNT,
9104           N_("@A @d @b array: %m\n"),
9105           PROMPT_NONE, PR_FATAL },
9106
9107         /* Error while scanning inodes */
9108         { PR_1_ISCAN_ERROR,
9109           N_("Error while scanning @is (%i): %m\n"),
9110           PROMPT_NONE, PR_FATAL },
9111
9112         /* Error while iterating over blocks */
9113         { PR_1_BLOCK_ITERATE,
9114           N_("Error while iterating over @bs in @i %i: %m\n"),
9115           PROMPT_NONE, PR_FATAL },
9116
9117         /* Error while storing inode count information */
9118         { PR_1_ICOUNT_STORE,
9119           N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
9120           PROMPT_NONE, PR_FATAL },
9121
9122         /* Error while storing directory block information */
9123         { PR_1_ADD_DBLOCK,
9124           N_("Error storing @d @b information "
9125           "(@i=%i, @b=%b, num=%N): %m\n"),
9126           PROMPT_NONE, PR_FATAL },
9127
9128         /* Error while reading inode (for clearing) */
9129         { PR_1_READ_INODE,
9130           N_("Error reading @i %i: %m\n"),
9131           PROMPT_NONE, PR_FATAL },
9132
9133         /* Suppress messages prompt */
9134         { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
9135
9136         /* Imagic flag set on an inode when filesystem doesn't support it */
9137         { PR_1_SET_IMAGIC,
9138           N_("@i %i has imagic flag set.  "),
9139           PROMPT_CLEAR, 0 },
9140
9141         /* Immutable flag set on a device or socket inode */
9142         { PR_1_SET_IMMUTABLE,
9143           N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
9144              "or append-only flag set.  "),
9145           PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
9146
9147         /* Compression flag set on an inode when filesystem doesn't support it */
9148         { PR_1_COMPR_SET,
9149           N_("@i %i has @cion flag set on @f without @cion support.  "),
9150           PROMPT_CLEAR, 0 },
9151
9152         /* Non-zero size for device, fifo or socket inode */
9153         { PR_1_SET_NONZSIZE,
9154           N_("Special (@v/socket/fifo) @i %i has non-zero size.  "),
9155           PROMPT_FIX, PR_PREEN_OK },
9156
9157         /* Filesystem revision is 0, but feature flags are set */
9158         { PR_1_FS_REV_LEVEL,
9159           N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
9160           PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
9161
9162         /* Journal inode is not in use, but contains data */
9163         { PR_1_JOURNAL_INODE_NOT_CLEAR,
9164           N_("@j @i is not in use, but contains data.  "),
9165           PROMPT_CLEAR, PR_PREEN_OK },
9166
9167         /* Journal has bad mode */
9168         { PR_1_JOURNAL_BAD_MODE,
9169           N_("@j is not regular file.  "),
9170           PROMPT_FIX, PR_PREEN_OK },
9171
9172         /* Deal with inodes that were part of orphan linked list */
9173         { PR_1_LOW_DTIME,
9174           N_("@i %i was part of the @o @i list.  "),
9175           PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
9176
9177         /* Deal with inodes that were part of corrupted orphan linked
9178            list (latch question) */
9179         { PR_1_ORPHAN_LIST_REFUGEES,
9180           N_("@is that were part of a corrupted orphan linked list found.  "),
9181           PROMPT_FIX, 0 },
9182
9183         /* Error allocating refcount structure */
9184         { PR_1_ALLOCATE_REFCOUNT,
9185           N_("@A refcount structure (%N): %m\n"),
9186           PROMPT_NONE, PR_FATAL },
9187
9188         /* Error reading extended attribute block */
9189         { PR_1_READ_EA_BLOCK,
9190           N_("Error reading @a @b %b for @i %i.  "),
9191           PROMPT_CLEAR, 0 },
9192
9193         /* Invalid extended attribute block */
9194         { PR_1_BAD_EA_BLOCK,
9195           N_("@i %i has a bad @a @b %b.  "),
9196           PROMPT_CLEAR, 0 },
9197
9198         /* Error reading Extended Attribute block while fixing refcount */
9199         { PR_1_EXTATTR_READ_ABORT,
9200           N_("Error reading @a @b %b (%m).  "),
9201           PROMPT_ABORT, 0 },
9202
9203         /* Extended attribute reference count incorrect */
9204         { PR_1_EXTATTR_REFCOUNT,
9205           N_("@a @b %b has reference count %B, @s %N.  "),
9206           PROMPT_FIX, 0 },
9207
9208         /* Error writing Extended Attribute block while fixing refcount */
9209         { PR_1_EXTATTR_WRITE,
9210           N_("Error writing @a @b %b (%m).  "),
9211           PROMPT_ABORT, 0 },
9212
9213         /* Multiple EA blocks not supported */
9214         { PR_1_EA_MULTI_BLOCK,
9215           N_("@a @b %b has h_@bs > 1.  "),
9216           PROMPT_CLEAR, 0},
9217
9218         /* Error allocating EA region allocation structure */
9219         { PR_1_EA_ALLOC_REGION,
9220           N_("@A @a @b %b.  "),
9221           PROMPT_ABORT, 0},
9222
9223         /* Error EA allocation collision */
9224         { PR_1_EA_ALLOC_COLLISION,
9225           N_("@a @b %b is corrupt (allocation collision).  "),
9226           PROMPT_CLEAR, 0},
9227
9228         /* Bad extended attribute name */
9229         { PR_1_EA_BAD_NAME,
9230           N_("@a @b %b is corrupt (@n name).  "),
9231           PROMPT_CLEAR, 0},
9232
9233         /* Bad extended attribute value */
9234         { PR_1_EA_BAD_VALUE,
9235           N_("@a @b %b is corrupt (@n value).  "),
9236           PROMPT_CLEAR, 0},
9237
9238         /* Inode too big (latch question) */
9239         { PR_1_INODE_TOOBIG,
9240           N_("@i %i is too big.  "), PROMPT_TRUNCATE, 0 },
9241
9242         /* Directory too big */
9243         { PR_1_TOOBIG_DIR,
9244           N_("@b #%B (%b) causes @d to be too big.  "),
9245           PROMPT_CLEAR, PR_LATCH_TOOBIG },
9246
9247         /* Regular file too big */
9248         { PR_1_TOOBIG_REG,
9249           N_("@b #%B (%b) causes file to be too big.  "),
9250           PROMPT_CLEAR, PR_LATCH_TOOBIG },
9251
9252         /* Symlink too big */
9253         { PR_1_TOOBIG_SYMLINK,
9254           N_("@b #%B (%b) causes symlink to be too big.  "),
9255           PROMPT_CLEAR, PR_LATCH_TOOBIG },
9256
9257         /* INDEX_FL flag set on a non-HTREE filesystem */
9258         { PR_1_HTREE_SET,
9259           N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
9260           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9261
9262         /* INDEX_FL flag set on a non-directory */
9263         { PR_1_HTREE_NODIR,
9264           N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
9265           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9266
9267         /* Invalid root node in HTREE directory */
9268         { PR_1_HTREE_BADROOT,
9269           N_("@h %i has an @n root node.\n"),
9270           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9271
9272         /* Unsupported hash version in HTREE directory */
9273         { PR_1_HTREE_HASHV,
9274           N_("@h %i has an unsupported hash version (%N)\n"),
9275           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9276
9277         /* Incompatible flag in HTREE root node */
9278         { PR_1_HTREE_INCOMPAT,
9279           N_("@h %i uses an incompatible htree root node flag.\n"),
9280           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9281
9282         /* HTREE too deep */
9283         { PR_1_HTREE_DEPTH,
9284           N_("@h %i has a tree depth (%N) which is too big\n"),
9285           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9286
9287         /* Bad block has indirect block that conflicts with filesystem block */
9288         { PR_1_BB_FS_BLOCK,
9289           N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
9290              "@f metadata.  "),
9291           PROMPT_CLEAR, PR_LATCH_BBLOCK },
9292
9293         /* Resize inode failed */
9294         { PR_1_RESIZE_INODE_CREATE,
9295           N_("Resize @i (re)creation failed: %m."),
9296           PROMPT_ABORT, 0 },
9297
9298         /* invalid inode->i_extra_isize */
9299         { PR_1_EXTRA_ISIZE,
9300           N_("@i %i has a extra size (%IS) which is @n\n"),
9301           PROMPT_FIX, PR_PREEN_OK },
9302
9303         /* invalid ea entry->e_name_len */
9304         { PR_1_ATTR_NAME_LEN,
9305           N_("@a in @i %i has a namelen (%N) which is @n\n"),
9306           PROMPT_CLEAR, PR_PREEN_OK },
9307
9308         /* invalid ea entry->e_value_size */
9309         { PR_1_ATTR_VALUE_SIZE,
9310           N_("@a in @i %i has a value size (%N) which is @n\n"),
9311           PROMPT_CLEAR, PR_PREEN_OK },
9312
9313         /* invalid ea entry->e_value_offs */
9314         { PR_1_ATTR_VALUE_OFFSET,
9315           N_("@a in @i %i has a value offset (%N) which is @n\n"),
9316           PROMPT_CLEAR, PR_PREEN_OK },
9317
9318         /* invalid ea entry->e_value_block */
9319         { PR_1_ATTR_VALUE_BLOCK,
9320           N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
9321           PROMPT_CLEAR, PR_PREEN_OK },
9322
9323         /* invalid ea entry->e_hash */
9324         { PR_1_ATTR_HASH,
9325           N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
9326           PROMPT_CLEAR, PR_PREEN_OK },
9327
9328         /* Pass 1b errors */
9329
9330         /* Pass 1B: Rescan for duplicate/bad blocks */
9331         { PR_1B_PASS_HEADER,
9332           N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
9333           "Pass 1B: Rescanning for @m @bs\n"),
9334           PROMPT_NONE, 0 },
9335
9336         /* Duplicate/bad block(s) header */
9337         { PR_1B_DUP_BLOCK_HEADER,
9338           N_("@m @b(s) in @i %i:"),
9339           PROMPT_NONE, 0 },
9340
9341         /* Duplicate/bad block(s) in inode */
9342         { PR_1B_DUP_BLOCK,
9343           " %b",
9344           PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
9345
9346         /* Duplicate/bad block(s) end */
9347         { PR_1B_DUP_BLOCK_END,
9348           "\n",
9349           PROMPT_NONE, PR_PREEN_NOHDR },
9350
9351         /* Error while scanning inodes */
9352         { PR_1B_ISCAN_ERROR,
9353           N_("Error while scanning inodes (%i): %m\n"),
9354           PROMPT_NONE, PR_FATAL },
9355
9356         /* Error allocating inode bitmap */
9357         { PR_1B_ALLOCATE_IBITMAP_ERROR,
9358           N_("@A @i @B (@i_dup_map): %m\n"),
9359           PROMPT_NONE, PR_FATAL },
9360
9361         /* Error while iterating over blocks */
9362         { PR_1B_BLOCK_ITERATE,
9363           N_("Error while iterating over @bs in @i %i (%s): %m\n"),
9364           PROMPT_NONE, 0 },
9365
9366         /* Error adjusting EA refcount */
9367         { PR_1B_ADJ_EA_REFCOUNT,
9368           N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9369           PROMPT_NONE, 0 },
9370
9371
9372         /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
9373         { PR_1C_PASS_HEADER,
9374           N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
9375           PROMPT_NONE, 0 },
9376
9377
9378         /* Pass 1D: Reconciling multiply-claimed blocks */
9379         { PR_1D_PASS_HEADER,
9380           N_("Pass 1D: Reconciling @m @bs\n"),
9381           PROMPT_NONE, 0 },
9382
9383         /* File has duplicate blocks */
9384         { PR_1D_DUP_FILE,
9385           N_("File %Q (@i #%i, mod time %IM) \n"
9386           "  has %B @m @b(s), shared with %N file(s):\n"),
9387           PROMPT_NONE, 0 },
9388
9389         /* List of files sharing duplicate blocks */
9390         { PR_1D_DUP_FILE_LIST,
9391           N_("\t%Q (@i #%i, mod time %IM)\n"),
9392           PROMPT_NONE, 0 },
9393
9394         /* File sharing blocks with filesystem metadata  */
9395         { PR_1D_SHARE_METADATA,
9396           N_("\t<@f metadata>\n"),
9397           PROMPT_NONE, 0 },
9398
9399         /* Report of how many duplicate/bad inodes */
9400         { PR_1D_NUM_DUP_INODES,
9401           N_("(There are %N @is containing @m @bs.)\n\n"),
9402           PROMPT_NONE, 0 },
9403
9404         /* Duplicated blocks already reassigned or cloned. */
9405         { PR_1D_DUP_BLOCKS_DEALT,
9406           N_("@m @bs already reassigned or cloned.\n\n"),
9407           PROMPT_NONE, 0 },
9408
9409         /* Clone duplicate/bad blocks? */
9410         { PR_1D_CLONE_QUESTION,
9411           "", PROMPT_CLONE, PR_NO_OK },
9412
9413         /* Delete file? */
9414         { PR_1D_DELETE_QUESTION,
9415           "", PROMPT_DELETE, 0 },
9416
9417         /* Couldn't clone file (error) */
9418         { PR_1D_CLONE_ERROR,
9419           N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
9420
9421         /* Pass 2 errors */
9422
9423         /* Pass 2: Checking directory structure */
9424         { PR_2_PASS_HEADER,
9425           N_("Pass 2: Checking @d structure\n"),
9426           PROMPT_NONE, 0 },
9427
9428         /* Bad inode number for '.' */
9429         { PR_2_BAD_INODE_DOT,
9430           N_("@n @i number for '.' in @d @i %i.\n"),
9431           PROMPT_FIX, 0 },
9432
9433         /* Directory entry has bad inode number */
9434         { PR_2_BAD_INO,
9435           N_("@E has @n @i #: %Di.\n"),
9436           PROMPT_CLEAR, 0 },
9437
9438         /* Directory entry has deleted or unused inode */
9439         { PR_2_UNUSED_INODE,
9440           N_("@E has @D/unused @i %Di.  "),
9441           PROMPT_CLEAR, PR_PREEN_OK },
9442
9443         /* Directry entry is link to '.' */
9444         { PR_2_LINK_DOT,
9445           N_("@E @L to '.'  "),
9446           PROMPT_CLEAR, 0 },
9447
9448         /* Directory entry points to inode now located in a bad block */
9449         { PR_2_BB_INODE,
9450           N_("@E points to @i (%Di) located in a bad @b.\n"),
9451           PROMPT_CLEAR, 0 },
9452
9453         /* Directory entry contains a link to a directory */
9454         { PR_2_LINK_DIR,
9455           N_("@E @L to @d %P (%Di).\n"),
9456           PROMPT_CLEAR, 0 },
9457
9458         /* Directory entry contains a link to the root directry */
9459         { PR_2_LINK_ROOT,
9460           N_("@E @L to the @r.\n"),
9461           PROMPT_CLEAR, 0 },
9462
9463         /* Directory entry has illegal characters in its name */
9464         { PR_2_BAD_NAME,
9465           N_("@E has illegal characters in its name.\n"),
9466           PROMPT_FIX, 0 },
9467
9468         /* Missing '.' in directory inode */
9469         { PR_2_MISSING_DOT,
9470           N_("Missing '.' in @d @i %i.\n"),
9471           PROMPT_FIX, 0 },
9472
9473         /* Missing '..' in directory inode */
9474         { PR_2_MISSING_DOT_DOT,
9475           N_("Missing '..' in @d @i %i.\n"),
9476           PROMPT_FIX, 0 },
9477
9478         /* First entry in directory inode doesn't contain '.' */
9479         { PR_2_1ST_NOT_DOT,
9480           N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9481           PROMPT_FIX, 0 },
9482
9483         /* Second entry in directory inode doesn't contain '..' */
9484         { PR_2_2ND_NOT_DOT_DOT,
9485           N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9486           PROMPT_FIX, 0 },
9487
9488         /* i_faddr should be zero */
9489         { PR_2_FADDR_ZERO,
9490           N_("i_faddr @F %IF, @s zero.\n"),
9491           PROMPT_CLEAR, 0 },
9492
9493         /* i_file_acl should be zero */
9494         { PR_2_FILE_ACL_ZERO,
9495           N_("i_file_acl @F %If, @s zero.\n"),
9496           PROMPT_CLEAR, 0 },
9497
9498         /* i_dir_acl should be zero */
9499         { PR_2_DIR_ACL_ZERO,
9500           N_("i_dir_acl @F %Id, @s zero.\n"),
9501           PROMPT_CLEAR, 0 },
9502
9503         /* i_frag should be zero */
9504         { PR_2_FRAG_ZERO,
9505           N_("i_frag @F %N, @s zero.\n"),
9506           PROMPT_CLEAR, 0 },
9507
9508         /* i_fsize should be zero */
9509         { PR_2_FSIZE_ZERO,
9510           N_("i_fsize @F %N, @s zero.\n"),
9511           PROMPT_CLEAR, 0 },
9512
9513         /* inode has bad mode */
9514         { PR_2_BAD_MODE,
9515           N_("@i %i (%Q) has @n mode (%Im).\n"),
9516           PROMPT_CLEAR, 0 },
9517
9518         /* directory corrupted */
9519         { PR_2_DIR_CORRUPTED,
9520           N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9521           PROMPT_SALVAGE, 0 },
9522
9523         /* filename too long */
9524         { PR_2_FILENAME_LONG,
9525           N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9526           PROMPT_TRUNCATE, 0 },
9527
9528         /* Directory inode has a missing block (hole) */
9529         { PR_2_DIRECTORY_HOLE,
9530           N_("@d @i %i has an unallocated @b #%B.  "),
9531           PROMPT_ALLOCATE, 0 },
9532
9533         /* '.' is not NULL terminated */
9534         { PR_2_DOT_NULL_TERM,
9535           N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9536           PROMPT_FIX, 0 },
9537
9538         /* '..' is not NULL terminated */
9539         { PR_2_DOT_DOT_NULL_TERM,
9540           N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9541           PROMPT_FIX, 0 },
9542
9543         /* Illegal character device inode */
9544         { PR_2_BAD_CHAR_DEV,
9545           N_("@i %i (%Q) is an @I character @v.\n"),
9546           PROMPT_CLEAR, 0 },
9547
9548         /* Illegal block device inode */
9549         { PR_2_BAD_BLOCK_DEV,
9550           N_("@i %i (%Q) is an @I @b @v.\n"),
9551           PROMPT_CLEAR, 0 },
9552
9553         /* Duplicate '.' entry */
9554         { PR_2_DUP_DOT,
9555           N_("@E is duplicate '.' @e.\n"),
9556           PROMPT_FIX, 0 },
9557
9558         /* Duplicate '..' entry */
9559         { PR_2_DUP_DOT_DOT,
9560           N_("@E is duplicate '..' @e.\n"),
9561           PROMPT_FIX, 0 },
9562
9563         /* Internal error: couldn't find dir_info */
9564         { PR_2_NO_DIRINFO,
9565           N_("Internal error: couldn't find dir_info for %i.\n"),
9566           PROMPT_NONE, PR_FATAL },
9567
9568         /* Final rec_len is wrong */
9569         { PR_2_FINAL_RECLEN,
9570           N_("@E has rec_len of %Dr, @s %N.\n"),
9571           PROMPT_FIX, 0 },
9572
9573         /* Error allocating icount structure */
9574         { PR_2_ALLOCATE_ICOUNT,
9575           N_("@A icount structure: %m\n"),
9576           PROMPT_NONE, PR_FATAL },
9577
9578         /* Error iterating over directory blocks */
9579         { PR_2_DBLIST_ITERATE,
9580           N_("Error iterating over @d @bs: %m\n"),
9581           PROMPT_NONE, PR_FATAL },
9582
9583         /* Error reading directory block */
9584         { PR_2_READ_DIRBLOCK,
9585           N_("Error reading @d @b %b (@i %i): %m\n"),
9586           PROMPT_CONTINUE, 0 },
9587
9588         /* Error writing directory block */
9589         { PR_2_WRITE_DIRBLOCK,
9590           N_("Error writing @d @b %b (@i %i): %m\n"),
9591           PROMPT_CONTINUE, 0 },
9592
9593         /* Error allocating new directory block */
9594         { PR_2_ALLOC_DIRBOCK,
9595           N_("@A new @d @b for @i %i (%s): %m\n"),
9596           PROMPT_NONE, 0 },
9597
9598         /* Error deallocating inode */
9599         { PR_2_DEALLOC_INODE,
9600           N_("Error deallocating @i %i: %m\n"),
9601           PROMPT_NONE, PR_FATAL },
9602
9603         /* Directory entry for '.' is big.  Split? */
9604         { PR_2_SPLIT_DOT,
9605           N_("@d @e for '.' is big.  "),
9606           PROMPT_SPLIT, PR_NO_OK },
9607
9608         /* Illegal FIFO inode */
9609         { PR_2_BAD_FIFO,
9610           N_("@i %i (%Q) is an @I FIFO.\n"),
9611           PROMPT_CLEAR, 0 },
9612
9613         /* Illegal socket inode */
9614         { PR_2_BAD_SOCKET,
9615           N_("@i %i (%Q) is an @I socket.\n"),
9616           PROMPT_CLEAR, 0 },
9617
9618         /* Directory filetype not set */
9619         { PR_2_SET_FILETYPE,
9620           N_("Setting filetype for @E to %N.\n"),
9621           PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9622
9623         /* Directory filetype incorrect */
9624         { PR_2_BAD_FILETYPE,
9625           N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9626           PROMPT_FIX, 0 },
9627
9628         /* Directory filetype set on filesystem */
9629         { PR_2_CLEAR_FILETYPE,
9630           N_("@E has filetype set.\n"),
9631           PROMPT_CLEAR, PR_PREEN_OK },
9632
9633         /* Directory filename is null */
9634         { PR_2_NULL_NAME,
9635           N_("@E has a @z name.\n"),
9636           PROMPT_CLEAR, 0 },
9637
9638         /* Invalid symlink */
9639         { PR_2_INVALID_SYMLINK,
9640           N_("Symlink %Q (@i #%i) is @n.\n"),
9641           PROMPT_CLEAR, 0 },
9642
9643         /* i_file_acl (extended attribute block) is bad */
9644         { PR_2_FILE_ACL_BAD,
9645           N_("@a @b @F @n (%If).\n"),
9646           PROMPT_CLEAR, 0 },
9647
9648         /* Filesystem contains large files, but has no such flag in sb */
9649         { PR_2_FEATURE_LARGE_FILES,
9650           N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9651           PROMPT_FIX, 0 },
9652
9653         /* Node in HTREE directory not referenced */
9654         { PR_2_HTREE_NOTREF,
9655           N_("@p @h %d: node (%B) not referenced\n"),
9656           PROMPT_NONE, 0 },
9657
9658         /* Node in HTREE directory referenced twice */
9659         { PR_2_HTREE_DUPREF,
9660           N_("@p @h %d: node (%B) referenced twice\n"),
9661           PROMPT_NONE, 0 },
9662
9663         /* Node in HTREE directory has bad min hash */
9664         { PR_2_HTREE_MIN_HASH,
9665           N_("@p @h %d: node (%B) has bad min hash\n"),
9666           PROMPT_NONE, 0 },
9667
9668         /* Node in HTREE directory has bad max hash */
9669         { PR_2_HTREE_MAX_HASH,
9670           N_("@p @h %d: node (%B) has bad max hash\n"),
9671           PROMPT_NONE, 0 },
9672
9673         /* Clear invalid HTREE directory */
9674         { PR_2_HTREE_CLEAR,
9675           N_("@n @h %d (%q).  "), PROMPT_CLEAR, 0 },
9676
9677         /* Bad block in htree interior node */
9678         { PR_2_HTREE_BADBLK,
9679           N_("@p @h %d (%q): bad @b number %b.\n"),
9680           PROMPT_CLEAR_HTREE, 0 },
9681
9682         /* Error adjusting EA refcount */
9683         { PR_2_ADJ_EA_REFCOUNT,
9684           N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9685           PROMPT_NONE, PR_FATAL },
9686
9687         /* Invalid HTREE root node */
9688         { PR_2_HTREE_BAD_ROOT,
9689           N_("@p @h %d: root node is @n\n"),
9690           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9691
9692         /* Invalid HTREE limit */
9693         { PR_2_HTREE_BAD_LIMIT,
9694           N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9695           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9696
9697         /* Invalid HTREE count */
9698         { PR_2_HTREE_BAD_COUNT,
9699           N_("@p @h %d: node (%B) has @n count (%N)\n"),
9700           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9701
9702         /* HTREE interior node has out-of-order hashes in table */
9703         { PR_2_HTREE_HASH_ORDER,
9704           N_("@p @h %d: node (%B) has an unordered hash table\n"),
9705           PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9706
9707         /* Node in HTREE directory has invalid depth */
9708         { PR_2_HTREE_BAD_DEPTH,
9709           N_("@p @h %d: node (%B) has @n depth\n"),
9710           PROMPT_NONE, 0 },
9711
9712         /* Duplicate directory entry found */
9713         { PR_2_DUPLICATE_DIRENT,
9714           N_("Duplicate @E found.  "),
9715           PROMPT_CLEAR, 0 },
9716
9717         /* Non-unique filename found */
9718         { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9719           N_("@E has a non-unique filename.\nRename to %s"),
9720           PROMPT_NULL, 0 },
9721
9722         /* Duplicate directory entry found */
9723         { PR_2_REPORT_DUP_DIRENT,
9724           N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9725           PROMPT_NONE, 0 },
9726
9727         /* Pass 3 errors */
9728
9729         /* Pass 3: Checking directory connectivity */
9730         { PR_3_PASS_HEADER,
9731           N_("Pass 3: Checking @d connectivity\n"),
9732           PROMPT_NONE, 0 },
9733
9734         /* Root inode not allocated */
9735         { PR_3_NO_ROOT_INODE,
9736           N_("@r not allocated.  "),
9737           PROMPT_ALLOCATE, 0 },
9738
9739         /* No room in lost+found */
9740         { PR_3_EXPAND_LF_DIR,
9741           N_("No room in @l @d.  "),
9742           PROMPT_EXPAND, 0 },
9743
9744         /* Unconnected directory inode */
9745         { PR_3_UNCONNECTED_DIR,
9746           N_("Unconnected @d @i %i (%p)\n"),
9747           PROMPT_CONNECT, 0 },
9748
9749         /* /lost+found not found */
9750         { PR_3_NO_LF_DIR,
9751           N_("/@l not found.  "),
9752           PROMPT_CREATE, PR_PREEN_OK },
9753
9754         /* .. entry is incorrect */
9755         { PR_3_BAD_DOT_DOT,
9756           N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9757           PROMPT_FIX, 0 },
9758
9759         /* Bad or non-existent /lost+found.  Cannot reconnect */
9760         { PR_3_NO_LPF,
9761           N_("Bad or non-existent /@l.  Cannot reconnect.\n"),
9762           PROMPT_NONE, 0 },
9763
9764         /* Could not expand /lost+found */
9765         { PR_3_CANT_EXPAND_LPF,
9766           N_("Could not expand /@l: %m\n"),
9767           PROMPT_NONE, 0 },
9768
9769         /* Could not reconnect inode */
9770         { PR_3_CANT_RECONNECT,
9771           N_("Could not reconnect %i: %m\n"),
9772           PROMPT_NONE, 0 },
9773
9774         /* Error while trying to find /lost+found */
9775         { PR_3_ERR_FIND_LPF,
9776           N_("Error while trying to find /@l: %m\n"),
9777           PROMPT_NONE, 0 },
9778
9779         /* Error in ext2fs_new_block while creating /lost+found */
9780         { PR_3_ERR_LPF_NEW_BLOCK,
9781           N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9782           PROMPT_NONE, 0 },
9783
9784         /* Error in ext2fs_new_inode while creating /lost+found */
9785         { PR_3_ERR_LPF_NEW_INODE,
9786           N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9787           PROMPT_NONE, 0 },
9788
9789         /* Error in ext2fs_new_dir_block while creating /lost+found */
9790         { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9791           N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9792           PROMPT_NONE, 0 },
9793
9794         /* Error while writing directory block for /lost+found */
9795         { PR_3_ERR_LPF_WRITE_BLOCK,
9796           N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9797           PROMPT_NONE, 0 },
9798
9799         /* Error while adjusting inode count */
9800         { PR_3_ADJUST_INODE,
9801           N_("Error while adjusting @i count on @i %i\n"),
9802           PROMPT_NONE, 0 },
9803
9804         /* Couldn't fix parent directory -- error */
9805         { PR_3_FIX_PARENT_ERR,
9806           N_("Couldn't fix parent of @i %i: %m\n\n"),
9807           PROMPT_NONE, 0 },
9808
9809         /* Couldn't fix parent directory -- couldn't find it */
9810         { PR_3_FIX_PARENT_NOFIND,
9811           N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9812           PROMPT_NONE, 0 },
9813
9814         /* Error allocating inode bitmap */
9815         { PR_3_ALLOCATE_IBITMAP_ERROR,
9816           N_("@A @i @B (%N): %m\n"),
9817           PROMPT_NONE, PR_FATAL },
9818
9819         /* Error creating root directory */
9820         { PR_3_CREATE_ROOT_ERROR,
9821           N_("Error creating root @d (%s): %m\n"),
9822           PROMPT_NONE, PR_FATAL },
9823
9824         /* Error creating lost and found directory */
9825         { PR_3_CREATE_LPF_ERROR,
9826           N_("Error creating /@l @d (%s): %m\n"),
9827           PROMPT_NONE, PR_FATAL },
9828
9829         /* Root inode is not directory; aborting */
9830         { PR_3_ROOT_NOT_DIR_ABORT,
9831           N_("@r is not a @d; aborting.\n"),
9832           PROMPT_NONE, PR_FATAL },
9833
9834         /* Cannot proceed without a root inode. */
9835         { PR_3_NO_ROOT_INODE_ABORT,
9836           N_("Cannot proceed without a @r.\n"),
9837           PROMPT_NONE, PR_FATAL },
9838
9839         /* Internal error: couldn't find dir_info */
9840         { PR_3_NO_DIRINFO,
9841           N_("Internal error: couldn't find dir_info for %i.\n"),
9842           PROMPT_NONE, PR_FATAL },
9843
9844         /* Lost+found not a directory */
9845         { PR_3_LPF_NOTDIR,
9846           N_("/@l is not a @d (ino=%i)\n"),
9847           PROMPT_UNLINK, 0 },
9848
9849         /* Pass 3A Directory Optimization       */
9850
9851         /* Pass 3A: Optimizing directories */
9852         { PR_3A_PASS_HEADER,
9853           N_("Pass 3A: Optimizing directories\n"),
9854           PROMPT_NONE, PR_PREEN_NOMSG },
9855
9856         /* Error iterating over directories */
9857         { PR_3A_OPTIMIZE_ITER,
9858           N_("Failed to create dirs_to_hash iterator: %m"),
9859           PROMPT_NONE, 0 },
9860
9861         /* Error rehash directory */
9862         { PR_3A_OPTIMIZE_DIR_ERR,
9863           N_("Failed to optimize directory %q (%d): %m"),
9864           PROMPT_NONE, 0 },
9865
9866         /* Rehashing dir header */
9867         { PR_3A_OPTIMIZE_DIR_HEADER,
9868           N_("Optimizing directories: "),
9869           PROMPT_NONE, PR_MSG_ONLY },
9870
9871         /* Rehashing directory %d */
9872         { PR_3A_OPTIMIZE_DIR,
9873           " %d",
9874           PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9875
9876         /* Rehashing dir end */
9877         { PR_3A_OPTIMIZE_DIR_END,
9878           "\n",
9879           PROMPT_NONE, PR_PREEN_NOHDR },
9880
9881         /* Pass 4 errors */
9882
9883         /* Pass 4: Checking reference counts */
9884         { PR_4_PASS_HEADER,
9885           N_("Pass 4: Checking reference counts\n"),
9886           PROMPT_NONE, 0 },
9887
9888         /* Unattached zero-length inode */
9889         { PR_4_ZERO_LEN_INODE,
9890           N_("@u @z @i %i.  "),
9891           PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9892
9893         /* Unattached inode */
9894         { PR_4_UNATTACHED_INODE,
9895           N_("@u @i %i\n"),
9896           PROMPT_CONNECT, 0 },
9897
9898         /* Inode ref count wrong */
9899         { PR_4_BAD_REF_COUNT,
9900           N_("@i %i ref count is %Il, @s %N.  "),
9901           PROMPT_FIX, PR_PREEN_OK },
9902
9903         { PR_4_INCONSISTENT_COUNT,
9904           N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9905           "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9906           "@i_link_info[%i] is %N, @i.i_links_count is %Il.  "
9907           "They @s the same!\n"),
9908           PROMPT_NONE, 0 },
9909
9910         /* Pass 5 errors */
9911
9912         /* Pass 5: Checking group summary information */
9913         { PR_5_PASS_HEADER,
9914           N_("Pass 5: Checking @g summary information\n"),
9915           PROMPT_NONE, 0 },
9916
9917         /* Padding at end of inode bitmap is not set. */
9918         { PR_5_INODE_BMAP_PADDING,
9919           N_("Padding at end of @i @B is not set. "),
9920           PROMPT_FIX, PR_PREEN_OK },
9921
9922         /* Padding at end of block bitmap is not set. */
9923         { PR_5_BLOCK_BMAP_PADDING,
9924           N_("Padding at end of @b @B is not set. "),
9925           PROMPT_FIX, PR_PREEN_OK },
9926
9927         /* Block bitmap differences header */
9928         { PR_5_BLOCK_BITMAP_HEADER,
9929           N_("@b @B differences: "),
9930           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9931
9932         /* Block not used, but marked in bitmap */
9933         { PR_5_BLOCK_UNUSED,
9934           " -%b",
9935           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9936
9937         /* Block used, but not marked used in bitmap */
9938         { PR_5_BLOCK_USED,
9939           " +%b",
9940           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9941
9942         /* Block bitmap differences end */
9943         { PR_5_BLOCK_BITMAP_END,
9944           "\n",
9945           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9946
9947         /* Inode bitmap differences header */
9948         { PR_5_INODE_BITMAP_HEADER,
9949           N_("@i @B differences: "),
9950           PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9951
9952         /* Inode not used, but marked in bitmap */
9953         { PR_5_INODE_UNUSED,
9954           " -%i",
9955           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9956
9957         /* Inode used, but not marked used in bitmap */
9958         { PR_5_INODE_USED,
9959           " +%i",
9960           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9961
9962         /* Inode bitmap differences end */
9963         { PR_5_INODE_BITMAP_END,
9964           "\n",
9965           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9966
9967         /* Free inodes count for group wrong */
9968         { PR_5_FREE_INODE_COUNT_GROUP,
9969           N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9970           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9971
9972         /* Directories count for group wrong */
9973         { PR_5_FREE_DIR_COUNT_GROUP,
9974           N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9975           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9976
9977         /* Free inodes count wrong */
9978         { PR_5_FREE_INODE_COUNT,
9979           N_("Free @is count wrong (%i, counted=%j).\n"),
9980           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9981
9982         /* Free blocks count for group wrong */
9983         { PR_5_FREE_BLOCK_COUNT_GROUP,
9984           N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9985           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9986
9987         /* Free blocks count wrong */
9988         { PR_5_FREE_BLOCK_COUNT,
9989           N_("Free @bs count wrong (%b, counted=%c).\n"),
9990           PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9991
9992         /* Programming error: bitmap endpoints don't match */
9993         { PR_5_BMAP_ENDPOINTS,
9994           N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9995           "match calculated @B endpoints (%i, %j)\n"),
9996           PROMPT_NONE, PR_FATAL },
9997
9998         /* Internal error: fudging end of bitmap */
9999         { PR_5_FUDGE_BITMAP_ERROR,
10000           N_("Internal error: fudging end of bitmap (%N)\n"),
10001           PROMPT_NONE, PR_FATAL },
10002
10003         /* Error copying in replacement inode bitmap */
10004         { PR_5_COPY_IBITMAP_ERROR,
10005           N_("Error copying in replacement @i @B: %m\n"),
10006           PROMPT_NONE, PR_FATAL },
10007
10008         /* Error copying in replacement block bitmap */
10009         { PR_5_COPY_BBITMAP_ERROR,
10010           N_("Error copying in replacement @b @B: %m\n"),
10011           PROMPT_NONE, PR_FATAL },
10012
10013         /* Block range not used, but marked in bitmap */
10014         { PR_5_BLOCK_RANGE_UNUSED,
10015           " -(%b--%c)",
10016           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10017
10018         /* Block range used, but not marked used in bitmap */
10019         { PR_5_BLOCK_RANGE_USED,
10020           " +(%b--%c)",
10021           PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10022
10023         /* Inode range not used, but marked in bitmap */
10024         { PR_5_INODE_RANGE_UNUSED,
10025           " -(%i--%j)",
10026           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10027
10028         /* Inode range used, but not marked used in bitmap */
10029         { PR_5_INODE_RANGE_USED,
10030           " +(%i--%j)",
10031           PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10032
10033         { 0 }
10034 };
10035
10036 /*
10037  * This is the latch flags register.  It allows several problems to be
10038  * "latched" together.  This means that the user has to answer but one
10039  * question for the set of problems, and all of the associated
10040  * problems will be either fixed or not fixed.
10041  */
10042 static struct latch_descr pr_latch_info[] = {
10043         { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
10044         { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
10045         { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
10046         { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
10047         { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
10048         { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
10049         { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
10050         { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
10051         { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
10052         { -1, 0, 0 },
10053 };
10054
10055 static const struct e2fsck_problem *find_problem(problem_t code)
10056 {
10057         int     i;
10058
10059         for (i=0; problem_table[i].e2p_code; i++) {
10060                 if (problem_table[i].e2p_code == code)
10061                         return &problem_table[i];
10062         }
10063         return 0;
10064 }
10065
10066 static struct latch_descr *find_latch(int code)
10067 {
10068         int     i;
10069
10070         for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
10071                 if (pr_latch_info[i].latch_code == code)
10072                         return &pr_latch_info[i];
10073         }
10074         return 0;
10075 }
10076
10077 int end_problem_latch(e2fsck_t ctx, int mask)
10078 {
10079         struct latch_descr *ldesc;
10080         struct problem_context pctx;
10081         int answer = -1;
10082
10083         ldesc = find_latch(mask);
10084         if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
10085                 clear_problem_context(&pctx);
10086                 answer = fix_problem(ctx, ldesc->end_message, &pctx);
10087         }
10088         ldesc->flags &= ~(PRL_VARIABLE);
10089         return answer;
10090 }
10091
10092 int set_latch_flags(int mask, int setflags, int clearflags)
10093 {
10094         struct latch_descr *ldesc;
10095
10096         ldesc = find_latch(mask);
10097         if (!ldesc)
10098                 return -1;
10099         ldesc->flags |= setflags;
10100         ldesc->flags &= ~clearflags;
10101         return 0;
10102 }
10103
10104 void clear_problem_context(struct problem_context *ctx)
10105 {
10106         memset(ctx, 0, sizeof(struct problem_context));
10107         ctx->blkcount = -1;
10108         ctx->group = -1;
10109 }
10110
10111 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
10112 {
10113         ext2_filsys fs = ctx->fs;
10114         const struct e2fsck_problem *ptr;
10115         struct latch_descr *ldesc = 0;
10116         const char *message;
10117         int             def_yn, answer, ans;
10118         int             print_answer = 0;
10119         int             suppress = 0;
10120
10121         ptr = find_problem(code);
10122         if (!ptr) {
10123                 printf(_("Unhandled error code (0x%x)!\n"), code);
10124                 return 0;
10125         }
10126         def_yn = 1;
10127         if ((ptr->flags & PR_NO_DEFAULT) ||
10128             ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
10129             (ctx->options & E2F_OPT_NO))
10130                 def_yn= 0;
10131
10132         /*
10133          * Do special latch processing.  This is where we ask the
10134          * latch question, if it exists
10135          */
10136         if (ptr->flags & PR_LATCH_MASK) {
10137                 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
10138                 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
10139                         ans = fix_problem(ctx, ldesc->question, pctx);
10140                         if (ans == 1)
10141                                 ldesc->flags |= PRL_YES;
10142                         if (ans == 0)
10143                                 ldesc->flags |= PRL_NO;
10144                         ldesc->flags |= PRL_LATCHED;
10145                 }
10146                 if (ldesc->flags & PRL_SUPPRESS)
10147                         suppress++;
10148         }
10149         if ((ptr->flags & PR_PREEN_NOMSG) &&
10150             (ctx->options & E2F_OPT_PREEN))
10151                 suppress++;
10152         if ((ptr->flags & PR_NO_NOMSG) &&
10153             (ctx->options & E2F_OPT_NO))
10154                 suppress++;
10155         if (!suppress) {
10156                 message = ptr->e2p_description;
10157                 if ((ctx->options & E2F_OPT_PREEN) &&
10158                     !(ptr->flags & PR_PREEN_NOHDR)) {
10159                         printf("%s: ", ctx->device_name ?
10160                                ctx->device_name : ctx->filesystem_name);
10161                 }
10162                 if (*message)
10163                         print_e2fsck_message(ctx, _(message), pctx, 1);
10164         }
10165         if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
10166                 preenhalt(ctx);
10167
10168         if (ptr->flags & PR_FATAL)
10169                 fatal_error(ctx, 0);
10170
10171         if (ptr->prompt == PROMPT_NONE) {
10172                 if (ptr->flags & PR_NOCOLLATE)
10173                         answer = -1;
10174                 else
10175                         answer = def_yn;
10176         } else {
10177                 if (ctx->options & E2F_OPT_PREEN) {
10178                         answer = def_yn;
10179                         if (!(ptr->flags & PR_PREEN_NOMSG))
10180                                 print_answer = 1;
10181                 } else if ((ptr->flags & PR_LATCH_MASK) &&
10182                            (ldesc->flags & (PRL_YES | PRL_NO))) {
10183                         if (!suppress)
10184                                 print_answer = 1;
10185                         if (ldesc->flags & PRL_YES)
10186                                 answer = 1;
10187                         else
10188                                 answer = 0;
10189                 } else
10190                         answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
10191                 if (!answer && !(ptr->flags & PR_NO_OK))
10192                         ext2fs_unmark_valid(fs);
10193
10194                 if (print_answer)
10195                         printf("%s.\n", answer ?
10196                                _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
10197
10198         }
10199
10200         if ((ptr->prompt == PROMPT_ABORT) && answer)
10201                 fatal_error(ctx, 0);
10202
10203         if (ptr->flags & PR_AFTER_CODE)
10204                 answer = fix_problem(ctx, ptr->second_code, pctx);
10205
10206         return answer;
10207 }
10208
10209 /*
10210  * linux/fs/recovery.c
10211  *
10212  * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
10213  */
10214
10215 /*
10216  * Maintain information about the progress of the recovery job, so that
10217  * the different passes can carry information between them.
10218  */
10219 struct recovery_info
10220 {
10221         tid_t           start_transaction;
10222         tid_t           end_transaction;
10223
10224         int             nr_replays;
10225         int             nr_revokes;
10226         int             nr_revoke_hits;
10227 };
10228
10229 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
10230 static int do_one_pass(journal_t *journal,
10231                                 struct recovery_info *info, enum passtype pass);
10232 static int scan_revoke_records(journal_t *, struct buffer_head *,
10233                                 tid_t, struct recovery_info *);
10234
10235 /*
10236  * Read a block from the journal
10237  */
10238
10239 static int jread(struct buffer_head **bhp, journal_t *journal,
10240                  unsigned int offset)
10241 {
10242         int err;
10243         unsigned long blocknr;
10244         struct buffer_head *bh;
10245
10246         *bhp = NULL;
10247
10248         err = journal_bmap(journal, offset, &blocknr);
10249
10250         if (err) {
10251                 printf ("JBD: bad block at offset %u\n", offset);
10252                 return err;
10253         }
10254
10255         bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
10256         if (!bh)
10257                 return -ENOMEM;
10258
10259         if (!buffer_uptodate(bh)) {
10260                 /* If this is a brand new buffer, start readahead.
10261                    Otherwise, we assume we are already reading it.  */
10262                 if (!buffer_req(bh))
10263                         do_readahead(journal, offset);
10264                 wait_on_buffer(bh);
10265         }
10266
10267         if (!buffer_uptodate(bh)) {
10268                 printf ("JBD: Failed to read block at offset %u\n", offset);
10269                 brelse(bh);
10270                 return -EIO;
10271         }
10272
10273         *bhp = bh;
10274         return 0;
10275 }
10276
10277
10278 /*
10279  * Count the number of in-use tags in a journal descriptor block.
10280  */
10281
10282 static int count_tags(struct buffer_head *bh, int size)
10283 {
10284         char *                  tagp;
10285         journal_block_tag_t *   tag;
10286         int                     nr = 0;
10287
10288         tagp = &bh->b_data[sizeof(journal_header_t)];
10289
10290         while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
10291                 tag = (journal_block_tag_t *) tagp;
10292
10293                 nr++;
10294                 tagp += sizeof(journal_block_tag_t);
10295                 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
10296                         tagp += 16;
10297
10298                 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
10299                         break;
10300         }
10301
10302         return nr;
10303 }
10304
10305
10306 /* Make sure we wrap around the log correctly! */
10307 #define wrap(journal, var)                                            \
10308 do {                                                                \
10309         if (var >= (journal)->j_last)                                   \
10310                 var -= ((journal)->j_last - (journal)->j_first);        \
10311 } while (0)
10312
10313 /**
10314  * int journal_recover(journal_t *journal) - recovers a on-disk journal
10315  * @journal: the journal to recover
10316  *
10317  * The primary function for recovering the log contents when mounting a
10318  * journaled device.
10319  *
10320  * Recovery is done in three passes.  In the first pass, we look for the
10321  * end of the log.  In the second, we assemble the list of revoke
10322  * blocks.  In the third and final pass, we replay any un-revoked blocks
10323  * in the log.
10324  */
10325 int journal_recover(journal_t *journal)
10326 {
10327         int                     err;
10328         journal_superblock_t *  sb;
10329
10330         struct recovery_info    info;
10331
10332         memset(&info, 0, sizeof(info));
10333         sb = journal->j_superblock;
10334
10335         /*
10336          * The journal superblock's s_start field (the current log head)
10337          * is always zero if, and only if, the journal was cleanly
10338          * unmounted.
10339          */
10340
10341         if (!sb->s_start) {
10342                 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
10343                 return 0;
10344         }
10345
10346         err = do_one_pass(journal, &info, PASS_SCAN);
10347         if (!err)
10348                 err = do_one_pass(journal, &info, PASS_REVOKE);
10349         if (!err)
10350                 err = do_one_pass(journal, &info, PASS_REPLAY);
10351
10352         /* Restart the log at the next transaction ID, thus invalidating
10353          * any existing commit records in the log. */
10354         journal->j_transaction_sequence = ++info.end_transaction;
10355
10356         journal_clear_revoke(journal);
10357         sync_blockdev(journal->j_fs_dev);
10358         return err;
10359 }
10360
10361 static int do_one_pass(journal_t *journal,
10362                         struct recovery_info *info, enum passtype pass)
10363 {
10364         unsigned int            first_commit_ID, next_commit_ID;
10365         unsigned long           next_log_block;
10366         int                     err, success = 0;
10367         journal_superblock_t *  sb;
10368         journal_header_t *      tmp;
10369         struct buffer_head *    bh;
10370         unsigned int            sequence;
10371         int                     blocktype;
10372
10373         /* Precompute the maximum metadata descriptors in a descriptor block */
10374         int                     MAX_BLOCKS_PER_DESC;
10375         MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
10376                                / sizeof(journal_block_tag_t));
10377
10378         /*
10379          * First thing is to establish what we expect to find in the log
10380          * (in terms of transaction IDs), and where (in terms of log
10381          * block offsets): query the superblock.
10382          */
10383
10384         sb = journal->j_superblock;
10385         next_commit_ID = ntohl(sb->s_sequence);
10386         next_log_block = ntohl(sb->s_start);
10387
10388         first_commit_ID = next_commit_ID;
10389         if (pass == PASS_SCAN)
10390                 info->start_transaction = first_commit_ID;
10391
10392         /*
10393          * Now we walk through the log, transaction by transaction,
10394          * making sure that each transaction has a commit block in the
10395          * expected place.  Each complete transaction gets replayed back
10396          * into the main filesystem.
10397          */
10398
10399         while (1) {
10400                 int                     flags;
10401                 char *                  tagp;
10402                 journal_block_tag_t *   tag;
10403                 struct buffer_head *    obh;
10404                 struct buffer_head *    nbh;
10405
10406                 /* If we already know where to stop the log traversal,
10407                  * check right now that we haven't gone past the end of
10408                  * the log. */
10409
10410                 if (pass != PASS_SCAN)
10411                         if (tid_geq(next_commit_ID, info->end_transaction))
10412                                 break;
10413
10414                 /* Skip over each chunk of the transaction looking
10415                  * either the next descriptor block or the final commit
10416                  * record. */
10417
10418                 err = jread(&bh, journal, next_log_block);
10419                 if (err)
10420                         goto failed;
10421
10422                 next_log_block++;
10423                 wrap(journal, next_log_block);
10424
10425                 /* What kind of buffer is it?
10426                  *
10427                  * If it is a descriptor block, check that it has the
10428                  * expected sequence number.  Otherwise, we're all done
10429                  * here. */
10430
10431                 tmp = (journal_header_t *)bh->b_data;
10432
10433                 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10434                         brelse(bh);
10435                         break;
10436                 }
10437
10438                 blocktype = ntohl(tmp->h_blocktype);
10439                 sequence = ntohl(tmp->h_sequence);
10440
10441                 if (sequence != next_commit_ID) {
10442                         brelse(bh);
10443                         break;
10444                 }
10445
10446                 /* OK, we have a valid descriptor block which matches
10447                  * all of the sequence number checks.  What are we going
10448                  * to do with it?  That depends on the pass... */
10449
10450                 switch(blocktype) {
10451                 case JFS_DESCRIPTOR_BLOCK:
10452                         /* If it is a valid descriptor block, replay it
10453                          * in pass REPLAY; otherwise, just skip over the
10454                          * blocks it describes. */
10455                         if (pass != PASS_REPLAY) {
10456                                 next_log_block +=
10457                                         count_tags(bh, journal->j_blocksize);
10458                                 wrap(journal, next_log_block);
10459                                 brelse(bh);
10460                                 continue;
10461                         }
10462
10463                         /* A descriptor block: we can now write all of
10464                          * the data blocks.  Yay, useful work is finally
10465                          * getting done here! */
10466
10467                         tagp = &bh->b_data[sizeof(journal_header_t)];
10468                         while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10469                                <= journal->j_blocksize) {
10470                                 unsigned long io_block;
10471
10472                                 tag = (journal_block_tag_t *) tagp;
10473                                 flags = ntohl(tag->t_flags);
10474
10475                                 io_block = next_log_block++;
10476                                 wrap(journal, next_log_block);
10477                                 err = jread(&obh, journal, io_block);
10478                                 if (err) {
10479                                         /* Recover what we can, but
10480                                          * report failure at the end. */
10481                                         success = err;
10482                                         printf ("JBD: IO error %d recovering "
10483                                                 "block %ld in log\n",
10484                                                 err, io_block);
10485                                 } else {
10486                                         unsigned long blocknr;
10487
10488                                         blocknr = ntohl(tag->t_blocknr);
10489
10490                                         /* If the block has been
10491                                          * revoked, then we're all done
10492                                          * here. */
10493                                         if (journal_test_revoke
10494                                             (journal, blocknr,
10495                                              next_commit_ID)) {
10496                                                 brelse(obh);
10497                                                 ++info->nr_revoke_hits;
10498                                                 goto skip_write;
10499                                         }
10500
10501                                         /* Find a buffer for the new
10502                                          * data being restored */
10503                                         nbh = getblk(journal->j_fs_dev,
10504                                                        blocknr,
10505                                                      journal->j_blocksize);
10506                                         if (nbh == NULL) {
10507                                                 printf ("JBD: Out of memory "
10508                                                        "during recovery.\n");
10509                                                 err = -ENOMEM;
10510                                                 brelse(bh);
10511                                                 brelse(obh);
10512                                                 goto failed;
10513                                         }
10514
10515                                         lock_buffer(nbh);
10516                                         memcpy(nbh->b_data, obh->b_data,
10517                                                         journal->j_blocksize);
10518                                         if (flags & JFS_FLAG_ESCAPE) {
10519                                                 *((unsigned int *)bh->b_data) =
10520                                                         htonl(JFS_MAGIC_NUMBER);
10521                                         }
10522
10523                                         mark_buffer_uptodate(nbh, 1);
10524                                         mark_buffer_dirty(nbh);
10525                                         ++info->nr_replays;
10526                                         /* ll_rw_block(WRITE, 1, &nbh); */
10527                                         unlock_buffer(nbh);
10528                                         brelse(obh);
10529                                         brelse(nbh);
10530                                 }
10531
10532                         skip_write:
10533                                 tagp += sizeof(journal_block_tag_t);
10534                                 if (!(flags & JFS_FLAG_SAME_UUID))
10535                                         tagp += 16;
10536
10537                                 if (flags & JFS_FLAG_LAST_TAG)
10538                                         break;
10539                         }
10540
10541                         brelse(bh);
10542                         continue;
10543
10544                 case JFS_COMMIT_BLOCK:
10545                         /* Found an expected commit block: not much to
10546                          * do other than move on to the next sequence
10547                          * number. */
10548                         brelse(bh);
10549                         next_commit_ID++;
10550                         continue;
10551
10552                 case JFS_REVOKE_BLOCK:
10553                         /* If we aren't in the REVOKE pass, then we can
10554                          * just skip over this block. */
10555                         if (pass != PASS_REVOKE) {
10556                                 brelse(bh);
10557                                 continue;
10558                         }
10559
10560                         err = scan_revoke_records(journal, bh,
10561                                                   next_commit_ID, info);
10562                         brelse(bh);
10563                         if (err)
10564                                 goto failed;
10565                         continue;
10566
10567                 default:
10568                         goto done;
10569                 }
10570         }
10571
10572  done:
10573         /*
10574          * We broke out of the log scan loop: either we came to the
10575          * known end of the log or we found an unexpected block in the
10576          * log.  If the latter happened, then we know that the "current"
10577          * transaction marks the end of the valid log.
10578          */
10579
10580         if (pass == PASS_SCAN)
10581                 info->end_transaction = next_commit_ID;
10582         else {
10583                 /* It's really bad news if different passes end up at
10584                  * different places (but possible due to IO errors). */
10585                 if (info->end_transaction != next_commit_ID) {
10586                         printf ("JBD: recovery pass %d ended at "
10587                                 "transaction %u, expected %u\n",
10588                                 pass, next_commit_ID, info->end_transaction);
10589                         if (!success)
10590                                 success = -EIO;
10591                 }
10592         }
10593
10594         return success;
10595
10596  failed:
10597         return err;
10598 }
10599
10600
10601 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10602
10603 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10604                                tid_t sequence, struct recovery_info *info)
10605 {
10606         journal_revoke_header_t *header;
10607         int offset, max;
10608
10609         header = (journal_revoke_header_t *) bh->b_data;
10610         offset = sizeof(journal_revoke_header_t);
10611         max = ntohl(header->r_count);
10612
10613         while (offset < max) {
10614                 unsigned long blocknr;
10615                 int err;
10616
10617                 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10618                 offset += 4;
10619                 err = journal_set_revoke(journal, blocknr, sequence);
10620                 if (err)
10621                         return err;
10622                 ++info->nr_revokes;
10623         }
10624         return 0;
10625 }
10626
10627
10628 /*
10629  * rehash.c --- rebuild hash tree directories
10630  *
10631  * This algorithm is designed for simplicity of implementation and to
10632  * pack the directory as much as possible.  It however requires twice
10633  * as much memory as the size of the directory.  The maximum size
10634  * directory supported using a 4k blocksize is roughly a gigabyte, and
10635  * so there may very well be problems with machines that don't have
10636  * virtual memory, and obscenely large directories.
10637  *
10638  * An alternate algorithm which is much more disk intensive could be
10639  * written, and probably will need to be written in the future.  The
10640  * design goals of such an algorithm are: (a) use (roughly) constant
10641  * amounts of memory, no matter how large the directory, (b) the
10642  * directory must be safe at all times, even if e2fsck is interrupted
10643  * in the middle, (c) we must use minimal amounts of extra disk
10644  * blocks.  This pretty much requires an incremental approach, where
10645  * we are reading from one part of the directory, and inserting into
10646  * the front half.  So the algorithm will have to keep track of a
10647  * moving block boundary between the new tree and the old tree, and
10648  * files will need to be moved from the old directory and inserted
10649  * into the new tree.  If the new directory requires space which isn't
10650  * yet available, blocks from the beginning part of the old directory
10651  * may need to be moved to the end of the directory to make room for
10652  * the new tree:
10653  *
10654  *    --------------------------------------------------------
10655  *    |  new tree   |        | old tree                      |
10656  *    --------------------------------------------------------
10657  *                  ^ ptr    ^ptr
10658  *                tail new   head old
10659  *
10660  * This is going to be a pain in the tuckus to implement, and will
10661  * require a lot more disk accesses.  So I'm going to skip it for now;
10662  * it's only really going to be an issue for really, really big
10663  * filesystems (when we reach the level of tens of millions of files
10664  * in a single directory).  It will probably be easier to simply
10665  * require that e2fsck use VM first.
10666  */
10667
10668 struct fill_dir_struct {
10669         char *buf;
10670         struct ext2_inode *inode;
10671         int err;
10672         e2fsck_t ctx;
10673         struct hash_entry *harray;
10674         int max_array, num_array;
10675         int dir_size;
10676         int compress;
10677         ino_t parent;
10678 };
10679
10680 struct hash_entry {
10681         ext2_dirhash_t  hash;
10682         ext2_dirhash_t  minor_hash;
10683         struct ext2_dir_entry   *dir;
10684 };
10685
10686 struct out_dir {
10687         int             num;
10688         int             max;
10689         char            *buf;
10690         ext2_dirhash_t  *hashes;
10691 };
10692
10693 static int fill_dir_block(ext2_filsys fs,
10694                           blk_t *block_nr,
10695                           e2_blkcnt_t blockcnt,
10696                           blk_t ref_block FSCK_ATTR((unused)),
10697                           int ref_offset FSCK_ATTR((unused)),
10698                           void *priv_data)
10699 {
10700         struct fill_dir_struct  *fd = (struct fill_dir_struct *) priv_data;
10701         struct hash_entry       *new_array, *ent;
10702         struct ext2_dir_entry   *dirent;
10703         char                    *dir;
10704         unsigned int            offset, dir_offset;
10705
10706         if (blockcnt < 0)
10707                 return 0;
10708
10709         offset = blockcnt * fs->blocksize;
10710         if (offset + fs->blocksize > fd->inode->i_size) {
10711                 fd->err = EXT2_ET_DIR_CORRUPTED;
10712                 return BLOCK_ABORT;
10713         }
10714         dir = (fd->buf+offset);
10715         if (HOLE_BLKADDR(*block_nr)) {
10716                 memset(dir, 0, fs->blocksize);
10717                 dirent = (struct ext2_dir_entry *) dir;
10718                 dirent->rec_len = fs->blocksize;
10719         } else {
10720                 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10721                 if (fd->err)
10722                         return BLOCK_ABORT;
10723         }
10724         /* While the directory block is "hot", index it. */
10725         dir_offset = 0;
10726         while (dir_offset < fs->blocksize) {
10727                 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10728                 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10729                     (dirent->rec_len < 8) ||
10730                     ((dirent->rec_len % 4) != 0) ||
10731                     (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10732                         fd->err = EXT2_ET_DIR_CORRUPTED;
10733                         return BLOCK_ABORT;
10734                 }
10735                 dir_offset += dirent->rec_len;
10736                 if (dirent->inode == 0)
10737                         continue;
10738                 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10739                     (dirent->name[0] == '.'))
10740                         continue;
10741                 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10742                     (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10743                         fd->parent = dirent->inode;
10744                         continue;
10745                 }
10746                 if (fd->num_array >= fd->max_array) {
10747                         new_array = realloc(fd->harray,
10748                             sizeof(struct hash_entry) * (fd->max_array+500));
10749                         if (!new_array) {
10750                                 fd->err = ENOMEM;
10751                                 return BLOCK_ABORT;
10752                         }
10753                         fd->harray = new_array;
10754                         fd->max_array += 500;
10755                 }
10756                 ent = fd->harray + fd->num_array++;
10757                 ent->dir = dirent;
10758                 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10759                 if (fd->compress)
10760                         ent->hash = ent->minor_hash = 0;
10761                 else {
10762                         fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10763                                                  dirent->name,
10764                                                  dirent->name_len & 0xFF,
10765                                                  fs->super->s_hash_seed,
10766                                                  &ent->hash, &ent->minor_hash);
10767                         if (fd->err)
10768                                 return BLOCK_ABORT;
10769                 }
10770         }
10771
10772         return 0;
10773 }
10774
10775 /* Used for sorting the hash entry */
10776 static EXT2_QSORT_TYPE name_cmp(const void *a, const void *b)
10777 {
10778         const struct hash_entry *he_a = (const struct hash_entry *) a;
10779         const struct hash_entry *he_b = (const struct hash_entry *) b;
10780         int     ret;
10781         int     min_len;
10782
10783         min_len = he_a->dir->name_len;
10784         if (min_len > he_b->dir->name_len)
10785                 min_len = he_b->dir->name_len;
10786
10787         ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10788         if (ret == 0) {
10789                 if (he_a->dir->name_len > he_b->dir->name_len)
10790                         ret = 1;
10791                 else if (he_a->dir->name_len < he_b->dir->name_len)
10792                         ret = -1;
10793                 else
10794                         ret = he_b->dir->inode - he_a->dir->inode;
10795         }
10796         return ret;
10797 }
10798
10799 /* Used for sorting the hash entry */
10800 static EXT2_QSORT_TYPE hash_cmp(const void *a, const void *b)
10801 {
10802         const struct hash_entry *he_a = (const struct hash_entry *) a;
10803         const struct hash_entry *he_b = (const struct hash_entry *) b;
10804         int     ret;
10805
10806         if (he_a->hash > he_b->hash)
10807                 ret = 1;
10808         else if (he_a->hash < he_b->hash)
10809                 ret = -1;
10810         else {
10811                 if (he_a->minor_hash > he_b->minor_hash)
10812                         ret = 1;
10813                 else if (he_a->minor_hash < he_b->minor_hash)
10814                         ret = -1;
10815                 else
10816                         ret = name_cmp(a, b);
10817         }
10818         return ret;
10819 }
10820
10821 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10822                                 int blocks)
10823 {
10824         void                    *new_mem;
10825
10826         if (outdir->max) {
10827                 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10828                 if (!new_mem)
10829                         return ENOMEM;
10830                 outdir->buf = new_mem;
10831                 new_mem = realloc(outdir->hashes,
10832                                   blocks * sizeof(ext2_dirhash_t));
10833                 if (!new_mem)
10834                         return ENOMEM;
10835                 outdir->hashes = new_mem;
10836         } else {
10837                 outdir->buf = malloc(blocks * fs->blocksize);
10838                 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10839                 outdir->num = 0;
10840         }
10841         outdir->max = blocks;
10842         return 0;
10843 }
10844
10845 static void free_out_dir(struct out_dir *outdir)
10846 {
10847         free(outdir->buf);
10848         free(outdir->hashes);
10849         outdir->max = 0;
10850         outdir->num =0;
10851 }
10852
10853 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10854                          char ** ret)
10855 {
10856         errcode_t       retval;
10857
10858         if (outdir->num >= outdir->max) {
10859                 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10860                 if (retval)
10861                         return retval;
10862         }
10863         *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10864         memset(*ret, 0, fs->blocksize);
10865         return 0;
10866 }
10867
10868 /*
10869  * This function is used to make a unique filename.  We do this by
10870  * appending ~0, and then incrementing the number.  However, we cannot
10871  * expand the length of the filename beyond the padding available in
10872  * the directory entry.
10873  */
10874 static void mutate_name(char *str, __u16 *len)
10875 {
10876         int     i;
10877         __u16   l = *len & 0xFF, h = *len & 0xff00;
10878
10879         /*
10880          * First check to see if it looks the name has been mutated
10881          * already
10882          */
10883         for (i = l-1; i > 0; i--) {
10884                 if (!isdigit(str[i]))
10885                         break;
10886         }
10887         if ((i == l-1) || (str[i] != '~')) {
10888                 if (((l-1) & 3) < 2)
10889                         l += 2;
10890                 else
10891                         l = (l+3) & ~3;
10892                 str[l-2] = '~';
10893                 str[l-1] = '0';
10894                 *len = l | h;
10895                 return;
10896         }
10897         for (i = l-1; i >= 0; i--) {
10898                 if (isdigit(str[i])) {
10899                         if (str[i] == '9')
10900                                 str[i] = '0';
10901                         else {
10902                                 str[i]++;
10903                                 return;
10904                         }
10905                         continue;
10906                 }
10907                 if (i == 1) {
10908                         if (str[0] == 'z')
10909                                 str[0] = 'A';
10910                         else if (str[0] == 'Z') {
10911                                 str[0] = '~';
10912                                 str[1] = '0';
10913                         } else
10914                                 str[0]++;
10915                 } else if (i > 0) {
10916                         str[i] = '1';
10917                         str[i-1] = '~';
10918                 } else {
10919                         if (str[0] == '~')
10920                                 str[0] = 'a';
10921                         else
10922                                 str[0]++;
10923                 }
10924                 break;
10925         }
10926 }
10927
10928 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10929                                     ext2_ino_t ino,
10930                                     struct fill_dir_struct *fd)
10931 {
10932         struct problem_context  pctx;
10933         struct hash_entry       *ent, *prev;
10934         int                     i, j;
10935         int                     fixed = 0;
10936         char                    new_name[256];
10937         __u16                   new_len;
10938
10939         clear_problem_context(&pctx);
10940         pctx.ino = ino;
10941
10942         for (i=1; i < fd->num_array; i++) {
10943                 ent = fd->harray + i;
10944                 prev = ent - 1;
10945                 if (!ent->dir->inode ||
10946                     ((ent->dir->name_len & 0xFF) !=
10947                      (prev->dir->name_len & 0xFF)) ||
10948                     (strncmp(ent->dir->name, prev->dir->name,
10949                              ent->dir->name_len & 0xFF)))
10950                         continue;
10951                 pctx.dirent = ent->dir;
10952                 if ((ent->dir->inode == prev->dir->inode) &&
10953                     fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10954                         e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10955                         ent->dir->inode = 0;
10956                         fixed++;
10957                         continue;
10958                 }
10959                 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10960                 new_len = ent->dir->name_len;
10961                 mutate_name(new_name, &new_len);
10962                 for (j=0; j < fd->num_array; j++) {
10963                         if ((i==j) ||
10964                             ((ent->dir->name_len & 0xFF) !=
10965                              (fd->harray[j].dir->name_len & 0xFF)) ||
10966                             (strncmp(new_name, fd->harray[j].dir->name,
10967                                      new_len & 0xFF)))
10968                                 continue;
10969                         mutate_name(new_name, &new_len);
10970
10971                         j = -1;
10972                 }
10973                 new_name[new_len & 0xFF] = 0;
10974                 pctx.str = new_name;
10975                 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10976                         memcpy(ent->dir->name, new_name, new_len & 0xFF);
10977                         ent->dir->name_len = new_len;
10978                         ext2fs_dirhash(fs->super->s_def_hash_version,
10979                                        ent->dir->name,
10980                                        ent->dir->name_len & 0xFF,
10981                                        fs->super->s_hash_seed,
10982                                        &ent->hash, &ent->minor_hash);
10983                         fixed++;
10984                 }
10985         }
10986         return fixed;
10987 }
10988
10989
10990 static errcode_t copy_dir_entries(ext2_filsys fs,
10991                                   struct fill_dir_struct *fd,
10992                                   struct out_dir *outdir)
10993 {
10994         errcode_t               retval;
10995         char                    *block_start;
10996         struct hash_entry       *ent;
10997         struct ext2_dir_entry   *dirent;
10998         int                     i, rec_len, left;
10999         ext2_dirhash_t          prev_hash;
11000         int                     offset;
11001
11002         outdir->max = 0;
11003         retval = alloc_size_dir(fs, outdir,
11004                                 (fd->dir_size / fs->blocksize) + 2);
11005         if (retval)
11006                 return retval;
11007         outdir->num = fd->compress ? 0 : 1;
11008         offset = 0;
11009         outdir->hashes[0] = 0;
11010         prev_hash = 1;
11011         if ((retval = get_next_block(fs, outdir, &block_start)))
11012                 return retval;
11013         dirent = (struct ext2_dir_entry *) block_start;
11014         left = fs->blocksize;
11015         for (i=0; i < fd->num_array; i++) {
11016                 ent = fd->harray + i;
11017                 if (ent->dir->inode == 0)
11018                         continue;
11019                 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
11020                 if (rec_len > left) {
11021                         if (left)
11022                                 dirent->rec_len += left;
11023                         if ((retval = get_next_block(fs, outdir,
11024                                                       &block_start)))
11025                                 return retval;
11026                         offset = 0;
11027                 }
11028                 left = fs->blocksize - offset;
11029                 dirent = (struct ext2_dir_entry *) (block_start + offset);
11030                 if (offset == 0) {
11031                         if (ent->hash == prev_hash)
11032                                 outdir->hashes[outdir->num-1] = ent->hash | 1;
11033                         else
11034                                 outdir->hashes[outdir->num-1] = ent->hash;
11035                 }
11036                 dirent->inode = ent->dir->inode;
11037                 dirent->name_len = ent->dir->name_len;
11038                 dirent->rec_len = rec_len;
11039                 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
11040                 offset += rec_len;
11041                 left -= rec_len;
11042                 if (left < 12) {
11043                         dirent->rec_len += left;
11044                         offset += left;
11045                         left = 0;
11046                 }
11047                 prev_hash = ent->hash;
11048         }
11049         if (left)
11050                 dirent->rec_len += left;
11051
11052         return 0;
11053 }
11054
11055
11056 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
11057                                     ext2_ino_t ino, ext2_ino_t parent)
11058 {
11059         struct ext2_dir_entry           *dir;
11060         struct ext2_dx_root_info        *root;
11061         struct ext2_dx_countlimit       *limits;
11062         int                             filetype = 0;
11063
11064         if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
11065                 filetype = EXT2_FT_DIR << 8;
11066
11067         memset(buf, 0, fs->blocksize);
11068         dir = (struct ext2_dir_entry *) buf;
11069         dir->inode = ino;
11070         dir->name[0] = '.';
11071         dir->name_len = 1 | filetype;
11072         dir->rec_len = 12;
11073         dir = (struct ext2_dir_entry *) (buf + 12);
11074         dir->inode = parent;
11075         dir->name[0] = '.';
11076         dir->name[1] = '.';
11077         dir->name_len = 2 | filetype;
11078         dir->rec_len = fs->blocksize - 12;
11079
11080         root = (struct ext2_dx_root_info *) (buf+24);
11081         root->reserved_zero = 0;
11082         root->hash_version = fs->super->s_def_hash_version;
11083         root->info_length = 8;
11084         root->indirect_levels = 0;
11085         root->unused_flags = 0;
11086
11087         limits = (struct ext2_dx_countlimit *) (buf+32);
11088         limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
11089         limits->count = 0;
11090
11091         return root;
11092 }
11093
11094
11095 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
11096 {
11097         struct ext2_dir_entry           *dir;
11098         struct ext2_dx_countlimit       *limits;
11099
11100         memset(buf, 0, fs->blocksize);
11101         dir = (struct ext2_dir_entry *) buf;
11102         dir->inode = 0;
11103         dir->rec_len = fs->blocksize;
11104
11105         limits = (struct ext2_dx_countlimit *) (buf+8);
11106         limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
11107         limits->count = 0;
11108
11109         return (struct ext2_dx_entry *) limits;
11110 }
11111
11112 /*
11113  * This function takes the leaf nodes which have been written in
11114  * outdir, and populates the root node and any necessary interior nodes.
11115  */
11116 static errcode_t calculate_tree(ext2_filsys fs,
11117                                 struct out_dir *outdir,
11118                                 ext2_ino_t ino,
11119                                 ext2_ino_t parent)
11120 {
11121         struct ext2_dx_root_info        *root_info;
11122         struct ext2_dx_entry            *root, *dx_ent = 0;
11123         struct ext2_dx_countlimit       *root_limit, *limit;
11124         errcode_t                       retval;
11125         char                            * block_start;
11126         int                             i, c1, c2, nblks;
11127         int                             limit_offset, root_offset;
11128
11129         root_info = set_root_node(fs, outdir->buf, ino, parent);
11130         root_offset = limit_offset = ((char *) root_info - outdir->buf) +
11131                 root_info->info_length;
11132         root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11133         c1 = root_limit->limit;
11134         nblks = outdir->num;
11135
11136         /* Write out the pointer blocks */
11137         if (nblks-1 <= c1) {
11138                 /* Just write out the root block, and we're done */
11139                 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
11140                 for (i=1; i < nblks; i++) {
11141                         root->block = ext2fs_cpu_to_le32(i);
11142                         if (i != 1)
11143                                 root->hash =
11144                                         ext2fs_cpu_to_le32(outdir->hashes[i]);
11145                         root++;
11146                         c1--;
11147                 }
11148         } else {
11149                 c2 = 0;
11150                 limit = 0;
11151                 root_info->indirect_levels = 1;
11152                 for (i=1; i < nblks; i++) {
11153                         if (c1 == 0)
11154                                 return ENOSPC;
11155                         if (c2 == 0) {
11156                                 if (limit)
11157                                         limit->limit = limit->count =
11158                 ext2fs_cpu_to_le16(limit->limit);
11159                                 root = (struct ext2_dx_entry *)
11160                                         (outdir->buf + root_offset);
11161                                 root->block = ext2fs_cpu_to_le32(outdir->num);
11162                                 if (i != 1)
11163                                         root->hash =
11164                         ext2fs_cpu_to_le32(outdir->hashes[i]);
11165                                 if ((retval =  get_next_block(fs, outdir,
11166                                                               &block_start)))
11167                                         return retval;
11168                                 dx_ent = set_int_node(fs, block_start);
11169                                 limit = (struct ext2_dx_countlimit *) dx_ent;
11170                                 c2 = limit->limit;
11171                                 root_offset += sizeof(struct ext2_dx_entry);
11172                                 c1--;
11173                         }
11174                         dx_ent->block = ext2fs_cpu_to_le32(i);
11175                         if (c2 != limit->limit)
11176                                 dx_ent->hash =
11177                                         ext2fs_cpu_to_le32(outdir->hashes[i]);
11178                         dx_ent++;
11179                         c2--;
11180                 }
11181                 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
11182                 limit->limit = ext2fs_cpu_to_le16(limit->limit);
11183         }
11184         root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11185         root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
11186         root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
11187
11188         return 0;
11189 }
11190
11191 struct write_dir_struct {
11192         struct out_dir *outdir;
11193         errcode_t       err;
11194         e2fsck_t        ctx;
11195         int             cleared;
11196 };
11197
11198 /*
11199  * Helper function which writes out a directory block.
11200  */
11201 static int write_dir_block(ext2_filsys fs,
11202                            blk_t        *block_nr,
11203                            e2_blkcnt_t blockcnt,
11204                            blk_t ref_block FSCK_ATTR((unused)),
11205                            int ref_offset FSCK_ATTR((unused)),
11206                            void *priv_data)
11207 {
11208         struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
11209         blk_t   blk;
11210         char    *dir;
11211
11212         if (*block_nr == 0)
11213                 return 0;
11214         if (blockcnt >= wd->outdir->num) {
11215                 e2fsck_read_bitmaps(wd->ctx);
11216                 blk = *block_nr;
11217                 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
11218                 ext2fs_block_alloc_stats(fs, blk, -1);
11219                 *block_nr = 0;
11220                 wd->cleared++;
11221                 return BLOCK_CHANGED;
11222         }
11223         if (blockcnt < 0)
11224                 return 0;
11225
11226         dir = wd->outdir->buf + (blockcnt * fs->blocksize);
11227         wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
11228         if (wd->err)
11229                 return BLOCK_ABORT;
11230         return 0;
11231 }
11232
11233 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
11234                                  struct out_dir *outdir,
11235                                  ext2_ino_t ino, int compress)
11236 {
11237         struct write_dir_struct wd;
11238         errcode_t       retval;
11239         struct ext2_inode       inode;
11240
11241         retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
11242         if (retval)
11243                 return retval;
11244
11245         wd.outdir = outdir;
11246         wd.err = 0;
11247         wd.ctx = ctx;
11248         wd.cleared = 0;
11249
11250         retval = ext2fs_block_iterate2(fs, ino, 0, 0,
11251                                        write_dir_block, &wd);
11252         if (retval)
11253                 return retval;
11254         if (wd.err)
11255                 return wd.err;
11256
11257         e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
11258         if (compress)
11259                 inode.i_flags &= ~EXT2_INDEX_FL;
11260         else
11261                 inode.i_flags |= EXT2_INDEX_FL;
11262         inode.i_size = outdir->num * fs->blocksize;
11263         inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
11264         e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
11265
11266         return 0;
11267 }
11268
11269 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
11270 {
11271         ext2_filsys             fs = ctx->fs;
11272         errcode_t               retval;
11273         struct ext2_inode       inode;
11274         char                    *dir_buf = 0;
11275         struct fill_dir_struct  fd;
11276         struct out_dir          outdir;
11277
11278         outdir.max = outdir.num = 0;
11279         outdir.buf = 0;
11280         outdir.hashes = 0;
11281         e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
11282
11283         retval = ENOMEM;
11284         fd.harray = 0;
11285         dir_buf = malloc(inode.i_size);
11286         if (!dir_buf)
11287                 goto errout;
11288
11289         fd.max_array = inode.i_size / 32;
11290         fd.num_array = 0;
11291         fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
11292         if (!fd.harray)
11293                 goto errout;
11294
11295         fd.ctx = ctx;
11296         fd.buf = dir_buf;
11297         fd.inode = &inode;
11298         fd.err = 0;
11299         fd.dir_size = 0;
11300         fd.compress = 0;
11301         if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
11302             (inode.i_size / fs->blocksize) < 2)
11303                 fd.compress = 1;
11304         fd.parent = 0;
11305
11306         /* Read in the entire directory into memory */
11307         retval = ext2fs_block_iterate2(fs, ino, 0, 0,
11308                                        fill_dir_block, &fd);
11309         if (fd.err) {
11310                 retval = fd.err;
11311                 goto errout;
11312         }
11313
11314         /* Sort the list */
11315 resort:
11316         if (fd.compress)
11317                 qsort(fd.harray+2, fd.num_array-2,
11318                       sizeof(struct hash_entry), name_cmp);
11319         else
11320                 qsort(fd.harray, fd.num_array,
11321                       sizeof(struct hash_entry), hash_cmp);
11322
11323         /*
11324          * Look for duplicates
11325          */
11326         if (duplicate_search_and_fix(ctx, fs, ino, &fd))
11327                 goto resort;
11328
11329         if (ctx->options & E2F_OPT_NO) {
11330                 retval = 0;
11331                 goto errout;
11332         }
11333
11334         /*
11335          * Copy the directory entries.  In a htree directory these
11336          * will become the leaf nodes.
11337          */
11338         retval = copy_dir_entries(fs, &fd, &outdir);
11339         if (retval)
11340                 goto errout;
11341
11342         free(dir_buf); dir_buf = 0;
11343
11344         if (!fd.compress) {
11345                 /* Calculate the interior nodes */
11346                 retval = calculate_tree(fs, &outdir, ino, fd.parent);
11347                 if (retval)
11348                         goto errout;
11349         }
11350
11351         retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
11352
11353 errout:
11354         free(dir_buf);
11355         free(fd.harray);
11356
11357         free_out_dir(&outdir);
11358         return retval;
11359 }
11360
11361 void e2fsck_rehash_directories(e2fsck_t ctx)
11362 {
11363         struct problem_context  pctx;
11364         struct dir_info         *dir;
11365         ext2_u32_iterate        iter;
11366         ext2_ino_t              ino;
11367         errcode_t               retval;
11368         int                     i, cur, max, all_dirs, dir_index, first = 1;
11369
11370         all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
11371
11372         if (!ctx->dirs_to_hash && !all_dirs)
11373                 return;
11374
11375         e2fsck_get_lost_and_found(ctx, 0);
11376
11377         clear_problem_context(&pctx);
11378
11379         dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
11380         cur = 0;
11381         if (all_dirs) {
11382                 i = 0;
11383                 max = e2fsck_get_num_dirinfo(ctx);
11384         } else {
11385                 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
11386                                                        &iter);
11387                 if (retval) {
11388                         pctx.errcode = retval;
11389                         fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
11390                         return;
11391                 }
11392                 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
11393         }
11394         while (1) {
11395                 if (all_dirs) {
11396                         if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
11397                                 break;
11398                         ino = dir->ino;
11399                 } else {
11400                         if (!ext2fs_u32_list_iterate(iter, &ino))
11401                                 break;
11402                 }
11403                 if (ino == ctx->lost_and_found)
11404                         continue;
11405                 pctx.dir = ino;
11406                 if (first) {
11407                         fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
11408                         first = 0;
11409                 }
11410                 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
11411                 if (pctx.errcode) {
11412                         end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11413                         fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
11414                 }
11415                 if (ctx->progress && !ctx->progress_fd)
11416                         e2fsck_simple_progress(ctx, "Rebuilding directory",
11417                                100.0 * (float) (++cur) / (float) max, ino);
11418         }
11419         end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11420         if (!all_dirs)
11421                 ext2fs_u32_list_iterate_end(iter);
11422
11423         ext2fs_u32_list_free(ctx->dirs_to_hash);
11424         ctx->dirs_to_hash = 0;
11425 }
11426
11427 /*
11428  * linux/fs/revoke.c
11429  *
11430  * Journal revoke routines for the generic filesystem journaling code;
11431  * part of the ext2fs journaling system.
11432  *
11433  * Revoke is the mechanism used to prevent old log records for deleted
11434  * metadata from being replayed on top of newer data using the same
11435  * blocks.  The revoke mechanism is used in two separate places:
11436  *
11437  * + Commit: during commit we write the entire list of the current
11438  *   transaction's revoked blocks to the journal
11439  *
11440  * + Recovery: during recovery we record the transaction ID of all
11441  *   revoked blocks.  If there are multiple revoke records in the log
11442  *   for a single block, only the last one counts, and if there is a log
11443  *   entry for a block beyond the last revoke, then that log entry still
11444  *   gets replayed.
11445  *
11446  * We can get interactions between revokes and new log data within a
11447  * single transaction:
11448  *
11449  * Block is revoked and then journaled:
11450  *   The desired end result is the journaling of the new block, so we
11451  *   cancel the revoke before the transaction commits.
11452  *
11453  * Block is journaled and then revoked:
11454  *   The revoke must take precedence over the write of the block, so we
11455  *   need either to cancel the journal entry or to write the revoke
11456  *   later in the log than the log block.  In this case, we choose the
11457  *   latter: journaling a block cancels any revoke record for that block
11458  *   in the current transaction, so any revoke for that block in the
11459  *   transaction must have happened after the block was journaled and so
11460  *   the revoke must take precedence.
11461  *
11462  * Block is revoked and then written as data:
11463  *   The data write is allowed to succeed, but the revoke is _not_
11464  *   cancelled.  We still need to prevent old log records from
11465  *   overwriting the new data.  We don't even need to clear the revoke
11466  *   bit here.
11467  *
11468  * Revoke information on buffers is a tri-state value:
11469  *
11470  * RevokeValid clear:   no cached revoke status, need to look it up
11471  * RevokeValid set, Revoked clear:
11472  *                      buffer has not been revoked, and cancel_revoke
11473  *                      need do nothing.
11474  * RevokeValid set, Revoked set:
11475  *                      buffer has been revoked.
11476  */
11477
11478 static kmem_cache_t *revoke_record_cache;
11479 static kmem_cache_t *revoke_table_cache;
11480
11481 /* Each revoke record represents one single revoked block.  During
11482    journal replay, this involves recording the transaction ID of the
11483    last transaction to revoke this block. */
11484
11485 struct jbd_revoke_record_s
11486 {
11487         struct list_head  hash;
11488         tid_t             sequence;     /* Used for recovery only */
11489         unsigned long     blocknr;
11490 };
11491
11492
11493 /* The revoke table is just a simple hash table of revoke records. */
11494 struct jbd_revoke_table_s
11495 {
11496         /* It is conceivable that we might want a larger hash table
11497          * for recovery.  Must be a power of two. */
11498         int               hash_size;
11499         int               hash_shift;
11500         struct list_head *hash_table;
11501 };
11502
11503
11504 /* Utility functions to maintain the revoke table */
11505
11506 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11507 static inline int hash(journal_t *journal, unsigned long block)
11508 {
11509         struct jbd_revoke_table_s *table = journal->j_revoke;
11510         int hash_shift = table->hash_shift;
11511
11512         return ((block << (hash_shift - 6)) ^
11513                 (block >> 13) ^
11514                 (block << (hash_shift - 12))) & (table->hash_size - 1);
11515 }
11516
11517 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11518                               tid_t seq)
11519 {
11520         struct list_head *hash_list;
11521         struct jbd_revoke_record_s *record;
11522
11523         record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11524         if (!record)
11525                 goto oom;
11526
11527         record->sequence = seq;
11528         record->blocknr = blocknr;
11529         hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11530         list_add(&record->hash, hash_list);
11531         return 0;
11532
11533 oom:
11534         return -ENOMEM;
11535 }
11536
11537 /* Find a revoke record in the journal's hash table. */
11538
11539 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11540                                                       unsigned long blocknr)
11541 {
11542         struct list_head *hash_list;
11543         struct jbd_revoke_record_s *record;
11544
11545         hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11546
11547         record = (struct jbd_revoke_record_s *) hash_list->next;
11548         while (&(record->hash) != hash_list) {
11549                 if (record->blocknr == blocknr)
11550                         return record;
11551                 record = (struct jbd_revoke_record_s *) record->hash.next;
11552         }
11553         return NULL;
11554 }
11555
11556 int journal_init_revoke_caches(void)
11557 {
11558         revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11559         if (revoke_record_cache == 0)
11560                 return -ENOMEM;
11561
11562         revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11563         if (revoke_table_cache == 0) {
11564                 do_cache_destroy(revoke_record_cache);
11565                 revoke_record_cache = NULL;
11566                 return -ENOMEM;
11567         }
11568         return 0;
11569 }
11570
11571 void journal_destroy_revoke_caches(void)
11572 {
11573         do_cache_destroy(revoke_record_cache);
11574         revoke_record_cache = 0;
11575         do_cache_destroy(revoke_table_cache);
11576         revoke_table_cache = 0;
11577 }
11578
11579 /* Initialise the revoke table for a given journal to a given size. */
11580
11581 int journal_init_revoke(journal_t *journal, int hash_size)
11582 {
11583         int shift, tmp;
11584
11585         journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11586         if (!journal->j_revoke)
11587                 return -ENOMEM;
11588
11589         /* Check that the hash_size is a power of two */
11590         journal->j_revoke->hash_size = hash_size;
11591
11592         shift = 0;
11593         tmp = hash_size;
11594         while((tmp >>= 1UL) != 0UL)
11595                 shift++;
11596         journal->j_revoke->hash_shift = shift;
11597
11598         journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11599         if (!journal->j_revoke->hash_table) {
11600                 free(journal->j_revoke);
11601                 journal->j_revoke = NULL;
11602                 return -ENOMEM;
11603         }
11604
11605         for (tmp = 0; tmp < hash_size; tmp++)
11606                 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11607
11608         return 0;
11609 }
11610
11611 /* Destoy a journal's revoke table.  The table must already be empty! */
11612
11613 void journal_destroy_revoke(journal_t *journal)
11614 {
11615         struct jbd_revoke_table_s *table;
11616         struct list_head *hash_list;
11617         int i;
11618
11619         table = journal->j_revoke;
11620         if (!table)
11621                 return;
11622
11623         for (i=0; i<table->hash_size; i++) {
11624                 hash_list = &table->hash_table[i];
11625         }
11626
11627         free(table->hash_table);
11628         free(table);
11629         journal->j_revoke = NULL;
11630 }
11631
11632 /*
11633  * Revoke support for recovery.
11634  *
11635  * Recovery needs to be able to:
11636  *
11637  *  record all revoke records, including the tid of the latest instance
11638  *  of each revoke in the journal
11639  *
11640  *  check whether a given block in a given transaction should be replayed
11641  *  (ie. has not been revoked by a revoke record in that or a subsequent
11642  *  transaction)
11643  *
11644  *  empty the revoke table after recovery.
11645  */
11646
11647 /*
11648  * First, setting revoke records.  We create a new revoke record for
11649  * every block ever revoked in the log as we scan it for recovery, and
11650  * we update the existing records if we find multiple revokes for a
11651  * single block.
11652  */
11653
11654 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11655                        tid_t sequence)
11656 {
11657         struct jbd_revoke_record_s *record;
11658
11659         record = find_revoke_record(journal, blocknr);
11660         if (record) {
11661                 /* If we have multiple occurences, only record the
11662                  * latest sequence number in the hashed record */
11663                 if (tid_gt(sequence, record->sequence))
11664                         record->sequence = sequence;
11665                 return 0;
11666         }
11667         return insert_revoke_hash(journal, blocknr, sequence);
11668 }
11669
11670 /*
11671  * Test revoke records.  For a given block referenced in the log, has
11672  * that block been revoked?  A revoke record with a given transaction
11673  * sequence number revokes all blocks in that transaction and earlier
11674  * ones, but later transactions still need replayed.
11675  */
11676
11677 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11678                         tid_t sequence)
11679 {
11680         struct jbd_revoke_record_s *record;
11681
11682         record = find_revoke_record(journal, blocknr);
11683         if (!record)
11684                 return 0;
11685         if (tid_gt(sequence, record->sequence))
11686                 return 0;
11687         return 1;
11688 }
11689
11690 /*
11691  * Finally, once recovery is over, we need to clear the revoke table so
11692  * that it can be reused by the running filesystem.
11693  */
11694
11695 void journal_clear_revoke(journal_t *journal)
11696 {
11697         int i;
11698         struct list_head *hash_list;
11699         struct jbd_revoke_record_s *record;
11700         struct jbd_revoke_table_s *revoke_var;
11701
11702         revoke_var = journal->j_revoke;
11703
11704         for (i = 0; i < revoke_var->hash_size; i++) {
11705                 hash_list = &revoke_var->hash_table[i];
11706                 while (!list_empty(hash_list)) {
11707                         record = (struct jbd_revoke_record_s*) hash_list->next;
11708                         list_del(&record->hash);
11709                         free(record);
11710                 }
11711         }
11712 }
11713
11714 /*
11715  * e2fsck.c - superblock checks
11716  */
11717
11718 #define MIN_CHECK 1
11719 #define MAX_CHECK 2
11720
11721 static void check_super_value(e2fsck_t ctx, const char *descr,
11722                               unsigned long value, int flags,
11723                               unsigned long min_val, unsigned long max_val)
11724 {
11725         struct          problem_context pctx;
11726
11727         if (((flags & MIN_CHECK) && (value < min_val)) ||
11728             ((flags & MAX_CHECK) && (value > max_val))) {
11729                 clear_problem_context(&pctx);
11730                 pctx.num = value;
11731                 pctx.str = descr;
11732                 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11733                 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11734         }
11735 }
11736
11737 /*
11738  * This routine may get stubbed out in special compilations of the
11739  * e2fsck code..
11740  */
11741 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11742 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11743 {
11744         return (ext2fs_get_device_size(ctx->filesystem_name,
11745                                        EXT2_BLOCK_SIZE(ctx->fs->super),
11746                                        &ctx->num_blocks));
11747 }
11748 #endif
11749
11750 /*
11751  * helper function to release an inode
11752  */
11753 struct process_block_struct {
11754         e2fsck_t        ctx;
11755         char            *buf;
11756         struct problem_context *pctx;
11757         int             truncating;
11758         int             truncate_offset;
11759         e2_blkcnt_t     truncate_block;
11760         int             truncated_blocks;
11761         int             abort;
11762         errcode_t       errcode;
11763 };
11764
11765 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11766                                e2_blkcnt_t blockcnt,
11767                                blk_t    ref_blk FSCK_ATTR((unused)),
11768                                int      ref_offset FSCK_ATTR((unused)),
11769                                void *priv_data)
11770 {
11771         struct process_block_struct *pb;
11772         e2fsck_t                ctx;
11773         struct problem_context  *pctx;
11774         blk_t                   blk = *block_nr;
11775         int                     retval = 0;
11776
11777         pb = (struct process_block_struct *) priv_data;
11778         ctx = pb->ctx;
11779         pctx = pb->pctx;
11780
11781         pctx->blk = blk;
11782         pctx->blkcount = blockcnt;
11783
11784         if (HOLE_BLKADDR(blk))
11785                 return 0;
11786
11787         if ((blk < fs->super->s_first_data_block) ||
11788             (blk >= fs->super->s_blocks_count)) {
11789                 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11790         return_abort:
11791                 pb->abort = 1;
11792                 return BLOCK_ABORT;
11793         }
11794
11795         if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11796                 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11797                 goto return_abort;
11798         }
11799
11800         /*
11801          * If we are deleting an orphan, then we leave the fields alone.
11802          * If we are truncating an orphan, then update the inode fields
11803          * and clean up any partial block data.
11804          */
11805         if (pb->truncating) {
11806                 /*
11807                  * We only remove indirect blocks if they are
11808                  * completely empty.
11809                  */
11810                 if (blockcnt < 0) {
11811                         int     i, limit;
11812                         blk_t   *bp;
11813
11814                         pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11815                                                         pb->buf);
11816                         if (pb->errcode)
11817                                 goto return_abort;
11818
11819                         limit = fs->blocksize >> 2;
11820                         for (i = 0, bp = (blk_t *) pb->buf;
11821                              i < limit;  i++, bp++)
11822                                 if (*bp)
11823                                         return 0;
11824                 }
11825                 /*
11826                  * We don't remove direct blocks until we've reached
11827                  * the truncation block.
11828                  */
11829                 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11830                         return 0;
11831                 /*
11832                  * If part of the last block needs truncating, we do
11833                  * it here.
11834                  */
11835                 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11836                         pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11837                                                         pb->buf);
11838                         if (pb->errcode)
11839                                 goto return_abort;
11840                         memset(pb->buf + pb->truncate_offset, 0,
11841                                fs->blocksize - pb->truncate_offset);
11842                         pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11843                                                          pb->buf);
11844                         if (pb->errcode)
11845                                 goto return_abort;
11846                 }
11847                 pb->truncated_blocks++;
11848                 *block_nr = 0;
11849                 retval |= BLOCK_CHANGED;
11850         }
11851
11852         ext2fs_block_alloc_stats(fs, blk, -1);
11853         return retval;
11854 }
11855
11856 /*
11857  * This function releases an inode.  Returns 1 if an inconsistency was
11858  * found.  If the inode has a link count, then it is being truncated and
11859  * not deleted.
11860  */
11861 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11862                                 struct ext2_inode *inode, char *block_buf,
11863                                 struct problem_context *pctx)
11864 {
11865         struct process_block_struct     pb;
11866         ext2_filsys                     fs = ctx->fs;
11867         errcode_t                       retval;
11868         __u32                           count;
11869
11870         if (!ext2fs_inode_has_valid_blocks(inode))
11871                 return 0;
11872
11873         pb.buf = block_buf + 3 * ctx->fs->blocksize;
11874         pb.ctx = ctx;
11875         pb.abort = 0;
11876         pb.errcode = 0;
11877         pb.pctx = pctx;
11878         if (inode->i_links_count) {
11879                 pb.truncating = 1;
11880                 pb.truncate_block = (e2_blkcnt_t)
11881                         ((((long long)inode->i_size_high << 32) +
11882                           inode->i_size + fs->blocksize - 1) /
11883                          fs->blocksize);
11884                 pb.truncate_offset = inode->i_size % fs->blocksize;
11885         } else {
11886                 pb.truncating = 0;
11887                 pb.truncate_block = 0;
11888                 pb.truncate_offset = 0;
11889         }
11890         pb.truncated_blocks = 0;
11891         retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11892                                       block_buf, release_inode_block, &pb);
11893         if (retval) {
11894                 com_err("release_inode_blocks", retval,
11895                         _("while calling ext2fs_block_iterate for inode %d"),
11896                         ino);
11897                 return 1;
11898         }
11899         if (pb.abort)
11900                 return 1;
11901
11902         /* Refresh the inode since ext2fs_block_iterate may have changed it */
11903         e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11904
11905         if (pb.truncated_blocks)
11906                 inode->i_blocks -= pb.truncated_blocks *
11907                         (fs->blocksize / 512);
11908
11909         if (inode->i_file_acl) {
11910                 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11911                                                    block_buf, -1, &count);
11912                 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11913                         retval = 0;
11914                         count = 1;
11915                 }
11916                 if (retval) {
11917                         com_err("release_inode_blocks", retval,
11918                 _("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11919                                 ino);
11920                         return 1;
11921                 }
11922                 if (count == 0)
11923                         ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11924                 inode->i_file_acl = 0;
11925         }
11926         return 0;
11927 }
11928
11929 /*
11930  * This function releases all of the orphan inodes.  It returns 1 if
11931  * it hit some error, and 0 on success.
11932  */
11933 static int release_orphan_inodes(e2fsck_t ctx)
11934 {
11935         ext2_filsys fs = ctx->fs;
11936         ext2_ino_t      ino, next_ino;
11937         struct ext2_inode inode;
11938         struct problem_context pctx;
11939         char *block_buf;
11940
11941         if ((ino = fs->super->s_last_orphan) == 0)
11942                 return 0;
11943
11944         /*
11945          * Win or lose, we won't be using the head of the orphan inode
11946          * list again.
11947          */
11948         fs->super->s_last_orphan = 0;
11949         ext2fs_mark_super_dirty(fs);
11950
11951         /*
11952          * If the filesystem contains errors, don't run the orphan
11953          * list, since the orphan list can't be trusted; and we're
11954          * going to be running a full e2fsck run anyway...
11955          */
11956         if (fs->super->s_state & EXT2_ERROR_FS)
11957                 return 0;
11958
11959         if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11960             (ino > fs->super->s_inodes_count)) {
11961                 clear_problem_context(&pctx);
11962                 pctx.ino = ino;
11963                 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11964                 return 1;
11965         }
11966
11967         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11968                                                     "block iterate buffer");
11969         e2fsck_read_bitmaps(ctx);
11970
11971         while (ino) {
11972                 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11973                 clear_problem_context(&pctx);
11974                 pctx.ino = ino;
11975                 pctx.inode = &inode;
11976                 pctx.str = inode.i_links_count ? _("Truncating") :
11977                         _("Clearing");
11978
11979                 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11980
11981                 next_ino = inode.i_dtime;
11982                 if (next_ino &&
11983                     ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11984                      (next_ino > fs->super->s_inodes_count))) {
11985                         pctx.ino = next_ino;
11986                         fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11987                         goto return_abort;
11988                 }
11989
11990                 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11991                         goto return_abort;
11992
11993                 if (!inode.i_links_count) {
11994                         ext2fs_inode_alloc_stats2(fs, ino, -1,
11995                                                   LINUX_S_ISDIR(inode.i_mode));
11996                         inode.i_dtime = time(0);
11997                 } else {
11998                         inode.i_dtime = 0;
11999                 }
12000                 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
12001                 ino = next_ino;
12002         }
12003         ext2fs_free_mem(&block_buf);
12004         return 0;
12005 return_abort:
12006         ext2fs_free_mem(&block_buf);
12007         return 1;
12008 }
12009
12010 /*
12011  * Check the resize inode to make sure it is sane.  We check both for
12012  * the case where on-line resizing is not enabled (in which case the
12013  * resize inode should be cleared) as well as the case where on-line
12014  * resizing is enabled.
12015  */
12016 static void check_resize_inode(e2fsck_t ctx)
12017 {
12018         ext2_filsys fs = ctx->fs;
12019         struct ext2_inode inode;
12020         struct problem_context  pctx;
12021         int             i, j, gdt_off, ind_off;
12022         blk_t           blk, pblk, expect;
12023         __u32           *dind_buf = 0, *ind_buf;
12024         errcode_t       retval;
12025
12026         clear_problem_context(&pctx);
12027
12028         /*
12029          * If the resize inode feature isn't set, then
12030          * s_reserved_gdt_blocks must be zero.
12031          */
12032         if (!(fs->super->s_feature_compat &
12033               EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12034                 if (fs->super->s_reserved_gdt_blocks) {
12035                         pctx.num = fs->super->s_reserved_gdt_blocks;
12036                         if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
12037                                         &pctx)) {
12038                                 fs->super->s_reserved_gdt_blocks = 0;
12039                                 ext2fs_mark_super_dirty(fs);
12040                         }
12041                 }
12042         }
12043
12044         /* Read the resize inode */
12045         pctx.ino = EXT2_RESIZE_INO;
12046         retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
12047         if (retval) {
12048                 if (fs->super->s_feature_compat &
12049                     EXT2_FEATURE_COMPAT_RESIZE_INODE)
12050                         ctx->flags |= E2F_FLAG_RESIZE_INODE;
12051                 return;
12052         }
12053
12054         /*
12055          * If the resize inode feature isn't set, check to make sure
12056          * the resize inode is cleared; then we're done.
12057          */
12058         if (!(fs->super->s_feature_compat &
12059               EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12060                 for (i=0; i < EXT2_N_BLOCKS; i++) {
12061                         if (inode.i_block[i])
12062                                 break;
12063                 }
12064                 if ((i < EXT2_N_BLOCKS) &&
12065                     fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
12066                         memset(&inode, 0, sizeof(inode));
12067                         e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12068                                            "clear_resize");
12069                 }
12070                 return;
12071         }
12072
12073         /*
12074          * The resize inode feature is enabled; check to make sure the
12075          * only block in use is the double indirect block
12076          */
12077         blk = inode.i_block[EXT2_DIND_BLOCK];
12078         for (i=0; i < EXT2_N_BLOCKS; i++) {
12079                 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
12080                         break;
12081         }
12082         if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
12083             !(inode.i_mode & LINUX_S_IFREG) ||
12084             (blk < fs->super->s_first_data_block ||
12085              blk >= fs->super->s_blocks_count)) {
12086         resize_inode_invalid:
12087                 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
12088                         memset(&inode, 0, sizeof(inode));
12089                         e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12090                                            "clear_resize");
12091                         ctx->flags |= E2F_FLAG_RESIZE_INODE;
12092                 }
12093                 if (!(ctx->options & E2F_OPT_READONLY)) {
12094                         fs->super->s_state &= ~EXT2_VALID_FS;
12095                         ext2fs_mark_super_dirty(fs);
12096                 }
12097                 goto cleanup;
12098         }
12099         dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
12100                                                     "resize dind buffer");
12101         ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
12102
12103         retval = ext2fs_read_ind_block(fs, blk, dind_buf);
12104         if (retval)
12105                 goto resize_inode_invalid;
12106
12107         gdt_off = fs->desc_blocks;
12108         pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
12109         for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
12110              i++, gdt_off++, pblk++) {
12111                 gdt_off %= fs->blocksize/4;
12112                 if (dind_buf[gdt_off] != pblk)
12113                         goto resize_inode_invalid;
12114                 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
12115                 if (retval)
12116                         goto resize_inode_invalid;
12117                 ind_off = 0;
12118                 for (j = 1; j < fs->group_desc_count; j++) {
12119                         if (!ext2fs_bg_has_super(fs, j))
12120                                 continue;
12121                         expect = pblk + (j * fs->super->s_blocks_per_group);
12122                         if (ind_buf[ind_off] != expect)
12123                                 goto resize_inode_invalid;
12124                         ind_off++;
12125                 }
12126         }
12127
12128 cleanup:
12129         ext2fs_free_mem(&dind_buf);
12130
12131  }
12132
12133 static void check_super_block(e2fsck_t ctx)
12134 {
12135         ext2_filsys fs = ctx->fs;
12136         blk_t   first_block, last_block;
12137         struct ext2_super_block *sb = fs->super;
12138         struct ext2_group_desc *gd;
12139         blk_t   blocks_per_group = fs->super->s_blocks_per_group;
12140         blk_t   bpg_max;
12141         int     inodes_per_block;
12142         int     ipg_max;
12143         int     inode_size;
12144         dgrp_t  i;
12145         blk_t   should_be;
12146         struct problem_context  pctx;
12147         __u32   free_blocks = 0, free_inodes = 0;
12148
12149         inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
12150         ipg_max = inodes_per_block * (blocks_per_group - 4);
12151         if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
12152                 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
12153         bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
12154         if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
12155                 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
12156
12157         ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
12158                  sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
12159         ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
12160                  sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
12161         ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
12162                 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
12163
12164         clear_problem_context(&pctx);
12165
12166         /*
12167          * Verify the super block constants...
12168          */
12169         check_super_value(ctx, "inodes_count", sb->s_inodes_count,
12170                           MIN_CHECK, 1, 0);
12171         check_super_value(ctx, "blocks_count", sb->s_blocks_count,
12172                           MIN_CHECK, 1, 0);
12173         check_super_value(ctx, "first_data_block", sb->s_first_data_block,
12174                           MAX_CHECK, 0, sb->s_blocks_count);
12175         check_super_value(ctx, "log_block_size", sb->s_log_block_size,
12176                           MIN_CHECK | MAX_CHECK, 0,
12177                           EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
12178         check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
12179                           MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
12180         check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
12181                           MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
12182                           bpg_max);
12183         check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
12184                           MIN_CHECK | MAX_CHECK, 8, bpg_max);
12185         check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
12186                           MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
12187         check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
12188                           MAX_CHECK, 0, sb->s_blocks_count / 2);
12189         check_super_value(ctx, "reserved_gdt_blocks",
12190                           sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
12191                           fs->blocksize/4);
12192         inode_size = EXT2_INODE_SIZE(sb);
12193         check_super_value(ctx, "inode_size",
12194                           inode_size, MIN_CHECK | MAX_CHECK,
12195                           EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
12196         if (inode_size & (inode_size - 1)) {
12197                 pctx.num = inode_size;
12198                 pctx.str = "inode_size";
12199                 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
12200                 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
12201                 return;
12202         }
12203
12204         if (!ctx->num_blocks) {
12205                 pctx.errcode = e2fsck_get_device_size(ctx);
12206                 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
12207                         fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
12208                         ctx->flags |= E2F_FLAG_ABORT;
12209                         return;
12210                 }
12211                 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
12212                     (ctx->num_blocks < sb->s_blocks_count)) {
12213                         pctx.blk = sb->s_blocks_count;
12214                         pctx.blk2 = ctx->num_blocks;
12215                         if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
12216                                 ctx->flags |= E2F_FLAG_ABORT;
12217                                 return;
12218                         }
12219                 }
12220         }
12221
12222         if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
12223                 pctx.blk = EXT2_BLOCK_SIZE(sb);
12224                 pctx.blk2 = EXT2_FRAG_SIZE(sb);
12225                 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
12226                 ctx->flags |= E2F_FLAG_ABORT;
12227                 return;
12228         }
12229
12230         should_be = sb->s_frags_per_group >>
12231                 (sb->s_log_block_size - sb->s_log_frag_size);
12232         if (sb->s_blocks_per_group != should_be) {
12233                 pctx.blk = sb->s_blocks_per_group;
12234                 pctx.blk2 = should_be;
12235                 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
12236                 ctx->flags |= E2F_FLAG_ABORT;
12237                 return;
12238         }
12239
12240         should_be = (sb->s_log_block_size == 0) ? 1 : 0;
12241         if (sb->s_first_data_block != should_be) {
12242                 pctx.blk = sb->s_first_data_block;
12243                 pctx.blk2 = should_be;
12244                 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
12245                 ctx->flags |= E2F_FLAG_ABORT;
12246                 return;
12247         }
12248
12249         should_be = sb->s_inodes_per_group * fs->group_desc_count;
12250         if (sb->s_inodes_count != should_be) {
12251                 pctx.ino = sb->s_inodes_count;
12252                 pctx.ino2 = should_be;
12253                 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
12254                         sb->s_inodes_count = should_be;
12255                         ext2fs_mark_super_dirty(fs);
12256                 }
12257         }
12258
12259         /*
12260          * Verify the group descriptors....
12261          */
12262         first_block =  sb->s_first_data_block;
12263         last_block = first_block + blocks_per_group;
12264
12265         for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
12266                 pctx.group = i;
12267
12268                 if (i == fs->group_desc_count - 1)
12269                         last_block = sb->s_blocks_count;
12270                 if ((gd->bg_block_bitmap < first_block) ||
12271                     (gd->bg_block_bitmap >= last_block)) {
12272                         pctx.blk = gd->bg_block_bitmap;
12273                         if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
12274                                 gd->bg_block_bitmap = 0;
12275                 }
12276                 if (gd->bg_block_bitmap == 0) {
12277                         ctx->invalid_block_bitmap_flag[i]++;
12278                         ctx->invalid_bitmaps++;
12279                 }
12280                 if ((gd->bg_inode_bitmap < first_block) ||
12281                     (gd->bg_inode_bitmap >= last_block)) {
12282                         pctx.blk = gd->bg_inode_bitmap;
12283                         if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
12284                                 gd->bg_inode_bitmap = 0;
12285                 }
12286                 if (gd->bg_inode_bitmap == 0) {
12287                         ctx->invalid_inode_bitmap_flag[i]++;
12288                         ctx->invalid_bitmaps++;
12289                 }
12290                 if ((gd->bg_inode_table < first_block) ||
12291                     ((gd->bg_inode_table +
12292                       fs->inode_blocks_per_group - 1) >= last_block)) {
12293                         pctx.blk = gd->bg_inode_table;
12294                         if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
12295                                 gd->bg_inode_table = 0;
12296                 }
12297                 if (gd->bg_inode_table == 0) {
12298                         ctx->invalid_inode_table_flag[i]++;
12299                         ctx->invalid_bitmaps++;
12300                 }
12301                 free_blocks += gd->bg_free_blocks_count;
12302                 free_inodes += gd->bg_free_inodes_count;
12303                 first_block += sb->s_blocks_per_group;
12304                 last_block += sb->s_blocks_per_group;
12305
12306                 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
12307                     (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
12308                     (gd->bg_used_dirs_count > sb->s_inodes_per_group))
12309                         ext2fs_unmark_valid(fs);
12310
12311         }
12312
12313         /*
12314          * Update the global counts from the block group counts.  This
12315          * is needed for an experimental patch which eliminates
12316          * locking the entire filesystem when allocating blocks or
12317          * inodes; if the filesystem is not unmounted cleanly, the
12318          * global counts may not be accurate.
12319          */
12320         if ((free_blocks != sb->s_free_blocks_count) ||
12321             (free_inodes != sb->s_free_inodes_count)) {
12322                 if (ctx->options & E2F_OPT_READONLY)
12323                         ext2fs_unmark_valid(fs);
12324                 else {
12325                         sb->s_free_blocks_count = free_blocks;
12326                         sb->s_free_inodes_count = free_inodes;
12327                         ext2fs_mark_super_dirty(fs);
12328                 }
12329         }
12330
12331         if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
12332             (sb->s_free_inodes_count > sb->s_inodes_count))
12333                 ext2fs_unmark_valid(fs);
12334
12335
12336         /*
12337          * If we have invalid bitmaps, set the error state of the
12338          * filesystem.
12339          */
12340         if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
12341                 sb->s_state &= ~EXT2_VALID_FS;
12342                 ext2fs_mark_super_dirty(fs);
12343         }
12344
12345         clear_problem_context(&pctx);
12346
12347         /*
12348          * If the UUID field isn't assigned, assign it.
12349          */
12350         if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
12351                 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
12352                         uuid_generate(sb->s_uuid);
12353                         ext2fs_mark_super_dirty(fs);
12354                         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12355                 }
12356         }
12357
12358         /* FIXME - HURD support?
12359          * For the Hurd, check to see if the filetype option is set,
12360          * since it doesn't support it.
12361          */
12362         if (!(ctx->options & E2F_OPT_READONLY) &&
12363             fs->super->s_creator_os == EXT2_OS_HURD &&
12364             (fs->super->s_feature_incompat &
12365              EXT2_FEATURE_INCOMPAT_FILETYPE)) {
12366                 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
12367                         fs->super->s_feature_incompat &=
12368                                 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
12369                         ext2fs_mark_super_dirty(fs);
12370
12371                 }
12372         }
12373
12374         /*
12375          * If we have any of the compatibility flags set, we need to have a
12376          * revision 1 filesystem.  Most kernels will not check the flags on
12377          * a rev 0 filesystem and we may have corruption issues because of
12378          * the incompatible changes to the filesystem.
12379          */
12380         if (!(ctx->options & E2F_OPT_READONLY) &&
12381             fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
12382             (fs->super->s_feature_compat ||
12383              fs->super->s_feature_ro_compat ||
12384              fs->super->s_feature_incompat) &&
12385             fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
12386                 ext2fs_update_dynamic_rev(fs);
12387                 ext2fs_mark_super_dirty(fs);
12388         }
12389
12390         check_resize_inode(ctx);
12391
12392         /*
12393          * Clean up any orphan inodes, if present.
12394          */
12395         if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
12396                 fs->super->s_state &= ~EXT2_VALID_FS;
12397                 ext2fs_mark_super_dirty(fs);
12398         }
12399
12400         /*
12401          * Move the ext3 journal file, if necessary.
12402          */
12403         e2fsck_move_ext3_journal(ctx);
12404         return;
12405 }
12406
12407 /*
12408  * swapfs.c --- byte-swap an ext2 filesystem
12409  */
12410
12411 #ifdef ENABLE_SWAPFS
12412
12413 struct swap_block_struct {
12414         ext2_ino_t      ino;
12415         int             isdir;
12416         errcode_t       errcode;
12417         char            *dir_buf;
12418         struct ext2_inode *inode;
12419 };
12420
12421 /*
12422  * This is a helper function for block_iterate.  We mark all of the
12423  * indirect and direct blocks as changed, so that block_iterate will
12424  * write them out.
12425  */
12426 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
12427                       void *priv_data)
12428 {
12429         errcode_t       retval;
12430
12431         struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
12432
12433         if (sb->isdir && (blockcnt >= 0) && *block_nr) {
12434                 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
12435                 if (retval) {
12436                         sb->errcode = retval;
12437                         return BLOCK_ABORT;
12438                 }
12439                 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
12440                 if (retval) {
12441                         sb->errcode = retval;
12442                         return BLOCK_ABORT;
12443                 }
12444         }
12445         if (blockcnt >= 0) {
12446                 if (blockcnt < EXT2_NDIR_BLOCKS)
12447                         return 0;
12448                 return BLOCK_CHANGED;
12449         }
12450         if (blockcnt == BLOCK_COUNT_IND) {
12451                 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
12452                         return 0;
12453                 return BLOCK_CHANGED;
12454         }
12455         if (blockcnt == BLOCK_COUNT_DIND) {
12456                 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12457                         return 0;
12458                 return BLOCK_CHANGED;
12459         }
12460         if (blockcnt == BLOCK_COUNT_TIND) {
12461                 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12462                         return 0;
12463                 return BLOCK_CHANGED;
12464         }
12465         return BLOCK_CHANGED;
12466 }
12467
12468 /*
12469  * This function is responsible for byte-swapping all of the indirect,
12470  * block pointers.  It is also responsible for byte-swapping directories.
12471  */
12472 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12473                               struct ext2_inode *inode)
12474 {
12475         errcode_t                       retval;
12476         struct swap_block_struct        sb;
12477
12478         sb.ino = ino;
12479         sb.inode = inode;
12480         sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12481         sb.errcode = 0;
12482         sb.isdir = 0;
12483         if (LINUX_S_ISDIR(inode->i_mode))
12484                 sb.isdir = 1;
12485
12486         retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12487                                       swap_block, &sb);
12488         if (retval) {
12489                 com_err("swap_inode_blocks", retval,
12490                         _("while calling ext2fs_block_iterate"));
12491                 ctx->flags |= E2F_FLAG_ABORT;
12492                 return;
12493         }
12494         if (sb.errcode) {
12495                 com_err("swap_inode_blocks", sb.errcode,
12496                         _("while calling iterator function"));
12497                 ctx->flags |= E2F_FLAG_ABORT;
12498                 return;
12499         }
12500 }
12501
12502 static void swap_inodes(e2fsck_t ctx)
12503 {
12504         ext2_filsys fs = ctx->fs;
12505         dgrp_t                  group;
12506         unsigned int            i;
12507         ext2_ino_t              ino = 1;
12508         char                    *buf, *block_buf;
12509         errcode_t               retval;
12510         struct ext2_inode *     inode;
12511
12512         e2fsck_use_inode_shortcuts(ctx, 1);
12513
12514         retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12515                                 &buf);
12516         if (retval) {
12517                 com_err("swap_inodes", retval,
12518                         _("while allocating inode buffer"));
12519                 ctx->flags |= E2F_FLAG_ABORT;
12520                 return;
12521         }
12522         block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12523                                                     "block interate buffer");
12524         for (group = 0; group < fs->group_desc_count; group++) {
12525                 retval = io_channel_read_blk(fs->io,
12526                       fs->group_desc[group].bg_inode_table,
12527                       fs->inode_blocks_per_group, buf);
12528                 if (retval) {
12529                         com_err("swap_inodes", retval,
12530                                 _("while reading inode table (group %d)"),
12531                                 group);
12532                         ctx->flags |= E2F_FLAG_ABORT;
12533                         return;
12534                 }
12535                 inode = (struct ext2_inode *) buf;
12536                 for (i=0; i < fs->super->s_inodes_per_group;
12537                      i++, ino++, inode++) {
12538                         ctx->stashed_ino = ino;
12539                         ctx->stashed_inode = inode;
12540
12541                         if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12542                                 ext2fs_swap_inode(fs, inode, inode, 0);
12543
12544                         /*
12545                          * Skip deleted files.
12546                          */
12547                         if (inode->i_links_count == 0)
12548                                 continue;
12549
12550                         if (LINUX_S_ISDIR(inode->i_mode) ||
12551                             ((inode->i_block[EXT2_IND_BLOCK] ||
12552                               inode->i_block[EXT2_DIND_BLOCK] ||
12553                               inode->i_block[EXT2_TIND_BLOCK]) &&
12554                              ext2fs_inode_has_valid_blocks(inode)))
12555                                 swap_inode_blocks(ctx, ino, block_buf, inode);
12556
12557                         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12558                                 return;
12559
12560                         if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12561                                 ext2fs_swap_inode(fs, inode, inode, 1);
12562                 }
12563                 retval = io_channel_write_blk(fs->io,
12564                       fs->group_desc[group].bg_inode_table,
12565                       fs->inode_blocks_per_group, buf);
12566                 if (retval) {
12567                         com_err("swap_inodes", retval,
12568                                 _("while writing inode table (group %d)"),
12569                                 group);
12570                         ctx->flags |= E2F_FLAG_ABORT;
12571                         return;
12572                 }
12573         }
12574         ext2fs_free_mem(&buf);
12575         ext2fs_free_mem(&block_buf);
12576         e2fsck_use_inode_shortcuts(ctx, 0);
12577         ext2fs_flush_icache(fs);
12578 }
12579
12580 #if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
12581 /*
12582  * On the PowerPC, the big-endian variant of the ext2 filesystem
12583  * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12584  * of each word.  Thus a bitmap with only bit 0 set would be, as
12585  * a string of bytes, 00 00 00 01 00 ...
12586  * To cope with this, we byte-reverse each word of a bitmap if
12587  * we have a big-endian filesystem, that is, if we are *not*
12588  * byte-swapping other word-sized numbers.
12589  */
12590 #define EXT2_BIG_ENDIAN_BITMAPS
12591 #endif
12592
12593 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12594 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12595 {
12596         __u32 *p = (__u32 *) bmap->bitmap;
12597         int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12598
12599         for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12600                 *p = ext2fs_swab32(*p);
12601 }
12602 #endif
12603
12604
12605 #ifdef ENABLE_SWAPFS
12606 static void swap_filesys(e2fsck_t ctx)
12607 {
12608         ext2_filsys fs = ctx->fs;
12609         if (!(ctx->options & E2F_OPT_PREEN))
12610                 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12611
12612         /* Byte swap */
12613
12614         if (fs->super->s_mnt_count) {
12615                 fprintf(stderr, _("%s: the filesystem must be freshly "
12616                         "checked using fsck\n"
12617                         "and not mounted before trying to "
12618                         "byte-swap it.\n"), ctx->device_name);
12619                 ctx->flags |= E2F_FLAG_ABORT;
12620                 return;
12621         }
12622         if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12623                 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12624                                EXT2_FLAG_SWAP_BYTES_WRITE);
12625                 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12626         } else {
12627                 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12628                 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12629         }
12630         swap_inodes(ctx);
12631         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12632                 return;
12633         if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12634                 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12635         fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12636                        EXT2_FLAG_SWAP_BYTES_WRITE);
12637
12638 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12639         e2fsck_read_bitmaps(ctx);
12640         ext2fs_swap_bitmap(fs->inode_map);
12641         ext2fs_swap_bitmap(fs->block_map);
12642         fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12643 #endif
12644         fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12645         ext2fs_flush(fs);
12646         fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12647 }
12648 #endif  /* ENABLE_SWAPFS */
12649
12650 #endif
12651
12652 /*
12653  * util.c --- miscellaneous utilities
12654  */
12655
12656
12657 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12658                              const char *description)
12659 {
12660         void *ret;
12661         char buf[256];
12662
12663         ret = malloc(size);
12664         if (!ret) {
12665                 sprintf(buf, "Can't allocate %s\n", description);
12666                 fatal_error(ctx, buf);
12667         }
12668         memset(ret, 0, size);
12669         return ret;
12670 }
12671
12672 static char *string_copy(const char *str, int len)
12673 {
12674         char    *ret;
12675
12676         if (!str)
12677                 return NULL;
12678         if (!len)
12679                 len = strlen(str);
12680         ret = malloc(len+1);
12681         if (ret) {
12682                 strncpy(ret, str, len);
12683                 ret[len] = 0;
12684         }
12685         return ret;
12686 }
12687
12688 #ifndef HAVE_CONIO_H
12689 static int read_a_char(void)
12690 {
12691         char    c;
12692         int     r;
12693         int     fail = 0;
12694
12695         while(1) {
12696                 if (e2fsck_global_ctx &&
12697                     (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12698                         return 3;
12699                 }
12700                 r = read(0, &c, 1);
12701                 if (r == 1)
12702                         return c;
12703                 if (fail++ > 100)
12704                         break;
12705         }
12706         return EOF;
12707 }
12708 #endif
12709
12710 static int ask_yn(const char * string, int def)
12711 {
12712         int             c;
12713         const char      *defstr;
12714         static const char short_yes[] = "yY";
12715         static const char short_no[] = "nN";
12716
12717 #ifdef HAVE_TERMIOS_H
12718         struct termios  termios, tmp;
12719
12720         tcgetattr (0, &termios);
12721         tmp = termios;
12722         tmp.c_lflag &= ~(ICANON | ECHO);
12723         tmp.c_cc[VMIN] = 1;
12724         tmp.c_cc[VTIME] = 0;
12725         tcsetattr (0, TCSANOW, &tmp);
12726 #endif
12727
12728         if (def == 1)
12729                 defstr = "<y>";
12730         else if (def == 0)
12731                 defstr = "<n>";
12732         else
12733                 defstr = " (y/n)";
12734         printf("%s%s? ", string, defstr);
12735         while (1) {
12736                 fflush (stdout);
12737                 if ((c = read_a_char()) == EOF)
12738                         break;
12739                 if (c == 3) {
12740 #ifdef HAVE_TERMIOS_H
12741                         tcsetattr (0, TCSANOW, &termios);
12742 #endif
12743                         if (e2fsck_global_ctx &&
12744                             e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12745                                 puts("\n");
12746                                 longjmp(e2fsck_global_ctx->abort_loc, 1);
12747                         }
12748                         puts(_("cancelled!\n"));
12749                         return 0;
12750                 }
12751                 if (strchr(short_yes, (char) c)) {
12752                         def = 1;
12753                         break;
12754                 }
12755                 else if (strchr(short_no, (char) c)) {
12756                         def = 0;
12757                         break;
12758                 }
12759                 else if ((c == ' ' || c == '\n') && (def != -1))
12760                         break;
12761         }
12762         if (def)
12763                 puts("yes\n");
12764         else
12765                 puts ("no\n");
12766 #ifdef HAVE_TERMIOS_H
12767         tcsetattr (0, TCSANOW, &termios);
12768 #endif
12769         return def;
12770 }
12771
12772 int ask (e2fsck_t ctx, const char * string, int def)
12773 {
12774         if (ctx->options & E2F_OPT_NO) {
12775                 printf (_("%s? no\n\n"), string);
12776                 return 0;
12777         }
12778         if (ctx->options & E2F_OPT_YES) {
12779                 printf (_("%s? yes\n\n"), string);
12780                 return 1;
12781         }
12782         if (ctx->options & E2F_OPT_PREEN) {
12783                 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
12784                 return def;
12785         }
12786         return ask_yn(string, def);
12787 }
12788
12789 void e2fsck_read_bitmaps(e2fsck_t ctx)
12790 {
12791         ext2_filsys fs = ctx->fs;
12792         errcode_t       retval;
12793
12794         if (ctx->invalid_bitmaps) {
12795                 com_err(ctx->program_name, 0,
12796                     _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12797                         ctx->device_name);
12798                 fatal_error(ctx, 0);
12799         }
12800
12801         ehandler_operation(_("reading inode and block bitmaps"));
12802         retval = ext2fs_read_bitmaps(fs);
12803         ehandler_operation(0);
12804         if (retval) {
12805                 com_err(ctx->program_name, retval,
12806                         _("while retrying to read bitmaps for %s"),
12807                         ctx->device_name);
12808                 fatal_error(ctx, 0);
12809         }
12810 }
12811
12812 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12813 {
12814         ext2_filsys fs = ctx->fs;
12815         errcode_t       retval;
12816
12817         if (ext2fs_test_bb_dirty(fs)) {
12818                 ehandler_operation(_("writing block bitmaps"));
12819                 retval = ext2fs_write_block_bitmap(fs);
12820                 ehandler_operation(0);
12821                 if (retval) {
12822                         com_err(ctx->program_name, retval,
12823                             _("while retrying to write block bitmaps for %s"),
12824                                 ctx->device_name);
12825                         fatal_error(ctx, 0);
12826                 }
12827         }
12828
12829         if (ext2fs_test_ib_dirty(fs)) {
12830                 ehandler_operation(_("writing inode bitmaps"));
12831                 retval = ext2fs_write_inode_bitmap(fs);
12832                 ehandler_operation(0);
12833                 if (retval) {
12834                         com_err(ctx->program_name, retval,
12835                             _("while retrying to write inode bitmaps for %s"),
12836                                 ctx->device_name);
12837                         fatal_error(ctx, 0);
12838                 }
12839         }
12840 }
12841
12842 void preenhalt(e2fsck_t ctx)
12843 {
12844         ext2_filsys fs = ctx->fs;
12845
12846         if (!(ctx->options & E2F_OPT_PREEN))
12847                 return;
12848         fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12849                 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12850                ctx->device_name);
12851         if (fs != NULL) {
12852                 fs->super->s_state |= EXT2_ERROR_FS;
12853                 ext2fs_mark_super_dirty(fs);
12854                 ext2fs_close(fs);
12855         }
12856         exit(EXIT_UNCORRECTED);
12857 }
12858
12859 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12860                               struct ext2_inode * inode, const char *proc)
12861 {
12862         int retval;
12863
12864         retval = ext2fs_read_inode(ctx->fs, ino, inode);
12865         if (retval) {
12866                 com_err("ext2fs_read_inode", retval,
12867                         _("while reading inode %ld in %s"), ino, proc);
12868                 fatal_error(ctx, 0);
12869         }
12870 }
12871
12872 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12873                                struct ext2_inode * inode, int bufsize,
12874                                const char *proc)
12875 {
12876         int retval;
12877
12878         retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12879         if (retval) {
12880                 com_err("ext2fs_write_inode", retval,
12881                         _("while writing inode %ld in %s"), ino, proc);
12882                 fatal_error(ctx, 0);
12883         }
12884 }
12885
12886 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12887                                struct ext2_inode * inode, const char *proc)
12888 {
12889         int retval;
12890
12891         retval = ext2fs_write_inode(ctx->fs, ino, inode);
12892         if (retval) {
12893                 com_err("ext2fs_write_inode", retval,
12894                         _("while writing inode %ld in %s"), ino, proc);
12895                 fatal_error(ctx, 0);
12896         }
12897 }
12898
12899 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12900                    io_manager manager)
12901 {
12902         struct ext2_super_block *sb;
12903         io_channel              io = NULL;
12904         void                    *buf = NULL;
12905         int                     blocksize;
12906         blk_t                   superblock, ret_sb = 8193;
12907
12908         if (fs && fs->super) {
12909                 ret_sb = (fs->super->s_blocks_per_group +
12910                           fs->super->s_first_data_block);
12911                 if (ctx) {
12912                         ctx->superblock = ret_sb;
12913                         ctx->blocksize = fs->blocksize;
12914                 }
12915                 return ret_sb;
12916         }
12917
12918         if (ctx) {
12919                 if (ctx->blocksize) {
12920                         ret_sb = ctx->blocksize * 8;
12921                         if (ctx->blocksize == 1024)
12922                                 ret_sb++;
12923                         ctx->superblock = ret_sb;
12924                         return ret_sb;
12925                 }
12926                 ctx->superblock = ret_sb;
12927                 ctx->blocksize = 1024;
12928         }
12929
12930         if (!name || !manager)
12931                 goto cleanup;
12932
12933         if (manager->open(name, 0, &io) != 0)
12934                 goto cleanup;
12935
12936         if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12937                 goto cleanup;
12938         sb = (struct ext2_super_block *) buf;
12939
12940         for (blocksize = EXT2_MIN_BLOCK_SIZE;
12941              blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
12942                 superblock = blocksize*8;
12943                 if (blocksize == 1024)
12944                         superblock++;
12945                 io_channel_set_blksize(io, blocksize);
12946                 if (io_channel_read_blk(io, superblock,
12947                                         -SUPERBLOCK_SIZE, buf))
12948                         continue;
12949 #ifdef EXT2FS_ENABLE_SWAPFS
12950                 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12951                         ext2fs_swap_super(sb);
12952 #endif
12953                 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12954                         ret_sb = superblock;
12955                         if (ctx) {
12956                                 ctx->superblock = superblock;
12957                                 ctx->blocksize = blocksize;
12958                         }
12959                         break;
12960                 }
12961         }
12962
12963 cleanup:
12964         if (io)
12965                 io_channel_close(io);
12966         ext2fs_free_mem(&buf);
12967         return (ret_sb);
12968 }
12969
12970
12971 /*
12972  * This function runs through the e2fsck passes and calls them all,
12973  * returning restart, abort, or cancel as necessary...
12974  */
12975 typedef void (*pass_t)(e2fsck_t ctx);
12976
12977 static const pass_t e2fsck_passes[] = {
12978         e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12979         e2fsck_pass5, 0 };
12980
12981 #define E2F_FLAG_RUN_RETURN     (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12982
12983 static int e2fsck_run(e2fsck_t ctx)
12984 {
12985         int     i;
12986         pass_t  e2fsck_pass;
12987
12988         if (setjmp(ctx->abort_loc)) {
12989                 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12990                 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12991         }
12992         ctx->flags |= E2F_FLAG_SETJMP_OK;
12993
12994         for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12995                 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12996                         break;
12997                 e2fsck_pass(ctx);
12998                 if (ctx->progress)
12999                         (void) (ctx->progress)(ctx, 0, 0, 0);
13000         }
13001         ctx->flags &= ~E2F_FLAG_SETJMP_OK;
13002
13003         if (ctx->flags & E2F_FLAG_RUN_RETURN)
13004                 return (ctx->flags & E2F_FLAG_RUN_RETURN);
13005         return 0;
13006 }
13007
13008
13009 /*
13010  * unix.c - The unix-specific code for e2fsck
13011  */
13012
13013
13014 /* Command line options */
13015 static int swapfs;
13016 #ifdef ENABLE_SWAPFS
13017 static int normalize_swapfs;
13018 #endif
13019 static int cflag;               /* check disk */
13020 static int show_version_only;
13021 static int verbose;
13022
13023 static int replace_bad_blocks;
13024 static int keep_bad_blocks;
13025 static char *bad_blocks_file;
13026
13027 #define P_E2(singular, plural, n)       n, ((n) == 1 ? singular : plural)
13028
13029 static void show_stats(e2fsck_t ctx)
13030 {
13031         ext2_filsys fs = ctx->fs;
13032         int inodes, inodes_used, blocks, blocks_used;
13033         int dir_links;
13034         int num_files, num_links;
13035         int frag_percent;
13036
13037         dir_links = 2 * ctx->fs_directory_count - 1;
13038         num_files = ctx->fs_total_count - dir_links;
13039         num_links = ctx->fs_links_count - dir_links;
13040         inodes = fs->super->s_inodes_count;
13041         inodes_used = (fs->super->s_inodes_count -
13042                        fs->super->s_free_inodes_count);
13043         blocks = fs->super->s_blocks_count;
13044         blocks_used = (fs->super->s_blocks_count -
13045                        fs->super->s_free_blocks_count);
13046
13047         frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
13048         frag_percent = (frag_percent + 5) / 10;
13049
13050         if (!verbose) {
13051                 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
13052                        ctx->device_name, inodes_used, inodes,
13053                        frag_percent / 10, frag_percent % 10,
13054                        blocks_used, blocks);
13055                 return;
13056         }
13057         printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
13058                 100 * inodes_used / inodes);
13059         printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
13060                 P_E2("", "s", ctx->fs_fragmented),
13061                 frag_percent / 10, frag_percent % 10);
13062         printf (_("         # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
13063                 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
13064         printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
13065                 (int) ((long long) 100 * blocks_used / blocks));
13066         printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count));
13067         printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
13068         printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
13069         printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
13070         printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
13071         printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
13072         printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
13073         printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
13074         printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
13075         printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
13076         printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
13077         printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
13078 }
13079
13080 static void check_mount(e2fsck_t ctx)
13081 {
13082         errcode_t       retval;
13083         int             cont;
13084
13085         retval = ext2fs_check_if_mounted(ctx->filesystem_name,
13086                                          &ctx->mount_flags);
13087         if (retval) {
13088                 com_err("ext2fs_check_if_mount", retval,
13089                         _("while determining whether %s is mounted."),
13090                         ctx->filesystem_name);
13091                 return;
13092         }
13093
13094         /*
13095          * If the filesystem isn't mounted, or it's the root filesystem
13096          * and it's mounted read-only, then everything's fine.
13097          */
13098         if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
13099             ((ctx->mount_flags & EXT2_MF_ISROOT) &&
13100              (ctx->mount_flags & EXT2_MF_READONLY)))
13101                 return;
13102
13103         if (ctx->options & E2F_OPT_READONLY) {
13104                 printf(_("Warning!  %s is mounted.\n"), ctx->filesystem_name);
13105                 return;
13106         }
13107
13108         printf(_("%s is mounted.  "), ctx->filesystem_name);
13109         if (!ctx->interactive)
13110                 fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
13111         printf(_("\n\n\007\007\007\007WARNING!!!  "
13112                "Running e2fsck on a mounted filesystem may cause\n"
13113                "SEVERE filesystem damage.\007\007\007\n\n"));
13114         cont = ask_yn(_("Do you really want to continue"), -1);
13115         if (!cont) {
13116                 printf (_("check aborted.\n"));
13117                 exit (0);
13118         }
13119         return;
13120 }
13121
13122 static int is_on_batt(void)
13123 {
13124         FILE    *f;
13125         DIR     *d;
13126         char    tmp[80], tmp2[80], fname[80];
13127         unsigned int    acflag;
13128         struct dirent*  de;
13129
13130         f = fopen("/proc/apm", "r");
13131         if (f) {
13132                 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
13133                         acflag = 1;
13134                 fclose(f);
13135                 return (acflag != 1);
13136         }
13137         d = opendir("/proc/acpi/ac_adapter");
13138         if (d) {
13139                 while ((de=readdir(d)) != NULL) {
13140                         if (!strncmp(".", de->d_name, 1))
13141                                 continue;
13142                         snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
13143                                  de->d_name);
13144                         f = fopen(fname, "r");
13145                         if (!f)
13146                                 continue;
13147                         if (fscanf(f, "%s %s", tmp2, tmp) != 2)
13148                                 tmp[0] = 0;
13149                         fclose(f);
13150                         if (strncmp(tmp, "off-line", 8) == 0) {
13151                                 closedir(d);
13152                                 return 1;
13153                         }
13154                 }
13155                 closedir(d);
13156         }
13157         return 0;
13158 }
13159
13160 /*
13161  * This routine checks to see if a filesystem can be skipped; if so,
13162  * it will exit with EXIT_OK.  Under some conditions it will print a
13163  * message explaining why a check is being forced.
13164  */
13165 static void check_if_skip(e2fsck_t ctx)
13166 {
13167         ext2_filsys fs = ctx->fs;
13168         const char *reason = NULL;
13169         unsigned int reason_arg = 0;
13170         long next_check;
13171         int batt = is_on_batt();
13172         time_t now = time(0);
13173
13174         if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
13175             cflag || swapfs)
13176                 return;
13177
13178         if ((fs->super->s_state & EXT2_ERROR_FS) ||
13179             !ext2fs_test_valid(fs))
13180                 reason = _(" contains a file system with errors");
13181         else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
13182                 reason = _(" was not cleanly unmounted");
13183         else if ((fs->super->s_max_mnt_count > 0) &&
13184                  (fs->super->s_mnt_count >=
13185                   (unsigned) fs->super->s_max_mnt_count)) {
13186                 reason = _(" has been mounted %u times without being checked");
13187                 reason_arg = fs->super->s_mnt_count;
13188                 if (batt && (fs->super->s_mnt_count <
13189                              (unsigned) fs->super->s_max_mnt_count*2))
13190                         reason = 0;
13191         } else if (fs->super->s_checkinterval &&
13192                    ((now - fs->super->s_lastcheck) >=
13193                     fs->super->s_checkinterval)) {
13194                 reason = _(" has gone %u days without being checked");
13195                 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
13196                 if (batt && ((now - fs->super->s_lastcheck) <
13197                              fs->super->s_checkinterval*2))
13198                         reason = 0;
13199         }
13200         if (reason) {
13201                 fputs(ctx->device_name, stdout);
13202                 printf(reason, reason_arg);
13203                 fputs(_(", check forced.\n"), stdout);
13204                 return;
13205         }
13206         printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
13207                fs->super->s_inodes_count - fs->super->s_free_inodes_count,
13208                fs->super->s_inodes_count,
13209                fs->super->s_blocks_count - fs->super->s_free_blocks_count,
13210                fs->super->s_blocks_count);
13211         next_check = 100000;
13212         if (fs->super->s_max_mnt_count > 0) {
13213                 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
13214                 if (next_check <= 0)
13215                         next_check = 1;
13216         }
13217         if (fs->super->s_checkinterval &&
13218             ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
13219                 next_check = 1;
13220         if (next_check <= 5) {
13221                 if (next_check == 1)
13222                         fputs(_(" (check after next mount)"), stdout);
13223                 else
13224                         printf(_(" (check in %ld mounts)"), next_check);
13225         }
13226         fputc('\n', stdout);
13227         ext2fs_close(fs);
13228         ctx->fs = NULL;
13229         e2fsck_free_context(ctx);
13230         exit(EXIT_OK);
13231 }
13232
13233 /*
13234  * For completion notice
13235  */
13236 struct percent_tbl {
13237         int     max_pass;
13238         int     table[32];
13239 };
13240 static const struct percent_tbl e2fsck_tbl = {
13241         5, { 0, 70, 90, 92,  95, 100 }
13242 };
13243
13244 static char bar[128], spaces[128];
13245
13246 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
13247                           int max)
13248 {
13249         float   percent;
13250
13251         if (pass <= 0)
13252                 return 0.0;
13253         if (pass > tbl->max_pass || max == 0)
13254                 return 100.0;
13255         percent = ((float) curr) / ((float) max);
13256         return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
13257                 + tbl->table[pass-1]);
13258 }
13259
13260 void e2fsck_clear_progbar(e2fsck_t ctx)
13261 {
13262         if (!(ctx->flags & E2F_FLAG_PROG_BAR))
13263                 return;
13264
13265         printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
13266                ctx->stop_meta);
13267         fflush(stdout);
13268         ctx->flags &= ~E2F_FLAG_PROG_BAR;
13269 }
13270
13271 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
13272                            unsigned int dpynum)
13273 {
13274         static const char spinner[] = "\\|/-";
13275         int     i;
13276         unsigned int    tick;
13277         struct timeval  tv;
13278         int dpywidth;
13279         int fixed_percent;
13280
13281         if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
13282                 return 0;
13283
13284         /*
13285          * Calculate the new progress position.  If the
13286          * percentage hasn't changed, then we skip out right
13287          * away.
13288          */
13289         fixed_percent = (int) ((10 * percent) + 0.5);
13290         if (ctx->progress_last_percent == fixed_percent)
13291                 return 0;
13292         ctx->progress_last_percent = fixed_percent;
13293
13294         /*
13295          * If we've already updated the spinner once within
13296          * the last 1/8th of a second, no point doing it
13297          * again.
13298          */
13299         gettimeofday(&tv, NULL);
13300         tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
13301         if ((tick == ctx->progress_last_time) &&
13302             (fixed_percent != 0) && (fixed_percent != 1000))
13303                 return 0;
13304         ctx->progress_last_time = tick;
13305
13306         /*
13307          * Advance the spinner, and note that the progress bar
13308          * will be on the screen
13309          */
13310         ctx->progress_pos = (ctx->progress_pos+1) & 3;
13311         ctx->flags |= E2F_FLAG_PROG_BAR;
13312
13313         dpywidth = 66 - strlen(label);
13314         dpywidth = 8 * (dpywidth / 8);
13315         if (dpynum)
13316                 dpywidth -= 8;
13317
13318         i = ((percent * dpywidth) + 50) / 100;
13319         printf("%s%s: |%s%s", ctx->start_meta, label,
13320                bar + (sizeof(bar) - (i+1)),
13321                spaces + (sizeof(spaces) - (dpywidth - i + 1)));
13322         if (fixed_percent == 1000)
13323                 fputc('|', stdout);
13324         else
13325                 fputc(spinner[ctx->progress_pos & 3], stdout);
13326         printf(" %4.1f%%  ", percent);
13327         if (dpynum)
13328                 printf("%u\r", dpynum);
13329         else
13330                 fputs(" \r", stdout);
13331         fputs(ctx->stop_meta, stdout);
13332
13333         if (fixed_percent == 1000)
13334                 e2fsck_clear_progbar(ctx);
13335         fflush(stdout);
13336
13337         return 0;
13338 }
13339
13340 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
13341                                   unsigned long cur, unsigned long max)
13342 {
13343         char buf[80];
13344         float percent;
13345
13346         if (pass == 0)
13347                 return 0;
13348
13349         if (ctx->progress_fd) {
13350                 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
13351                 write(ctx->progress_fd, buf, strlen(buf));
13352         } else {
13353                 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
13354                 e2fsck_simple_progress(ctx, ctx->device_name,
13355                                        percent, 0);
13356         }
13357         return 0;
13358 }
13359
13360 static void reserve_stdio_fds(void)
13361 {
13362         int     fd;
13363
13364         while (1) {
13365                 fd = open(bb_dev_null, O_RDWR);
13366                 if (fd > 2)
13367                         break;
13368                 if (fd < 0) {
13369                         fprintf(stderr, _("ERROR: Couldn't open "
13370                                 "/dev/null (%s)\n"),
13371                                 strerror(errno));
13372                         break;
13373                 }
13374         }
13375         close(fd);
13376 }
13377
13378 static void signal_progress_on(int sig FSCK_ATTR((unused)))
13379 {
13380         e2fsck_t ctx = e2fsck_global_ctx;
13381
13382         if (!ctx)
13383                 return;
13384
13385         ctx->progress = e2fsck_update_progress;
13386         ctx->progress_fd = 0;
13387 }
13388
13389 static void signal_progress_off(int sig FSCK_ATTR((unused)))
13390 {
13391         e2fsck_t ctx = e2fsck_global_ctx;
13392
13393         if (!ctx)
13394                 return;
13395
13396         e2fsck_clear_progbar(ctx);
13397         ctx->progress = 0;
13398 }
13399
13400 static void signal_cancel(int sig FSCK_ATTR((unused)))
13401 {
13402         e2fsck_t ctx = e2fsck_global_ctx;
13403
13404         if (!ctx)
13405                 exit(FSCK_CANCELED);
13406
13407         ctx->flags |= E2F_FLAG_CANCEL;
13408 }
13409
13410 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
13411 {
13412         char    *buf, *token, *next, *p, *arg;
13413         int     ea_ver;
13414         int     extended_usage = 0;
13415
13416         buf = string_copy(opts, 0);
13417         for (token = buf; token && *token; token = next) {
13418                 p = strchr(token, ',');
13419                 next = 0;
13420                 if (p) {
13421                         *p = 0;
13422                         next = p+1;
13423                 }
13424                 arg = strchr(token, '=');
13425                 if (arg) {
13426                         *arg = 0;
13427                         arg++;
13428                 }
13429                 if (strcmp(token, "ea_ver") == 0) {
13430                         if (!arg) {
13431                                 extended_usage++;
13432                                 continue;
13433                         }
13434                         ea_ver = strtoul(arg, &p, 0);
13435                         if (*p ||
13436                             ((ea_ver != 1) && (ea_ver != 2))) {
13437                                 fprintf(stderr,
13438                                         _("Invalid EA version.\n"));
13439                                 extended_usage++;
13440                                 continue;
13441                         }
13442                         ctx->ext_attr_ver = ea_ver;
13443                 } else {
13444                         fprintf(stderr, _("Unknown extended option: %s\n"),
13445                                 token);
13446                         extended_usage++;
13447                 }
13448         }
13449         if (extended_usage) {
13450                 bb_error_msg_and_die(
13451                         "Extended options are separated by commas, "
13452                         "and may take an argument which\n"
13453                         "is set off by an equals ('=') sign.  "
13454                         "Valid extended options are:\n"
13455                         "\tea_ver=<ea_version (1 or 2)>\n\n");
13456         }
13457 }
13458
13459
13460 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
13461 {
13462         int             flush = 0;
13463         int             c, fd;
13464         e2fsck_t        ctx;
13465         errcode_t       retval;
13466         struct sigaction        sa;
13467         char            *extended_opts = 0;
13468
13469         retval = e2fsck_allocate_context(&ctx);
13470         if (retval)
13471                 return retval;
13472
13473         *ret_ctx = ctx;
13474
13475         setvbuf(stdout, NULL, _IONBF, BUFSIZ);
13476         setvbuf(stderr, NULL, _IONBF, BUFSIZ);
13477         if (isatty(0) && isatty(1)) {
13478                 ctx->interactive = 1;
13479         } else {
13480                 ctx->start_meta[0] = '\001';
13481                 ctx->stop_meta[0] = '\002';
13482         }
13483         memset(bar, '=', sizeof(bar)-1);
13484         memset(spaces, ' ', sizeof(spaces)-1);
13485         blkid_get_cache(&ctx->blkid, NULL);
13486
13487         if (argc && *argv)
13488                 ctx->program_name = *argv;
13489         else
13490                 ctx->program_name = "e2fsck";
13491         while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13492                 switch (c) {
13493                 case 'C':
13494                         ctx->progress = e2fsck_update_progress;
13495                         ctx->progress_fd = atoi(optarg);
13496                         if (!ctx->progress_fd)
13497                                 break;
13498                         /* Validate the file descriptor to avoid disasters */
13499                         fd = dup(ctx->progress_fd);
13500                         if (fd < 0) {
13501                                 fprintf(stderr,
13502                                 _("Error validating file descriptor %d: %s\n"),
13503                                         ctx->progress_fd,
13504                                         error_message(errno));
13505                                 fatal_error(ctx,
13506                         _("Invalid completion information file descriptor"));
13507                         } else
13508                                 close(fd);
13509                         break;
13510                 case 'D':
13511                         ctx->options |= E2F_OPT_COMPRESS_DIRS;
13512                         break;
13513                 case 'E':
13514                         extended_opts = optarg;
13515                         break;
13516                 case 'p':
13517                 case 'a':
13518                         if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13519                         conflict_opt:
13520                                 fatal_error(ctx,
13521         _("Only one the options -p/-a, -n or -y may be specified."));
13522                         }
13523                         ctx->options |= E2F_OPT_PREEN;
13524                         break;
13525                 case 'n':
13526                         if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13527                                 goto conflict_opt;
13528                         ctx->options |= E2F_OPT_NO;
13529                         break;
13530                 case 'y':
13531                         if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13532                                 goto conflict_opt;
13533                         ctx->options |= E2F_OPT_YES;
13534                         break;
13535                 case 't':
13536                         /* FIXME - This needs to go away in a future path - will change binary */
13537                         fprintf(stderr, _("The -t option is not "
13538                                 "supported on this version of e2fsck.\n"));
13539                         break;
13540                 case 'c':
13541                         if (cflag++)
13542                                 ctx->options |= E2F_OPT_WRITECHECK;
13543                         ctx->options |= E2F_OPT_CHECKBLOCKS;
13544                         break;
13545                 case 'r':
13546                         /* What we do by default, anyway! */
13547                         break;
13548                 case 'b':
13549                         ctx->use_superblock = atoi(optarg);
13550                         ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13551                         break;
13552                 case 'B':
13553                         ctx->blocksize = atoi(optarg);
13554                         break;
13555                 case 'I':
13556                         ctx->inode_buffer_blocks = atoi(optarg);
13557                         break;
13558                 case 'j':
13559                         ctx->journal_name = string_copy(optarg, 0);
13560                         break;
13561                 case 'P':
13562                         ctx->process_inode_size = atoi(optarg);
13563                         break;
13564                 case 'L':
13565                         replace_bad_blocks++;
13566                 case 'l':
13567                         bad_blocks_file = string_copy(optarg, 0);
13568                         break;
13569                 case 'd':
13570                         ctx->options |= E2F_OPT_DEBUG;
13571                         break;
13572                 case 'f':
13573                         ctx->options |= E2F_OPT_FORCE;
13574                         break;
13575                 case 'F':
13576                         flush = 1;
13577                         break;
13578                 case 'v':
13579                         verbose = 1;
13580                         break;
13581                 case 'V':
13582                         show_version_only = 1;
13583                         break;
13584                 case 'N':
13585                         ctx->device_name = optarg;
13586                         break;
13587 #ifdef ENABLE_SWAPFS
13588                 case 's':
13589                         normalize_swapfs = 1;
13590                 case 'S':
13591                         swapfs = 1;
13592                         break;
13593 #else
13594                 case 's':
13595                 case 'S':
13596                         fprintf(stderr, _("Byte-swapping filesystems "
13597                                           "not compiled in this version "
13598                                           "of e2fsck\n"));
13599                         exit(1);
13600 #endif
13601                 case 'k':
13602                         keep_bad_blocks++;
13603                         break;
13604                 default:
13605                         usage();
13606                 }
13607         if (show_version_only)
13608                 return 0;
13609         if (optind != argc - 1)
13610                 usage();
13611         if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
13612             !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13613                 ctx->options |= E2F_OPT_READONLY;
13614         ctx->io_options = strchr(argv[optind], '?');
13615         if (ctx->io_options)
13616                 *ctx->io_options++ = 0;
13617         ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13618         if (!ctx->filesystem_name) {
13619                 com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
13620                         argv[optind]);
13621                 fatal_error(ctx, 0);
13622         }
13623         if (extended_opts)
13624                 parse_extended_opts(ctx, extended_opts);
13625
13626         if (flush) {
13627                 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13628                 if (fd < 0) {
13629                         com_err("open", errno,
13630                                 _("while opening %s for flushing"),
13631                                 ctx->filesystem_name);
13632                         fatal_error(ctx, 0);
13633                 }
13634                 if ((retval = ext2fs_sync_device(fd, 1))) {
13635                         com_err("ext2fs_sync_device", retval,
13636                                 _("while trying to flush %s"),
13637                                 ctx->filesystem_name);
13638                         fatal_error(ctx, 0);
13639                 }
13640                 close(fd);
13641         }
13642 #ifdef ENABLE_SWAPFS
13643         if (swapfs) {
13644                 if (cflag || bad_blocks_file) {
13645                         fprintf(stderr, _("Incompatible options not "
13646                                           "allowed when byte-swapping.\n"));
13647                         exit(EXIT_USAGE);
13648                 }
13649         }
13650 #endif
13651         if (cflag && bad_blocks_file) {
13652                 fprintf(stderr, _("The -c and the -l/-L options may "
13653                                   "not be both used at the same time.\n"));
13654                 exit(EXIT_USAGE);
13655         }
13656         /*
13657          * Set up signal action
13658          */
13659         memset(&sa, 0, sizeof(struct sigaction));
13660         sa.sa_handler = signal_cancel;
13661         sigaction(SIGINT, &sa, 0);
13662         sigaction(SIGTERM, &sa, 0);
13663 #ifdef SA_RESTART
13664         sa.sa_flags = SA_RESTART;
13665 #endif
13666         e2fsck_global_ctx = ctx;
13667         sa.sa_handler = signal_progress_on;
13668         sigaction(SIGUSR1, &sa, 0);
13669         sa.sa_handler = signal_progress_off;
13670         sigaction(SIGUSR2, &sa, 0);
13671
13672         /* Update our PATH to include /sbin if we need to run badblocks  */
13673         if (cflag)
13674                 e2fs_set_sbin_path();
13675         return 0;
13676 }
13677
13678 static const char my_ver_string[] = E2FSPROGS_VERSION;
13679 static const char my_ver_date[] = E2FSPROGS_DATE;
13680
13681 int e2fsck_main (int argc, char *argv[])
13682 {
13683         errcode_t       retval;
13684         int             exit_value = EXIT_OK;
13685         ext2_filsys     fs = 0;
13686         io_manager      io_ptr;
13687         struct ext2_super_block *sb;
13688         const char      *lib_ver_date;
13689         int             my_ver, lib_ver;
13690         e2fsck_t        ctx;
13691         struct problem_context pctx;
13692         int flags, run_result;
13693
13694         clear_problem_context(&pctx);
13695
13696         my_ver = ext2fs_parse_version_string(my_ver_string);
13697         lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13698         if (my_ver > lib_ver) {
13699                 fprintf( stderr, _("Error: ext2fs library version "
13700                         "out of date!\n"));
13701                 show_version_only++;
13702         }
13703
13704         retval = PRS(argc, argv, &ctx);
13705         if (retval) {
13706                 com_err("e2fsck", retval,
13707                         _("while trying to initialize program"));
13708                 exit(EXIT_ERROR);
13709         }
13710         reserve_stdio_fds();
13711
13712         if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13713                 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13714                          my_ver_date);
13715
13716         if (show_version_only) {
13717                 fprintf(stderr, _("\tUsing %s, %s\n"),
13718                         error_message(EXT2_ET_BASE), lib_ver_date);
13719                 exit(EXIT_OK);
13720         }
13721
13722         check_mount(ctx);
13723
13724         if (!(ctx->options & E2F_OPT_PREEN) &&
13725             !(ctx->options & E2F_OPT_NO) &&
13726             !(ctx->options & E2F_OPT_YES)) {
13727                 if (!ctx->interactive)
13728                         fatal_error(ctx,
13729                                     _("need terminal for interactive repairs"));
13730         }
13731         ctx->superblock = ctx->use_superblock;
13732 restart:
13733 #ifdef CONFIG_TESTIO_DEBUG
13734         io_ptr = test_io_manager;
13735         test_io_backing_manager = unix_io_manager;
13736 #else
13737         io_ptr = unix_io_manager;
13738 #endif
13739         flags = 0;
13740         if ((ctx->options & E2F_OPT_READONLY) == 0)
13741                 flags |= EXT2_FLAG_RW;
13742
13743         if (ctx->superblock && ctx->blocksize) {
13744                 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13745                                       flags, ctx->superblock, ctx->blocksize,
13746                                       io_ptr, &fs);
13747         } else if (ctx->superblock) {
13748                 int blocksize;
13749                 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13750                      blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13751                         retval = ext2fs_open2(ctx->filesystem_name,
13752                                               ctx->io_options, flags,
13753                                               ctx->superblock, blocksize,
13754                                               io_ptr, &fs);
13755                         if (!retval)
13756                                 break;
13757                 }
13758         } else
13759                 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13760                                       flags, 0, 0, io_ptr, &fs);
13761         if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13762             !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13763             ((retval == EXT2_ET_BAD_MAGIC) ||
13764              ((retval == 0) && ext2fs_check_desc(fs)))) {
13765                 if (!fs || (fs->group_desc_count > 1)) {
13766                         printf(_("%s trying backup blocks...\n"),
13767                                retval ? _("Couldn't find ext2 superblock,") :
13768                                _("Group descriptors look bad..."));
13769                         get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13770                         if (fs)
13771                                 ext2fs_close(fs);
13772                         goto restart;
13773                 }
13774         }
13775         if (retval) {
13776                 com_err(ctx->program_name, retval, _("while trying to open %s"),
13777                         ctx->filesystem_name);
13778                 if (retval == EXT2_ET_REV_TOO_HIGH) {
13779                         printf(_("The filesystem revision is apparently "
13780                                "too high for this version of e2fsck.\n"
13781                                "(Or the filesystem superblock "
13782                                "is corrupt)\n\n"));
13783                         fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13784                 } else if (retval == EXT2_ET_SHORT_READ)
13785                         printf(_("Could this be a zero-length partition?\n"));
13786                 else if ((retval == EPERM) || (retval == EACCES))
13787                         printf(_("You must have %s access to the "
13788                                "filesystem or be root\n"),
13789                                (ctx->options & E2F_OPT_READONLY) ?
13790                                "r/o" : "r/w");
13791                 else if (retval == ENXIO)
13792                         printf(_("Possibly non-existent or swap device?\n"));
13793 #ifdef EROFS
13794                 else if (retval == EROFS)
13795                         printf(_("Disk write-protected; use the -n option "
13796                                "to do a read-only\n"
13797                                "check of the device.\n"));
13798 #endif
13799                 else
13800                         fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13801                 fatal_error(ctx, 0);
13802         }
13803         ctx->fs = fs;
13804         fs->priv_data = ctx;
13805         sb = fs->super;
13806         if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13807                 com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
13808                         _("while trying to open %s"),
13809                         ctx->filesystem_name);
13810         get_newer:
13811                 fatal_error(ctx, _("Get a newer version of e2fsck!"));
13812         }
13813
13814         /*
13815          * Set the device name, which is used whenever we print error
13816          * or informational messages to the user.
13817          */
13818         if (ctx->device_name == 0 &&
13819             (sb->s_volume_name[0] != 0)) {
13820                 ctx->device_name = string_copy(sb->s_volume_name,
13821                                                sizeof(sb->s_volume_name));
13822         }
13823         if (ctx->device_name == 0)
13824                 ctx->device_name = ctx->filesystem_name;
13825
13826         /*
13827          * Make sure the ext3 superblock fields are consistent.
13828          */
13829         retval = e2fsck_check_ext3_journal(ctx);
13830         if (retval) {
13831                 com_err(ctx->program_name, retval,
13832                         _("while checking ext3 journal for %s"),
13833                         ctx->device_name);
13834                 fatal_error(ctx, 0);
13835         }
13836
13837         /*
13838          * Check to see if we need to do ext3-style recovery.  If so,
13839          * do it, and then restart the fsck.
13840          */
13841         if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13842                 if (ctx->options & E2F_OPT_READONLY) {
13843                         printf(_("Warning: skipping journal recovery "
13844                                  "because doing a read-only filesystem "
13845                                  "check.\n"));
13846                         io_channel_flush(ctx->fs->io);
13847                 } else {
13848                         if (ctx->flags & E2F_FLAG_RESTARTED) {
13849                                 /*
13850                                  * Whoops, we attempted to run the
13851                                  * journal twice.  This should never
13852                                  * happen, unless the hardware or
13853                                  * device driver is being bogus.
13854                                  */
13855                                 com_err(ctx->program_name, 0,
13856                                         _("unable to set superblock flags on %s\n"), ctx->device_name);
13857                                 fatal_error(ctx, 0);
13858                         }
13859                         retval = e2fsck_run_ext3_journal(ctx);
13860                         if (retval) {
13861                                 com_err(ctx->program_name, retval,
13862                                 _("while recovering ext3 journal of %s"),
13863                                         ctx->device_name);
13864                                 fatal_error(ctx, 0);
13865                         }
13866                         ext2fs_close(ctx->fs);
13867                         ctx->fs = 0;
13868                         ctx->flags |= E2F_FLAG_RESTARTED;
13869                         goto restart;
13870                 }
13871         }
13872
13873         /*
13874          * Check for compatibility with the feature sets.  We need to
13875          * be more stringent than ext2fs_open().
13876          */
13877         if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13878             (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13879                 com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE,
13880                         "(%s)", ctx->device_name);
13881                 goto get_newer;
13882         }
13883         if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13884                 com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE,
13885                         "(%s)", ctx->device_name);
13886                 goto get_newer;
13887         }
13888 #ifdef ENABLE_COMPRESSION
13889         /* FIXME - do we support this at all? */
13890         if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13891                 com_err(ctx->program_name, 0,
13892                         _("Warning: compression support is experimental.\n"));
13893 #endif
13894 #ifndef ENABLE_HTREE
13895         if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13896                 com_err(ctx->program_name, 0,
13897                         _("E2fsck not compiled with HTREE support,\n\t"
13898                           "but filesystem %s has HTREE directories.\n"),
13899                         ctx->device_name);
13900                 goto get_newer;
13901         }
13902 #endif
13903
13904         /*
13905          * If the user specified a specific superblock, presumably the
13906          * master superblock has been trashed.  So we mark the
13907          * superblock as dirty, so it can be written out.
13908          */
13909         if (ctx->superblock &&
13910             !(ctx->options & E2F_OPT_READONLY))
13911                 ext2fs_mark_super_dirty(fs);
13912
13913         /*
13914          * We only update the master superblock because (a) paranoia;
13915          * we don't want to corrupt the backup superblocks, and (b) we
13916          * don't need to update the mount count and last checked
13917          * fields in the backup superblock (the kernel doesn't
13918          * update the backup superblocks anyway).
13919          */
13920         fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13921
13922         ehandler_init(fs->io);
13923
13924         if (ctx->superblock)
13925                 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13926         ext2fs_mark_valid(fs);
13927         check_super_block(ctx);
13928         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13929                 fatal_error(ctx, 0);
13930         check_if_skip(ctx);
13931         if (bad_blocks_file)
13932                 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
13933         else if (cflag)
13934                 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
13935         if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13936                 fatal_error(ctx, 0);
13937 #ifdef ENABLE_SWAPFS
13938
13939 #ifdef WORDS_BIGENDIAN
13940 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13941 #else
13942 #define NATIVE_FLAG 0
13943 #endif
13944
13945
13946         if (normalize_swapfs) {
13947                 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13948                         fprintf(stderr, _("%s: Filesystem byte order "
13949                                 "already normalized.\n"), ctx->device_name);
13950                         fatal_error(ctx, 0);
13951                 }
13952         }
13953         if (swapfs) {
13954                 swap_filesys(ctx);
13955                 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13956                         fatal_error(ctx, 0);
13957         }
13958 #endif
13959
13960         /*
13961          * Mark the system as valid, 'til proven otherwise
13962          */
13963         ext2fs_mark_valid(fs);
13964
13965         retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13966         if (retval) {
13967                 com_err(ctx->program_name, retval,
13968                         _("while reading bad blocks inode"));
13969                 preenhalt(ctx);
13970                 printf(_("This doesn't bode well,"
13971                          " but we'll try to go on...\n"));
13972         }
13973
13974         run_result = e2fsck_run(ctx);
13975         e2fsck_clear_progbar(ctx);
13976         if (run_result == E2F_FLAG_RESTART) {
13977                 printf(_("Restarting e2fsck from the beginning...\n"));
13978                 retval = e2fsck_reset_context(ctx);
13979                 if (retval) {
13980                         com_err(ctx->program_name, retval,
13981                                 _("while resetting context"));
13982                         fatal_error(ctx, 0);
13983                 }
13984                 ext2fs_close(fs);
13985                 goto restart;
13986         }
13987         if (run_result & E2F_FLAG_CANCEL) {
13988                 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13989                        ctx->device_name : ctx->filesystem_name);
13990                 exit_value |= FSCK_CANCELED;
13991         }
13992         if (run_result & E2F_FLAG_ABORT)
13993                 fatal_error(ctx, _("aborted"));
13994
13995         /* Cleanup */
13996         if (ext2fs_test_changed(fs)) {
13997                 exit_value |= EXIT_NONDESTRUCT;
13998                 if (!(ctx->options & E2F_OPT_PREEN))
13999                     printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
14000                                ctx->device_name);
14001                 if (ctx->mount_flags & EXT2_MF_ISROOT) {
14002                         printf(_("%s: ***** REBOOT LINUX *****\n"),
14003                                ctx->device_name);
14004                         exit_value |= EXIT_DESTRUCT;
14005                 }
14006         }
14007         if (!ext2fs_test_valid(fs)) {
14008                 printf(_("\n%s: ********** WARNING: Filesystem still has "
14009                          "errors **********\n\n"), ctx->device_name);
14010                 exit_value |= EXIT_UNCORRECTED;
14011                 exit_value &= ~EXIT_NONDESTRUCT;
14012         }
14013         if (exit_value & FSCK_CANCELED)
14014                 exit_value &= ~EXIT_NONDESTRUCT;
14015         else {
14016                 show_stats(ctx);
14017                 if (!(ctx->options & E2F_OPT_READONLY)) {
14018                         if (ext2fs_test_valid(fs)) {
14019                                 if (!(sb->s_state & EXT2_VALID_FS))
14020                                         exit_value |= EXIT_NONDESTRUCT;
14021                                 sb->s_state = EXT2_VALID_FS;
14022                         } else
14023                                 sb->s_state &= ~EXT2_VALID_FS;
14024                         sb->s_mnt_count = 0;
14025                         sb->s_lastcheck = time(NULL);
14026                         ext2fs_mark_super_dirty(fs);
14027                 }
14028         }
14029
14030         e2fsck_write_bitmaps(ctx);
14031
14032         ext2fs_close(fs);
14033         ctx->fs = NULL;
14034         free(ctx->filesystem_name);
14035         free(ctx->journal_name);
14036         e2fsck_free_context(ctx);
14037
14038         return exit_value;
14039 }