• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/router/busybox-1.x/e2fsprogs/old_e2fsprogs/
1/* vi: set sw=4 ts=4: */
2/*
3 * e2fsck
4 *
5 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6 * Copyright (C) 2006 Garrett Kajmowicz
7 *
8 * Dictionary Abstract Data Type
9 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
10 * Free Software License:
11 * All rights are reserved by the author, with the following exceptions:
12 * Permission is granted to freely reproduce and distribute this software,
13 * possibly in exchange for a fee, provided that this copyright notice appears
14 * intact. Permission is also granted to adapt this software to produce
15 * derivative works, as long as the modified versions carry this copyright
16 * notice and additional notices stating that the work has been modified.
17 * This source code may be translated into executable form and incorporated
18 * into proprietary software; there is no requirement for such software to
19 * contain a copyright notice related to this source.
20 *
21 * linux/fs/recovery  and linux/fs/revoke
22 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
23 *
24 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
25 *
26 * Journal recovery routines for the generic filesystem journaling code;
27 * part of the ext2fs journaling system.
28 *
29 * Licensed under GPLv2 or later, see file License in this tarball for details.
30 */
31
32#ifndef _GNU_SOURCE
33#define _GNU_SOURCE 1 /* get strnlen() */
34#endif
35
36#include "e2fsck.h"	/*Put all of our defines here to clean things up*/
37
38#define _(x) x
39#define N_(x) x
40
41/*
42 * Procedure declarations
43 */
44
45static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
46
47/* pass1.c */
48static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
49
50/* pass2.c */
51static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
52				    ext2_ino_t ino, char *buf);
53
54/* pass3.c */
55static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
56static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
57					 int num, int gauranteed_size);
58static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
59static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
60					   int adj);
61
62/* rehash.c */
63static void e2fsck_rehash_directories(e2fsck_t ctx);
64
65/* util.c */
66static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
67				    const char *description);
68static int ask(e2fsck_t ctx, const char * string, int def);
69static void e2fsck_read_bitmaps(e2fsck_t ctx);
70static void preenhalt(e2fsck_t ctx);
71static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
72			      struct ext2_inode * inode, const char * proc);
73static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
74			       struct ext2_inode * inode, const char * proc);
75static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
76			   const char *name, io_manager manager);
77
78/* unix.c */
79static void e2fsck_clear_progbar(e2fsck_t ctx);
80static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
81				  float percent, unsigned int dpynum);
82
83
84/*
85 * problem.h --- e2fsck problem error codes
86 */
87
88typedef __u32 problem_t;
89
90struct problem_context {
91	errcode_t       errcode;
92	ext2_ino_t ino, ino2, dir;
93	struct ext2_inode *inode;
94	struct ext2_dir_entry *dirent;
95	blk_t   blk, blk2;
96	e2_blkcnt_t     blkcount;
97	int             group;
98	__u64   num;
99	const char *str;
100};
101
102
103/*
104 * Function declarations
105 */
106static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
107static int end_problem_latch(e2fsck_t ctx, int mask);
108static int set_latch_flags(int mask, int setflags, int clearflags);
109static void clear_problem_context(struct problem_context *ctx);
110
111/*
112 * Dictionary Abstract Data Type
113 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
114 *
115 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
116 * kazlib_1_20
117 */
118
119#ifndef DICT_H
120#define DICT_H
121
122/*
123 * Blurb for inclusion into C++ translation units
124 */
125
126typedef unsigned long dictcount_t;
127#define DICTCOUNT_T_MAX ULONG_MAX
128
129/*
130 * The dictionary is implemented as a red-black tree
131 */
132
133typedef enum { dnode_red, dnode_black } dnode_color_t;
134
135typedef struct dnode_t {
136    struct dnode_t *dict_left;
137    struct dnode_t *dict_right;
138    struct dnode_t *dict_parent;
139    dnode_color_t dict_color;
140    const void *dict_key;
141    void *dict_data;
142} dnode_t;
143
144typedef int (*dict_comp_t)(const void *, const void *);
145typedef void (*dnode_free_t)(dnode_t *);
146
147typedef struct dict_t {
148    dnode_t dict_nilnode;
149    dictcount_t dict_nodecount;
150    dictcount_t dict_maxcount;
151    dict_comp_t dict_compare;
152    dnode_free_t dict_freenode;
153    int dict_dupes;
154} dict_t;
155
156typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
157
158typedef struct dict_load_t {
159    dict_t *dict_dictptr;
160    dnode_t dict_nilnode;
161} dict_load_t;
162
163#define dict_count(D) ((D)->dict_nodecount)
164#define dnode_get(N) ((N)->dict_data)
165#define dnode_getkey(N) ((N)->dict_key)
166
167#endif
168
169/*
170 * Compatibility header file for e2fsck which should be included
171 * instead of linux/jfs.h
172 *
173 * Copyright (C) 2000 Stephen C. Tweedie
174 */
175
176/*
177 * Pull in the definition of the e2fsck context structure
178 */
179
180struct buffer_head {
181	char            b_data[8192];
182	e2fsck_t        b_ctx;
183	io_channel      b_io;
184	int             b_size;
185	blk_t           b_blocknr;
186	int             b_dirty;
187	int             b_uptodate;
188	int             b_err;
189};
190
191
192#define K_DEV_FS        1
193#define K_DEV_JOURNAL   2
194
195#define lock_buffer(bh) do {} while(0)
196#define unlock_buffer(bh) do {} while(0)
197#define buffer_req(bh) 1
198#define do_readahead(journal, start) do {} while(0)
199
200static e2fsck_t e2fsck_global_ctx;  /* Try your very best not to use this! */
201
202typedef struct {
203	int     object_length;
204} kmem_cache_t;
205
206#define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
207
208/*
209 * We use the standard libext2fs portability tricks for inline
210 * functions.
211 */
212
213static kmem_cache_t * do_cache_create(int len)
214{
215	kmem_cache_t *new_cache;
216
217	new_cache = malloc(sizeof(*new_cache));
218	if (new_cache)
219		new_cache->object_length = len;
220	return new_cache;
221}
222
223static void do_cache_destroy(kmem_cache_t *cache)
224{
225	free(cache);
226}
227
228
229/*
230 * Dictionary Abstract Data Type
231 */
232
233
234/*
235 * These macros provide short convenient names for structure members,
236 * which are embellished with dict_ prefixes so that they are
237 * properly confined to the documented namespace. It's legal for a
238 * program which uses dict to define, for instance, a macro called ``parent''.
239 * Such a macro would interfere with the dnode_t struct definition.
240 * In general, highly portable and reusable C modules which expose their
241 * structures need to confine structure member names to well-defined spaces.
242 * The resulting identifiers aren't necessarily convenient to use, nor
243 * readable, in the implementation, however!
244 */
245
246#define left dict_left
247#define right dict_right
248#define parent dict_parent
249#define color dict_color
250#define key dict_key
251#define data dict_data
252
253#define nilnode dict_nilnode
254#define maxcount dict_maxcount
255#define compare dict_compare
256#define dupes dict_dupes
257
258#define dict_root(D) ((D)->nilnode.left)
259#define dict_nil(D) (&(D)->nilnode)
260
261static void dnode_free(dnode_t *node);
262
263/*
264 * Perform a ``left rotation'' adjustment on the tree.  The given node P and
265 * its right child C are rearranged so that the P instead becomes the left
266 * child of C.   The left subtree of C is inherited as the new right subtree
267 * for P.  The ordering of the keys within the tree is thus preserved.
268 */
269
270static void rotate_left(dnode_t *upper)
271{
272    dnode_t *lower, *lowleft, *upparent;
273
274    lower = upper->right;
275    upper->right = lowleft = lower->left;
276    lowleft->parent = upper;
277
278    lower->parent = upparent = upper->parent;
279
280    /* don't need to check for root node here because root->parent is
281       the sentinel nil node, and root->parent->left points back to root */
282
283    if (upper == upparent->left) {
284	upparent->left = lower;
285    } else {
286	assert (upper == upparent->right);
287	upparent->right = lower;
288    }
289
290    lower->left = upper;
291    upper->parent = lower;
292}
293
294/*
295 * This operation is the ``mirror'' image of rotate_left. It is
296 * the same procedure, but with left and right interchanged.
297 */
298
299static void rotate_right(dnode_t *upper)
300{
301    dnode_t *lower, *lowright, *upparent;
302
303    lower = upper->left;
304    upper->left = lowright = lower->right;
305    lowright->parent = upper;
306
307    lower->parent = upparent = upper->parent;
308
309    if (upper == upparent->right) {
310	upparent->right = lower;
311    } else {
312	assert (upper == upparent->left);
313	upparent->left = lower;
314    }
315
316    lower->right = upper;
317    upper->parent = lower;
318}
319
320/*
321 * Do a postorder traversal of the tree rooted at the specified
322 * node and free everything under it.  Used by dict_free().
323 */
324
325static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
326{
327    if (node == nil)
328	return;
329    free_nodes(dict, node->left, nil);
330    free_nodes(dict, node->right, nil);
331    dict->dict_freenode(node);
332}
333
334/*
335 * Verify that the tree contains the given node. This is done by
336 * traversing all of the nodes and comparing their pointers to the
337 * given pointer. Returns 1 if the node is found, otherwise
338 * returns zero. It is intended for debugging purposes.
339 */
340
341static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
342{
343    if (root != nil) {
344	return root == node
345		|| verify_dict_has_node(nil, root->left, node)
346		|| verify_dict_has_node(nil, root->right, node);
347    }
348    return 0;
349}
350
351
352/*
353 * Select a different set of node allocator routines.
354 */
355
356static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
357{
358    assert (dict_count(dict) == 0);
359    dict->dict_freenode = fr;
360}
361
362/*
363 * Free all the nodes in the dictionary by using the dictionary's
364 * installed free routine. The dictionary is emptied.
365 */
366
367static void dict_free_nodes(dict_t *dict)
368{
369    dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
370    free_nodes(dict, root, nil);
371    dict->dict_nodecount = 0;
372    dict->nilnode.left = &dict->nilnode;
373    dict->nilnode.right = &dict->nilnode;
374}
375
376/*
377 * Initialize a user-supplied dictionary object.
378 */
379
380static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
381{
382    dict->compare = comp;
383    dict->dict_freenode = dnode_free;
384    dict->dict_nodecount = 0;
385    dict->maxcount = maxcount;
386    dict->nilnode.left = &dict->nilnode;
387    dict->nilnode.right = &dict->nilnode;
388    dict->nilnode.parent = &dict->nilnode;
389    dict->nilnode.color = dnode_black;
390    dict->dupes = 0;
391    return dict;
392}
393
394/*
395 * Locate a node in the dictionary having the given key.
396 * If the node is not found, a null a pointer is returned (rather than
397 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
398 * located node is returned.
399 */
400
401static dnode_t *dict_lookup(dict_t *dict, const void *key)
402{
403    dnode_t *root = dict_root(dict);
404    dnode_t *nil = dict_nil(dict);
405    dnode_t *saved;
406    int result;
407
408    /* simple binary search adapted for trees that contain duplicate keys */
409
410    while (root != nil) {
411	result = dict->compare(key, root->key);
412	if (result < 0)
413	    root = root->left;
414	else if (result > 0)
415	    root = root->right;
416	else {
417	    if (!dict->dupes) { /* no duplicates, return match          */
418		return root;
419	    } else {            /* could be dupes, find leftmost one    */
420		do {
421		    saved = root;
422		    root = root->left;
423		    while (root != nil && dict->compare(key, root->key))
424			root = root->right;
425		} while (root != nil);
426		return saved;
427	    }
428	}
429    }
430
431    return NULL;
432}
433
434/*
435 * Insert a node into the dictionary. The node should have been
436 * initialized with a data field. All other fields are ignored.
437 * The behavior is undefined if the user attempts to insert into
438 * a dictionary that is already full (for which the dict_isfull()
439 * function returns true).
440 */
441
442static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
443{
444    dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
445    dnode_t *parent = nil, *uncle, *grandpa;
446    int result = -1;
447
448    node->key = key;
449
450    /* basic binary tree insert */
451
452    while (where != nil) {
453	parent = where;
454	result = dict->compare(key, where->key);
455	/* trap attempts at duplicate key insertion unless it's explicitly allowed */
456	assert (dict->dupes || result != 0);
457	if (result < 0)
458	    where = where->left;
459	else
460	    where = where->right;
461    }
462
463    assert (where == nil);
464
465    if (result < 0)
466	parent->left = node;
467    else
468	parent->right = node;
469
470    node->parent = parent;
471    node->left = nil;
472    node->right = nil;
473
474    dict->dict_nodecount++;
475
476    /* red black adjustments */
477
478    node->color = dnode_red;
479
480    while (parent->color == dnode_red) {
481	grandpa = parent->parent;
482	if (parent == grandpa->left) {
483	    uncle = grandpa->right;
484	    if (uncle->color == dnode_red) {    /* red parent, red uncle */
485		parent->color = dnode_black;
486		uncle->color = dnode_black;
487		grandpa->color = dnode_red;
488		node = grandpa;
489		parent = grandpa->parent;
490	    } else {                            /* red parent, black uncle */
491		if (node == parent->right) {
492		    rotate_left(parent);
493		    parent = node;
494		    assert (grandpa == parent->parent);
495		    /* rotation between parent and child preserves grandpa */
496		}
497		parent->color = dnode_black;
498		grandpa->color = dnode_red;
499		rotate_right(grandpa);
500		break;
501	    }
502	} else {        /* symmetric cases: parent == parent->parent->right */
503	    uncle = grandpa->left;
504	    if (uncle->color == dnode_red) {
505		parent->color = dnode_black;
506		uncle->color = dnode_black;
507		grandpa->color = dnode_red;
508		node = grandpa;
509		parent = grandpa->parent;
510	    } else {
511		if (node == parent->left) {
512		    rotate_right(parent);
513		    parent = node;
514		    assert (grandpa == parent->parent);
515		}
516		parent->color = dnode_black;
517		grandpa->color = dnode_red;
518		rotate_left(grandpa);
519		break;
520	    }
521	}
522    }
523
524    dict_root(dict)->color = dnode_black;
525
526}
527
528/*
529 * Allocate a node using the dictionary's allocator routine, give it
530 * the data item.
531 */
532
533static dnode_t *dnode_init(dnode_t *dnode, void *data)
534{
535    dnode->data = data;
536    dnode->parent = NULL;
537    dnode->left = NULL;
538    dnode->right = NULL;
539    return dnode;
540}
541
542static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
543{
544    dnode_t *node = malloc(sizeof(dnode_t));
545
546    if (node) {
547	dnode_init(node, data);
548	dict_insert(dict, node, key);
549	return 1;
550    }
551    return 0;
552}
553
554/*
555 * Return the node with the lowest (leftmost) key. If the dictionary is empty
556 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
557 */
558
559static dnode_t *dict_first(dict_t *dict)
560{
561    dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
562
563    if (root != nil)
564	while ((left = root->left) != nil)
565	    root = left;
566
567    return (root == nil) ? NULL : root;
568}
569
570/*
571 * Return the given node's successor node---the node which has the
572 * next key in the the left to right ordering. If the node has
573 * no successor, a null pointer is returned rather than a pointer to
574 * the nil node.
575 */
576
577static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
578{
579    dnode_t *nil = dict_nil(dict), *parent, *left;
580
581    if (curr->right != nil) {
582	curr = curr->right;
583	while ((left = curr->left) != nil)
584	    curr = left;
585	return curr;
586    }
587
588    parent = curr->parent;
589
590    while (parent != nil && curr == parent->right) {
591	curr = parent;
592	parent = curr->parent;
593    }
594
595    return (parent == nil) ? NULL : parent;
596}
597
598
599static void dnode_free(dnode_t *node)
600{
601    free(node);
602}
603
604
605#undef left
606#undef right
607#undef parent
608#undef color
609#undef key
610#undef data
611
612#undef nilnode
613#undef maxcount
614#undef compare
615#undef dupes
616
617
618/*
619 * dirinfo.c --- maintains the directory information table for e2fsck.
620 */
621
622/*
623 * This subroutine is called during pass1 to create a directory info
624 * entry.  During pass1, the passed-in parent is 0; it will get filled
625 * in during pass2.
626 */
627static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
628{
629	struct dir_info *dir;
630	int             i, j;
631	ext2_ino_t      num_dirs;
632	errcode_t       retval;
633	unsigned long   old_size;
634
635	if (!ctx->dir_info) {
636		ctx->dir_info_count = 0;
637		retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
638		if (retval)
639			num_dirs = 1024;        /* Guess */
640		ctx->dir_info_size = num_dirs + 10;
641		ctx->dir_info  = (struct dir_info *)
642			e2fsck_allocate_memory(ctx, ctx->dir_info_size
643					       * sizeof (struct dir_info),
644					       "directory map");
645	}
646
647	if (ctx->dir_info_count >= ctx->dir_info_size) {
648		old_size = ctx->dir_info_size * sizeof(struct dir_info);
649		ctx->dir_info_size += 10;
650		retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
651					   sizeof(struct dir_info),
652					   &ctx->dir_info);
653		if (retval) {
654			ctx->dir_info_size -= 10;
655			return;
656		}
657	}
658
659	/*
660	 * Normally, add_dir_info is called with each inode in
661	 * sequential order; but once in a while (like when pass 3
662	 * needs to recreate the root directory or lost+found
663	 * directory) it is called out of order.  In those cases, we
664	 * need to move the dir_info entries down to make room, since
665	 * the dir_info array needs to be sorted by inode number for
666	 * get_dir_info()'s sake.
667	 */
668	if (ctx->dir_info_count &&
669	    ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
670		for (i = ctx->dir_info_count-1; i > 0; i--)
671			if (ctx->dir_info[i-1].ino < ino)
672				break;
673		dir = &ctx->dir_info[i];
674		if (dir->ino != ino)
675			for (j = ctx->dir_info_count++; j > i; j--)
676				ctx->dir_info[j] = ctx->dir_info[j-1];
677	} else
678		dir = &ctx->dir_info[ctx->dir_info_count++];
679
680	dir->ino = ino;
681	dir->dotdot = parent;
682	dir->parent = parent;
683}
684
685/*
686 * get_dir_info() --- given an inode number, try to find the directory
687 * information entry for it.
688 */
689static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
690{
691	int     low, high, mid;
692
693	low = 0;
694	high = ctx->dir_info_count-1;
695	if (!ctx->dir_info)
696		return 0;
697	if (ino == ctx->dir_info[low].ino)
698		return &ctx->dir_info[low];
699	if  (ino == ctx->dir_info[high].ino)
700		return &ctx->dir_info[high];
701
702	while (low < high) {
703		mid = (low+high)/2;
704		if (mid == low || mid == high)
705			break;
706		if (ino == ctx->dir_info[mid].ino)
707			return &ctx->dir_info[mid];
708		if (ino < ctx->dir_info[mid].ino)
709			high = mid;
710		else
711			low = mid;
712	}
713	return 0;
714}
715
716/*
717 * Free the dir_info structure when it isn't needed any more.
718 */
719static void e2fsck_free_dir_info(e2fsck_t ctx)
720{
721	ext2fs_free_mem(&ctx->dir_info);
722	ctx->dir_info_size = 0;
723	ctx->dir_info_count = 0;
724}
725
726/*
727 * Return the count of number of directories in the dir_info structure
728 */
729static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
730{
731	return ctx->dir_info_count;
732}
733
734/*
735 * A simple interator function
736 */
737static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
738{
739	if (*control >= ctx->dir_info_count)
740		return 0;
741
742	return ctx->dir_info + (*control)++;
743}
744
745/*
746 * dirinfo.c --- maintains the directory information table for e2fsck.
747 *
748 */
749
750#ifdef ENABLE_HTREE
751
752/*
753 * This subroutine is called during pass1 to create a directory info
754 * entry.  During pass1, the passed-in parent is 0; it will get filled
755 * in during pass2.
756 */
757static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
758{
759	struct dx_dir_info *dir;
760	int             i, j;
761	errcode_t       retval;
762	unsigned long   old_size;
763
764	if (!ctx->dx_dir_info) {
765		ctx->dx_dir_info_count = 0;
766		ctx->dx_dir_info_size = 100; /* Guess */
767		ctx->dx_dir_info  = (struct dx_dir_info *)
768			e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
769					       * sizeof (struct dx_dir_info),
770					       "directory map");
771	}
772
773	if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
774		old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
775		ctx->dx_dir_info_size += 10;
776		retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
777					   sizeof(struct dx_dir_info),
778					   &ctx->dx_dir_info);
779		if (retval) {
780			ctx->dx_dir_info_size -= 10;
781			return;
782		}
783	}
784
785	/*
786	 * Normally, add_dx_dir_info is called with each inode in
787	 * sequential order; but once in a while (like when pass 3
788	 * needs to recreate the root directory or lost+found
789	 * directory) it is called out of order.  In those cases, we
790	 * need to move the dx_dir_info entries down to make room, since
791	 * the dx_dir_info array needs to be sorted by inode number for
792	 * get_dx_dir_info()'s sake.
793	 */
794	if (ctx->dx_dir_info_count &&
795	    ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
796		for (i = ctx->dx_dir_info_count-1; i > 0; i--)
797			if (ctx->dx_dir_info[i-1].ino < ino)
798				break;
799		dir = &ctx->dx_dir_info[i];
800		if (dir->ino != ino)
801			for (j = ctx->dx_dir_info_count++; j > i; j--)
802				ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
803	} else
804		dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
805
806	dir->ino = ino;
807	dir->numblocks = num_blocks;
808	dir->hashversion = 0;
809	dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
810				       * sizeof (struct dx_dirblock_info),
811				       "dx_block info array");
812
813}
814
815/*
816 * get_dx_dir_info() --- given an inode number, try to find the directory
817 * information entry for it.
818 */
819static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
820{
821	int     low, high, mid;
822
823	low = 0;
824	high = ctx->dx_dir_info_count-1;
825	if (!ctx->dx_dir_info)
826		return 0;
827	if (ino == ctx->dx_dir_info[low].ino)
828		return &ctx->dx_dir_info[low];
829	if  (ino == ctx->dx_dir_info[high].ino)
830		return &ctx->dx_dir_info[high];
831
832	while (low < high) {
833		mid = (low+high)/2;
834		if (mid == low || mid == high)
835			break;
836		if (ino == ctx->dx_dir_info[mid].ino)
837			return &ctx->dx_dir_info[mid];
838		if (ino < ctx->dx_dir_info[mid].ino)
839			high = mid;
840		else
841			low = mid;
842	}
843	return 0;
844}
845
846/*
847 * Free the dx_dir_info structure when it isn't needed any more.
848 */
849static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
850{
851	int     i;
852	struct dx_dir_info *dir;
853
854	if (ctx->dx_dir_info) {
855		dir = ctx->dx_dir_info;
856		for (i=0; i < ctx->dx_dir_info_count; i++) {
857			ext2fs_free_mem(&dir->dx_block);
858		}
859		ext2fs_free_mem(&ctx->dx_dir_info);
860	}
861	ctx->dx_dir_info_size = 0;
862	ctx->dx_dir_info_count = 0;
863}
864
865/*
866 * A simple interator function
867 */
868static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
869{
870	if (*control >= ctx->dx_dir_info_count)
871		return 0;
872
873	return ctx->dx_dir_info + (*control)++;
874}
875
876#endif /* ENABLE_HTREE */
877/*
878 * e2fsck.c - a consistency checker for the new extended file system.
879 *
880 */
881
882/*
883 * This function allocates an e2fsck context
884 */
885static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
886{
887	e2fsck_t        context;
888	errcode_t       retval;
889
890	retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
891	if (retval)
892		return retval;
893
894	memset(context, 0, sizeof(struct e2fsck_struct));
895
896	context->process_inode_size = 256;
897	context->ext_attr_ver = 2;
898
899	*ret = context;
900	return 0;
901}
902
903struct ea_refcount_el {
904	blk_t   ea_blk;
905	int     ea_count;
906};
907
908struct ea_refcount {
909	blk_t           count;
910	blk_t           size;
911	blk_t           cursor;
912	struct ea_refcount_el   *list;
913};
914
915static void ea_refcount_free(ext2_refcount_t refcount)
916{
917	if (!refcount)
918		return;
919
920	ext2fs_free_mem(&refcount->list);
921	ext2fs_free_mem(&refcount);
922}
923
924/*
925 * This function resets an e2fsck context; it is called when e2fsck
926 * needs to be restarted.
927 */
928static errcode_t e2fsck_reset_context(e2fsck_t ctx)
929{
930	ctx->flags = 0;
931	ctx->lost_and_found = 0;
932	ctx->bad_lost_and_found = 0;
933	ext2fs_free_inode_bitmap(ctx->inode_used_map);
934	ctx->inode_used_map = 0;
935	ext2fs_free_inode_bitmap(ctx->inode_dir_map);
936	ctx->inode_dir_map = 0;
937	ext2fs_free_inode_bitmap(ctx->inode_reg_map);
938	ctx->inode_reg_map = 0;
939	ext2fs_free_block_bitmap(ctx->block_found_map);
940	ctx->block_found_map = 0;
941	ext2fs_free_icount(ctx->inode_link_info);
942	ctx->inode_link_info = 0;
943	if (ctx->journal_io) {
944		if (ctx->fs && ctx->fs->io != ctx->journal_io)
945			io_channel_close(ctx->journal_io);
946		ctx->journal_io = 0;
947	}
948	if (ctx->fs) {
949		ext2fs_free_dblist(ctx->fs->dblist);
950		ctx->fs->dblist = 0;
951	}
952	e2fsck_free_dir_info(ctx);
953#ifdef ENABLE_HTREE
954	e2fsck_free_dx_dir_info(ctx);
955#endif
956	ea_refcount_free(ctx->refcount);
957	ctx->refcount = 0;
958	ea_refcount_free(ctx->refcount_extra);
959	ctx->refcount_extra = 0;
960	ext2fs_free_block_bitmap(ctx->block_dup_map);
961	ctx->block_dup_map = 0;
962	ext2fs_free_block_bitmap(ctx->block_ea_map);
963	ctx->block_ea_map = 0;
964	ext2fs_free_inode_bitmap(ctx->inode_bad_map);
965	ctx->inode_bad_map = 0;
966	ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
967	ctx->inode_imagic_map = 0;
968	ext2fs_u32_list_free(ctx->dirs_to_hash);
969	ctx->dirs_to_hash = 0;
970
971	/*
972	 * Clear the array of invalid meta-data flags
973	 */
974	ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
975	ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
976	ext2fs_free_mem(&ctx->invalid_inode_table_flag);
977
978	/* Clear statistic counters */
979	ctx->fs_directory_count = 0;
980	ctx->fs_regular_count = 0;
981	ctx->fs_blockdev_count = 0;
982	ctx->fs_chardev_count = 0;
983	ctx->fs_links_count = 0;
984	ctx->fs_symlinks_count = 0;
985	ctx->fs_fast_symlinks_count = 0;
986	ctx->fs_fifo_count = 0;
987	ctx->fs_total_count = 0;
988	ctx->fs_sockets_count = 0;
989	ctx->fs_ind_count = 0;
990	ctx->fs_dind_count = 0;
991	ctx->fs_tind_count = 0;
992	ctx->fs_fragmented = 0;
993	ctx->large_files = 0;
994
995	/* Reset the superblock to the user's requested value */
996	ctx->superblock = ctx->use_superblock;
997
998	return 0;
999}
1000
1001static void e2fsck_free_context(e2fsck_t ctx)
1002{
1003	if (!ctx)
1004		return;
1005
1006	e2fsck_reset_context(ctx);
1007	if (ctx->blkid)
1008		blkid_put_cache(ctx->blkid);
1009
1010	ext2fs_free_mem(&ctx);
1011}
1012
1013/*
1014 * ea_refcount.c
1015 */
1016
1017/*
1018 * The strategy we use for keeping track of EA refcounts is as
1019 * follows.  We keep a sorted array of first EA blocks and its
1020 * reference counts.  Once the refcount has dropped to zero, it is
1021 * removed from the array to save memory space.  Once the EA block is
1022 * checked, its bit is set in the block_ea_map bitmap.
1023 */
1024
1025
1026static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1027{
1028	ext2_refcount_t refcount;
1029	errcode_t       retval;
1030	size_t          bytes;
1031
1032	retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1033	if (retval)
1034		return retval;
1035	memset(refcount, 0, sizeof(struct ea_refcount));
1036
1037	if (!size)
1038		size = 500;
1039	refcount->size = size;
1040	bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1041#ifdef DEBUG
1042	printf("Refcount allocated %d entries, %d bytes.\n",
1043	       refcount->size, bytes);
1044#endif
1045	retval = ext2fs_get_mem(bytes, &refcount->list);
1046	if (retval)
1047		goto errout;
1048	memset(refcount->list, 0, bytes);
1049
1050	refcount->count = 0;
1051	refcount->cursor = 0;
1052
1053	*ret = refcount;
1054	return 0;
1055
1056errout:
1057	ea_refcount_free(refcount);
1058	return retval;
1059}
1060
1061/*
1062 * collapse_refcount() --- go through the refcount array, and get rid
1063 * of any count == zero entries
1064 */
1065static void refcount_collapse(ext2_refcount_t refcount)
1066{
1067	unsigned int    i, j;
1068	struct ea_refcount_el   *list;
1069
1070	list = refcount->list;
1071	for (i = 0, j = 0; i < refcount->count; i++) {
1072		if (list[i].ea_count) {
1073			if (i != j)
1074				list[j] = list[i];
1075			j++;
1076		}
1077	}
1078#if defined(DEBUG) || defined(TEST_PROGRAM)
1079	printf("Refcount_collapse: size was %d, now %d\n",
1080	       refcount->count, j);
1081#endif
1082	refcount->count = j;
1083}
1084
1085
1086/*
1087 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1088 *      specified position.
1089 */
1090static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1091						 blk_t blk, int pos)
1092{
1093	struct ea_refcount_el   *el;
1094	errcode_t               retval;
1095	blk_t                   new_size = 0;
1096	int                     num;
1097
1098	if (refcount->count >= refcount->size) {
1099		new_size = refcount->size + 100;
1100#ifdef DEBUG
1101		printf("Reallocating refcount %d entries...\n", new_size);
1102#endif
1103		retval = ext2fs_resize_mem((size_t) refcount->size *
1104					   sizeof(struct ea_refcount_el),
1105					   (size_t) new_size *
1106					   sizeof(struct ea_refcount_el),
1107					   &refcount->list);
1108		if (retval)
1109			return 0;
1110		refcount->size = new_size;
1111	}
1112	num = (int) refcount->count - pos;
1113	if (num < 0)
1114		return 0;       /* should never happen */
1115	if (num) {
1116		memmove(&refcount->list[pos+1], &refcount->list[pos],
1117			sizeof(struct ea_refcount_el) * num);
1118	}
1119	refcount->count++;
1120	el = &refcount->list[pos];
1121	el->ea_count = 0;
1122	el->ea_blk = blk;
1123	return el;
1124}
1125
1126
1127/*
1128 * get_refcount_el() --- given an block number, try to find refcount
1129 *      information in the sorted list.  If the create flag is set,
1130 *      and we can't find an entry, create one in the sorted list.
1131 */
1132static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1133					      blk_t blk, int create)
1134{
1135	float   range;
1136	int     low, high, mid;
1137	blk_t   lowval, highval;
1138
1139	if (!refcount || !refcount->list)
1140		return 0;
1141retry:
1142	low = 0;
1143	high = (int) refcount->count-1;
1144	if (create && ((refcount->count == 0) ||
1145		       (blk > refcount->list[high].ea_blk))) {
1146		if (refcount->count >= refcount->size)
1147			refcount_collapse(refcount);
1148
1149		return insert_refcount_el(refcount, blk,
1150					  (unsigned) refcount->count);
1151	}
1152	if (refcount->count == 0)
1153		return 0;
1154
1155	if (refcount->cursor >= refcount->count)
1156		refcount->cursor = 0;
1157	if (blk == refcount->list[refcount->cursor].ea_blk)
1158		return &refcount->list[refcount->cursor++];
1159#ifdef DEBUG
1160	printf("Non-cursor get_refcount_el: %u\n", blk);
1161#endif
1162	while (low <= high) {
1163		if (low == high)
1164			mid = low;
1165		else {
1166			/* Interpolate for efficiency */
1167			lowval = refcount->list[low].ea_blk;
1168			highval = refcount->list[high].ea_blk;
1169
1170			if (blk < lowval)
1171				range = 0;
1172			else if (blk > highval)
1173				range = 1;
1174			else
1175				range = ((float) (blk - lowval)) /
1176					(highval - lowval);
1177			mid = low + ((int) (range * (high-low)));
1178		}
1179
1180		if (blk == refcount->list[mid].ea_blk) {
1181			refcount->cursor = mid+1;
1182			return &refcount->list[mid];
1183		}
1184		if (blk < refcount->list[mid].ea_blk)
1185			high = mid-1;
1186		else
1187			low = mid+1;
1188	}
1189	/*
1190	 * If we need to create a new entry, it should be right at
1191	 * low (where high will be left at low-1).
1192	 */
1193	if (create) {
1194		if (refcount->count >= refcount->size) {
1195			refcount_collapse(refcount);
1196			if (refcount->count < refcount->size)
1197				goto retry;
1198		}
1199		return insert_refcount_el(refcount, blk, low);
1200	}
1201	return 0;
1202}
1203
1204static errcode_t
1205ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1206{
1207	struct ea_refcount_el   *el;
1208
1209	el = get_refcount_el(refcount, blk, 1);
1210	if (!el)
1211		return EXT2_ET_NO_MEMORY;
1212	el->ea_count++;
1213
1214	if (ret)
1215		*ret = el->ea_count;
1216	return 0;
1217}
1218
1219static errcode_t
1220ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1221{
1222	struct ea_refcount_el   *el;
1223
1224	el = get_refcount_el(refcount, blk, 0);
1225	if (!el || el->ea_count == 0)
1226		return EXT2_ET_INVALID_ARGUMENT;
1227
1228	el->ea_count--;
1229
1230	if (ret)
1231		*ret = el->ea_count;
1232	return 0;
1233}
1234
1235static errcode_t
1236ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1237{
1238	struct ea_refcount_el   *el;
1239
1240	/*
1241	 * Get the refcount element
1242	 */
1243	el = get_refcount_el(refcount, blk, count ? 1 : 0);
1244	if (!el)
1245		return count ? EXT2_ET_NO_MEMORY : 0;
1246	el->ea_count = count;
1247	return 0;
1248}
1249
1250static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1251{
1252	refcount->cursor = 0;
1253}
1254
1255
1256static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1257{
1258	struct ea_refcount_el   *list;
1259
1260	while (1) {
1261		if (refcount->cursor >= refcount->count)
1262			return 0;
1263		list = refcount->list;
1264		if (list[refcount->cursor].ea_count) {
1265			if (ret)
1266				*ret = list[refcount->cursor].ea_count;
1267			return list[refcount->cursor++].ea_blk;
1268		}
1269		refcount->cursor++;
1270	}
1271}
1272
1273
1274/*
1275 * ehandler.c --- handle bad block errors which come up during the
1276 *      course of an e2fsck session.
1277 */
1278
1279
1280static const char *operation;
1281
1282static errcode_t
1283e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1284			 void *data, size_t size FSCK_ATTR((unused)),
1285			 int actual FSCK_ATTR((unused)), errcode_t error)
1286{
1287	int     i;
1288	char    *p;
1289	ext2_filsys fs = (ext2_filsys) channel->app_data;
1290	e2fsck_t ctx;
1291
1292	ctx = (e2fsck_t) fs->priv_data;
1293
1294	/*
1295	 * If more than one block was read, try reading each block
1296	 * separately.  We could use the actual bytes read to figure
1297	 * out where to start, but we don't bother.
1298	 */
1299	if (count > 1) {
1300		p = (char *) data;
1301		for (i=0; i < count; i++, p += channel->block_size, block++) {
1302			error = io_channel_read_blk(channel, block,
1303						    1, p);
1304			if (error)
1305				return error;
1306		}
1307		return 0;
1308	}
1309	if (operation)
1310		printf(_("Error reading block %lu (%s) while %s.  "), block,
1311		       error_message(error), operation);
1312	else
1313		printf(_("Error reading block %lu (%s).  "), block,
1314		       error_message(error));
1315	preenhalt(ctx);
1316	if (ask(ctx, _("Ignore error"), 1)) {
1317		if (ask(ctx, _("Force rewrite"), 1))
1318			io_channel_write_blk(channel, block, 1, data);
1319		return 0;
1320	}
1321
1322	return error;
1323}
1324
1325static errcode_t
1326e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1327			const void *data, size_t size FSCK_ATTR((unused)),
1328			int actual FSCK_ATTR((unused)), errcode_t error)
1329{
1330	int             i;
1331	const char      *p;
1332	ext2_filsys fs = (ext2_filsys) channel->app_data;
1333	e2fsck_t ctx;
1334
1335	ctx = (e2fsck_t) fs->priv_data;
1336
1337	/*
1338	 * If more than one block was written, try writing each block
1339	 * separately.  We could use the actual bytes read to figure
1340	 * out where to start, but we don't bother.
1341	 */
1342	if (count > 1) {
1343		p = (const char *) data;
1344		for (i=0; i < count; i++, p += channel->block_size, block++) {
1345			error = io_channel_write_blk(channel, block,
1346						     1, p);
1347			if (error)
1348				return error;
1349		}
1350		return 0;
1351	}
1352
1353	if (operation)
1354		printf(_("Error writing block %lu (%s) while %s.  "), block,
1355		       error_message(error), operation);
1356	else
1357		printf(_("Error writing block %lu (%s).  "), block,
1358		       error_message(error));
1359	preenhalt(ctx);
1360	if (ask(ctx, _("Ignore error"), 1))
1361		return 0;
1362
1363	return error;
1364}
1365
1366static const char *ehandler_operation(const char *op)
1367{
1368	const char *ret = operation;
1369
1370	operation = op;
1371	return ret;
1372}
1373
1374static void ehandler_init(io_channel channel)
1375{
1376	channel->read_error = e2fsck_handle_read_error;
1377	channel->write_error = e2fsck_handle_write_error;
1378}
1379
1380/*
1381 * journal.c --- code for handling the "ext3" journal
1382 *
1383 * Copyright (C) 2000 Andreas Dilger
1384 * Copyright (C) 2000 Theodore Ts'o
1385 *
1386 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1387 * Copyright (C) 1999 Red Hat Software
1388 *
1389 * This file may be redistributed under the terms of the
1390 * GNU General Public License version 2 or at your discretion
1391 * any later version.
1392 */
1393
1394/*
1395 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1396 * This creates a larger static binary, and a smaller binary using
1397 * shared libraries.  It's also probably slightly less CPU-efficient,
1398 * which is why it's not on by default.  But, it's a good way of
1399 * testing the functions in inode_io.c and fileio.c.
1400 */
1401#undef USE_INODE_IO
1402
1403/* Kernel compatibility functions for handling the journal.  These allow us
1404 * to use the recovery.c file virtually unchanged from the kernel, so we
1405 * don't have to do much to keep kernel and user recovery in sync.
1406 */
1407static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1408{
1409#ifdef USE_INODE_IO
1410	*phys = block;
1411	return 0;
1412#else
1413	struct inode    *inode = journal->j_inode;
1414	errcode_t       retval;
1415	blk_t           pblk;
1416
1417	if (!inode) {
1418		*phys = block;
1419		return 0;
1420	}
1421
1422	retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1423			    &inode->i_ext2, NULL, 0, block, &pblk);
1424	*phys = pblk;
1425	return retval;
1426#endif
1427}
1428
1429static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1430{
1431	struct buffer_head *bh;
1432
1433	bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1434	if (!bh)
1435		return NULL;
1436
1437	bh->b_ctx = kdev->k_ctx;
1438	if (kdev->k_dev == K_DEV_FS)
1439		bh->b_io = kdev->k_ctx->fs->io;
1440	else
1441		bh->b_io = kdev->k_ctx->journal_io;
1442	bh->b_size = blocksize;
1443	bh->b_blocknr = blocknr;
1444
1445	return bh;
1446}
1447
1448static void sync_blockdev(kdev_t kdev)
1449{
1450	io_channel      io;
1451
1452	if (kdev->k_dev == K_DEV_FS)
1453		io = kdev->k_ctx->fs->io;
1454	else
1455		io = kdev->k_ctx->journal_io;
1456
1457	io_channel_flush(io);
1458}
1459
1460static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1461{
1462	int retval;
1463	struct buffer_head *bh;
1464
1465	for (; nr > 0; --nr) {
1466		bh = *bhp++;
1467		if (rw == READ && !bh->b_uptodate) {
1468			retval = io_channel_read_blk(bh->b_io,
1469						     bh->b_blocknr,
1470						     1, bh->b_data);
1471			if (retval) {
1472				bb_error_msg("while reading block %lu",
1473					(unsigned long) bh->b_blocknr);
1474				bh->b_err = retval;
1475				continue;
1476			}
1477			bh->b_uptodate = 1;
1478		} else if (rw == WRITE && bh->b_dirty) {
1479			retval = io_channel_write_blk(bh->b_io,
1480						      bh->b_blocknr,
1481						      1, bh->b_data);
1482			if (retval) {
1483				bb_error_msg("while writing block %lu",
1484					(unsigned long) bh->b_blocknr);
1485				bh->b_err = retval;
1486				continue;
1487			}
1488			bh->b_dirty = 0;
1489			bh->b_uptodate = 1;
1490		}
1491	}
1492}
1493
1494static void mark_buffer_dirty(struct buffer_head *bh)
1495{
1496	bh->b_dirty = 1;
1497}
1498
1499static inline void mark_buffer_clean(struct buffer_head * bh)
1500{
1501	bh->b_dirty = 0;
1502}
1503
1504static void brelse(struct buffer_head *bh)
1505{
1506	if (bh->b_dirty)
1507		ll_rw_block(WRITE, 1, &bh);
1508	ext2fs_free_mem(&bh);
1509}
1510
1511static int buffer_uptodate(struct buffer_head *bh)
1512{
1513	return bh->b_uptodate;
1514}
1515
1516static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1517{
1518	bh->b_uptodate = val;
1519}
1520
1521static void wait_on_buffer(struct buffer_head *bh)
1522{
1523	if (!bh->b_uptodate)
1524		ll_rw_block(READ, 1, &bh);
1525}
1526
1527
1528static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1529{
1530	ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1531
1532	/* if we had an error doing journal recovery, we need a full fsck */
1533	if (error)
1534		ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1535	ext2fs_mark_super_dirty(ctx->fs);
1536}
1537
1538static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1539{
1540	struct ext2_super_block *sb = ctx->fs->super;
1541	struct ext2_super_block jsuper;
1542	struct problem_context  pctx;
1543	struct buffer_head      *bh;
1544	struct inode            *j_inode = NULL;
1545	struct kdev_s           *dev_fs = NULL, *dev_journal;
1546	const char              *journal_name = 0;
1547	journal_t               *journal = NULL;
1548	errcode_t               retval = 0;
1549	io_manager              io_ptr = 0;
1550	unsigned long           start = 0;
1551	blk_t                   blk;
1552	int                     ext_journal = 0;
1553	int                     tried_backup_jnl = 0;
1554	int                     i;
1555
1556	clear_problem_context(&pctx);
1557
1558	journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1559	if (!journal) {
1560		return EXT2_ET_NO_MEMORY;
1561	}
1562
1563	dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1564	if (!dev_fs) {
1565		retval = EXT2_ET_NO_MEMORY;
1566		goto errout;
1567	}
1568	dev_journal = dev_fs+1;
1569
1570	dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1571	dev_fs->k_dev = K_DEV_FS;
1572	dev_journal->k_dev = K_DEV_JOURNAL;
1573
1574	journal->j_dev = dev_journal;
1575	journal->j_fs_dev = dev_fs;
1576	journal->j_inode = NULL;
1577	journal->j_blocksize = ctx->fs->blocksize;
1578
1579	if (uuid_is_null(sb->s_journal_uuid)) {
1580		if (!sb->s_journal_inum)
1581			return EXT2_ET_BAD_INODE_NUM;
1582		j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1583						 "journal inode");
1584		if (!j_inode) {
1585			retval = EXT2_ET_NO_MEMORY;
1586			goto errout;
1587		}
1588
1589		j_inode->i_ctx = ctx;
1590		j_inode->i_ino = sb->s_journal_inum;
1591
1592		if ((retval = ext2fs_read_inode(ctx->fs,
1593						sb->s_journal_inum,
1594						&j_inode->i_ext2))) {
1595		try_backup_journal:
1596			if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1597			    tried_backup_jnl)
1598				goto errout;
1599			memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1600			memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1601			       EXT2_N_BLOCKS*4);
1602			j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1603			j_inode->i_ext2.i_links_count = 1;
1604			j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1605			tried_backup_jnl++;
1606		}
1607		if (!j_inode->i_ext2.i_links_count ||
1608		    !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1609			retval = EXT2_ET_NO_JOURNAL;
1610			goto try_backup_journal;
1611		}
1612		if (j_inode->i_ext2.i_size / journal->j_blocksize <
1613		    JFS_MIN_JOURNAL_BLOCKS) {
1614			retval = EXT2_ET_JOURNAL_TOO_SMALL;
1615			goto try_backup_journal;
1616		}
1617		for (i=0; i < EXT2_N_BLOCKS; i++) {
1618			blk = j_inode->i_ext2.i_block[i];
1619			if (!blk) {
1620				if (i < EXT2_NDIR_BLOCKS) {
1621					retval = EXT2_ET_JOURNAL_TOO_SMALL;
1622					goto try_backup_journal;
1623				}
1624				continue;
1625			}
1626			if (blk < sb->s_first_data_block ||
1627			    blk >= sb->s_blocks_count) {
1628				retval = EXT2_ET_BAD_BLOCK_NUM;
1629				goto try_backup_journal;
1630			}
1631		}
1632		journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1633
1634#ifdef USE_INODE_IO
1635		retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1636						 &j_inode->i_ext2,
1637						 &journal_name);
1638		if (retval)
1639			goto errout;
1640
1641		io_ptr = inode_io_manager;
1642#else
1643		journal->j_inode = j_inode;
1644		ctx->journal_io = ctx->fs->io;
1645		if ((retval = journal_bmap(journal, 0, &start)) != 0)
1646			goto errout;
1647#endif
1648	} else {
1649		ext_journal = 1;
1650		if (!ctx->journal_name) {
1651			char uuid[37];
1652
1653			uuid_unparse(sb->s_journal_uuid, uuid);
1654			ctx->journal_name = blkid_get_devname(ctx->blkid,
1655							      "UUID", uuid);
1656			if (!ctx->journal_name)
1657				ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1658		}
1659		journal_name = ctx->journal_name;
1660
1661		if (!journal_name) {
1662			fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1663			return EXT2_ET_LOAD_EXT_JOURNAL;
1664		}
1665
1666		io_ptr = unix_io_manager;
1667	}
1668
1669#ifndef USE_INODE_IO
1670	if (ext_journal)
1671#endif
1672		retval = io_ptr->open(journal_name, IO_FLAG_RW,
1673				      &ctx->journal_io);
1674	if (retval)
1675		goto errout;
1676
1677	io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1678
1679	if (ext_journal) {
1680		if (ctx->fs->blocksize == 1024)
1681			start = 1;
1682		bh = getblk(dev_journal, start, ctx->fs->blocksize);
1683		if (!bh) {
1684			retval = EXT2_ET_NO_MEMORY;
1685			goto errout;
1686		}
1687		ll_rw_block(READ, 1, &bh);
1688		if ((retval = bh->b_err) != 0)
1689			goto errout;
1690		memcpy(&jsuper, start ? bh->b_data :  bh->b_data + 1024,
1691		       sizeof(jsuper));
1692		brelse(bh);
1693#if BB_BIG_ENDIAN
1694		if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1695			ext2fs_swap_super(&jsuper);
1696#endif
1697		if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1698		    !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1699			fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1700			retval = EXT2_ET_LOAD_EXT_JOURNAL;
1701			goto errout;
1702		}
1703		/* Make sure the journal UUID is correct */
1704		if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1705			   sizeof(jsuper.s_uuid))) {
1706			fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1707			retval = EXT2_ET_LOAD_EXT_JOURNAL;
1708			goto errout;
1709		}
1710
1711		journal->j_maxlen = jsuper.s_blocks_count;
1712		start++;
1713	}
1714
1715	if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1716		retval = EXT2_ET_NO_MEMORY;
1717		goto errout;
1718	}
1719
1720	journal->j_sb_buffer = bh;
1721	journal->j_superblock = (journal_superblock_t *)bh->b_data;
1722
1723#ifdef USE_INODE_IO
1724	ext2fs_free_mem(&j_inode);
1725#endif
1726
1727	*ret_journal = journal;
1728	return 0;
1729
1730errout:
1731	ext2fs_free_mem(&dev_fs);
1732	ext2fs_free_mem(&j_inode);
1733	ext2fs_free_mem(&journal);
1734	return retval;
1735
1736}
1737
1738static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1739					      struct problem_context *pctx)
1740{
1741	struct ext2_super_block *sb = ctx->fs->super;
1742	int recover = ctx->fs->super->s_feature_incompat &
1743		EXT3_FEATURE_INCOMPAT_RECOVER;
1744	int has_journal = ctx->fs->super->s_feature_compat &
1745		EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1746
1747	if (has_journal || sb->s_journal_inum) {
1748		/* The journal inode is bogus, remove and force full fsck */
1749		pctx->ino = sb->s_journal_inum;
1750		if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1751			if (has_journal && sb->s_journal_inum)
1752				printf("*** ext3 journal has been deleted - "
1753				       "filesystem is now ext2 only ***\n\n");
1754			sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1755			sb->s_journal_inum = 0;
1756			ctx->flags |= E2F_FLAG_JOURNAL_INODE;
1757			e2fsck_clear_recover(ctx, 1);
1758			return 0;
1759		}
1760		return EXT2_ET_BAD_INODE_NUM;
1761	} else if (recover) {
1762		if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1763			e2fsck_clear_recover(ctx, 1);
1764			return 0;
1765		}
1766		return EXT2_ET_UNSUPP_FEATURE;
1767	}
1768	return 0;
1769}
1770
1771#define V1_SB_SIZE      0x0024
1772static void clear_v2_journal_fields(journal_t *journal)
1773{
1774	e2fsck_t ctx = journal->j_dev->k_ctx;
1775	struct problem_context pctx;
1776
1777	clear_problem_context(&pctx);
1778
1779	if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1780		return;
1781
1782	memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1783	       ctx->fs->blocksize-V1_SB_SIZE);
1784	mark_buffer_dirty(journal->j_sb_buffer);
1785}
1786
1787
1788static errcode_t e2fsck_journal_load(journal_t *journal)
1789{
1790	e2fsck_t ctx = journal->j_dev->k_ctx;
1791	journal_superblock_t *jsb;
1792	struct buffer_head *jbh = journal->j_sb_buffer;
1793	struct problem_context pctx;
1794
1795	clear_problem_context(&pctx);
1796
1797	ll_rw_block(READ, 1, &jbh);
1798	if (jbh->b_err) {
1799		bb_error_msg(_("reading journal superblock"));
1800		return jbh->b_err;
1801	}
1802
1803	jsb = journal->j_superblock;
1804	/* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1805	if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1806		return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1807
1808	switch (ntohl(jsb->s_header.h_blocktype)) {
1809	case JFS_SUPERBLOCK_V1:
1810		journal->j_format_version = 1;
1811		if (jsb->s_feature_compat ||
1812		    jsb->s_feature_incompat ||
1813		    jsb->s_feature_ro_compat ||
1814		    jsb->s_nr_users)
1815			clear_v2_journal_fields(journal);
1816		break;
1817
1818	case JFS_SUPERBLOCK_V2:
1819		journal->j_format_version = 2;
1820		if (ntohl(jsb->s_nr_users) > 1 &&
1821		    uuid_is_null(ctx->fs->super->s_journal_uuid))
1822			clear_v2_journal_fields(journal);
1823		if (ntohl(jsb->s_nr_users) > 1) {
1824			fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1825			return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1826		}
1827		break;
1828
1829	/*
1830	 * These should never appear in a journal super block, so if
1831	 * they do, the journal is badly corrupted.
1832	 */
1833	case JFS_DESCRIPTOR_BLOCK:
1834	case JFS_COMMIT_BLOCK:
1835	case JFS_REVOKE_BLOCK:
1836		return EXT2_ET_CORRUPT_SUPERBLOCK;
1837
1838	/* If we don't understand the superblock major type, but there
1839	 * is a magic number, then it is likely to be a new format we
1840	 * just don't understand, so leave it alone. */
1841	default:
1842		return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1843	}
1844
1845	if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1846		return EXT2_ET_UNSUPP_FEATURE;
1847
1848	if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1849		return EXT2_ET_RO_UNSUPP_FEATURE;
1850
1851	/* We have now checked whether we know enough about the journal
1852	 * format to be able to proceed safely, so any other checks that
1853	 * fail we should attempt to recover from. */
1854	if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1855		bb_error_msg(_("%s: no valid journal superblock found"),
1856			ctx->device_name);
1857		return EXT2_ET_CORRUPT_SUPERBLOCK;
1858	}
1859
1860	if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1861		journal->j_maxlen = ntohl(jsb->s_maxlen);
1862	else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1863		bb_error_msg(_("%s: journal too short"),
1864			ctx->device_name);
1865		return EXT2_ET_CORRUPT_SUPERBLOCK;
1866	}
1867
1868	journal->j_tail_sequence = ntohl(jsb->s_sequence);
1869	journal->j_transaction_sequence = journal->j_tail_sequence;
1870	journal->j_tail = ntohl(jsb->s_start);
1871	journal->j_first = ntohl(jsb->s_first);
1872	journal->j_last = ntohl(jsb->s_maxlen);
1873
1874	return 0;
1875}
1876
1877static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
1878				       journal_t *journal)
1879{
1880	char *p;
1881	union {
1882		uuid_t uuid;
1883		__u32 val[4];
1884	} u;
1885	__u32 new_seq = 0;
1886	int i;
1887
1888	/* Leave a valid existing V1 superblock signature alone.
1889	 * Anything unrecognisable we overwrite with a new V2
1890	 * signature. */
1891
1892	if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
1893	    jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
1894		jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
1895		jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
1896	}
1897
1898	/* Zero out everything else beyond the superblock header */
1899
1900	p = ((char *) jsb) + sizeof(journal_header_t);
1901	memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
1902
1903	jsb->s_blocksize = htonl(ctx->fs->blocksize);
1904	jsb->s_maxlen = htonl(journal->j_maxlen);
1905	jsb->s_first = htonl(1);
1906
1907	/* Initialize the journal sequence number so that there is "no"
1908	 * chance we will find old "valid" transactions in the journal.
1909	 * This avoids the need to zero the whole journal (slow to do,
1910	 * and risky when we are just recovering the filesystem).
1911	 */
1912	uuid_generate(u.uuid);
1913	for (i = 0; i < 4; i ++)
1914		new_seq ^= u.val[i];
1915	jsb->s_sequence = htonl(new_seq);
1916
1917	mark_buffer_dirty(journal->j_sb_buffer);
1918	ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
1919}
1920
1921static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
1922						  journal_t *journal,
1923						  struct problem_context *pctx)
1924{
1925	struct ext2_super_block *sb = ctx->fs->super;
1926	int recover = ctx->fs->super->s_feature_incompat &
1927		EXT3_FEATURE_INCOMPAT_RECOVER;
1928
1929	if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
1930		if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
1931			e2fsck_journal_reset_super(ctx, journal->j_superblock,
1932						   journal);
1933			journal->j_transaction_sequence = 1;
1934			e2fsck_clear_recover(ctx, recover);
1935			return 0;
1936		}
1937		return EXT2_ET_CORRUPT_SUPERBLOCK;
1938	} else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
1939		return EXT2_ET_CORRUPT_SUPERBLOCK;
1940
1941	return 0;
1942}
1943
1944static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
1945				   int reset, int drop)
1946{
1947	journal_superblock_t *jsb;
1948
1949	if (drop)
1950		mark_buffer_clean(journal->j_sb_buffer);
1951	else if (!(ctx->options & E2F_OPT_READONLY)) {
1952		jsb = journal->j_superblock;
1953		jsb->s_sequence = htonl(journal->j_transaction_sequence);
1954		if (reset)
1955			jsb->s_start = 0; /* this marks the journal as empty */
1956		mark_buffer_dirty(journal->j_sb_buffer);
1957	}
1958	brelse(journal->j_sb_buffer);
1959
1960	if (ctx->journal_io) {
1961		if (ctx->fs && ctx->fs->io != ctx->journal_io)
1962			io_channel_close(ctx->journal_io);
1963		ctx->journal_io = 0;
1964	}
1965
1966#ifndef USE_INODE_IO
1967	ext2fs_free_mem(&journal->j_inode);
1968#endif
1969	ext2fs_free_mem(&journal->j_fs_dev);
1970	ext2fs_free_mem(&journal);
1971}
1972
1973/*
1974 * This function makes sure that the superblock fields regarding the
1975 * journal are consistent.
1976 */
1977static int e2fsck_check_ext3_journal(e2fsck_t ctx)
1978{
1979	struct ext2_super_block *sb = ctx->fs->super;
1980	journal_t *journal;
1981	int recover = ctx->fs->super->s_feature_incompat &
1982		EXT3_FEATURE_INCOMPAT_RECOVER;
1983	struct problem_context pctx;
1984	problem_t problem;
1985	int reset = 0, force_fsck = 0;
1986	int retval;
1987
1988	/* If we don't have any journal features, don't do anything more */
1989	if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
1990	    !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
1991	    uuid_is_null(sb->s_journal_uuid))
1992		return 0;
1993
1994	clear_problem_context(&pctx);
1995	pctx.num = sb->s_journal_inum;
1996
1997	retval = e2fsck_get_journal(ctx, &journal);
1998	if (retval) {
1999		if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2000		    (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2001		    (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2002		    (retval == EXT2_ET_NO_JOURNAL))
2003			return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2004		return retval;
2005	}
2006
2007	retval = e2fsck_journal_load(journal);
2008	if (retval) {
2009		if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2010		    ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2011		    (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2012				  &pctx))) ||
2013		    ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2014		    (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2015				  &pctx))) ||
2016		    ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2017		    (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2018			retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2019								  &pctx);
2020		e2fsck_journal_release(ctx, journal, 0, 1);
2021		return retval;
2022	}
2023
2024	/*
2025	 * We want to make the flags consistent here.  We will not leave with
2026	 * needs_recovery set but has_journal clear.  We can't get in a loop
2027	 * with -y, -n, or -p, only if a user isn't making up their mind.
2028	 */
2029no_has_journal:
2030	if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2031		recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2032		pctx.str = "inode";
2033		if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2034			if (recover &&
2035			    !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2036				goto no_has_journal;
2037			/*
2038			 * Need a full fsck if we are releasing a
2039			 * journal stored on a reserved inode.
2040			 */
2041			force_fsck = recover ||
2042				(sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2043			/* Clear all of the journal fields */
2044			sb->s_journal_inum = 0;
2045			sb->s_journal_dev = 0;
2046			memset(sb->s_journal_uuid, 0,
2047			       sizeof(sb->s_journal_uuid));
2048			e2fsck_clear_recover(ctx, force_fsck);
2049		} else if (!(ctx->options & E2F_OPT_READONLY)) {
2050			sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2051			ext2fs_mark_super_dirty(ctx->fs);
2052		}
2053	}
2054
2055	if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2056	    !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2057	    journal->j_superblock->s_start != 0) {
2058		/* Print status information */
2059		fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2060		if (ctx->superblock)
2061			problem = PR_0_JOURNAL_RUN_DEFAULT;
2062		else
2063			problem = PR_0_JOURNAL_RUN;
2064		if (fix_problem(ctx, problem, &pctx)) {
2065			ctx->options |= E2F_OPT_FORCE;
2066			sb->s_feature_incompat |=
2067				EXT3_FEATURE_INCOMPAT_RECOVER;
2068			ext2fs_mark_super_dirty(ctx->fs);
2069		} else if (fix_problem(ctx,
2070				       PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2071			reset = 1;
2072			sb->s_state &= ~EXT2_VALID_FS;
2073			ext2fs_mark_super_dirty(ctx->fs);
2074		}
2075	}
2076
2077	e2fsck_journal_release(ctx, journal, reset, 0);
2078	return retval;
2079}
2080
2081static errcode_t recover_ext3_journal(e2fsck_t ctx)
2082{
2083	journal_t *journal;
2084	int retval;
2085
2086	journal_init_revoke_caches();
2087	retval = e2fsck_get_journal(ctx, &journal);
2088	if (retval)
2089		return retval;
2090
2091	retval = e2fsck_journal_load(journal);
2092	if (retval)
2093		goto errout;
2094
2095	retval = journal_init_revoke(journal, 1024);
2096	if (retval)
2097		goto errout;
2098
2099	retval = -journal_recover(journal);
2100	if (retval)
2101		goto errout;
2102
2103	if (journal->j_superblock->s_errno) {
2104		ctx->fs->super->s_state |= EXT2_ERROR_FS;
2105		ext2fs_mark_super_dirty(ctx->fs);
2106		journal->j_superblock->s_errno = 0;
2107		mark_buffer_dirty(journal->j_sb_buffer);
2108	}
2109
2110errout:
2111	journal_destroy_revoke(journal);
2112	journal_destroy_revoke_caches();
2113	e2fsck_journal_release(ctx, journal, 1, 0);
2114	return retval;
2115}
2116
2117static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2118{
2119	io_manager io_ptr = ctx->fs->io->manager;
2120	int blocksize = ctx->fs->blocksize;
2121	errcode_t       retval, recover_retval;
2122
2123	printf(_("%s: recovering journal\n"), ctx->device_name);
2124	if (ctx->options & E2F_OPT_READONLY) {
2125		printf(_("%s: won't do journal recovery while read-only\n"),
2126		       ctx->device_name);
2127		return EXT2_ET_FILE_RO;
2128	}
2129
2130	if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2131		ext2fs_flush(ctx->fs);  /* Force out any modifications */
2132
2133	recover_retval = recover_ext3_journal(ctx);
2134
2135	/*
2136	 * Reload the filesystem context to get up-to-date data from disk
2137	 * because journal recovery will change the filesystem under us.
2138	 */
2139	ext2fs_close(ctx->fs);
2140	retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2141			     ctx->superblock, blocksize, io_ptr,
2142			     &ctx->fs);
2143
2144	if (retval) {
2145		bb_error_msg(_("while trying to re-open %s"),
2146			ctx->device_name);
2147		bb_error_msg_and_die(0);
2148	}
2149	ctx->fs->priv_data = ctx;
2150
2151	/* Set the superblock flags */
2152	e2fsck_clear_recover(ctx, recover_retval);
2153	return recover_retval;
2154}
2155
2156/*
2157 * This function will move the journal inode from a visible file in
2158 * the filesystem directory hierarchy to the reserved inode if necessary.
2159 */
2160static const char *const journal_names[] = {
2161	".journal", "journal", ".journal.dat", "journal.dat", 0 };
2162
2163static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2164{
2165	struct ext2_super_block *sb = ctx->fs->super;
2166	struct problem_context  pctx;
2167	struct ext2_inode       inode;
2168	ext2_filsys             fs = ctx->fs;
2169	ext2_ino_t              ino;
2170	errcode_t               retval;
2171	const char *const *    cpp;
2172	int                     group, mount_flags;
2173
2174	clear_problem_context(&pctx);
2175
2176	/*
2177	 * If the filesystem is opened read-only, or there is no
2178	 * journal, then do nothing.
2179	 */
2180	if ((ctx->options & E2F_OPT_READONLY) ||
2181	    (sb->s_journal_inum == 0) ||
2182	    !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2183		return;
2184
2185	/*
2186	 * Read in the journal inode
2187	 */
2188	if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2189		return;
2190
2191	/*
2192	 * If it's necessary to backup the journal inode, do so.
2193	 */
2194	if ((sb->s_jnl_backup_type == 0) ||
2195	    ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2196	     memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2197		if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2198			memcpy(sb->s_jnl_blocks, inode.i_block,
2199			       EXT2_N_BLOCKS*4);
2200			sb->s_jnl_blocks[16] = inode.i_size;
2201			sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2202			ext2fs_mark_super_dirty(fs);
2203			fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2204		}
2205	}
2206
2207	/*
2208	 * If the journal is already the hidden inode, then do nothing
2209	 */
2210	if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2211		return;
2212
2213	/*
2214	 * The journal inode had better have only one link and not be readable.
2215	 */
2216	if (inode.i_links_count != 1)
2217		return;
2218
2219	/*
2220	 * If the filesystem is mounted, or we can't tell whether
2221	 * or not it's mounted, do nothing.
2222	 */
2223	retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2224	if (retval || (mount_flags & EXT2_MF_MOUNTED))
2225		return;
2226
2227	/*
2228	 * If we can't find the name of the journal inode, then do
2229	 * nothing.
2230	 */
2231	for (cpp = journal_names; *cpp; cpp++) {
2232		retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2233				       strlen(*cpp), 0, &ino);
2234		if ((retval == 0) && (ino == sb->s_journal_inum))
2235			break;
2236	}
2237	if (*cpp == 0)
2238		return;
2239
2240	/* We need the inode bitmap to be loaded */
2241	retval = ext2fs_read_bitmaps(fs);
2242	if (retval)
2243		return;
2244
2245	pctx.str = *cpp;
2246	if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2247		return;
2248
2249	/*
2250	 * OK, we've done all the checks, let's actually move the
2251	 * journal inode.  Errors at this point mean we need to force
2252	 * an ext2 filesystem check.
2253	 */
2254	if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2255		goto err_out;
2256	if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2257		goto err_out;
2258	sb->s_journal_inum = EXT2_JOURNAL_INO;
2259	ext2fs_mark_super_dirty(fs);
2260	fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2261	inode.i_links_count = 0;
2262	inode.i_dtime = time(0);
2263	if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2264		goto err_out;
2265
2266	group = ext2fs_group_of_ino(fs, ino);
2267	ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2268	ext2fs_mark_ib_dirty(fs);
2269	fs->group_desc[group].bg_free_inodes_count++;
2270	fs->super->s_free_inodes_count++;
2271	return;
2272
2273err_out:
2274	pctx.errcode = retval;
2275	fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2276	fs->super->s_state &= ~EXT2_VALID_FS;
2277	ext2fs_mark_super_dirty(fs);
2278}
2279
2280/*
2281 * message.c --- print e2fsck messages (with compression)
2282 *
2283 * print_e2fsck_message() prints a message to the user, using
2284 * compression techniques and expansions of abbreviations.
2285 *
2286 * The following % expansions are supported:
2287 *
2288 *      %b      <blk>                   block number
2289 *      %B      <blkcount>              integer
2290 *      %c      <blk2>                  block number
2291 *      %Di     <dirent>->ino           inode number
2292 *      %Dn     <dirent>->name          string
2293 *      %Dr     <dirent>->rec_len
2294 *      %Dl     <dirent>->name_len
2295 *      %Dt     <dirent>->filetype
2296 *      %d      <dir>                   inode number
2297 *      %g      <group>                 integer
2298 *      %i      <ino>                   inode number
2299 *      %Is     <inode> -> i_size
2300 *      %IS     <inode> -> i_extra_isize
2301 *      %Ib     <inode> -> i_blocks
2302 *      %Il     <inode> -> i_links_count
2303 *      %Im     <inode> -> i_mode
2304 *      %IM     <inode> -> i_mtime
2305 *      %IF     <inode> -> i_faddr
2306 *      %If     <inode> -> i_file_acl
2307 *      %Id     <inode> -> i_dir_acl
2308 *      %Iu     <inode> -> i_uid
2309 *      %Ig     <inode> -> i_gid
2310 *      %j      <ino2>                  inode number
2311 *      %m      <com_err error message>
2312 *      %N      <num>
2313 *      %p      ext2fs_get_pathname of directory <ino>
2314 *      %P      ext2fs_get_pathname of <dirent>->ino with <ino2> as
2315 *                      the containing directory.  (If dirent is NULL
2316 *                      then return the pathname of directory <ino2>)
2317 *      %q      ext2fs_get_pathname of directory <dir>
2318 *      %Q      ext2fs_get_pathname of directory <ino> with <dir> as
2319 *                      the containing directory.
2320 *      %s      <str>                   miscellaneous string
2321 *      %S      backup superblock
2322 *      %X      <num> hexadecimal format
2323 *
2324 * The following '@' expansions are supported:
2325 *
2326 *      @a      extended attribute
2327 *      @A      error allocating
2328 *      @b      block
2329 *      @B      bitmap
2330 *      @c      compress
2331 *      @C      conflicts with some other fs block
2332 *      @D      deleted
2333 *      @d      directory
2334 *      @e      entry
2335 *      @E      Entry '%Dn' in %p (%i)
2336 *      @f      filesystem
2337 *      @F      for @i %i (%Q) is
2338 *      @g      group
2339 *      @h      HTREE directory inode
2340 *      @i      inode
2341 *      @I      illegal
2342 *      @j      journal
2343 *      @l      lost+found
2344 *      @L      is a link
2345 *      @m      multiply-claimed
2346 *      @n      invalid
2347 *      @o      orphaned
2348 *      @p      problem in
2349 *      @r      root inode
2350 *      @s      should be
2351 *      @S      superblock
2352 *      @u      unattached
2353 *      @v      device
2354 *      @z      zero-length
2355 */
2356
2357
2358/*
2359 * This structure defines the abbreviations used by the text strings
2360 * below.  The first character in the string is the index letter.  An
2361 * abbreviation of the form '@<i>' is expanded by looking up the index
2362 * letter <i> in the table below.
2363 */
2364static const char *const abbrevs[] = {
2365	N_("aextended attribute"),
2366	N_("Aerror allocating"),
2367	N_("bblock"),
2368	N_("Bbitmap"),
2369	N_("ccompress"),
2370	N_("Cconflicts with some other fs @b"),
2371	N_("iinode"),
2372	N_("Iillegal"),
2373	N_("jjournal"),
2374	N_("Ddeleted"),
2375	N_("ddirectory"),
2376	N_("eentry"),
2377	N_("E@e '%Dn' in %p (%i)"),
2378	N_("ffilesystem"),
2379	N_("Ffor @i %i (%Q) is"),
2380	N_("ggroup"),
2381	N_("hHTREE @d @i"),
2382	N_("llost+found"),
2383	N_("Lis a link"),
2384    N_("mmultiply-claimed"),
2385    N_("ninvalid"),
2386	N_("oorphaned"),
2387	N_("pproblem in"),
2388	N_("rroot @i"),
2389	N_("sshould be"),
2390	N_("Ssuper@b"),
2391	N_("uunattached"),
2392	N_("vdevice"),
2393	N_("zzero-length"),
2394	"@@",
2395	0
2396	};
2397
2398/*
2399 * Give more user friendly names to the "special" inodes.
2400 */
2401#define num_special_inodes      11
2402static const char *const special_inode_name[] =
2403{
2404	N_("<The NULL inode>"),                 /* 0 */
2405	N_("<The bad blocks inode>"),           /* 1 */
2406	"/",                                    /* 2 */
2407	N_("<The ACL index inode>"),            /* 3 */
2408	N_("<The ACL data inode>"),             /* 4 */
2409	N_("<The boot loader inode>"),          /* 5 */
2410	N_("<The undelete directory inode>"),   /* 6 */
2411	N_("<The group descriptor inode>"),     /* 7 */
2412	N_("<The journal inode>"),              /* 8 */
2413	N_("<Reserved inode 9>"),               /* 9 */
2414	N_("<Reserved inode 10>"),              /* 10 */
2415};
2416
2417/*
2418 * This function does "safe" printing.  It will convert non-printable
2419 * ASCII characters using '^' and M- notation.
2420 */
2421static void safe_print(const char *cp, int len)
2422{
2423	unsigned char   ch;
2424
2425	if (len < 0)
2426		len = strlen(cp);
2427
2428	while (len--) {
2429		ch = *cp++;
2430		if (ch > 128) {
2431			fputs("M-", stdout);
2432			ch -= 128;
2433		}
2434		if ((ch < 32) || (ch == 0x7f)) {
2435			fputc('^', stdout);
2436			ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2437		}
2438		fputc(ch, stdout);
2439	}
2440}
2441
2442
2443/*
2444 * This function prints a pathname, using the ext2fs_get_pathname
2445 * function
2446 */
2447static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2448{
2449	errcode_t       retval;
2450	char            *path;
2451
2452	if (!dir && (ino < num_special_inodes)) {
2453		fputs(_(special_inode_name[ino]), stdout);
2454		return;
2455	}
2456
2457	retval = ext2fs_get_pathname(fs, dir, ino, &path);
2458	if (retval)
2459		fputs("???", stdout);
2460	else {
2461		safe_print(path, -1);
2462		ext2fs_free_mem(&path);
2463	}
2464}
2465
2466static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2467			  struct problem_context *pctx, int first);
2468/*
2469 * This function handles the '@' expansion.  We allow recursive
2470 * expansion; an @ expression can contain further '@' and '%'
2471 * expressions.
2472 */
2473static void expand_at_expression(e2fsck_t ctx, char ch,
2474					  struct problem_context *pctx,
2475					  int *first)
2476{
2477	const char *const *cpp;
2478	const char *str;
2479
2480	/* Search for the abbreviation */
2481	for (cpp = abbrevs; *cpp; cpp++) {
2482		if (ch == *cpp[0])
2483			break;
2484	}
2485	if (*cpp) {
2486		str = _(*cpp) + 1;
2487		if (*first && islower(*str)) {
2488			*first = 0;
2489			fputc(toupper(*str++), stdout);
2490		}
2491		print_e2fsck_message(ctx, str, pctx, *first);
2492	} else
2493		printf("@%c", ch);
2494}
2495
2496/*
2497 * This function expands '%IX' expressions
2498 */
2499static void expand_inode_expression(char ch,
2500					     struct problem_context *ctx)
2501{
2502	struct ext2_inode       *inode;
2503	struct ext2_inode_large *large_inode;
2504	char *                  time_str;
2505	time_t                  t;
2506	int                     do_gmt = -1;
2507
2508	if (!ctx || !ctx->inode)
2509		goto no_inode;
2510
2511	inode = ctx->inode;
2512	large_inode = (struct ext2_inode_large *) inode;
2513
2514	switch (ch) {
2515	case 's':
2516		if (LINUX_S_ISDIR(inode->i_mode))
2517			printf("%u", inode->i_size);
2518		else {
2519			printf("%"PRIu64, (inode->i_size |
2520					((uint64_t) inode->i_size_high << 32)));
2521		}
2522		break;
2523	case 'S':
2524		printf("%u", large_inode->i_extra_isize);
2525		break;
2526	case 'b':
2527		printf("%u", inode->i_blocks);
2528		break;
2529	case 'l':
2530		printf("%d", inode->i_links_count);
2531		break;
2532	case 'm':
2533		printf("0%o", inode->i_mode);
2534		break;
2535	case 'M':
2536		/* The diet libc doesn't respect the TZ environemnt variable */
2537		if (do_gmt == -1) {
2538			time_str = getenv("TZ");
2539			if (!time_str)
2540				time_str = "";
2541			do_gmt = !strcmp(time_str, "GMT");
2542		}
2543		t = inode->i_mtime;
2544		time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2545		printf("%.24s", time_str);
2546		break;
2547	case 'F':
2548		printf("%u", inode->i_faddr);
2549		break;
2550	case 'f':
2551		printf("%u", inode->i_file_acl);
2552		break;
2553	case 'd':
2554		printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2555			      inode->i_dir_acl : 0));
2556		break;
2557	case 'u':
2558		printf("%d", (inode->i_uid |
2559			      (inode->osd2.linux2.l_i_uid_high << 16)));
2560		break;
2561	case 'g':
2562		printf("%d", (inode->i_gid |
2563			      (inode->osd2.linux2.l_i_gid_high << 16)));
2564		break;
2565	default:
2566	no_inode:
2567		printf("%%I%c", ch);
2568		break;
2569	}
2570}
2571
2572/*
2573 * This function expands '%dX' expressions
2574 */
2575static void expand_dirent_expression(char ch,
2576					      struct problem_context *ctx)
2577{
2578	struct ext2_dir_entry   *dirent;
2579	int     len;
2580
2581	if (!ctx || !ctx->dirent)
2582		goto no_dirent;
2583
2584	dirent = ctx->dirent;
2585
2586	switch (ch) {
2587	case 'i':
2588		printf("%u", dirent->inode);
2589		break;
2590	case 'n':
2591		len = dirent->name_len & 0xFF;
2592		if (len > EXT2_NAME_LEN)
2593			len = EXT2_NAME_LEN;
2594		if (len > dirent->rec_len)
2595			len = dirent->rec_len;
2596		safe_print(dirent->name, len);
2597		break;
2598	case 'r':
2599		printf("%u", dirent->rec_len);
2600		break;
2601	case 'l':
2602		printf("%u", dirent->name_len & 0xFF);
2603		break;
2604	case 't':
2605		printf("%u", dirent->name_len >> 8);
2606		break;
2607	default:
2608	no_dirent:
2609		printf("%%D%c", ch);
2610		break;
2611	}
2612}
2613
2614static void expand_percent_expression(ext2_filsys fs, char ch,
2615					       struct problem_context *ctx)
2616{
2617	if (!ctx)
2618		goto no_context;
2619
2620	switch (ch) {
2621	case '%':
2622		fputc('%', stdout);
2623		break;
2624	case 'b':
2625		printf("%u", ctx->blk);
2626		break;
2627	case 'B':
2628		printf("%"PRIi64, ctx->blkcount);
2629		break;
2630	case 'c':
2631		printf("%u", ctx->blk2);
2632		break;
2633	case 'd':
2634		printf("%u", ctx->dir);
2635		break;
2636	case 'g':
2637		printf("%d", ctx->group);
2638		break;
2639	case 'i':
2640		printf("%u", ctx->ino);
2641		break;
2642	case 'j':
2643		printf("%u", ctx->ino2);
2644		break;
2645	case 'm':
2646		printf("%s", error_message(ctx->errcode));
2647		break;
2648	case 'N':
2649		printf("%"PRIi64, ctx->num);
2650		break;
2651	case 'p':
2652		print_pathname(fs, ctx->ino, 0);
2653		break;
2654	case 'P':
2655		print_pathname(fs, ctx->ino2,
2656			       ctx->dirent ? ctx->dirent->inode : 0);
2657		break;
2658	case 'q':
2659		print_pathname(fs, ctx->dir, 0);
2660		break;
2661	case 'Q':
2662		print_pathname(fs, ctx->dir, ctx->ino);
2663		break;
2664	case 'S':
2665		printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2666		break;
2667	case 's':
2668		printf("%s", ctx->str ? ctx->str : "NULL");
2669		break;
2670	case 'X':
2671		printf("0x%"PRIi64, ctx->num);
2672		break;
2673	default:
2674	no_context:
2675		printf("%%%c", ch);
2676		break;
2677	}
2678}
2679
2680
2681static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2682			  struct problem_context *pctx, int first)
2683{
2684	ext2_filsys fs = ctx->fs;
2685	const char *    cp;
2686	int             i;
2687
2688	e2fsck_clear_progbar(ctx);
2689	for (cp = msg; *cp; cp++) {
2690		if (cp[0] == '@') {
2691			cp++;
2692			expand_at_expression(ctx, *cp, pctx, &first);
2693		} else if (cp[0] == '%' && cp[1] == 'I') {
2694			cp += 2;
2695			expand_inode_expression(*cp, pctx);
2696		} else if (cp[0] == '%' && cp[1] == 'D') {
2697			cp += 2;
2698			expand_dirent_expression(*cp, pctx);
2699		} else if ((cp[0] == '%')) {
2700			cp++;
2701			expand_percent_expression(fs, *cp, pctx);
2702		} else {
2703			for (i=0; cp[i]; i++)
2704				if ((cp[i] == '@') || cp[i] == '%')
2705					break;
2706			printf("%.*s", i, cp);
2707			cp += i-1;
2708		}
2709		first = 0;
2710	}
2711}
2712
2713
2714/*
2715 * region.c --- code which manages allocations within a region.
2716 */
2717
2718struct region_el {
2719	region_addr_t   start;
2720	region_addr_t   end;
2721	struct region_el *next;
2722};
2723
2724struct region_struct {
2725	region_addr_t   min;
2726	region_addr_t   max;
2727	struct region_el *allocated;
2728};
2729
2730static region_t region_create(region_addr_t min, region_addr_t max)
2731{
2732	region_t        region;
2733
2734	region = malloc(sizeof(struct region_struct));
2735	if (!region)
2736		return NULL;
2737	memset(region, 0, sizeof(struct region_struct));
2738	region->min = min;
2739	region->max = max;
2740	return region;
2741}
2742
2743static void region_free(region_t region)
2744{
2745	struct region_el        *r, *next;
2746
2747	for (r = region->allocated; r; r = next) {
2748		next = r->next;
2749		free(r);
2750	}
2751	memset(region, 0, sizeof(struct region_struct));
2752	free(region);
2753}
2754
2755static int region_allocate(region_t region, region_addr_t start, int n)
2756{
2757	struct region_el        *r, *new_region, *prev, *next;
2758	region_addr_t end;
2759
2760	end = start+n;
2761	if ((start < region->min) || (end > region->max))
2762		return -1;
2763	if (n == 0)
2764		return 1;
2765
2766	/*
2767	 * Search through the linked list.  If we find that it
2768	 * conflicts witih something that's already allocated, return
2769	 * 1; if we can find an existing region which we can grow, do
2770	 * so.  Otherwise, stop when we find the appropriate place
2771	 * insert a new region element into the linked list.
2772	 */
2773	for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2774		if (((start >= r->start) && (start < r->end)) ||
2775		    ((end > r->start) && (end <= r->end)) ||
2776		    ((start <= r->start) && (end >= r->end)))
2777			return 1;
2778		if (end == r->start) {
2779			r->start = start;
2780			return 0;
2781		}
2782		if (start == r->end) {
2783			if ((next = r->next)) {
2784				if (end > next->start)
2785					return 1;
2786				if (end == next->start) {
2787					r->end = next->end;
2788					r->next = next->next;
2789					free(next);
2790					return 0;
2791				}
2792			}
2793			r->end = end;
2794			return 0;
2795		}
2796		if (start < r->start)
2797			break;
2798	}
2799	/*
2800	 * Insert a new region element structure into the linked list
2801	 */
2802	new_region = malloc(sizeof(struct region_el));
2803	if (!new_region)
2804		return -1;
2805	new_region->start = start;
2806	new_region->end = start + n;
2807	new_region->next = r;
2808	if (prev)
2809		prev->next = new_region;
2810	else
2811		region->allocated = new_region;
2812	return 0;
2813}
2814
2815/*
2816 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2817 *
2818 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2819 * and applies the following tests to each inode:
2820 *
2821 *      - The mode field of the inode must be legal.
2822 *      - The size and block count fields of the inode are correct.
2823 *      - A data block must not be used by another inode
2824 *
2825 * Pass 1 also gathers the collects the following information:
2826 *
2827 *      - A bitmap of which inodes are in use.          (inode_used_map)
2828 *      - A bitmap of which inodes are directories.     (inode_dir_map)
2829 *      - A bitmap of which inodes are regular files.   (inode_reg_map)
2830 *      - A bitmap of which inodes have bad fields.     (inode_bad_map)
2831 *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
2832 *      - A bitmap of which blocks are in use.          (block_found_map)
2833 *      - A bitmap of which blocks are in use by two inodes     (block_dup_map)
2834 *      - The data blocks of the directory inodes.      (dir_map)
2835 *
2836 * Pass 1 is designed to stash away enough information so that the
2837 * other passes should not need to read in the inode information
2838 * during the normal course of a filesystem check.  (Althogh if an
2839 * inconsistency is detected, other passes may need to read in an
2840 * inode to fix it.)
2841 *
2842 * Note that pass 1B will be invoked if there are any duplicate blocks
2843 * found.
2844 */
2845
2846
2847static int process_block(ext2_filsys fs, blk_t  *blocknr,
2848			 e2_blkcnt_t blockcnt, blk_t ref_blk,
2849			 int ref_offset, void *priv_data);
2850static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2851			     e2_blkcnt_t blockcnt, blk_t ref_blk,
2852			     int ref_offset, void *priv_data);
2853static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2854			 char *block_buf);
2855static void mark_table_blocks(e2fsck_t ctx);
2856static void alloc_imagic_map(e2fsck_t ctx);
2857static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2858static void handle_fs_bad_blocks(e2fsck_t ctx);
2859static void process_inodes(e2fsck_t ctx, char *block_buf);
2860static int process_inode_cmp(const void *a, const void *b);
2861static errcode_t scan_callback(ext2_filsys fs,
2862				  dgrp_t group, void * priv_data);
2863static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2864				    char *block_buf, int adjust_sign);
2865/* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2866
2867static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2868			       struct ext2_inode * inode, int bufsize,
2869			       const char *proc);
2870
2871struct process_block_struct_1 {
2872	ext2_ino_t      ino;
2873	unsigned        is_dir:1, is_reg:1, clear:1, suppress:1,
2874				fragmented:1, compressed:1, bbcheck:1;
2875	blk_t           num_blocks;
2876	blk_t           max_blocks;
2877	e2_blkcnt_t     last_block;
2878	int             num_illegal_blocks;
2879	blk_t           previous_block;
2880	struct ext2_inode *inode;
2881	struct problem_context *pctx;
2882	ext2fs_block_bitmap fs_meta_blocks;
2883	e2fsck_t        ctx;
2884};
2885
2886struct process_inode_block {
2887	ext2_ino_t ino;
2888	struct ext2_inode inode;
2889};
2890
2891struct scan_callback_struct {
2892	e2fsck_t        ctx;
2893	char            *block_buf;
2894};
2895
2896/*
2897 * For the inodes to process list.
2898 */
2899static struct process_inode_block *inodes_to_process;
2900static int process_inode_count;
2901
2902static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2903			    EXT2_MIN_BLOCK_LOG_SIZE + 1];
2904
2905/*
2906 * Free all memory allocated by pass1 in preparation for restarting
2907 * things.
2908 */
2909static void unwind_pass1(void)
2910{
2911	ext2fs_free_mem(&inodes_to_process);
2912}
2913
2914/*
2915 * Check to make sure a device inode is real.  Returns 1 if the device
2916 * checks out, 0 if not.
2917 *
2918 * Note: this routine is now also used to check FIFO's and Sockets,
2919 * since they have the same requirement; the i_block fields should be
2920 * zero.
2921 */
2922static int
2923e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2924{
2925	int     i;
2926
2927	/*
2928	 * If i_blocks is non-zero, or the index flag is set, then
2929	 * this is a bogus device/fifo/socket
2930	 */
2931	if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2932	    (inode->i_flags & EXT2_INDEX_FL))
2933		return 0;
2934
2935	/*
2936	 * We should be able to do the test below all the time, but
2937	 * because the kernel doesn't forcibly clear the device
2938	 * inode's additional i_block fields, there are some rare
2939	 * occasions when a legitimate device inode will have non-zero
2940	 * additional i_block fields.  So for now, we only complain
2941	 * when the immutable flag is set, which should never happen
2942	 * for devices.  (And that's when the problem is caused, since
2943	 * you can't set or clear immutable flags for devices.)  Once
2944	 * the kernel has been fixed we can change this...
2945	 */
2946	if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2947		for (i=4; i < EXT2_N_BLOCKS; i++)
2948			if (inode->i_block[i])
2949				return 0;
2950	}
2951	return 1;
2952}
2953
2954/*
2955 * Check to make sure a symlink inode is real.  Returns 1 if the symlink
2956 * checks out, 0 if not.
2957 */
2958static int
2959e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
2960{
2961	unsigned int len;
2962	int i;
2963	blk_t   blocks;
2964
2965	if ((inode->i_size_high || inode->i_size == 0) ||
2966	    (inode->i_flags & EXT2_INDEX_FL))
2967		return 0;
2968
2969	blocks = ext2fs_inode_data_blocks(fs, inode);
2970	if (blocks) {
2971		if ((inode->i_size >= fs->blocksize) ||
2972		    (blocks != fs->blocksize >> 9) ||
2973		    (inode->i_block[0] < fs->super->s_first_data_block) ||
2974		    (inode->i_block[0] >= fs->super->s_blocks_count))
2975			return 0;
2976
2977		for (i = 1; i < EXT2_N_BLOCKS; i++)
2978			if (inode->i_block[i])
2979				return 0;
2980
2981		if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
2982			return 0;
2983
2984		len = strnlen(buf, fs->blocksize);
2985		if (len == fs->blocksize)
2986			return 0;
2987	} else {
2988		if (inode->i_size >= sizeof(inode->i_block))
2989			return 0;
2990
2991		len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
2992		if (len == sizeof(inode->i_block))
2993			return 0;
2994	}
2995	if (len != inode->i_size)
2996		return 0;
2997	return 1;
2998}
2999
3000/*
3001 * If the immutable (or append-only) flag is set on the inode, offer
3002 * to clear it.
3003 */
3004#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3005static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3006{
3007	if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3008		return;
3009
3010	if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3011		return;
3012
3013	pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3014	e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3015}
3016
3017/*
3018 * If device, fifo or socket, check size is zero -- if not offer to
3019 * clear it
3020 */
3021static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3022{
3023	struct ext2_inode *inode = pctx->inode;
3024
3025	if ((inode->i_size == 0) && (inode->i_size_high == 0))
3026		return;
3027
3028	if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3029		return;
3030
3031	inode->i_size = 0;
3032	inode->i_size_high = 0;
3033	e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3034}
3035
3036static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3037{
3038	struct ext2_super_block *sb = ctx->fs->super;
3039	struct ext2_inode_large *inode;
3040	struct ext2_ext_attr_entry *entry;
3041	char *start, *end;
3042	int storage_size, remain, offs;
3043	int problem = 0;
3044
3045	inode = (struct ext2_inode_large *) pctx->inode;
3046	storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3047		inode->i_extra_isize;
3048	start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3049		inode->i_extra_isize + sizeof(__u32);
3050	end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3051	entry = (struct ext2_ext_attr_entry *) start;
3052
3053	/* scan all entry's headers first */
3054
3055	/* take finish entry 0UL into account */
3056	remain = storage_size - sizeof(__u32);
3057	offs = end - start;
3058
3059	while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3060
3061		/* header eats this space */
3062		remain -= sizeof(struct ext2_ext_attr_entry);
3063
3064		/* is attribute name valid? */
3065		if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3066			pctx->num = entry->e_name_len;
3067			problem = PR_1_ATTR_NAME_LEN;
3068			goto fix;
3069		}
3070
3071		/* attribute len eats this space */
3072		remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3073
3074		/* check value size */
3075		if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3076			pctx->num = entry->e_value_size;
3077			problem = PR_1_ATTR_VALUE_SIZE;
3078			goto fix;
3079		}
3080
3081		/* check value placement */
3082		if (entry->e_value_offs +
3083		    EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3084			printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3085			pctx->num = entry->e_value_offs;
3086			problem = PR_1_ATTR_VALUE_OFFSET;
3087			goto fix;
3088		}
3089
3090		/* e_value_block must be 0 in inode's ea */
3091		if (entry->e_value_block != 0) {
3092			pctx->num = entry->e_value_block;
3093			problem = PR_1_ATTR_VALUE_BLOCK;
3094			goto fix;
3095		}
3096
3097		/* e_hash must be 0 in inode's ea */
3098		if (entry->e_hash != 0) {
3099			pctx->num = entry->e_hash;
3100			problem = PR_1_ATTR_HASH;
3101			goto fix;
3102		}
3103
3104		remain -= entry->e_value_size;
3105		offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3106
3107		entry = EXT2_EXT_ATTR_NEXT(entry);
3108	}
3109fix:
3110	/*
3111	 * it seems like a corruption. it's very unlikely we could repair
3112	 * EA(s) in automatic fashion -bzzz
3113	 */
3114	if (problem == 0 || !fix_problem(ctx, problem, pctx))
3115		return;
3116
3117	/* simple remove all possible EA(s) */
3118	*((__u32 *)start) = 0UL;
3119	e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3120				EXT2_INODE_SIZE(sb), "pass1");
3121}
3122
3123static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3124{
3125	struct ext2_super_block *sb = ctx->fs->super;
3126	struct ext2_inode_large *inode;
3127	__u32 *eamagic;
3128	int min, max;
3129
3130	inode = (struct ext2_inode_large *) pctx->inode;
3131	if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3132		/* this isn't large inode. so, nothing to check */
3133		return;
3134	}
3135
3136	/* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3137	min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3138	max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3139	/*
3140	 * For now we will allow i_extra_isize to be 0, but really
3141	 * implementations should never allow i_extra_isize to be 0
3142	 */
3143	if (inode->i_extra_isize &&
3144	    (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3145		if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3146			return;
3147		inode->i_extra_isize = min;
3148		e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3149					EXT2_INODE_SIZE(sb), "pass1");
3150		return;
3151	}
3152
3153	eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3154			inode->i_extra_isize);
3155	if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3156		/* it seems inode has an extended attribute(s) in body */
3157		check_ea_in_inode(ctx, pctx);
3158	}
3159}
3160
3161static void e2fsck_pass1(e2fsck_t ctx)
3162{
3163	int     i;
3164	__u64   max_sizes;
3165	ext2_filsys fs = ctx->fs;
3166	ext2_ino_t      ino;
3167	struct ext2_inode *inode;
3168	ext2_inode_scan scan;
3169	char            *block_buf;
3170	unsigned char   frag, fsize;
3171	struct          problem_context pctx;
3172	struct          scan_callback_struct scan_struct;
3173	struct ext2_super_block *sb = ctx->fs->super;
3174	int             imagic_fs;
3175	int             busted_fs_time = 0;
3176	int             inode_size;
3177
3178	clear_problem_context(&pctx);
3179
3180	if (!(ctx->options & E2F_OPT_PREEN))
3181		fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3182
3183	if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3184	    !(ctx->options & E2F_OPT_NO)) {
3185		if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3186			ctx->dirs_to_hash = 0;
3187	}
3188
3189	/* Pass 1 */
3190
3191#define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3192
3193	for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3194		max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3195		max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3196		max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3197		max_sizes = (max_sizes * (1UL << i)) - 1;
3198		ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3199	}
3200#undef EXT2_BPP
3201
3202	imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3203
3204	/*
3205	 * Allocate bitmaps structures
3206	 */
3207	pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3208					      &ctx->inode_used_map);
3209	if (pctx.errcode) {
3210		pctx.num = 1;
3211		fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3212		ctx->flags |= E2F_FLAG_ABORT;
3213		return;
3214	}
3215	pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3216				_("directory inode map"), &ctx->inode_dir_map);
3217	if (pctx.errcode) {
3218		pctx.num = 2;
3219		fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3220		ctx->flags |= E2F_FLAG_ABORT;
3221		return;
3222	}
3223	pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3224			_("regular file inode map"), &ctx->inode_reg_map);
3225	if (pctx.errcode) {
3226		pctx.num = 6;
3227		fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3228		ctx->flags |= E2F_FLAG_ABORT;
3229		return;
3230	}
3231	pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3232					      &ctx->block_found_map);
3233	if (pctx.errcode) {
3234		pctx.num = 1;
3235		fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3236		ctx->flags |= E2F_FLAG_ABORT;
3237		return;
3238	}
3239	pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3240					     &ctx->inode_link_info);
3241	if (pctx.errcode) {
3242		fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3243		ctx->flags |= E2F_FLAG_ABORT;
3244		return;
3245	}
3246	inode_size = EXT2_INODE_SIZE(fs->super);
3247	inode = (struct ext2_inode *)
3248		e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3249
3250	inodes_to_process = (struct process_inode_block *)
3251		e2fsck_allocate_memory(ctx,
3252				       (ctx->process_inode_size *
3253					sizeof(struct process_inode_block)),
3254				       "array of inodes to process");
3255	process_inode_count = 0;
3256
3257	pctx.errcode = ext2fs_init_dblist(fs, 0);
3258	if (pctx.errcode) {
3259		fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3260		ctx->flags |= E2F_FLAG_ABORT;
3261		return;
3262	}
3263
3264	/*
3265	 * If the last orphan field is set, clear it, since the pass1
3266	 * processing will automatically find and clear the orphans.
3267	 * In the future, we may want to try using the last_orphan
3268	 * linked list ourselves, but for now, we clear it so that the
3269	 * ext3 mount code won't get confused.
3270	 */
3271	if (!(ctx->options & E2F_OPT_READONLY)) {
3272		if (fs->super->s_last_orphan) {
3273			fs->super->s_last_orphan = 0;
3274			ext2fs_mark_super_dirty(fs);
3275		}
3276	}
3277
3278	mark_table_blocks(ctx);
3279	block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3280						    "block interate buffer");
3281	e2fsck_use_inode_shortcuts(ctx, 1);
3282	ehandler_operation(_("doing inode scan"));
3283	pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3284					      &scan);
3285	if (pctx.errcode) {
3286		fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3287		ctx->flags |= E2F_FLAG_ABORT;
3288		return;
3289	}
3290	ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3291	ctx->stashed_inode = inode;
3292	scan_struct.ctx = ctx;
3293	scan_struct.block_buf = block_buf;
3294	ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3295	if (ctx->progress)
3296		if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3297			return;
3298	if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3299	    (fs->super->s_mtime < fs->super->s_inodes_count))
3300		busted_fs_time = 1;
3301
3302	while (1) {
3303		pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3304							  inode, inode_size);
3305		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3306			return;
3307		if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3308			continue;
3309		}
3310		if (pctx.errcode) {
3311			fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3312			ctx->flags |= E2F_FLAG_ABORT;
3313			return;
3314		}
3315		if (!ino)
3316			break;
3317		pctx.ino = ino;
3318		pctx.inode = inode;
3319		ctx->stashed_ino = ino;
3320		if (inode->i_links_count) {
3321			pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3322					   ino, inode->i_links_count);
3323			if (pctx.errcode) {
3324				pctx.num = inode->i_links_count;
3325				fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3326				ctx->flags |= E2F_FLAG_ABORT;
3327				return;
3328			}
3329		}
3330		if (ino == EXT2_BAD_INO) {
3331			struct process_block_struct_1 pb;
3332
3333			pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3334							  &pb.fs_meta_blocks);
3335			if (pctx.errcode) {
3336				pctx.num = 4;
3337				fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3338				ctx->flags |= E2F_FLAG_ABORT;
3339				return;
3340			}
3341			pb.ino = EXT2_BAD_INO;
3342			pb.num_blocks = pb.last_block = 0;
3343			pb.num_illegal_blocks = 0;
3344			pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3345			pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3346			pb.inode = inode;
3347			pb.pctx = &pctx;
3348			pb.ctx = ctx;
3349			pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3350				     block_buf, process_bad_block, &pb);
3351			ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3352			if (pctx.errcode) {
3353				fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3354				ctx->flags |= E2F_FLAG_ABORT;
3355				return;
3356			}
3357			if (pb.bbcheck)
3358				if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3359				ctx->flags |= E2F_FLAG_ABORT;
3360				return;
3361			}
3362			ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3363			clear_problem_context(&pctx);
3364			continue;
3365		} else if (ino == EXT2_ROOT_INO) {
3366			/*
3367			 * Make sure the root inode is a directory; if
3368			 * not, offer to clear it.  It will be
3369			 * regnerated in pass #3.
3370			 */
3371			if (!LINUX_S_ISDIR(inode->i_mode)) {
3372				if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3373					inode->i_dtime = time(0);
3374					inode->i_links_count = 0;
3375					ext2fs_icount_store(ctx->inode_link_info,
3376							    ino, 0);
3377					e2fsck_write_inode(ctx, ino, inode,
3378							   "pass1");
3379				}
3380
3381			}
3382			/*
3383			 * If dtime is set, offer to clear it.  mke2fs
3384			 * version 0.2b created filesystems with the
3385			 * dtime field set for the root and lost+found
3386			 * directories.  We won't worry about
3387			 * /lost+found, since that can be regenerated
3388			 * easily.  But we will fix the root directory
3389			 * as a special case.
3390			 */
3391			if (inode->i_dtime && inode->i_links_count) {
3392				if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3393					inode->i_dtime = 0;
3394					e2fsck_write_inode(ctx, ino, inode,
3395							   "pass1");
3396				}
3397			}
3398		} else if (ino == EXT2_JOURNAL_INO) {
3399			ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3400			if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3401				if (!LINUX_S_ISREG(inode->i_mode) &&
3402				    fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3403						&pctx)) {
3404					inode->i_mode = LINUX_S_IFREG;
3405					e2fsck_write_inode(ctx, ino, inode,
3406							   "pass1");
3407				}
3408				check_blocks(ctx, &pctx, block_buf);
3409				continue;
3410			}
3411			if ((inode->i_links_count || inode->i_blocks ||
3412			     inode->i_blocks || inode->i_block[0]) &&
3413			    fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3414					&pctx)) {
3415				memset(inode, 0, inode_size);
3416				ext2fs_icount_store(ctx->inode_link_info,
3417						    ino, 0);
3418				e2fsck_write_inode_full(ctx, ino, inode,
3419							inode_size, "pass1");
3420			}
3421		} else if (ino < EXT2_FIRST_INODE(fs->super)) {
3422			int     problem = 0;
3423
3424			ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3425			if (ino == EXT2_BOOT_LOADER_INO) {
3426				if (LINUX_S_ISDIR(inode->i_mode))
3427					problem = PR_1_RESERVED_BAD_MODE;
3428			} else if (ino == EXT2_RESIZE_INO) {
3429				if (inode->i_mode &&
3430				    !LINUX_S_ISREG(inode->i_mode))
3431					problem = PR_1_RESERVED_BAD_MODE;
3432			} else {
3433				if (inode->i_mode != 0)
3434					problem = PR_1_RESERVED_BAD_MODE;
3435			}
3436			if (problem) {
3437				if (fix_problem(ctx, problem, &pctx)) {
3438					inode->i_mode = 0;
3439					e2fsck_write_inode(ctx, ino, inode,
3440							   "pass1");
3441				}
3442			}
3443			check_blocks(ctx, &pctx, block_buf);
3444			continue;
3445		}
3446		if (inode->i_dtime && !busted_fs_time &&
3447		    inode->i_dtime < ctx->fs->super->s_inodes_count) {
3448			if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3449				inode->i_dtime = inode->i_links_count ?
3450					0 : time(0);
3451				e2fsck_write_inode(ctx, ino, inode,
3452						   "pass1");
3453			}
3454		}
3455
3456		/*
3457		 * This code assumes that deleted inodes have
3458		 * i_links_count set to 0.
3459		 */
3460		if (!inode->i_links_count) {
3461			if (!inode->i_dtime && inode->i_mode) {
3462				if (fix_problem(ctx,
3463					    PR_1_ZERO_DTIME, &pctx)) {
3464					inode->i_dtime = time(0);
3465					e2fsck_write_inode(ctx, ino, inode,
3466							   "pass1");
3467				}
3468			}
3469			continue;
3470		}
3471		/*
3472		 * n.b.  0.3c ext2fs code didn't clear i_links_count for
3473		 * deleted files.  Oops.
3474		 *
3475		 * Since all new ext2 implementations get this right,
3476		 * we now assume that the case of non-zero
3477		 * i_links_count and non-zero dtime means that we
3478		 * should keep the file, not delete it.
3479		 *
3480		 */
3481		if (inode->i_dtime) {
3482			if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3483				inode->i_dtime = 0;
3484				e2fsck_write_inode(ctx, ino, inode, "pass1");
3485			}
3486		}
3487
3488		ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3489		switch (fs->super->s_creator_os) {
3490		    case EXT2_OS_LINUX:
3491			frag = inode->osd2.linux2.l_i_frag;
3492			fsize = inode->osd2.linux2.l_i_fsize;
3493			break;
3494		    case EXT2_OS_HURD:
3495			frag = inode->osd2.hurd2.h_i_frag;
3496			fsize = inode->osd2.hurd2.h_i_fsize;
3497			break;
3498		    case EXT2_OS_MASIX:
3499			frag = inode->osd2.masix2.m_i_frag;
3500			fsize = inode->osd2.masix2.m_i_fsize;
3501			break;
3502		    default:
3503			frag = fsize = 0;
3504		}
3505
3506		if (inode->i_faddr || frag || fsize ||
3507		    (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3508			mark_inode_bad(ctx, ino);
3509		if (inode->i_flags & EXT2_IMAGIC_FL) {
3510			if (imagic_fs) {
3511				if (!ctx->inode_imagic_map)
3512					alloc_imagic_map(ctx);
3513				ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3514							 ino);
3515			} else {
3516				if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3517					inode->i_flags &= ~EXT2_IMAGIC_FL;
3518					e2fsck_write_inode(ctx, ino,
3519							   inode, "pass1");
3520				}
3521			}
3522		}
3523
3524		check_inode_extra_space(ctx, &pctx);
3525
3526		if (LINUX_S_ISDIR(inode->i_mode)) {
3527			ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3528			e2fsck_add_dir_info(ctx, ino, 0);
3529			ctx->fs_directory_count++;
3530		} else if (LINUX_S_ISREG (inode->i_mode)) {
3531			ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3532			ctx->fs_regular_count++;
3533		} else if (LINUX_S_ISCHR (inode->i_mode) &&
3534			   e2fsck_pass1_check_device_inode(fs, inode)) {
3535			check_immutable(ctx, &pctx);
3536			check_size(ctx, &pctx);
3537			ctx->fs_chardev_count++;
3538		} else if (LINUX_S_ISBLK (inode->i_mode) &&
3539			   e2fsck_pass1_check_device_inode(fs, inode)) {
3540			check_immutable(ctx, &pctx);
3541			check_size(ctx, &pctx);
3542			ctx->fs_blockdev_count++;
3543		} else if (LINUX_S_ISLNK (inode->i_mode) &&
3544			   e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3545			check_immutable(ctx, &pctx);
3546			ctx->fs_symlinks_count++;
3547			if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3548				ctx->fs_fast_symlinks_count++;
3549				check_blocks(ctx, &pctx, block_buf);
3550				continue;
3551			}
3552		}
3553		else if (LINUX_S_ISFIFO (inode->i_mode) &&
3554			 e2fsck_pass1_check_device_inode(fs, inode)) {
3555			check_immutable(ctx, &pctx);
3556			check_size(ctx, &pctx);
3557			ctx->fs_fifo_count++;
3558		} else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3559			   e2fsck_pass1_check_device_inode(fs, inode)) {
3560			check_immutable(ctx, &pctx);
3561			check_size(ctx, &pctx);
3562			ctx->fs_sockets_count++;
3563		} else
3564			mark_inode_bad(ctx, ino);
3565		if (inode->i_block[EXT2_IND_BLOCK])
3566			ctx->fs_ind_count++;
3567		if (inode->i_block[EXT2_DIND_BLOCK])
3568			ctx->fs_dind_count++;
3569		if (inode->i_block[EXT2_TIND_BLOCK])
3570			ctx->fs_tind_count++;
3571		if (inode->i_block[EXT2_IND_BLOCK] ||
3572		    inode->i_block[EXT2_DIND_BLOCK] ||
3573		    inode->i_block[EXT2_TIND_BLOCK] ||
3574		    inode->i_file_acl) {
3575			inodes_to_process[process_inode_count].ino = ino;
3576			inodes_to_process[process_inode_count].inode = *inode;
3577			process_inode_count++;
3578		} else
3579			check_blocks(ctx, &pctx, block_buf);
3580
3581		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3582			return;
3583
3584		if (process_inode_count >= ctx->process_inode_size) {
3585			process_inodes(ctx, block_buf);
3586
3587			if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3588				return;
3589		}
3590	}
3591	process_inodes(ctx, block_buf);
3592	ext2fs_close_inode_scan(scan);
3593	ehandler_operation(0);
3594
3595	/*
3596	 * If any extended attribute blocks' reference counts need to
3597	 * be adjusted, either up (ctx->refcount_extra), or down
3598	 * (ctx->refcount), then fix them.
3599	 */
3600	if (ctx->refcount) {
3601		adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3602		ea_refcount_free(ctx->refcount);
3603		ctx->refcount = 0;
3604	}
3605	if (ctx->refcount_extra) {
3606		adjust_extattr_refcount(ctx, ctx->refcount_extra,
3607					block_buf, +1);
3608		ea_refcount_free(ctx->refcount_extra);
3609		ctx->refcount_extra = 0;
3610	}
3611
3612	if (ctx->invalid_bitmaps)
3613		handle_fs_bad_blocks(ctx);
3614
3615	/* We don't need the block_ea_map any more */
3616	ext2fs_free_block_bitmap(ctx->block_ea_map);
3617	ctx->block_ea_map = 0;
3618
3619	if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3620		ext2fs_block_bitmap save_bmap;
3621
3622		save_bmap = fs->block_map;
3623		fs->block_map = ctx->block_found_map;
3624		clear_problem_context(&pctx);
3625		pctx.errcode = ext2fs_create_resize_inode(fs);
3626		if (pctx.errcode) {
3627			fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3628			/* Should never get here */
3629			ctx->flags |= E2F_FLAG_ABORT;
3630			return;
3631		}
3632		e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3633				  "recreate inode");
3634		inode->i_mtime = time(0);
3635		e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3636				  "recreate inode");
3637		fs->block_map = save_bmap;
3638		ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3639	}
3640
3641	if (ctx->flags & E2F_FLAG_RESTART) {
3642		/*
3643		 * Only the master copy of the superblock and block
3644		 * group descriptors are going to be written during a
3645		 * restart, so set the superblock to be used to be the
3646		 * master superblock.
3647		 */
3648		ctx->use_superblock = 0;
3649		unwind_pass1();
3650		goto endit;
3651	}
3652
3653	if (ctx->block_dup_map) {
3654		if (ctx->options & E2F_OPT_PREEN) {
3655			clear_problem_context(&pctx);
3656			fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3657		}
3658		e2fsck_pass1_dupblocks(ctx, block_buf);
3659	}
3660	ext2fs_free_mem(&inodes_to_process);
3661endit:
3662	e2fsck_use_inode_shortcuts(ctx, 0);
3663
3664	ext2fs_free_mem(&block_buf);
3665	ext2fs_free_mem(&inode);
3666
3667}
3668
3669/*
3670 * When the inode_scan routines call this callback at the end of the
3671 * glock group, call process_inodes.
3672 */
3673static errcode_t scan_callback(ext2_filsys fs,
3674			       dgrp_t group, void * priv_data)
3675{
3676	struct scan_callback_struct *scan_struct;
3677	e2fsck_t ctx;
3678
3679	scan_struct = (struct scan_callback_struct *) priv_data;
3680	ctx = scan_struct->ctx;
3681
3682	process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3683
3684	if (ctx->progress)
3685		if ((ctx->progress)(ctx, 1, group+1,
3686				    ctx->fs->group_desc_count))
3687			return EXT2_ET_CANCEL_REQUESTED;
3688
3689	return 0;
3690}
3691
3692/*
3693 * Process the inodes in the "inodes to process" list.
3694 */
3695static void process_inodes(e2fsck_t ctx, char *block_buf)
3696{
3697	int                     i;
3698	struct ext2_inode       *old_stashed_inode;
3699	ext2_ino_t              old_stashed_ino;
3700	const char              *old_operation;
3701	char                    buf[80];
3702	struct problem_context  pctx;
3703
3704	/* begin process_inodes */
3705	if (process_inode_count == 0)
3706		return;
3707	old_operation = ehandler_operation(0);
3708	old_stashed_inode = ctx->stashed_inode;
3709	old_stashed_ino = ctx->stashed_ino;
3710	qsort(inodes_to_process, process_inode_count,
3711		      sizeof(struct process_inode_block), process_inode_cmp);
3712	clear_problem_context(&pctx);
3713	for (i=0; i < process_inode_count; i++) {
3714		pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3715		pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3716		sprintf(buf, _("reading indirect blocks of inode %u"),
3717			pctx.ino);
3718		ehandler_operation(buf);
3719		check_blocks(ctx, &pctx, block_buf);
3720		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3721			break;
3722	}
3723	ctx->stashed_inode = old_stashed_inode;
3724	ctx->stashed_ino = old_stashed_ino;
3725	process_inode_count = 0;
3726	/* end process inodes */
3727
3728	ehandler_operation(old_operation);
3729}
3730
3731static int process_inode_cmp(const void *a, const void *b)
3732{
3733	const struct process_inode_block *ib_a =
3734		(const struct process_inode_block *) a;
3735	const struct process_inode_block *ib_b =
3736		(const struct process_inode_block *) b;
3737	int     ret;
3738
3739	ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3740	       ib_b->inode.i_block[EXT2_IND_BLOCK]);
3741	if (ret == 0)
3742		ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3743	return ret;
3744}
3745
3746/*
3747 * Mark an inode as being bad in some what
3748 */
3749static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3750{
3751	struct          problem_context pctx;
3752
3753	if (!ctx->inode_bad_map) {
3754		clear_problem_context(&pctx);
3755
3756		pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3757			    _("bad inode map"), &ctx->inode_bad_map);
3758		if (pctx.errcode) {
3759			pctx.num = 3;
3760			fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3761			/* Should never get here */
3762			ctx->flags |= E2F_FLAG_ABORT;
3763			return;
3764		}
3765	}
3766	ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3767}
3768
3769
3770/*
3771 * This procedure will allocate the inode imagic table
3772 */
3773static void alloc_imagic_map(e2fsck_t ctx)
3774{
3775	struct          problem_context pctx;
3776
3777	clear_problem_context(&pctx);
3778	pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3779					      _("imagic inode map"),
3780					      &ctx->inode_imagic_map);
3781	if (pctx.errcode) {
3782		pctx.num = 5;
3783		fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3784		/* Should never get here */
3785		ctx->flags |= E2F_FLAG_ABORT;
3786		return;
3787	}
3788}
3789
3790/*
3791 * Marks a block as in use, setting the dup_map if it's been set
3792 * already.  Called by process_block and process_bad_block.
3793 *
3794 * WARNING: Assumes checks have already been done to make sure block
3795 * is valid.  This is true in both process_block and process_bad_block.
3796 */
3797static void mark_block_used(e2fsck_t ctx, blk_t block)
3798{
3799	struct          problem_context pctx;
3800
3801	clear_problem_context(&pctx);
3802
3803	if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3804		if (!ctx->block_dup_map) {
3805			pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3806			      _("multiply claimed block map"),
3807			      &ctx->block_dup_map);
3808			if (pctx.errcode) {
3809				pctx.num = 3;
3810				fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3811					    &pctx);
3812				/* Should never get here */
3813				ctx->flags |= E2F_FLAG_ABORT;
3814				return;
3815			}
3816		}
3817		ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3818	} else {
3819		ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3820	}
3821}
3822
3823/*
3824 * Adjust the extended attribute block's reference counts at the end
3825 * of pass 1, either by subtracting out references for EA blocks that
3826 * are still referenced in ctx->refcount, or by adding references for
3827 * EA blocks that had extra references as accounted for in
3828 * ctx->refcount_extra.
3829 */
3830static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3831				    char *block_buf, int adjust_sign)
3832{
3833	struct ext2_ext_attr_header     *header;
3834	struct problem_context          pctx;
3835	ext2_filsys                     fs = ctx->fs;
3836	blk_t                           blk;
3837	__u32                           should_be;
3838	int                             count;
3839
3840	clear_problem_context(&pctx);
3841
3842	ea_refcount_intr_begin(refcount);
3843	while (1) {
3844		if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3845			break;
3846		pctx.blk = blk;
3847		pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3848		if (pctx.errcode) {
3849			fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3850			return;
3851		}
3852		header = (struct ext2_ext_attr_header *) block_buf;
3853		pctx.blkcount = header->h_refcount;
3854		should_be = header->h_refcount + adjust_sign * count;
3855		pctx.num = should_be;
3856		if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3857			header->h_refcount = should_be;
3858			pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3859							     block_buf);
3860			if (pctx.errcode) {
3861				fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3862				continue;
3863			}
3864		}
3865	}
3866}
3867
3868/*
3869 * Handle processing the extended attribute blocks
3870 */
3871static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3872			   char *block_buf)
3873{
3874	ext2_filsys fs = ctx->fs;
3875	ext2_ino_t      ino = pctx->ino;
3876	struct ext2_inode *inode = pctx->inode;
3877	blk_t           blk;
3878	char *          end;
3879	struct ext2_ext_attr_header *header;
3880	struct ext2_ext_attr_entry *entry;
3881	int             count;
3882	region_t        region;
3883
3884	blk = inode->i_file_acl;
3885	if (blk == 0)
3886		return 0;
3887
3888	/*
3889	 * If the Extended attribute flag isn't set, then a non-zero
3890	 * file acl means that the inode is corrupted.
3891	 *
3892	 * Or if the extended attribute block is an invalid block,
3893	 * then the inode is also corrupted.
3894	 */
3895	if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3896	    (blk < fs->super->s_first_data_block) ||
3897	    (blk >= fs->super->s_blocks_count)) {
3898		mark_inode_bad(ctx, ino);
3899		return 0;
3900	}
3901
3902	/* If ea bitmap hasn't been allocated, create it */
3903	if (!ctx->block_ea_map) {
3904		pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3905						      _("ext attr block map"),
3906						      &ctx->block_ea_map);
3907		if (pctx->errcode) {
3908			pctx->num = 2;
3909			fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3910			ctx->flags |= E2F_FLAG_ABORT;
3911			return 0;
3912		}
3913	}
3914
3915	/* Create the EA refcount structure if necessary */
3916	if (!ctx->refcount) {
3917		pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3918		if (pctx->errcode) {
3919			pctx->num = 1;
3920			fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3921			ctx->flags |= E2F_FLAG_ABORT;
3922			return 0;
3923		}
3924	}
3925
3926	/* Have we seen this EA block before? */
3927	if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3928		if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3929			return 1;
3930		/* Ooops, this EA was referenced more than it stated */
3931		if (!ctx->refcount_extra) {
3932			pctx->errcode = ea_refcount_create(0,
3933					   &ctx->refcount_extra);
3934			if (pctx->errcode) {
3935				pctx->num = 2;
3936				fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3937				ctx->flags |= E2F_FLAG_ABORT;
3938				return 0;
3939			}
3940		}
3941		ea_refcount_increment(ctx->refcount_extra, blk, 0);
3942		return 1;
3943	}
3944
3945	/*
3946	 * OK, we haven't seen this EA block yet.  So we need to
3947	 * validate it
3948	 */
3949	pctx->blk = blk;
3950	pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3951	if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
3952		goto clear_extattr;
3953	header = (struct ext2_ext_attr_header *) block_buf;
3954	pctx->blk = inode->i_file_acl;
3955	if (((ctx->ext_attr_ver == 1) &&
3956	     (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
3957	    ((ctx->ext_attr_ver == 2) &&
3958	     (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
3959		if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
3960			goto clear_extattr;
3961	}
3962
3963	if (header->h_blocks != 1) {
3964		if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
3965			goto clear_extattr;
3966	}
3967
3968	region = region_create(0, fs->blocksize);
3969	if (!region) {
3970		fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
3971		ctx->flags |= E2F_FLAG_ABORT;
3972		return 0;
3973	}
3974	if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
3975		if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
3976			goto clear_extattr;
3977	}
3978
3979	entry = (struct ext2_ext_attr_entry *)(header+1);
3980	end = block_buf + fs->blocksize;
3981	while ((char *)entry < end && *(__u32 *)entry) {
3982		if (region_allocate(region, (char *)entry - (char *)header,
3983				   EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
3984			if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
3985				goto clear_extattr;
3986		}
3987		if ((ctx->ext_attr_ver == 1 &&
3988		     (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
3989		    (ctx->ext_attr_ver == 2 &&
3990		     entry->e_name_index == 0)) {
3991			if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
3992				goto clear_extattr;
3993		}
3994		if (entry->e_value_block != 0) {
3995			if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
3996				goto clear_extattr;
3997		}
3998		if (entry->e_value_size &&
3999		    region_allocate(region, entry->e_value_offs,
4000				    EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4001			if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4002				goto clear_extattr;
4003		}
4004		entry = EXT2_EXT_ATTR_NEXT(entry);
4005	}
4006	if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4007		if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4008			goto clear_extattr;
4009	}
4010	region_free(region);
4011
4012	count = header->h_refcount - 1;
4013	if (count)
4014		ea_refcount_store(ctx->refcount, blk, count);
4015	mark_block_used(ctx, blk);
4016	ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4017
4018	return 1;
4019
4020clear_extattr:
4021	inode->i_file_acl = 0;
4022	e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4023	return 0;
4024}
4025
4026/* Returns 1 if bad htree, 0 if OK */
4027static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4028			ext2_ino_t ino FSCK_ATTR((unused)),
4029			struct ext2_inode *inode,
4030			char *block_buf)
4031{
4032	struct ext2_dx_root_info        *root;
4033	ext2_filsys                     fs = ctx->fs;
4034	errcode_t                       retval;
4035	blk_t                           blk;
4036
4037	if ((!LINUX_S_ISDIR(inode->i_mode) &&
4038	     fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4039	    (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4040	     fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4041		return 1;
4042
4043	blk = inode->i_block[0];
4044	if (((blk == 0) ||
4045	     (blk < fs->super->s_first_data_block) ||
4046	     (blk >= fs->super->s_blocks_count)) &&
4047	    fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4048		return 1;
4049
4050	retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4051	if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4052		return 1;
4053
4054	root = (struct ext2_dx_root_info *) (block_buf + 24);
4055
4056	if ((root->reserved_zero || root->info_length < 8) &&
4057	    fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4058		return 1;
4059
4060	pctx->num = root->hash_version;
4061	if ((root->hash_version != EXT2_HASH_LEGACY) &&
4062	    (root->hash_version != EXT2_HASH_HALF_MD4) &&
4063	    (root->hash_version != EXT2_HASH_TEA) &&
4064	    fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4065		return 1;
4066
4067	if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4068	    fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4069		return 1;
4070
4071	pctx->num = root->indirect_levels;
4072	if ((root->indirect_levels > 1) &&
4073	    fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4074		return 1;
4075
4076	return 0;
4077}
4078
4079/*
4080 * This subroutine is called on each inode to account for all of the
4081 * blocks used by that inode.
4082 */
4083static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4084			 char *block_buf)
4085{
4086	ext2_filsys fs = ctx->fs;
4087	struct process_block_struct_1 pb;
4088	ext2_ino_t      ino = pctx->ino;
4089	struct ext2_inode *inode = pctx->inode;
4090	int             bad_size = 0;
4091	int             dirty_inode = 0;
4092	__u64           size;
4093
4094	pb.ino = ino;
4095	pb.num_blocks = 0;
4096	pb.last_block = -1;
4097	pb.num_illegal_blocks = 0;
4098	pb.suppress = 0; pb.clear = 0;
4099	pb.fragmented = 0;
4100	pb.compressed = 0;
4101	pb.previous_block = 0;
4102	pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4103	pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4104	pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4105	pb.inode = inode;
4106	pb.pctx = pctx;
4107	pb.ctx = ctx;
4108	pctx->ino = ino;
4109	pctx->errcode = 0;
4110
4111	if (inode->i_flags & EXT2_COMPRBLK_FL) {
4112		if (fs->super->s_feature_incompat &
4113		    EXT2_FEATURE_INCOMPAT_COMPRESSION)
4114			pb.compressed = 1;
4115		else {
4116			if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4117				inode->i_flags &= ~EXT2_COMPRBLK_FL;
4118				dirty_inode++;
4119			}
4120		}
4121	}
4122
4123	if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4124		pb.num_blocks++;
4125
4126	if (ext2fs_inode_has_valid_blocks(inode))
4127		pctx->errcode = ext2fs_block_iterate2(fs, ino,
4128				       pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4129				       block_buf, process_block, &pb);
4130	end_problem_latch(ctx, PR_LATCH_BLOCK);
4131	end_problem_latch(ctx, PR_LATCH_TOOBIG);
4132	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4133		goto out;
4134	if (pctx->errcode)
4135		fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4136
4137	if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4138		ctx->fs_fragmented++;
4139
4140	if (pb.clear) {
4141		inode->i_links_count = 0;
4142		ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4143		inode->i_dtime = time(0);
4144		dirty_inode++;
4145		ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4146		ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4147		ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4148		/*
4149		 * The inode was probably partially accounted for
4150		 * before processing was aborted, so we need to
4151		 * restart the pass 1 scan.
4152		 */
4153		ctx->flags |= E2F_FLAG_RESTART;
4154		goto out;
4155	}
4156
4157	if (inode->i_flags & EXT2_INDEX_FL) {
4158		if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4159			inode->i_flags &= ~EXT2_INDEX_FL;
4160			dirty_inode++;
4161		} else {
4162#ifdef ENABLE_HTREE
4163			e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4164#endif
4165		}
4166	}
4167	if (ctx->dirs_to_hash && pb.is_dir &&
4168	    !(inode->i_flags & EXT2_INDEX_FL) &&
4169	    ((inode->i_size / fs->blocksize) >= 3))
4170		ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4171
4172	if (!pb.num_blocks && pb.is_dir) {
4173		if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4174			inode->i_links_count = 0;
4175			ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4176			inode->i_dtime = time(0);
4177			dirty_inode++;
4178			ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4179			ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4180			ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4181			ctx->fs_directory_count--;
4182			goto out;
4183		}
4184	}
4185
4186	pb.num_blocks *= (fs->blocksize / 512);
4187
4188	if (pb.is_dir) {
4189		int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4190		if (nblock > (pb.last_block + 1))
4191			bad_size = 1;
4192		else if (nblock < (pb.last_block + 1)) {
4193			if (((pb.last_block + 1) - nblock) >
4194			    fs->super->s_prealloc_dir_blocks)
4195				bad_size = 2;
4196		}
4197	} else {
4198		size = EXT2_I_SIZE(inode);
4199		if ((pb.last_block >= 0) &&
4200		    (size < (__u64) pb.last_block * fs->blocksize))
4201			bad_size = 3;
4202		else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4203			bad_size = 4;
4204	}
4205	/* i_size for symlinks is checked elsewhere */
4206	if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4207		pctx->num = (pb.last_block+1) * fs->blocksize;
4208		if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4209			inode->i_size = pctx->num;
4210			if (!LINUX_S_ISDIR(inode->i_mode))
4211				inode->i_size_high = pctx->num >> 32;
4212			dirty_inode++;
4213		}
4214		pctx->num = 0;
4215	}
4216	if (LINUX_S_ISREG(inode->i_mode) &&
4217	    (inode->i_size_high || inode->i_size & 0x80000000UL))
4218		ctx->large_files++;
4219	if (pb.num_blocks != inode->i_blocks) {
4220		pctx->num = pb.num_blocks;
4221		if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4222			inode->i_blocks = pb.num_blocks;
4223			dirty_inode++;
4224		}
4225		pctx->num = 0;
4226	}
4227out:
4228	if (dirty_inode)
4229		e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4230}
4231
4232
4233/*
4234 * This is a helper function for check_blocks().
4235 */
4236static int process_block(ext2_filsys fs,
4237		  blk_t *block_nr,
4238		  e2_blkcnt_t blockcnt,
4239		  blk_t ref_block FSCK_ATTR((unused)),
4240		  int ref_offset FSCK_ATTR((unused)),
4241		  void *priv_data)
4242{
4243	struct process_block_struct_1 *p;
4244	struct problem_context *pctx;
4245	blk_t   blk = *block_nr;
4246	int     ret_code = 0;
4247	int     problem = 0;
4248	e2fsck_t        ctx;
4249
4250	p = (struct process_block_struct_1 *) priv_data;
4251	pctx = p->pctx;
4252	ctx = p->ctx;
4253
4254	if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4255		/* todo: Check that the comprblk_fl is high, that the
4256		   blkaddr pattern looks right (all non-holes up to
4257		   first EXT2FS_COMPRESSED_BLKADDR, then all
4258		   EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4259		   that the feature_incompat bit is high, and that the
4260		   inode is a regular file.  If we're doing a "full
4261		   check" (a concept introduced to e2fsck by e2compr,
4262		   meaning that we look at data blocks as well as
4263		   metadata) then call some library routine that
4264		   checks the compressed data.  I'll have to think
4265		   about this, because one particularly important
4266		   problem to be able to fix is to recalculate the
4267		   cluster size if necessary.  I think that perhaps
4268		   we'd better do most/all e2compr-specific checks
4269		   separately, after the non-e2compr checks.  If not
4270		   doing a full check, it may be useful to test that
4271		   the personality is linux; e.g. if it isn't then
4272		   perhaps this really is just an illegal block. */
4273		return 0;
4274	}
4275
4276	if (blk == 0) {
4277		if (p->is_dir == 0) {
4278			/*
4279			 * Should never happen, since only directories
4280			 * get called with BLOCK_FLAG_HOLE
4281			 */
4282#ifdef DEBUG_E2FSCK
4283			printf("process_block() called with blk == 0, "
4284			       "blockcnt=%d, inode %lu???\n",
4285			       blockcnt, p->ino);
4286#endif
4287			return 0;
4288		}
4289		if (blockcnt < 0)
4290			return 0;
4291		if (blockcnt * fs->blocksize < p->inode->i_size) {
4292			goto mark_dir;
4293		}
4294		return 0;
4295	}
4296
4297	/*
4298	 * Simplistic fragmentation check.  We merely require that the
4299	 * file be contiguous.  (Which can never be true for really
4300	 * big files that are greater than a block group.)
4301	 */
4302	if (!HOLE_BLKADDR(p->previous_block)) {
4303		if (p->previous_block+1 != blk)
4304			p->fragmented = 1;
4305	}
4306	p->previous_block = blk;
4307
4308	if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4309		problem = PR_1_TOOBIG_DIR;
4310	if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4311		problem = PR_1_TOOBIG_REG;
4312	if (!p->is_dir && !p->is_reg && blockcnt > 0)
4313		problem = PR_1_TOOBIG_SYMLINK;
4314
4315	if (blk < fs->super->s_first_data_block ||
4316	    blk >= fs->super->s_blocks_count)
4317		problem = PR_1_ILLEGAL_BLOCK_NUM;
4318
4319	if (problem) {
4320		p->num_illegal_blocks++;
4321		if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4322			if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4323				p->clear = 1;
4324				return BLOCK_ABORT;
4325			}
4326			if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4327				p->suppress = 1;
4328				set_latch_flags(PR_LATCH_BLOCK,
4329						PRL_SUPPRESS, 0);
4330			}
4331		}
4332		pctx->blk = blk;
4333		pctx->blkcount = blockcnt;
4334		if (fix_problem(ctx, problem, pctx)) {
4335			blk = *block_nr = 0;
4336			ret_code = BLOCK_CHANGED;
4337			goto mark_dir;
4338		} else
4339			return 0;
4340	}
4341
4342	if (p->ino == EXT2_RESIZE_INO) {
4343		/*
4344		 * The resize inode has already be sanity checked
4345		 * during pass #0 (the superblock checks).  All we
4346		 * have to do is mark the double indirect block as
4347		 * being in use; all of the other blocks are handled
4348		 * by mark_table_blocks()).
4349		 */
4350		if (blockcnt == BLOCK_COUNT_DIND)
4351			mark_block_used(ctx, blk);
4352	} else
4353		mark_block_used(ctx, blk);
4354	p->num_blocks++;
4355	if (blockcnt >= 0)
4356		p->last_block = blockcnt;
4357mark_dir:
4358	if (p->is_dir && (blockcnt >= 0)) {
4359		pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4360						    blk, blockcnt);
4361		if (pctx->errcode) {
4362			pctx->blk = blk;
4363			pctx->num = blockcnt;
4364			fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4365			/* Should never get here */
4366			ctx->flags |= E2F_FLAG_ABORT;
4367			return BLOCK_ABORT;
4368		}
4369	}
4370	return ret_code;
4371}
4372
4373static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4374		      blk_t *block_nr,
4375		      e2_blkcnt_t blockcnt,
4376		      blk_t ref_block FSCK_ATTR((unused)),
4377		      int ref_offset FSCK_ATTR((unused)),
4378		      void *priv_data EXT2FS_ATTR((unused)))
4379{
4380	/*
4381	 * Note: This function processes blocks for the bad blocks
4382	 * inode, which is never compressed.  So we don't use HOLE_BLKADDR().
4383	 */
4384
4385	printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4386	return BLOCK_ERROR;
4387}
4388
4389/*
4390 * This routine gets called at the end of pass 1 if bad blocks are
4391 * detected in the superblock, group descriptors, inode_bitmaps, or
4392 * block bitmaps.  At this point, all of the blocks have been mapped
4393 * out, so we can try to allocate new block(s) to replace the bad
4394 * blocks.
4395 */
4396static void handle_fs_bad_blocks(e2fsck_t ctx)
4397{
4398	printf("Bad blocks detected on your filesystem\n"
4399		"You should get your data off as the device will soon die\n");
4400}
4401
4402/*
4403 * This routine marks all blocks which are used by the superblock,
4404 * group descriptors, inode bitmaps, and block bitmaps.
4405 */
4406static void mark_table_blocks(e2fsck_t ctx)
4407{
4408	ext2_filsys fs = ctx->fs;
4409	blk_t   block, b;
4410	dgrp_t  i;
4411	int     j;
4412	struct problem_context pctx;
4413
4414	clear_problem_context(&pctx);
4415
4416	block = fs->super->s_first_data_block;
4417	for (i = 0; i < fs->group_desc_count; i++) {
4418		pctx.group = i;
4419
4420		ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4421
4422		/*
4423		 * Mark the blocks used for the inode table
4424		 */
4425		if (fs->group_desc[i].bg_inode_table) {
4426			for (j = 0, b = fs->group_desc[i].bg_inode_table;
4427			     j < fs->inode_blocks_per_group;
4428			     j++, b++) {
4429				if (ext2fs_test_block_bitmap(ctx->block_found_map,
4430							     b)) {
4431					pctx.blk = b;
4432					if (fix_problem(ctx,
4433						PR_1_ITABLE_CONFLICT, &pctx)) {
4434						ctx->invalid_inode_table_flag[i]++;
4435						ctx->invalid_bitmaps++;
4436					}
4437				} else {
4438				    ext2fs_mark_block_bitmap(ctx->block_found_map,
4439							     b);
4440				}
4441			}
4442		}
4443
4444		/*
4445		 * Mark block used for the block bitmap
4446		 */
4447		if (fs->group_desc[i].bg_block_bitmap) {
4448			if (ext2fs_test_block_bitmap(ctx->block_found_map,
4449				     fs->group_desc[i].bg_block_bitmap)) {
4450				pctx.blk = fs->group_desc[i].bg_block_bitmap;
4451				if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4452					ctx->invalid_block_bitmap_flag[i]++;
4453					ctx->invalid_bitmaps++;
4454				}
4455			} else {
4456			    ext2fs_mark_block_bitmap(ctx->block_found_map,
4457				     fs->group_desc[i].bg_block_bitmap);
4458		    }
4459
4460		}
4461		/*
4462		 * Mark block used for the inode bitmap
4463		 */
4464		if (fs->group_desc[i].bg_inode_bitmap) {
4465			if (ext2fs_test_block_bitmap(ctx->block_found_map,
4466				     fs->group_desc[i].bg_inode_bitmap)) {
4467				pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4468				if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4469					ctx->invalid_inode_bitmap_flag[i]++;
4470					ctx->invalid_bitmaps++;
4471				}
4472			} else {
4473			    ext2fs_mark_block_bitmap(ctx->block_found_map,
4474				     fs->group_desc[i].bg_inode_bitmap);
4475			}
4476		}
4477		block += fs->super->s_blocks_per_group;
4478	}
4479}
4480
4481/*
4482 * Thes subroutines short circuits ext2fs_get_blocks and
4483 * ext2fs_check_directory; we use them since we already have the inode
4484 * structure, so there's no point in letting the ext2fs library read
4485 * the inode again.
4486 */
4487static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4488				  blk_t *blocks)
4489{
4490	e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4491	int     i;
4492
4493	if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4494		return EXT2_ET_CALLBACK_NOTHANDLED;
4495
4496	for (i=0; i < EXT2_N_BLOCKS; i++)
4497		blocks[i] = ctx->stashed_inode->i_block[i];
4498	return 0;
4499}
4500
4501static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4502				  struct ext2_inode *inode)
4503{
4504	e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4505
4506	if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4507		return EXT2_ET_CALLBACK_NOTHANDLED;
4508	*inode = *ctx->stashed_inode;
4509	return 0;
4510}
4511
4512static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4513			    struct ext2_inode *inode)
4514{
4515	e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4516
4517	if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4518		*ctx->stashed_inode = *inode;
4519	return EXT2_ET_CALLBACK_NOTHANDLED;
4520}
4521
4522static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4523{
4524	e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4525
4526	if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4527		return EXT2_ET_CALLBACK_NOTHANDLED;
4528
4529	if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4530		return EXT2_ET_NO_DIRECTORY;
4531	return 0;
4532}
4533
4534void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4535{
4536	ext2_filsys fs = ctx->fs;
4537
4538	if (bool) {
4539		fs->get_blocks = pass1_get_blocks;
4540		fs->check_directory = pass1_check_directory;
4541		fs->read_inode = pass1_read_inode;
4542		fs->write_inode = pass1_write_inode;
4543		ctx->stashed_ino = 0;
4544	} else {
4545		fs->get_blocks = 0;
4546		fs->check_directory = 0;
4547		fs->read_inode = 0;
4548		fs->write_inode = 0;
4549	}
4550}
4551
4552/*
4553 * pass1b.c --- Pass #1b of e2fsck
4554 *
4555 * This file contains pass1B, pass1C, and pass1D of e2fsck.  They are
4556 * only invoked if pass 1 discovered blocks which are in use by more
4557 * than one inode.
4558 *
4559 * Pass1B scans the data blocks of all the inodes again, generating a
4560 * complete list of duplicate blocks and which inodes have claimed
4561 * them.
4562 *
4563 * Pass1C does a tree-traversal of the filesystem, to determine the
4564 * parent directories of these inodes.  This step is necessary so that
4565 * e2fsck can print out the pathnames of affected inodes.
4566 *
4567 * Pass1D is a reconciliation pass.  For each inode with duplicate
4568 * blocks, the user is prompted if s/he would like to clone the file
4569 * (so that the file gets a fresh copy of the duplicated blocks) or
4570 * simply to delete the file.
4571 *
4572 */
4573
4574
4575/* Needed for architectures where sizeof(int) != sizeof(void *) */
4576#define INT_TO_VOIDPTR(val)  ((void *)(intptr_t)(val))
4577#define VOIDPTR_TO_INT(ptr)  ((int)(intptr_t)(ptr))
4578
4579/* Define an extension to the ext2 library's block count information */
4580#define BLOCK_COUNT_EXTATTR     (-5)
4581
4582struct block_el {
4583	blk_t   block;
4584	struct block_el *next;
4585};
4586
4587struct inode_el {
4588	ext2_ino_t      inode;
4589	struct inode_el *next;
4590};
4591
4592struct dup_block {
4593	int             num_bad;
4594	struct inode_el *inode_list;
4595};
4596
4597/*
4598 * This structure stores information about a particular inode which
4599 * is sharing blocks with other inodes.  This information is collected
4600 * to display to the user, so that the user knows what files he or she
4601 * is dealing with, when trying to decide how to resolve the conflict
4602 * of multiply-claimed blocks.
4603 */
4604struct dup_inode {
4605	ext2_ino_t              dir;
4606	int                     num_dupblocks;
4607	struct ext2_inode       inode;
4608	struct block_el         *block_list;
4609};
4610
4611static int process_pass1b_block(ext2_filsys fs, blk_t   *blocknr,
4612				e2_blkcnt_t blockcnt, blk_t ref_blk,
4613				int ref_offset, void *priv_data);
4614static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4615			struct dup_inode *dp, char *block_buf);
4616static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4617		      struct dup_inode *dp, char* block_buf);
4618static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4619
4620static void pass1b(e2fsck_t ctx, char *block_buf);
4621static void pass1c(e2fsck_t ctx, char *block_buf);
4622static void pass1d(e2fsck_t ctx, char *block_buf);
4623
4624static int dup_inode_count = 0;
4625
4626static dict_t blk_dict, ino_dict;
4627
4628static ext2fs_inode_bitmap inode_dup_map;
4629
4630static int dict_int_cmp(const void *a, const void *b)
4631{
4632	intptr_t        ia, ib;
4633
4634	ia = (intptr_t)a;
4635	ib = (intptr_t)b;
4636
4637	return (ia-ib);
4638}
4639
4640/*
4641 * Add a duplicate block record
4642 */
4643static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4644		     struct ext2_inode *inode)
4645{
4646	dnode_t *n;
4647	struct dup_block        *db;
4648	struct dup_inode        *di;
4649	struct block_el         *blk_el;
4650	struct inode_el         *ino_el;
4651
4652	n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4653	if (n)
4654		db = (struct dup_block *) dnode_get(n);
4655	else {
4656		db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4657			 sizeof(struct dup_block), "duplicate block header");
4658		db->num_bad = 0;
4659		db->inode_list = 0;
4660		dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4661	}
4662	ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4663			 sizeof(struct inode_el), "inode element");
4664	ino_el->inode = ino;
4665	ino_el->next = db->inode_list;
4666	db->inode_list = ino_el;
4667	db->num_bad++;
4668
4669	n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4670	if (n)
4671		di = (struct dup_inode *) dnode_get(n);
4672	else {
4673		di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4674			 sizeof(struct dup_inode), "duplicate inode header");
4675		di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0;
4676		di->num_dupblocks = 0;
4677		di->block_list = 0;
4678		di->inode = *inode;
4679		dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4680	}
4681	blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4682			 sizeof(struct block_el), "block element");
4683	blk_el->block = blk;
4684	blk_el->next = di->block_list;
4685	di->block_list = blk_el;
4686	di->num_dupblocks++;
4687}
4688
4689/*
4690 * Free a duplicate inode record
4691 */
4692static void inode_dnode_free(dnode_t *node)
4693{
4694	struct dup_inode        *di;
4695	struct block_el         *p, *next;
4696
4697	di = (struct dup_inode *) dnode_get(node);
4698	for (p = di->block_list; p; p = next) {
4699		next = p->next;
4700		free(p);
4701	}
4702	free(node);
4703}
4704
4705/*
4706 * Free a duplicate block record
4707 */
4708static void block_dnode_free(dnode_t *node)
4709{
4710	struct dup_block        *db;
4711	struct inode_el         *p, *next;
4712
4713	db = (struct dup_block *) dnode_get(node);
4714	for (p = db->inode_list; p; p = next) {
4715		next = p->next;
4716		free(p);
4717	}
4718	free(node);
4719}
4720
4721
4722/*
4723 * Main procedure for handling duplicate blocks
4724 */
4725void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4726{
4727	ext2_filsys             fs = ctx->fs;
4728	struct problem_context  pctx;
4729
4730	clear_problem_context(&pctx);
4731
4732	pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4733		      _("multiply claimed inode map"), &inode_dup_map);
4734	if (pctx.errcode) {
4735		fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4736		ctx->flags |= E2F_FLAG_ABORT;
4737		return;
4738	}
4739
4740	dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4741	dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4742	dict_set_allocator(&ino_dict, inode_dnode_free);
4743	dict_set_allocator(&blk_dict, block_dnode_free);
4744
4745	pass1b(ctx, block_buf);
4746	pass1c(ctx, block_buf);
4747	pass1d(ctx, block_buf);
4748
4749	/*
4750	 * Time to free all of the accumulated data structures that we
4751	 * don't need anymore.
4752	 */
4753	dict_free_nodes(&ino_dict);
4754	dict_free_nodes(&blk_dict);
4755}
4756
4757/*
4758 * Scan the inodes looking for inodes that contain duplicate blocks.
4759 */
4760struct process_block_struct_1b {
4761	e2fsck_t        ctx;
4762	ext2_ino_t      ino;
4763	int             dup_blocks;
4764	struct ext2_inode *inode;
4765	struct problem_context *pctx;
4766};
4767
4768static void pass1b(e2fsck_t ctx, char *block_buf)
4769{
4770	ext2_filsys fs = ctx->fs;
4771	ext2_ino_t ino;
4772	struct ext2_inode inode;
4773	ext2_inode_scan scan;
4774	struct process_block_struct_1b pb;
4775	struct problem_context pctx;
4776
4777	clear_problem_context(&pctx);
4778
4779	if (!(ctx->options & E2F_OPT_PREEN))
4780		fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4781	pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4782					      &scan);
4783	if (pctx.errcode) {
4784		fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4785		ctx->flags |= E2F_FLAG_ABORT;
4786		return;
4787	}
4788	ctx->stashed_inode = &inode;
4789	pb.ctx = ctx;
4790	pb.pctx = &pctx;
4791	pctx.str = "pass1b";
4792	while (1) {
4793		pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4794		if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4795			continue;
4796		if (pctx.errcode) {
4797			fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4798			ctx->flags |= E2F_FLAG_ABORT;
4799			return;
4800		}
4801		if (!ino)
4802			break;
4803		pctx.ino = ctx->stashed_ino = ino;
4804		if ((ino != EXT2_BAD_INO) &&
4805		    !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4806			continue;
4807
4808		pb.ino = ino;
4809		pb.dup_blocks = 0;
4810		pb.inode = &inode;
4811
4812		if (ext2fs_inode_has_valid_blocks(&inode) ||
4813		    (ino == EXT2_BAD_INO))
4814			pctx.errcode = ext2fs_block_iterate2(fs, ino,
4815				     0, block_buf, process_pass1b_block, &pb);
4816		if (inode.i_file_acl)
4817			process_pass1b_block(fs, &inode.i_file_acl,
4818					     BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4819		if (pb.dup_blocks) {
4820			end_problem_latch(ctx, PR_LATCH_DBLOCK);
4821			if (ino >= EXT2_FIRST_INODE(fs->super) ||
4822			    ino == EXT2_ROOT_INO)
4823				dup_inode_count++;
4824		}
4825		if (pctx.errcode)
4826			fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4827	}
4828	ext2fs_close_inode_scan(scan);
4829	e2fsck_use_inode_shortcuts(ctx, 0);
4830}
4831
4832static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4833				blk_t   *block_nr,
4834				e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4835				blk_t ref_blk FSCK_ATTR((unused)),
4836				int ref_offset FSCK_ATTR((unused)),
4837				void *priv_data)
4838{
4839	struct process_block_struct_1b *p;
4840	e2fsck_t ctx;
4841
4842	if (HOLE_BLKADDR(*block_nr))
4843		return 0;
4844	p = (struct process_block_struct_1b *) priv_data;
4845	ctx = p->ctx;
4846
4847	if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4848		return 0;
4849
4850	/* OK, this is a duplicate block */
4851	if (p->ino != EXT2_BAD_INO) {
4852		p->pctx->blk = *block_nr;
4853		fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4854	}
4855	p->dup_blocks++;
4856	ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4857
4858	add_dupe(ctx, p->ino, *block_nr, p->inode);
4859
4860	return 0;
4861}
4862
4863/*
4864 * Pass 1c: Scan directories for inodes with duplicate blocks.  This
4865 * is used so that we can print pathnames when prompting the user for
4866 * what to do.
4867 */
4868struct search_dir_struct {
4869	int             count;
4870	ext2_ino_t      first_inode;
4871	ext2_ino_t      max_inode;
4872};
4873
4874static int search_dirent_proc(ext2_ino_t dir, int entry,
4875			      struct ext2_dir_entry *dirent,
4876			      int offset FSCK_ATTR((unused)),
4877			      int blocksize FSCK_ATTR((unused)),
4878			      char *buf FSCK_ATTR((unused)),
4879			      void *priv_data)
4880{
4881	struct search_dir_struct *sd;
4882	struct dup_inode        *p;
4883	dnode_t                 *n;
4884
4885	sd = (struct search_dir_struct *) priv_data;
4886
4887	if (dirent->inode > sd->max_inode)
4888		/* Should abort this inode, but not everything */
4889		return 0;
4890
4891	if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4892	    !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4893		return 0;
4894
4895	n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4896	if (!n)
4897		return 0;
4898	p = (struct dup_inode *) dnode_get(n);
4899	p->dir = dir;
4900	sd->count--;
4901
4902	return sd->count ? 0 : DIRENT_ABORT;
4903}
4904
4905
4906static void pass1c(e2fsck_t ctx, char *block_buf)
4907{
4908	ext2_filsys fs = ctx->fs;
4909	struct search_dir_struct sd;
4910	struct problem_context pctx;
4911
4912	clear_problem_context(&pctx);
4913
4914	if (!(ctx->options & E2F_OPT_PREEN))
4915		fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4916
4917	/*
4918	 * Search through all directories to translate inodes to names
4919	 * (by searching for the containing directory for that inode.)
4920	 */
4921	sd.count = dup_inode_count;
4922	sd.first_inode = EXT2_FIRST_INODE(fs->super);
4923	sd.max_inode = fs->super->s_inodes_count;
4924	ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4925				  search_dirent_proc, &sd);
4926}
4927
4928static void pass1d(e2fsck_t ctx, char *block_buf)
4929{
4930	ext2_filsys fs = ctx->fs;
4931	struct dup_inode        *p, *t;
4932	struct dup_block        *q;
4933	ext2_ino_t              *shared, ino;
4934	int     shared_len;
4935	int     i;
4936	int     file_ok;
4937	int     meta_data = 0;
4938	struct problem_context pctx;
4939	dnode_t *n, *m;
4940	struct block_el *s;
4941	struct inode_el *r;
4942
4943	clear_problem_context(&pctx);
4944
4945	if (!(ctx->options & E2F_OPT_PREEN))
4946		fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
4947	e2fsck_read_bitmaps(ctx);
4948
4949	pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
4950	fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
4951	shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
4952				sizeof(ext2_ino_t) * dict_count(&ino_dict),
4953				"Shared inode list");
4954	for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
4955		p = (struct dup_inode *) dnode_get(n);
4956		shared_len = 0;
4957		file_ok = 1;
4958		ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
4959		if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
4960			continue;
4961
4962		/*
4963		 * Find all of the inodes which share blocks with this
4964		 * one.  First we find all of the duplicate blocks
4965		 * belonging to this inode, and then search each block
4966		 * get the list of inodes, and merge them together.
4967		 */
4968		for (s = p->block_list; s; s = s->next) {
4969			m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
4970			if (!m)
4971				continue; /* Should never happen... */
4972			q = (struct dup_block *) dnode_get(m);
4973			if (q->num_bad > 1)
4974				file_ok = 0;
4975			if (check_if_fs_block(ctx, s->block)) {
4976				file_ok = 0;
4977				meta_data = 1;
4978			}
4979
4980			/*
4981			 * Add all inodes used by this block to the
4982			 * shared[] --- which is a unique list, so
4983			 * if an inode is already in shared[], don't
4984			 * add it again.
4985			 */
4986			for (r = q->inode_list; r; r = r->next) {
4987				if (r->inode == ino)
4988					continue;
4989				for (i = 0; i < shared_len; i++)
4990					if (shared[i] == r->inode)
4991						break;
4992				if (i == shared_len) {
4993					shared[shared_len++] = r->inode;
4994				}
4995			}
4996		}
4997
4998		/*
4999		 * Report the inode that we are working on
5000		 */
5001		pctx.inode = &p->inode;
5002		pctx.ino = ino;
5003		pctx.dir = p->dir;
5004		pctx.blkcount = p->num_dupblocks;
5005		pctx.num = meta_data ? shared_len+1 : shared_len;
5006		fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5007		pctx.blkcount = 0;
5008		pctx.num = 0;
5009
5010		if (meta_data)
5011			fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5012
5013		for (i = 0; i < shared_len; i++) {
5014			m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5015			if (!m)
5016				continue; /* should never happen */
5017			t = (struct dup_inode *) dnode_get(m);
5018			/*
5019			 * Report the inode that we are sharing with
5020			 */
5021			pctx.inode = &t->inode;
5022			pctx.ino = shared[i];
5023			pctx.dir = t->dir;
5024			fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5025		}
5026		if (file_ok) {
5027			fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5028			continue;
5029		}
5030		if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5031			pctx.errcode = clone_file(ctx, ino, p, block_buf);
5032			if (pctx.errcode)
5033				fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5034			else
5035				continue;
5036		}
5037		if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5038			delete_file(ctx, ino, p, block_buf);
5039		else
5040			ext2fs_unmark_valid(fs);
5041	}
5042	ext2fs_free_mem(&shared);
5043}
5044
5045/*
5046 * Drop the refcount on the dup_block structure, and clear the entry
5047 * in the block_dup_map if appropriate.
5048 */
5049static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5050{
5051	p->num_bad--;
5052	if (p->num_bad <= 0 ||
5053	    (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5054		ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5055}
5056
5057static int delete_file_block(ext2_filsys fs,
5058			     blk_t      *block_nr,
5059			     e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5060			     blk_t ref_block FSCK_ATTR((unused)),
5061			     int ref_offset FSCK_ATTR((unused)),
5062			     void *priv_data)
5063{
5064	struct process_block_struct_1b *pb;
5065	struct dup_block *p;
5066	dnode_t *n;
5067	e2fsck_t ctx;
5068
5069	pb = (struct process_block_struct_1b *) priv_data;
5070	ctx = pb->ctx;
5071
5072	if (HOLE_BLKADDR(*block_nr))
5073		return 0;
5074
5075	if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5076		n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5077		if (n) {
5078			p = (struct dup_block *) dnode_get(n);
5079			decrement_badcount(ctx, *block_nr, p);
5080		} else
5081			bb_error_msg(_("internal error; can't find dup_blk for %d"),
5082				*block_nr);
5083	} else {
5084		ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5085		ext2fs_block_alloc_stats(fs, *block_nr, -1);
5086	}
5087
5088	return 0;
5089}
5090
5091static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5092			struct dup_inode *dp, char* block_buf)
5093{
5094	ext2_filsys fs = ctx->fs;
5095	struct process_block_struct_1b pb;
5096	struct ext2_inode       inode;
5097	struct problem_context  pctx;
5098	unsigned int            count;
5099
5100	clear_problem_context(&pctx);
5101	pctx.ino = pb.ino = ino;
5102	pb.dup_blocks = dp->num_dupblocks;
5103	pb.ctx = ctx;
5104	pctx.str = "delete_file";
5105
5106	e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5107	if (ext2fs_inode_has_valid_blocks(&inode))
5108		pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5109						     delete_file_block, &pb);
5110	if (pctx.errcode)
5111		fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5112	ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5113	ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5114	if (ctx->inode_bad_map)
5115		ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5116	ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5117
5118	/* Inode may have changed by block_iterate, so reread it */
5119	e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5120	inode.i_links_count = 0;
5121	inode.i_dtime = time(0);
5122	if (inode.i_file_acl &&
5123	    (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5124		count = 1;
5125		pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5126						   block_buf, -1, &count);
5127		if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5128			pctx.errcode = 0;
5129			count = 1;
5130		}
5131		if (pctx.errcode) {
5132			pctx.blk = inode.i_file_acl;
5133			fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5134		}
5135		/*
5136		 * If the count is zero, then arrange to have the
5137		 * block deleted.  If the block is in the block_dup_map,
5138		 * also call delete_file_block since it will take care
5139		 * of keeping the accounting straight.
5140		 */
5141		if ((count == 0) ||
5142		    ext2fs_test_block_bitmap(ctx->block_dup_map,
5143					     inode.i_file_acl))
5144			delete_file_block(fs, &inode.i_file_acl,
5145					  BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5146	}
5147	e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5148}
5149
5150struct clone_struct {
5151	errcode_t       errcode;
5152	ext2_ino_t      dir;
5153	char    *buf;
5154	e2fsck_t ctx;
5155};
5156
5157static int clone_file_block(ext2_filsys fs,
5158			    blk_t       *block_nr,
5159			    e2_blkcnt_t blockcnt,
5160			    blk_t ref_block FSCK_ATTR((unused)),
5161			    int ref_offset FSCK_ATTR((unused)),
5162			    void *priv_data)
5163{
5164	struct dup_block *p;
5165	blk_t   new_block;
5166	errcode_t       retval;
5167	struct clone_struct *cs = (struct clone_struct *) priv_data;
5168	dnode_t *n;
5169	e2fsck_t ctx;
5170
5171	ctx = cs->ctx;
5172
5173	if (HOLE_BLKADDR(*block_nr))
5174		return 0;
5175
5176	if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5177		n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5178		if (n) {
5179			p = (struct dup_block *) dnode_get(n);
5180			retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5181						  &new_block);
5182			if (retval) {
5183				cs->errcode = retval;
5184				return BLOCK_ABORT;
5185			}
5186			if (cs->dir && (blockcnt >= 0)) {
5187				retval = ext2fs_set_dir_block(fs->dblist,
5188				      cs->dir, new_block, blockcnt);
5189				if (retval) {
5190					cs->errcode = retval;
5191					return BLOCK_ABORT;
5192				}
5193			}
5194
5195			retval = io_channel_read_blk(fs->io, *block_nr, 1,
5196						     cs->buf);
5197			if (retval) {
5198				cs->errcode = retval;
5199				return BLOCK_ABORT;
5200			}
5201			retval = io_channel_write_blk(fs->io, new_block, 1,
5202						      cs->buf);
5203			if (retval) {
5204				cs->errcode = retval;
5205				return BLOCK_ABORT;
5206			}
5207			decrement_badcount(ctx, *block_nr, p);
5208			*block_nr = new_block;
5209			ext2fs_mark_block_bitmap(ctx->block_found_map,
5210						 new_block);
5211			ext2fs_mark_block_bitmap(fs->block_map, new_block);
5212			return BLOCK_CHANGED;
5213		} else
5214			bb_error_msg(_("internal error; can't find dup_blk for %d"),
5215				*block_nr);
5216	}
5217	return 0;
5218}
5219
5220static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5221		      struct dup_inode *dp, char* block_buf)
5222{
5223	ext2_filsys fs = ctx->fs;
5224	errcode_t       retval;
5225	struct clone_struct cs;
5226	struct problem_context  pctx;
5227	blk_t           blk;
5228	dnode_t         *n;
5229	struct inode_el *ino_el;
5230	struct dup_block        *db;
5231	struct dup_inode        *di;
5232
5233	clear_problem_context(&pctx);
5234	cs.errcode = 0;
5235	cs.dir = 0;
5236	cs.ctx = ctx;
5237	retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5238	if (retval)
5239		return retval;
5240
5241	if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5242		cs.dir = ino;
5243
5244	pctx.ino = ino;
5245	pctx.str = "clone_file";
5246	if (ext2fs_inode_has_valid_blocks(&dp->inode))
5247		pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5248						     clone_file_block, &cs);
5249	ext2fs_mark_bb_dirty(fs);
5250	if (pctx.errcode) {
5251		fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5252		retval = pctx.errcode;
5253		goto errout;
5254	}
5255	if (cs.errcode) {
5256		bb_error_msg(_("returned from clone_file_block"));
5257		retval = cs.errcode;
5258		goto errout;
5259	}
5260	/* The inode may have changed on disk, so we have to re-read it */
5261	e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5262	blk = dp->inode.i_file_acl;
5263	if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5264				     BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5265		    BLOCK_CHANGED)) {
5266		e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5267		/*
5268		 * If we cloned the EA block, find all other inodes
5269		 * which refered to that EA block, and modify
5270		 * them to point to the new EA block.
5271		 */
5272		n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5273		db = (struct dup_block *) dnode_get(n);
5274		for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5275			if (ino_el->inode == ino)
5276				continue;
5277			n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5278			di = (struct dup_inode *) dnode_get(n);
5279			if (di->inode.i_file_acl == blk) {
5280				di->inode.i_file_acl = dp->inode.i_file_acl;
5281				e2fsck_write_inode(ctx, ino_el->inode,
5282					   &di->inode, "clone file EA");
5283				decrement_badcount(ctx, blk, db);
5284			}
5285		}
5286	}
5287	retval = 0;
5288errout:
5289	ext2fs_free_mem(&cs.buf);
5290	return retval;
5291}
5292
5293/*
5294 * This routine returns 1 if a block overlaps with one of the superblocks,
5295 * group descriptors, inode bitmaps, or block bitmaps.
5296 */
5297static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5298{
5299	ext2_filsys fs = ctx->fs;
5300	blk_t   block;
5301	dgrp_t  i;
5302
5303	block = fs->super->s_first_data_block;
5304	for (i = 0; i < fs->group_desc_count; i++) {
5305
5306		/* Check superblocks/block group descriptros */
5307		if (ext2fs_bg_has_super(fs, i)) {
5308			if (test_block >= block &&
5309			    (test_block <= block + fs->desc_blocks))
5310				return 1;
5311		}
5312
5313		/* Check the inode table */
5314		if ((fs->group_desc[i].bg_inode_table) &&
5315		    (test_block >= fs->group_desc[i].bg_inode_table) &&
5316		    (test_block < (fs->group_desc[i].bg_inode_table +
5317				   fs->inode_blocks_per_group)))
5318			return 1;
5319
5320		/* Check the bitmap blocks */
5321		if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5322		    (test_block == fs->group_desc[i].bg_inode_bitmap))
5323			return 1;
5324
5325		block += fs->super->s_blocks_per_group;
5326	}
5327	return 0;
5328}
5329/*
5330 * pass2.c --- check directory structure
5331 *
5332 * Pass 2 of e2fsck iterates through all active directory inodes, and
5333 * applies to following tests to each directory entry in the directory
5334 * blocks in the inodes:
5335 *
5336 *      - The length of the directory entry (rec_len) should be at
5337 *              least 8 bytes, and no more than the remaining space
5338 *              left in the directory block.
5339 *      - The length of the name in the directory entry (name_len)
5340 *              should be less than (rec_len - 8).
5341 *      - The inode number in the directory entry should be within
5342 *              legal bounds.
5343 *      - The inode number should refer to a in-use inode.
5344 *      - The first entry should be '.', and its inode should be
5345 *              the inode of the directory.
5346 *      - The second entry should be '..'.
5347 *
5348 * To minimize disk seek time, the directory blocks are processed in
5349 * sorted order of block numbers.
5350 *
5351 * Pass 2 also collects the following information:
5352 *      - The inode numbers of the subdirectories for each directory.
5353 *
5354 * Pass 2 relies on the following information from previous passes:
5355 *      - The directory information collected in pass 1.
5356 *      - The inode_used_map bitmap
5357 *      - The inode_bad_map bitmap
5358 *      - The inode_dir_map bitmap
5359 *
5360 * Pass 2 frees the following data structures
5361 *      - The inode_bad_map bitmap
5362 *      - The inode_reg_map bitmap
5363 */
5364
5365/*
5366 * Keeps track of how many times an inode is referenced.
5367 */
5368static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5369static int check_dir_block(ext2_filsys fs,
5370			   struct ext2_db_entry *dir_blocks_info,
5371			   void *priv_data);
5372static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5373			      struct problem_context *pctx);
5374static int update_dir_block(ext2_filsys fs,
5375			    blk_t       *block_nr,
5376			    e2_blkcnt_t blockcnt,
5377			    blk_t       ref_block,
5378			    int         ref_offset,
5379			    void        *priv_data);
5380static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5381static int htree_depth(struct dx_dir_info *dx_dir,
5382		       struct dx_dirblock_info *dx_db);
5383static int special_dir_block_cmp(const void *a, const void *b);
5384
5385struct check_dir_struct {
5386	char *buf;
5387	struct problem_context  pctx;
5388	int     count, max;
5389	e2fsck_t ctx;
5390};
5391
5392static void e2fsck_pass2(e2fsck_t ctx)
5393{
5394	struct ext2_super_block *sb = ctx->fs->super;
5395	struct problem_context  pctx;
5396	ext2_filsys             fs = ctx->fs;
5397	char                    *buf;
5398	struct dir_info         *dir;
5399	struct check_dir_struct cd;
5400	struct dx_dir_info      *dx_dir;
5401	struct dx_dirblock_info *dx_db, *dx_parent;
5402	int                     b;
5403	int                     i, depth;
5404	problem_t               code;
5405	int                     bad_dir;
5406
5407	clear_problem_context(&cd.pctx);
5408
5409	/* Pass 2 */
5410
5411	if (!(ctx->options & E2F_OPT_PREEN))
5412		fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5413
5414	cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5415						0, ctx->inode_link_info,
5416						&ctx->inode_count);
5417	if (cd.pctx.errcode) {
5418		fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5419		ctx->flags |= E2F_FLAG_ABORT;
5420		return;
5421	}
5422	buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5423					      "directory scan buffer");
5424
5425	/*
5426	 * Set up the parent pointer for the root directory, if
5427	 * present.  (If the root directory is not present, we will
5428	 * create it in pass 3.)
5429	 */
5430	dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5431	if (dir)
5432		dir->parent = EXT2_ROOT_INO;
5433
5434	cd.buf = buf;
5435	cd.ctx = ctx;
5436	cd.count = 1;
5437	cd.max = ext2fs_dblist_count(fs->dblist);
5438
5439	if (ctx->progress)
5440		(void) (ctx->progress)(ctx, 2, 0, cd.max);
5441
5442	if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5443		ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5444
5445	cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5446						&cd);
5447	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5448		return;
5449	if (cd.pctx.errcode) {
5450		fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5451		ctx->flags |= E2F_FLAG_ABORT;
5452		return;
5453	}
5454
5455#ifdef ENABLE_HTREE
5456	for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5457		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5458			return;
5459		if (dx_dir->numblocks == 0)
5460			continue;
5461		clear_problem_context(&pctx);
5462		bad_dir = 0;
5463		pctx.dir = dx_dir->ino;
5464		dx_db = dx_dir->dx_block;
5465		if (dx_db->flags & DX_FLAG_REFERENCED)
5466			dx_db->flags |= DX_FLAG_DUP_REF;
5467		else
5468			dx_db->flags |= DX_FLAG_REFERENCED;
5469		/*
5470		 * Find all of the first and last leaf blocks, and
5471		 * update their parent's min and max hash values
5472		 */
5473		for (b=0, dx_db = dx_dir->dx_block;
5474		     b < dx_dir->numblocks;
5475		     b++, dx_db++) {
5476			if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5477			    !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5478				continue;
5479			dx_parent = &dx_dir->dx_block[dx_db->parent];
5480			if (dx_db->flags & DX_FLAG_FIRST)
5481				dx_parent->min_hash = dx_db->min_hash;
5482			if (dx_db->flags & DX_FLAG_LAST)
5483				dx_parent->max_hash = dx_db->max_hash;
5484		}
5485
5486		for (b=0, dx_db = dx_dir->dx_block;
5487		     b < dx_dir->numblocks;
5488		     b++, dx_db++) {
5489			pctx.blkcount = b;
5490			pctx.group = dx_db->parent;
5491			code = 0;
5492			if (!(dx_db->flags & DX_FLAG_FIRST) &&
5493			    (dx_db->min_hash < dx_db->node_min_hash)) {
5494				pctx.blk = dx_db->min_hash;
5495				pctx.blk2 = dx_db->node_min_hash;
5496				code = PR_2_HTREE_MIN_HASH;
5497				fix_problem(ctx, code, &pctx);
5498				bad_dir++;
5499			}
5500			if (dx_db->type == DX_DIRBLOCK_LEAF) {
5501				depth = htree_depth(dx_dir, dx_db);
5502				if (depth != dx_dir->depth) {
5503					code = PR_2_HTREE_BAD_DEPTH;
5504					fix_problem(ctx, code, &pctx);
5505					bad_dir++;
5506				}
5507			}
5508			/*
5509			 * This test doesn't apply for the root block
5510			 * at block #0
5511			 */
5512			if (b &&
5513			    (dx_db->max_hash > dx_db->node_max_hash)) {
5514				pctx.blk = dx_db->max_hash;
5515				pctx.blk2 = dx_db->node_max_hash;
5516				code = PR_2_HTREE_MAX_HASH;
5517				fix_problem(ctx, code, &pctx);
5518				bad_dir++;
5519			}
5520			if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5521				code = PR_2_HTREE_NOTREF;
5522				fix_problem(ctx, code, &pctx);
5523				bad_dir++;
5524			} else if (dx_db->flags & DX_FLAG_DUP_REF) {
5525				code = PR_2_HTREE_DUPREF;
5526				fix_problem(ctx, code, &pctx);
5527				bad_dir++;
5528			}
5529			if (code == 0)
5530				continue;
5531		}
5532		if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5533			clear_htree(ctx, dx_dir->ino);
5534			dx_dir->numblocks = 0;
5535		}
5536	}
5537#endif
5538	ext2fs_free_mem(&buf);
5539	ext2fs_free_dblist(fs->dblist);
5540
5541	ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5542	ctx->inode_bad_map = 0;
5543	ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5544	ctx->inode_reg_map = 0;
5545
5546	clear_problem_context(&pctx);
5547	if (ctx->large_files) {
5548		if (!(sb->s_feature_ro_compat &
5549		      EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5550		    fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5551			sb->s_feature_ro_compat |=
5552				EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5553			ext2fs_mark_super_dirty(fs);
5554		}
5555		if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5556		    fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5557			ext2fs_update_dynamic_rev(fs);
5558			ext2fs_mark_super_dirty(fs);
5559		}
5560	} else if (!ctx->large_files &&
5561	    (sb->s_feature_ro_compat &
5562	      EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5563		if (fs->flags & EXT2_FLAG_RW) {
5564			sb->s_feature_ro_compat &=
5565				~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5566			ext2fs_mark_super_dirty(fs);
5567		}
5568	}
5569
5570}
5571
5572#define MAX_DEPTH 32000
5573static int htree_depth(struct dx_dir_info *dx_dir,
5574		       struct dx_dirblock_info *dx_db)
5575{
5576	int     depth = 0;
5577
5578	while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5579		dx_db = &dx_dir->dx_block[dx_db->parent];
5580		depth++;
5581	}
5582	return depth;
5583}
5584
5585static int dict_de_cmp(const void *a, const void *b)
5586{
5587	const struct ext2_dir_entry *de_a, *de_b;
5588	int     a_len, b_len;
5589
5590	de_a = (const struct ext2_dir_entry *) a;
5591	a_len = de_a->name_len & 0xFF;
5592	de_b = (const struct ext2_dir_entry *) b;
5593	b_len = de_b->name_len & 0xFF;
5594
5595	if (a_len != b_len)
5596		return (a_len - b_len);
5597
5598	return strncmp(de_a->name, de_b->name, a_len);
5599}
5600
5601/*
5602 * This is special sort function that makes sure that directory blocks
5603 * with a dirblock of zero are sorted to the beginning of the list.
5604 * This guarantees that the root node of the htree directories are
5605 * processed first, so we know what hash version to use.
5606 */
5607static int special_dir_block_cmp(const void *a, const void *b)
5608{
5609	const struct ext2_db_entry *db_a =
5610		(const struct ext2_db_entry *) a;
5611	const struct ext2_db_entry *db_b =
5612		(const struct ext2_db_entry *) b;
5613
5614	if (db_a->blockcnt && !db_b->blockcnt)
5615		return 1;
5616
5617	if (!db_a->blockcnt && db_b->blockcnt)
5618		return -1;
5619
5620	if (db_a->blk != db_b->blk)
5621		return (int) (db_a->blk - db_b->blk);
5622
5623	if (db_a->ino != db_b->ino)
5624		return (int) (db_a->ino - db_b->ino);
5625
5626	return (int) (db_a->blockcnt - db_b->blockcnt);
5627}
5628
5629
5630/*
5631 * Make sure the first entry in the directory is '.', and that the
5632 * directory entry is sane.
5633 */
5634static int check_dot(e2fsck_t ctx,
5635		     struct ext2_dir_entry *dirent,
5636		     ext2_ino_t ino, struct problem_context *pctx)
5637{
5638	struct ext2_dir_entry *nextdir;
5639	int     status = 0;
5640	int     created = 0;
5641	int     new_len;
5642	int     problem = 0;
5643
5644	if (!dirent->inode)
5645		problem = PR_2_MISSING_DOT;
5646	else if (((dirent->name_len & 0xFF) != 1) ||
5647		 (dirent->name[0] != '.'))
5648		problem = PR_2_1ST_NOT_DOT;
5649	else if (dirent->name[1] != '\0')
5650		problem = PR_2_DOT_NULL_TERM;
5651
5652	if (problem) {
5653		if (fix_problem(ctx, problem, pctx)) {
5654			if (dirent->rec_len < 12)
5655				dirent->rec_len = 12;
5656			dirent->inode = ino;
5657			dirent->name_len = 1;
5658			dirent->name[0] = '.';
5659			dirent->name[1] = '\0';
5660			status = 1;
5661			created = 1;
5662		}
5663	}
5664	if (dirent->inode != ino) {
5665		if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5666			dirent->inode = ino;
5667			status = 1;
5668		}
5669	}
5670	if (dirent->rec_len > 12) {
5671		new_len = dirent->rec_len - 12;
5672		if (new_len > 12) {
5673			if (created ||
5674			    fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5675				nextdir = (struct ext2_dir_entry *)
5676					((char *) dirent + 12);
5677				dirent->rec_len = 12;
5678				nextdir->rec_len = new_len;
5679				nextdir->inode = 0;
5680				nextdir->name_len = 0;
5681				status = 1;
5682			}
5683		}
5684	}
5685	return status;
5686}
5687
5688/*
5689 * Make sure the second entry in the directory is '..', and that the
5690 * directory entry is sane.  We do not check the inode number of '..'
5691 * here; this gets done in pass 3.
5692 */
5693static int check_dotdot(e2fsck_t ctx,
5694			struct ext2_dir_entry *dirent,
5695			struct dir_info *dir, struct problem_context *pctx)
5696{
5697	int             problem = 0;
5698
5699	if (!dirent->inode)
5700		problem = PR_2_MISSING_DOT_DOT;
5701	else if (((dirent->name_len & 0xFF) != 2) ||
5702		 (dirent->name[0] != '.') ||
5703		 (dirent->name[1] != '.'))
5704		problem = PR_2_2ND_NOT_DOT_DOT;
5705	else if (dirent->name[2] != '\0')
5706		problem = PR_2_DOT_DOT_NULL_TERM;
5707
5708	if (problem) {
5709		if (fix_problem(ctx, problem, pctx)) {
5710			if (dirent->rec_len < 12)
5711				dirent->rec_len = 12;
5712			/*
5713			 * Note: we don't have the parent inode just
5714			 * yet, so we will fill it in with the root
5715			 * inode.  This will get fixed in pass 3.
5716			 */
5717			dirent->inode = EXT2_ROOT_INO;
5718			dirent->name_len = 2;
5719			dirent->name[0] = '.';
5720			dirent->name[1] = '.';
5721			dirent->name[2] = '\0';
5722			return 1;
5723		}
5724		return 0;
5725	}
5726	dir->dotdot = dirent->inode;
5727	return 0;
5728}
5729
5730/*
5731 * Check to make sure a directory entry doesn't contain any illegal
5732 * characters.
5733 */
5734static int check_name(e2fsck_t ctx,
5735		      struct ext2_dir_entry *dirent,
5736		      struct problem_context *pctx)
5737{
5738	int     i;
5739	int     fixup = -1;
5740	int     ret = 0;
5741
5742	for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5743		if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5744			if (fixup < 0) {
5745				fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5746			}
5747			if (fixup) {
5748				dirent->name[i] = '.';
5749				ret = 1;
5750			}
5751		}
5752	}
5753	return ret;
5754}
5755
5756/*
5757 * Check the directory filetype (if present)
5758 */
5759
5760/*
5761 * Given a mode, return the ext2 file type
5762 */
5763static int ext2_file_type(unsigned int mode)
5764{
5765	if (LINUX_S_ISREG(mode))
5766		return EXT2_FT_REG_FILE;
5767
5768	if (LINUX_S_ISDIR(mode))
5769		return EXT2_FT_DIR;
5770
5771	if (LINUX_S_ISCHR(mode))
5772		return EXT2_FT_CHRDEV;
5773
5774	if (LINUX_S_ISBLK(mode))
5775		return EXT2_FT_BLKDEV;
5776
5777	if (LINUX_S_ISLNK(mode))
5778		return EXT2_FT_SYMLINK;
5779
5780	if (LINUX_S_ISFIFO(mode))
5781		return EXT2_FT_FIFO;
5782
5783	if (LINUX_S_ISSOCK(mode))
5784		return EXT2_FT_SOCK;
5785
5786	return 0;
5787}
5788
5789static int check_filetype(e2fsck_t ctx,
5790				   struct ext2_dir_entry *dirent,
5791				   struct problem_context *pctx)
5792{
5793	int     filetype = dirent->name_len >> 8;
5794	int     should_be = EXT2_FT_UNKNOWN;
5795	struct ext2_inode       inode;
5796
5797	if (!(ctx->fs->super->s_feature_incompat &
5798	      EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5799		if (filetype == 0 ||
5800		    !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5801			return 0;
5802		dirent->name_len = dirent->name_len & 0xFF;
5803		return 1;
5804	}
5805
5806	if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5807		should_be = EXT2_FT_DIR;
5808	} else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5809					    dirent->inode)) {
5810		should_be = EXT2_FT_REG_FILE;
5811	} else if (ctx->inode_bad_map &&
5812		   ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5813					    dirent->inode))
5814		should_be = 0;
5815	else {
5816		e2fsck_read_inode(ctx, dirent->inode, &inode,
5817				  "check_filetype");
5818		should_be = ext2_file_type(inode.i_mode);
5819	}
5820	if (filetype == should_be)
5821		return 0;
5822	pctx->num = should_be;
5823
5824	if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5825			pctx) == 0)
5826		return 0;
5827
5828	dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5829	return 1;
5830}
5831
5832#ifdef ENABLE_HTREE
5833static void parse_int_node(ext2_filsys fs,
5834			   struct ext2_db_entry *db,
5835			   struct check_dir_struct *cd,
5836			   struct dx_dir_info   *dx_dir,
5837			   char *block_buf)
5838{
5839	struct          ext2_dx_root_info  *root;
5840	struct          ext2_dx_entry *ent;
5841	struct          ext2_dx_countlimit *limit;
5842	struct dx_dirblock_info *dx_db;
5843	int             i, expect_limit, count;
5844	blk_t           blk;
5845	ext2_dirhash_t  min_hash = 0xffffffff;
5846	ext2_dirhash_t  max_hash = 0;
5847	ext2_dirhash_t  hash = 0, prev_hash;
5848
5849	if (db->blockcnt == 0) {
5850		root = (struct ext2_dx_root_info *) (block_buf + 24);
5851		ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5852	} else {
5853		ent = (struct ext2_dx_entry *) (block_buf+8);
5854	}
5855	limit = (struct ext2_dx_countlimit *) ent;
5856
5857	count = ext2fs_le16_to_cpu(limit->count);
5858	expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5859		sizeof(struct ext2_dx_entry);
5860	if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5861		cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5862		if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5863			goto clear_and_exit;
5864	}
5865	if (count > expect_limit) {
5866		cd->pctx.num = count;
5867		if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5868			goto clear_and_exit;
5869		count = expect_limit;
5870	}
5871
5872	for (i=0; i < count; i++) {
5873		prev_hash = hash;
5874		hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5875		blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5876		/* Check to make sure the block is valid */
5877		if (blk > (blk_t) dx_dir->numblocks) {
5878			cd->pctx.blk = blk;
5879			if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5880					&cd->pctx))
5881				goto clear_and_exit;
5882		}
5883		if (hash < prev_hash &&
5884		    fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5885			goto clear_and_exit;
5886		dx_db = &dx_dir->dx_block[blk];
5887		if (dx_db->flags & DX_FLAG_REFERENCED) {
5888			dx_db->flags |= DX_FLAG_DUP_REF;
5889		} else {
5890			dx_db->flags |= DX_FLAG_REFERENCED;
5891			dx_db->parent = db->blockcnt;
5892		}
5893		if (hash < min_hash)
5894			min_hash = hash;
5895		if (hash > max_hash)
5896			max_hash = hash;
5897		dx_db->node_min_hash = hash;
5898		if ((i+1) < count)
5899			dx_db->node_max_hash =
5900			  ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5901		else {
5902			dx_db->node_max_hash = 0xfffffffe;
5903			dx_db->flags |= DX_FLAG_LAST;
5904		}
5905		if (i == 0)
5906			dx_db->flags |= DX_FLAG_FIRST;
5907	}
5908	dx_db = &dx_dir->dx_block[db->blockcnt];
5909	dx_db->min_hash = min_hash;
5910	dx_db->max_hash = max_hash;
5911	return;
5912
5913clear_and_exit:
5914	clear_htree(cd->ctx, cd->pctx.ino);
5915	dx_dir->numblocks = 0;
5916}
5917#endif /* ENABLE_HTREE */
5918
5919/*
5920 * Given a busted directory, try to salvage it somehow.
5921 *
5922 */
5923static void salvage_directory(ext2_filsys fs,
5924			      struct ext2_dir_entry *dirent,
5925			      struct ext2_dir_entry *prev,
5926			      unsigned int *offset)
5927{
5928	char    *cp = (char *) dirent;
5929	int left = fs->blocksize - *offset - dirent->rec_len;
5930	int name_len = dirent->name_len & 0xFF;
5931
5932	/*
5933	 * Special case of directory entry of size 8: copy what's left
5934	 * of the directory block up to cover up the invalid hole.
5935	 */
5936	if ((left >= 12) && (dirent->rec_len == 8)) {
5937		memmove(cp, cp+8, left);
5938		memset(cp + left, 0, 8);
5939		return;
5940	}
5941	/*
5942	 * If the directory entry overruns the end of the directory
5943	 * block, and the name is small enough to fit, then adjust the
5944	 * record length.
5945	 */
5946	if ((left < 0) &&
5947	    (name_len + 8 <= dirent->rec_len + left) &&
5948	    dirent->inode <= fs->super->s_inodes_count &&
5949	    strnlen(dirent->name, name_len) == name_len) {
5950		dirent->rec_len += left;
5951		return;
5952	}
5953	/*
5954	 * If the directory entry is a multiple of four, so it is
5955	 * valid, let the previous directory entry absorb the invalid
5956	 * one.
5957	 */
5958	if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
5959		prev->rec_len += dirent->rec_len;
5960		*offset += dirent->rec_len;
5961		return;
5962	}
5963	/*
5964	 * Default salvage method --- kill all of the directory
5965	 * entries for the rest of the block.  We will either try to
5966	 * absorb it into the previous directory entry, or create a
5967	 * new empty directory entry the rest of the directory block.
5968	 */
5969	if (prev) {
5970		prev->rec_len += fs->blocksize - *offset;
5971		*offset = fs->blocksize;
5972	} else {
5973		dirent->rec_len = fs->blocksize - *offset;
5974		dirent->name_len = 0;
5975		dirent->inode = 0;
5976	}
5977}
5978
5979static int check_dir_block(ext2_filsys fs,
5980			   struct ext2_db_entry *db,
5981			   void *priv_data)
5982{
5983	struct dir_info         *subdir, *dir;
5984	struct dx_dir_info      *dx_dir;
5985#ifdef ENABLE_HTREE
5986	struct dx_dirblock_info *dx_db = 0;
5987#endif /* ENABLE_HTREE */
5988	struct ext2_dir_entry   *dirent, *prev;
5989	ext2_dirhash_t          hash;
5990	unsigned int            offset = 0;
5991	int                     dir_modified = 0;
5992	int                     dot_state;
5993	blk_t                   block_nr = db->blk;
5994	ext2_ino_t              ino = db->ino;
5995	__u16                   links;
5996	struct check_dir_struct *cd;
5997	char                    *buf;
5998	e2fsck_t                ctx;
5999	int                     problem;
6000	struct ext2_dx_root_info *root;
6001	struct ext2_dx_countlimit *limit;
6002	static dict_t de_dict;
6003	struct problem_context  pctx;
6004	int     dups_found = 0;
6005
6006	cd = (struct check_dir_struct *) priv_data;
6007	buf = cd->buf;
6008	ctx = cd->ctx;
6009
6010	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6011		return DIRENT_ABORT;
6012
6013	if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6014		return DIRENT_ABORT;
6015
6016	/*
6017	 * Make sure the inode is still in use (could have been
6018	 * deleted in the duplicate/bad blocks pass.
6019	 */
6020	if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6021		return 0;
6022
6023	cd->pctx.ino = ino;
6024	cd->pctx.blk = block_nr;
6025	cd->pctx.blkcount = db->blockcnt;
6026	cd->pctx.ino2 = 0;
6027	cd->pctx.dirent = 0;
6028	cd->pctx.num = 0;
6029
6030	if (db->blk == 0) {
6031		if (allocate_dir_block(ctx, db, &cd->pctx))
6032			return 0;
6033		block_nr = db->blk;
6034	}
6035
6036	if (db->blockcnt)
6037		dot_state = 2;
6038	else
6039		dot_state = 0;
6040
6041	if (ctx->dirs_to_hash &&
6042	    ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6043		dups_found++;
6044
6045	cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6046	if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6047		cd->pctx.errcode = 0; /* We'll handle this ourselves */
6048	if (cd->pctx.errcode) {
6049		if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6050			ctx->flags |= E2F_FLAG_ABORT;
6051			return DIRENT_ABORT;
6052		}
6053		memset(buf, 0, fs->blocksize);
6054	}
6055#ifdef ENABLE_HTREE
6056	dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6057	if (dx_dir && dx_dir->numblocks) {
6058		if (db->blockcnt >= dx_dir->numblocks) {
6059			printf("XXX should never happen!!!\n");
6060			abort();
6061		}
6062		dx_db = &dx_dir->dx_block[db->blockcnt];
6063		dx_db->type = DX_DIRBLOCK_LEAF;
6064		dx_db->phys = block_nr;
6065		dx_db->min_hash = ~0;
6066		dx_db->max_hash = 0;
6067
6068		dirent = (struct ext2_dir_entry *) buf;
6069		limit = (struct ext2_dx_countlimit *) (buf+8);
6070		if (db->blockcnt == 0) {
6071			root = (struct ext2_dx_root_info *) (buf + 24);
6072			dx_db->type = DX_DIRBLOCK_ROOT;
6073			dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6074			if ((root->reserved_zero ||
6075			     root->info_length < 8 ||
6076			     root->indirect_levels > 1) &&
6077			    fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6078				clear_htree(ctx, ino);
6079				dx_dir->numblocks = 0;
6080				dx_db = 0;
6081			}
6082			dx_dir->hashversion = root->hash_version;
6083			dx_dir->depth = root->indirect_levels + 1;
6084		} else if ((dirent->inode == 0) &&
6085			   (dirent->rec_len == fs->blocksize) &&
6086			   (dirent->name_len == 0) &&
6087			   (ext2fs_le16_to_cpu(limit->limit) ==
6088			    ((fs->blocksize-8) /
6089			     sizeof(struct ext2_dx_entry))))
6090			dx_db->type = DX_DIRBLOCK_NODE;
6091	}
6092#endif /* ENABLE_HTREE */
6093
6094	dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6095	prev = 0;
6096	do {
6097		problem = 0;
6098		dirent = (struct ext2_dir_entry *) (buf + offset);
6099		cd->pctx.dirent = dirent;
6100		cd->pctx.num = offset;
6101		if (((offset + dirent->rec_len) > fs->blocksize) ||
6102		    (dirent->rec_len < 12) ||
6103		    ((dirent->rec_len % 4) != 0) ||
6104		    (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6105			if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6106				salvage_directory(fs, dirent, prev, &offset);
6107				dir_modified++;
6108				continue;
6109			} else
6110				goto abort_free_dict;
6111		}
6112		if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6113			if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6114				dirent->name_len = EXT2_NAME_LEN;
6115				dir_modified++;
6116			}
6117		}
6118
6119		if (dot_state == 0) {
6120			if (check_dot(ctx, dirent, ino, &cd->pctx))
6121				dir_modified++;
6122		} else if (dot_state == 1) {
6123			dir = e2fsck_get_dir_info(ctx, ino);
6124			if (!dir) {
6125				fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6126				goto abort_free_dict;
6127			}
6128			if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6129				dir_modified++;
6130		} else if (dirent->inode == ino) {
6131			problem = PR_2_LINK_DOT;
6132			if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6133				dirent->inode = 0;
6134				dir_modified++;
6135				goto next;
6136			}
6137		}
6138		if (!dirent->inode)
6139			goto next;
6140
6141		/*
6142		 * Make sure the inode listed is a legal one.
6143		 */
6144		if (((dirent->inode != EXT2_ROOT_INO) &&
6145		     (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6146		    (dirent->inode > fs->super->s_inodes_count)) {
6147			problem = PR_2_BAD_INO;
6148		} else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6149					       dirent->inode))) {
6150			/*
6151			 * If the inode is unused, offer to clear it.
6152			 */
6153			problem = PR_2_UNUSED_INODE;
6154		} else if ((dot_state > 1) &&
6155			   ((dirent->name_len & 0xFF) == 1) &&
6156			   (dirent->name[0] == '.')) {
6157			/*
6158			 * If there's a '.' entry in anything other
6159			 * than the first directory entry, it's a
6160			 * duplicate entry that should be removed.
6161			 */
6162			problem = PR_2_DUP_DOT;
6163		} else if ((dot_state > 1) &&
6164			   ((dirent->name_len & 0xFF) == 2) &&
6165			   (dirent->name[0] == '.') &&
6166			   (dirent->name[1] == '.')) {
6167			/*
6168			 * If there's a '..' entry in anything other
6169			 * than the second directory entry, it's a
6170			 * duplicate entry that should be removed.
6171			 */
6172			problem = PR_2_DUP_DOT_DOT;
6173		} else if ((dot_state > 1) &&
6174			   (dirent->inode == EXT2_ROOT_INO)) {
6175			/*
6176			 * Don't allow links to the root directory.
6177			 * We check this specially to make sure we
6178			 * catch this error case even if the root
6179			 * directory hasn't been created yet.
6180			 */
6181			problem = PR_2_LINK_ROOT;
6182		} else if ((dot_state > 1) &&
6183			   (dirent->name_len & 0xFF) == 0) {
6184			/*
6185			 * Don't allow zero-length directory names.
6186			 */
6187			problem = PR_2_NULL_NAME;
6188		}
6189
6190		if (problem) {
6191			if (fix_problem(ctx, problem, &cd->pctx)) {
6192				dirent->inode = 0;
6193				dir_modified++;
6194				goto next;
6195			} else {
6196				ext2fs_unmark_valid(fs);
6197				if (problem == PR_2_BAD_INO)
6198					goto next;
6199			}
6200		}
6201
6202		/*
6203		 * If the inode was marked as having bad fields in
6204		 * pass1, process it and offer to fix/clear it.
6205		 * (We wait until now so that we can display the
6206		 * pathname to the user.)
6207		 */
6208		if (ctx->inode_bad_map &&
6209		    ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6210					     dirent->inode)) {
6211			if (e2fsck_process_bad_inode(ctx, ino,
6212						     dirent->inode,
6213						     buf + fs->blocksize)) {
6214				dirent->inode = 0;
6215				dir_modified++;
6216				goto next;
6217			}
6218			if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6219				return DIRENT_ABORT;
6220		}
6221
6222		if (check_name(ctx, dirent, &cd->pctx))
6223			dir_modified++;
6224
6225		if (check_filetype(ctx, dirent, &cd->pctx))
6226			dir_modified++;
6227
6228#ifdef ENABLE_HTREE
6229		if (dx_db) {
6230			ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6231				       (dirent->name_len & 0xFF),
6232				       fs->super->s_hash_seed, &hash, 0);
6233			if (hash < dx_db->min_hash)
6234				dx_db->min_hash = hash;
6235			if (hash > dx_db->max_hash)
6236				dx_db->max_hash = hash;
6237		}
6238#endif
6239
6240		/*
6241		 * If this is a directory, then mark its parent in its
6242		 * dir_info structure.  If the parent field is already
6243		 * filled in, then this directory has more than one
6244		 * hard link.  We assume the first link is correct,
6245		 * and ask the user if he/she wants to clear this one.
6246		 */
6247		if ((dot_state > 1) &&
6248		    (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6249					      dirent->inode))) {
6250			subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6251			if (!subdir) {
6252				cd->pctx.ino = dirent->inode;
6253				fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6254				goto abort_free_dict;
6255			}
6256			if (subdir->parent) {
6257				cd->pctx.ino2 = subdir->parent;
6258				if (fix_problem(ctx, PR_2_LINK_DIR,
6259						&cd->pctx)) {
6260					dirent->inode = 0;
6261					dir_modified++;
6262					goto next;
6263				}
6264				cd->pctx.ino2 = 0;
6265			} else
6266				subdir->parent = ino;
6267		}
6268
6269		if (dups_found) {
6270			;
6271		} else if (dict_lookup(&de_dict, dirent)) {
6272			clear_problem_context(&pctx);
6273			pctx.ino = ino;
6274			pctx.dirent = dirent;
6275			fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6276			if (!ctx->dirs_to_hash)
6277				ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6278			if (ctx->dirs_to_hash)
6279				ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6280			dups_found++;
6281		} else
6282			dict_alloc_insert(&de_dict, dirent, dirent);
6283
6284		ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6285					&links);
6286		if (links > 1)
6287			ctx->fs_links_count++;
6288		ctx->fs_total_count++;
6289	next:
6290		prev = dirent;
6291		offset += dirent->rec_len;
6292		dot_state++;
6293	} while (offset < fs->blocksize);
6294#ifdef ENABLE_HTREE
6295	if (dx_db) {
6296		cd->pctx.dir = cd->pctx.ino;
6297		if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6298		    (dx_db->type == DX_DIRBLOCK_NODE))
6299			parse_int_node(fs, db, cd, dx_dir, buf);
6300	}
6301#endif /* ENABLE_HTREE */
6302	if (offset != fs->blocksize) {
6303		cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6304		if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6305			dirent->rec_len = cd->pctx.num;
6306			dir_modified++;
6307		}
6308	}
6309	if (dir_modified) {
6310		cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6311		if (cd->pctx.errcode) {
6312			if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6313					 &cd->pctx))
6314				goto abort_free_dict;
6315		}
6316		ext2fs_mark_changed(fs);
6317	}
6318	dict_free_nodes(&de_dict);
6319	return 0;
6320abort_free_dict:
6321	dict_free_nodes(&de_dict);
6322	ctx->flags |= E2F_FLAG_ABORT;
6323	return DIRENT_ABORT;
6324}
6325
6326/*
6327 * This function is called to deallocate a block, and is an interator
6328 * functioned called by deallocate inode via ext2fs_iterate_block().
6329 */
6330static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6331				  e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6332				  blk_t ref_block FSCK_ATTR((unused)),
6333				  int ref_offset FSCK_ATTR((unused)),
6334				  void *priv_data)
6335{
6336	e2fsck_t        ctx = (e2fsck_t) priv_data;
6337
6338	if (HOLE_BLKADDR(*block_nr))
6339		return 0;
6340	if ((*block_nr < fs->super->s_first_data_block) ||
6341	    (*block_nr >= fs->super->s_blocks_count))
6342		return 0;
6343	ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6344	ext2fs_block_alloc_stats(fs, *block_nr, -1);
6345	return 0;
6346}
6347
6348/*
6349 * This fuction deallocates an inode
6350 */
6351static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6352{
6353	ext2_filsys fs = ctx->fs;
6354	struct ext2_inode       inode;
6355	struct problem_context  pctx;
6356	__u32                   count;
6357
6358	ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6359	e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6360	inode.i_links_count = 0;
6361	inode.i_dtime = time(0);
6362	e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6363	clear_problem_context(&pctx);
6364	pctx.ino = ino;
6365
6366	/*
6367	 * Fix up the bitmaps...
6368	 */
6369	e2fsck_read_bitmaps(ctx);
6370	ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6371	ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6372	if (ctx->inode_bad_map)
6373		ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6374	ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6375
6376	if (inode.i_file_acl &&
6377	    (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6378		pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6379						   block_buf, -1, &count);
6380		if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6381			pctx.errcode = 0;
6382			count = 1;
6383		}
6384		if (pctx.errcode) {
6385			pctx.blk = inode.i_file_acl;
6386			fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6387			ctx->flags |= E2F_FLAG_ABORT;
6388			return;
6389		}
6390		if (count == 0) {
6391			ext2fs_unmark_block_bitmap(ctx->block_found_map,
6392						   inode.i_file_acl);
6393			ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6394		}
6395		inode.i_file_acl = 0;
6396	}
6397
6398	if (!ext2fs_inode_has_valid_blocks(&inode))
6399		return;
6400
6401	if (LINUX_S_ISREG(inode.i_mode) &&
6402	    (inode.i_size_high || inode.i_size & 0x80000000UL))
6403		ctx->large_files--;
6404
6405	pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6406					    deallocate_inode_block, ctx);
6407	if (pctx.errcode) {
6408		fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6409		ctx->flags |= E2F_FLAG_ABORT;
6410		return;
6411	}
6412}
6413
6414/*
6415 * This fuction clears the htree flag on an inode
6416 */
6417static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6418{
6419	struct ext2_inode       inode;
6420
6421	e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6422	inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6423	e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6424	if (ctx->dirs_to_hash)
6425		ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6426}
6427
6428
6429static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6430				    ext2_ino_t ino, char *buf)
6431{
6432	ext2_filsys fs = ctx->fs;
6433	struct ext2_inode       inode;
6434	int                     inode_modified = 0;
6435	int                     not_fixed = 0;
6436	unsigned char           *frag, *fsize;
6437	struct problem_context  pctx;
6438	int     problem = 0;
6439
6440	e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6441
6442	clear_problem_context(&pctx);
6443	pctx.ino = ino;
6444	pctx.dir = dir;
6445	pctx.inode = &inode;
6446
6447	if (inode.i_file_acl &&
6448	    !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6449	    fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6450		inode.i_file_acl = 0;
6451#if BB_BIG_ENDIAN
6452		/*
6453		 * This is a special kludge to deal with long symlinks
6454		 * on big endian systems.  i_blocks had already been
6455		 * decremented earlier in pass 1, but since i_file_acl
6456		 * hadn't yet been cleared, ext2fs_read_inode()
6457		 * assumed that the file was short symlink and would
6458		 * not have byte swapped i_block[0].  Hence, we have
6459		 * to byte-swap it here.
6460		 */
6461		if (LINUX_S_ISLNK(inode.i_mode) &&
6462		    (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6463		    (inode.i_blocks == fs->blocksize >> 9))
6464			inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6465#endif
6466		inode_modified++;
6467	} else
6468		not_fixed++;
6469
6470	if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6471	    !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6472	    !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6473	    !(LINUX_S_ISSOCK(inode.i_mode)))
6474		problem = PR_2_BAD_MODE;
6475	else if (LINUX_S_ISCHR(inode.i_mode)
6476		 && !e2fsck_pass1_check_device_inode(fs, &inode))
6477		problem = PR_2_BAD_CHAR_DEV;
6478	else if (LINUX_S_ISBLK(inode.i_mode)
6479		 && !e2fsck_pass1_check_device_inode(fs, &inode))
6480		problem = PR_2_BAD_BLOCK_DEV;
6481	else if (LINUX_S_ISFIFO(inode.i_mode)
6482		 && !e2fsck_pass1_check_device_inode(fs, &inode))
6483		problem = PR_2_BAD_FIFO;
6484	else if (LINUX_S_ISSOCK(inode.i_mode)
6485		 && !e2fsck_pass1_check_device_inode(fs, &inode))
6486		problem = PR_2_BAD_SOCKET;
6487	else if (LINUX_S_ISLNK(inode.i_mode)
6488		 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6489		problem = PR_2_INVALID_SYMLINK;
6490	}
6491
6492	if (problem) {
6493		if (fix_problem(ctx, problem, &pctx)) {
6494			deallocate_inode(ctx, ino, 0);
6495			if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6496				return 0;
6497			return 1;
6498		} else
6499			not_fixed++;
6500		problem = 0;
6501	}
6502
6503	if (inode.i_faddr) {
6504		if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6505			inode.i_faddr = 0;
6506			inode_modified++;
6507		} else
6508			not_fixed++;
6509	}
6510
6511	switch (fs->super->s_creator_os) {
6512	    case EXT2_OS_LINUX:
6513		frag = &inode.osd2.linux2.l_i_frag;
6514		fsize = &inode.osd2.linux2.l_i_fsize;
6515		break;
6516	    case EXT2_OS_HURD:
6517		frag = &inode.osd2.hurd2.h_i_frag;
6518		fsize = &inode.osd2.hurd2.h_i_fsize;
6519		break;
6520	    case EXT2_OS_MASIX:
6521		frag = &inode.osd2.masix2.m_i_frag;
6522		fsize = &inode.osd2.masix2.m_i_fsize;
6523		break;
6524	    default:
6525		frag = fsize = 0;
6526	}
6527	if (frag && *frag) {
6528		pctx.num = *frag;
6529		if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6530			*frag = 0;
6531			inode_modified++;
6532		} else
6533			not_fixed++;
6534		pctx.num = 0;
6535	}
6536	if (fsize && *fsize) {
6537		pctx.num = *fsize;
6538		if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6539			*fsize = 0;
6540			inode_modified++;
6541		} else
6542			not_fixed++;
6543		pctx.num = 0;
6544	}
6545
6546	if (inode.i_file_acl &&
6547	    ((inode.i_file_acl < fs->super->s_first_data_block) ||
6548	     (inode.i_file_acl >= fs->super->s_blocks_count))) {
6549		if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6550			inode.i_file_acl = 0;
6551			inode_modified++;
6552		} else
6553			not_fixed++;
6554	}
6555	if (inode.i_dir_acl &&
6556	    LINUX_S_ISDIR(inode.i_mode)) {
6557		if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6558			inode.i_dir_acl = 0;
6559			inode_modified++;
6560		} else
6561			not_fixed++;
6562	}
6563
6564	if (inode_modified)
6565		e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6566	if (!not_fixed)
6567		ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6568	return 0;
6569}
6570
6571
6572/*
6573 * allocate_dir_block --- this function allocates a new directory
6574 *      block for a particular inode; this is done if a directory has
6575 *      a "hole" in it, or if a directory has a illegal block number
6576 *      that was zeroed out and now needs to be replaced.
6577 */
6578static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6579			      struct problem_context *pctx)
6580{
6581	ext2_filsys fs = ctx->fs;
6582	blk_t                   blk;
6583	char                    *block;
6584	struct ext2_inode       inode;
6585
6586	if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6587		return 1;
6588
6589	/*
6590	 * Read the inode and block bitmaps in; we'll be messing with
6591	 * them.
6592	 */
6593	e2fsck_read_bitmaps(ctx);
6594
6595	/*
6596	 * First, find a free block
6597	 */
6598	pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6599	if (pctx->errcode) {
6600		pctx->str = "ext2fs_new_block";
6601		fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6602		return 1;
6603	}
6604	ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6605	ext2fs_mark_block_bitmap(fs->block_map, blk);
6606	ext2fs_mark_bb_dirty(fs);
6607
6608	/*
6609	 * Now let's create the actual data block for the inode
6610	 */
6611	if (db->blockcnt)
6612		pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6613	else
6614		pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6615						     EXT2_ROOT_INO, &block);
6616
6617	if (pctx->errcode) {
6618		pctx->str = "ext2fs_new_dir_block";
6619		fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6620		return 1;
6621	}
6622
6623	pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6624	ext2fs_free_mem(&block);
6625	if (pctx->errcode) {
6626		pctx->str = "ext2fs_write_dir_block";
6627		fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6628		return 1;
6629	}
6630
6631	/*
6632	 * Update the inode block count
6633	 */
6634	e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6635	inode.i_blocks += fs->blocksize / 512;
6636	if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6637		inode.i_size = (db->blockcnt+1) * fs->blocksize;
6638	e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6639
6640	/*
6641	 * Finally, update the block pointers for the inode
6642	 */
6643	db->blk = blk;
6644	pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6645				      0, update_dir_block, db);
6646	if (pctx->errcode) {
6647		pctx->str = "ext2fs_block_iterate";
6648		fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6649		return 1;
6650	}
6651
6652	return 0;
6653}
6654
6655/*
6656 * This is a helper function for allocate_dir_block().
6657 */
6658static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6659			    blk_t       *block_nr,
6660			    e2_blkcnt_t blockcnt,
6661			    blk_t ref_block FSCK_ATTR((unused)),
6662			    int ref_offset FSCK_ATTR((unused)),
6663			    void *priv_data)
6664{
6665	struct ext2_db_entry *db;
6666
6667	db = (struct ext2_db_entry *) priv_data;
6668	if (db->blockcnt == (int) blockcnt) {
6669		*block_nr = db->blk;
6670		return BLOCK_CHANGED;
6671	}
6672	return 0;
6673}
6674
6675/*
6676 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6677 *
6678 * Pass #3 assures that all directories are connected to the
6679 * filesystem tree, using the following algorithm:
6680 *
6681 * First, the root directory is checked to make sure it exists; if
6682 * not, e2fsck will offer to create a new one.  It is then marked as
6683 * "done".
6684 *
6685 * Then, pass3 interates over all directory inodes; for each directory
6686 * it attempts to trace up the filesystem tree, using dirinfo.parent
6687 * until it reaches a directory which has been marked "done".  If it
6688 * cannot do so, then the directory must be disconnected, and e2fsck
6689 * will offer to reconnect it to /lost+found.  While it is chasing
6690 * parent pointers up the filesystem tree, if pass3 sees a directory
6691 * twice, then it has detected a filesystem loop, and it will again
6692 * offer to reconnect the directory to /lost+found in to break the
6693 * filesystem loop.
6694 *
6695 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6696 * reconnect inodes to /lost+found; this subroutine is also used by
6697 * pass 4.  e2fsck_reconnect_file() calls get_lost_and_found(), which
6698 * is responsible for creating /lost+found if it does not exist.
6699 *
6700 * Pass 3 frees the following data structures:
6701 *      - The dirinfo directory information cache.
6702 */
6703
6704static void check_root(e2fsck_t ctx);
6705static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6706			   struct problem_context *pctx);
6707static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6708
6709static ext2fs_inode_bitmap inode_loop_detect;
6710static ext2fs_inode_bitmap inode_done_map;
6711
6712static void e2fsck_pass3(e2fsck_t ctx)
6713{
6714	ext2_filsys fs = ctx->fs;
6715	int             i;
6716	struct problem_context  pctx;
6717	struct dir_info *dir;
6718	unsigned long maxdirs, count;
6719
6720	clear_problem_context(&pctx);
6721
6722	/* Pass 3 */
6723
6724	if (!(ctx->options & E2F_OPT_PREEN))
6725		fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6726
6727	/*
6728	 * Allocate some bitmaps to do loop detection.
6729	 */
6730	pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6731						    &inode_done_map);
6732	if (pctx.errcode) {
6733		pctx.num = 2;
6734		fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6735		ctx->flags |= E2F_FLAG_ABORT;
6736		goto abort_exit;
6737	}
6738	check_root(ctx);
6739	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6740		goto abort_exit;
6741
6742	ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6743
6744	maxdirs = e2fsck_get_num_dirinfo(ctx);
6745	count = 1;
6746
6747	if (ctx->progress)
6748		if ((ctx->progress)(ctx, 3, 0, maxdirs))
6749			goto abort_exit;
6750
6751	for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6752		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6753			goto abort_exit;
6754		if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6755			goto abort_exit;
6756		if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6757			if (check_directory(ctx, dir, &pctx))
6758				goto abort_exit;
6759	}
6760
6761	/*
6762	 * Force the creation of /lost+found if not present
6763	 */
6764	if ((ctx->flags & E2F_OPT_READONLY) == 0)
6765		e2fsck_get_lost_and_found(ctx, 1);
6766
6767	/*
6768	 * If there are any directories that need to be indexed or
6769	 * optimized, do it here.
6770	 */
6771	e2fsck_rehash_directories(ctx);
6772
6773abort_exit:
6774	e2fsck_free_dir_info(ctx);
6775	ext2fs_free_inode_bitmap(inode_loop_detect);
6776	inode_loop_detect = 0;
6777	ext2fs_free_inode_bitmap(inode_done_map);
6778	inode_done_map = 0;
6779}
6780
6781/*
6782 * This makes sure the root inode is present; if not, we ask if the
6783 * user wants us to create it.  Not creating it is a fatal error.
6784 */
6785static void check_root(e2fsck_t ctx)
6786{
6787	ext2_filsys fs = ctx->fs;
6788	blk_t                   blk;
6789	struct ext2_inode       inode;
6790	char *                  block;
6791	struct problem_context  pctx;
6792
6793	clear_problem_context(&pctx);
6794
6795	if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6796		/*
6797		 * If the root inode is not a directory, die here.  The
6798		 * user must have answered 'no' in pass1 when we
6799		 * offered to clear it.
6800		 */
6801		if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6802					       EXT2_ROOT_INO))) {
6803			fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6804			ctx->flags |= E2F_FLAG_ABORT;
6805		}
6806		return;
6807	}
6808
6809	if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6810		fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6811		ctx->flags |= E2F_FLAG_ABORT;
6812		return;
6813	}
6814
6815	e2fsck_read_bitmaps(ctx);
6816
6817	/*
6818	 * First, find a free block
6819	 */
6820	pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6821	if (pctx.errcode) {
6822		pctx.str = "ext2fs_new_block";
6823		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6824		ctx->flags |= E2F_FLAG_ABORT;
6825		return;
6826	}
6827	ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6828	ext2fs_mark_block_bitmap(fs->block_map, blk);
6829	ext2fs_mark_bb_dirty(fs);
6830
6831	/*
6832	 * Now let's create the actual data block for the inode
6833	 */
6834	pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6835					    &block);
6836	if (pctx.errcode) {
6837		pctx.str = "ext2fs_new_dir_block";
6838		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6839		ctx->flags |= E2F_FLAG_ABORT;
6840		return;
6841	}
6842
6843	pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6844	if (pctx.errcode) {
6845		pctx.str = "ext2fs_write_dir_block";
6846		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6847		ctx->flags |= E2F_FLAG_ABORT;
6848		return;
6849	}
6850	ext2fs_free_mem(&block);
6851
6852	/*
6853	 * Set up the inode structure
6854	 */
6855	memset(&inode, 0, sizeof(inode));
6856	inode.i_mode = 040755;
6857	inode.i_size = fs->blocksize;
6858	inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
6859	inode.i_links_count = 2;
6860	inode.i_blocks = fs->blocksize / 512;
6861	inode.i_block[0] = blk;
6862
6863	/*
6864	 * Write out the inode.
6865	 */
6866	pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6867	if (pctx.errcode) {
6868		pctx.str = "ext2fs_write_inode";
6869		fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6870		ctx->flags |= E2F_FLAG_ABORT;
6871		return;
6872	}
6873
6874	/*
6875	 * Miscellaneous bookkeeping...
6876	 */
6877	e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6878	ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6879	ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6880
6881	ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6882	ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6883	ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6884	ext2fs_mark_ib_dirty(fs);
6885}
6886
6887/*
6888 * This subroutine is responsible for making sure that a particular
6889 * directory is connected to the root; if it isn't we trace it up as
6890 * far as we can go, and then offer to connect the resulting parent to
6891 * the lost+found.  We have to do loop detection; if we ever discover
6892 * a loop, we treat that as a disconnected directory and offer to
6893 * reparent it to lost+found.
6894 *
6895 * However, loop detection is expensive, because for very large
6896 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6897 * is non-trivial.  Loops in filesystems are also a rare error case,
6898 * and we shouldn't optimize for error cases.  So we try two passes of
6899 * the algorithm.  The first time, we ignore loop detection and merely
6900 * increment a counter; if the counter exceeds some extreme threshold,
6901 * then we try again with the loop detection bitmap enabled.
6902 */
6903static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6904			   struct problem_context *pctx)
6905{
6906	ext2_filsys     fs = ctx->fs;
6907	struct dir_info *p = dir;
6908	int             loop_pass = 0, parent_count = 0;
6909
6910	if (!p)
6911		return 0;
6912
6913	while (1) {
6914		/*
6915		 * Mark this inode as being "done"; by the time we
6916		 * return from this function, the inode we either be
6917		 * verified as being connected to the directory tree,
6918		 * or we will have offered to reconnect this to
6919		 * lost+found.
6920		 *
6921		 * If it was marked done already, then we've reached a
6922		 * parent we've already checked.
6923		 */
6924		if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6925			break;
6926
6927		/*
6928		 * If this directory doesn't have a parent, or we've
6929		 * seen the parent once already, then offer to
6930		 * reparent it to lost+found
6931		 */
6932		if (!p->parent ||
6933		    (loop_pass &&
6934		     (ext2fs_test_inode_bitmap(inode_loop_detect,
6935					      p->parent)))) {
6936			pctx->ino = p->ino;
6937			if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6938				if (e2fsck_reconnect_file(ctx, pctx->ino))
6939					ext2fs_unmark_valid(fs);
6940				else {
6941					p = e2fsck_get_dir_info(ctx, pctx->ino);
6942					p->parent = ctx->lost_and_found;
6943					fix_dotdot(ctx, p, ctx->lost_and_found);
6944				}
6945			}
6946			break;
6947		}
6948		p = e2fsck_get_dir_info(ctx, p->parent);
6949		if (!p) {
6950			fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
6951			return 0;
6952		}
6953		if (loop_pass) {
6954			ext2fs_mark_inode_bitmap(inode_loop_detect,
6955						 p->ino);
6956		} else if (parent_count++ > 2048) {
6957			/*
6958			 * If we've run into a path depth that's
6959			 * greater than 2048, try again with the inode
6960			 * loop bitmap turned on and start from the
6961			 * top.
6962			 */
6963			loop_pass = 1;
6964			if (inode_loop_detect)
6965				ext2fs_clear_inode_bitmap(inode_loop_detect);
6966			else {
6967				pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
6968				if (pctx->errcode) {
6969					pctx->num = 1;
6970					fix_problem(ctx,
6971				    PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
6972					ctx->flags |= E2F_FLAG_ABORT;
6973					return -1;
6974				}
6975			}
6976			p = dir;
6977		}
6978	}
6979
6980	/*
6981	 * Make sure that .. and the parent directory are the same;
6982	 * offer to fix it if not.
6983	 */
6984	if (dir->parent != dir->dotdot) {
6985		pctx->ino = dir->ino;
6986		pctx->ino2 = dir->dotdot;
6987		pctx->dir = dir->parent;
6988		if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
6989			fix_dotdot(ctx, dir, dir->parent);
6990	}
6991	return 0;
6992}
6993
6994/*
6995 * This routine gets the lost_and_found inode, making it a directory
6996 * if necessary
6997 */
6998ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
6999{
7000	ext2_filsys fs = ctx->fs;
7001	ext2_ino_t                      ino;
7002	blk_t                   blk;
7003	errcode_t               retval;
7004	struct ext2_inode       inode;
7005	char *                  block;
7006	static const char       name[] = "lost+found";
7007	struct  problem_context pctx;
7008	struct dir_info         *dirinfo;
7009
7010	if (ctx->lost_and_found)
7011		return ctx->lost_and_found;
7012
7013	clear_problem_context(&pctx);
7014
7015	retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7016			       sizeof(name)-1, 0, &ino);
7017	if (retval && !fix)
7018		return 0;
7019	if (!retval) {
7020		if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7021			ctx->lost_and_found = ino;
7022			return ino;
7023		}
7024
7025		/* Lost+found isn't a directory! */
7026		if (!fix)
7027			return 0;
7028		pctx.ino = ino;
7029		if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7030			return 0;
7031
7032		/* OK, unlink the old /lost+found file. */
7033		pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7034		if (pctx.errcode) {
7035			pctx.str = "ext2fs_unlink";
7036			fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7037			return 0;
7038		}
7039		dirinfo = e2fsck_get_dir_info(ctx, ino);
7040		if (dirinfo)
7041			dirinfo->parent = 0;
7042		e2fsck_adjust_inode_count(ctx, ino, -1);
7043	} else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7044		pctx.errcode = retval;
7045		fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7046	}
7047	if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7048		return 0;
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	retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7060	if (retval) {
7061		pctx.errcode = retval;
7062		fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7063		return 0;
7064	}
7065	ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7066	ext2fs_block_alloc_stats(fs, blk, +1);
7067
7068	/*
7069	 * Next find a free inode.
7070	 */
7071	retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7072				  ctx->inode_used_map, &ino);
7073	if (retval) {
7074		pctx.errcode = retval;
7075		fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7076		return 0;
7077	}
7078	ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7079	ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7080	ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7081
7082	/*
7083	 * Now let's create the actual data block for the inode
7084	 */
7085	retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7086	if (retval) {
7087		pctx.errcode = retval;
7088		fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7089		return 0;
7090	}
7091
7092	retval = ext2fs_write_dir_block(fs, blk, block);
7093	ext2fs_free_mem(&block);
7094	if (retval) {
7095		pctx.errcode = retval;
7096		fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7097		return 0;
7098	}
7099
7100	/*
7101	 * Set up the inode structure
7102	 */
7103	memset(&inode, 0, sizeof(inode));
7104	inode.i_mode = 040700;
7105	inode.i_size = fs->blocksize;
7106	inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7107	inode.i_links_count = 2;
7108	inode.i_blocks = fs->blocksize / 512;
7109	inode.i_block[0] = blk;
7110
7111	/*
7112	 * Next, write out the inode.
7113	 */
7114	pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7115	if (pctx.errcode) {
7116		pctx.str = "ext2fs_write_inode";
7117		fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7118		return 0;
7119	}
7120	/*
7121	 * Finally, create the directory link
7122	 */
7123	pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7124	if (pctx.errcode) {
7125		pctx.str = "ext2fs_link";
7126		fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7127		return 0;
7128	}
7129
7130	/*
7131	 * Miscellaneous bookkeeping that needs to be kept straight.
7132	 */
7133	e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7134	e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7135	ext2fs_icount_store(ctx->inode_count, ino, 2);
7136	ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7137	ctx->lost_and_found = ino;
7138	return ino;
7139}
7140
7141/*
7142 * This routine will connect a file to lost+found
7143 */
7144int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7145{
7146	ext2_filsys fs = ctx->fs;
7147	errcode_t       retval;
7148	char            name[80];
7149	struct problem_context  pctx;
7150	struct ext2_inode       inode;
7151	int             file_type = 0;
7152
7153	clear_problem_context(&pctx);
7154	pctx.ino = ino;
7155
7156	if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7157		if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7158			ctx->bad_lost_and_found++;
7159	}
7160	if (ctx->bad_lost_and_found) {
7161		fix_problem(ctx, PR_3_NO_LPF, &pctx);
7162		return 1;
7163	}
7164
7165	sprintf(name, "#%u", ino);
7166	if (ext2fs_read_inode(fs, ino, &inode) == 0)
7167		file_type = ext2_file_type(inode.i_mode);
7168	retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7169	if (retval == EXT2_ET_DIR_NO_SPACE) {
7170		if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7171			return 1;
7172		retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7173						 1, 0);
7174		if (retval) {
7175			pctx.errcode = retval;
7176			fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7177			return 1;
7178		}
7179		retval = ext2fs_link(fs, ctx->lost_and_found, name,
7180				     ino, file_type);
7181	}
7182	if (retval) {
7183		pctx.errcode = retval;
7184		fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7185		return 1;
7186	}
7187	e2fsck_adjust_inode_count(ctx, ino, 1);
7188
7189	return 0;
7190}
7191
7192/*
7193 * Utility routine to adjust the inode counts on an inode.
7194 */
7195errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7196{
7197	ext2_filsys fs = ctx->fs;
7198	errcode_t               retval;
7199	struct ext2_inode       inode;
7200
7201	if (!ino)
7202		return 0;
7203
7204	retval = ext2fs_read_inode(fs, ino, &inode);
7205	if (retval)
7206		return retval;
7207
7208	if (adj == 1) {
7209		ext2fs_icount_increment(ctx->inode_count, ino, 0);
7210		if (inode.i_links_count == (__u16) ~0)
7211			return 0;
7212		ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7213		inode.i_links_count++;
7214	} else if (adj == -1) {
7215		ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7216		if (inode.i_links_count == 0)
7217			return 0;
7218		ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7219		inode.i_links_count--;
7220	}
7221
7222	retval = ext2fs_write_inode(fs, ino, &inode);
7223	if (retval)
7224		return retval;
7225
7226	return 0;
7227}
7228
7229/*
7230 * Fix parent --- this routine fixes up the parent of a directory.
7231 */
7232struct fix_dotdot_struct {
7233	ext2_filsys     fs;
7234	ext2_ino_t      parent;
7235	int             done;
7236	e2fsck_t        ctx;
7237};
7238
7239static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7240			   int  offset FSCK_ATTR((unused)),
7241			   int  blocksize FSCK_ATTR((unused)),
7242			   char *buf FSCK_ATTR((unused)),
7243			   void *priv_data)
7244{
7245	struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7246	errcode_t       retval;
7247	struct problem_context pctx;
7248
7249	if ((dirent->name_len & 0xFF) != 2)
7250		return 0;
7251	if (strncmp(dirent->name, "..", 2))
7252		return 0;
7253
7254	clear_problem_context(&pctx);
7255
7256	retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7257	if (retval) {
7258		pctx.errcode = retval;
7259		fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7260	}
7261	retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7262	if (retval) {
7263		pctx.errcode = retval;
7264		fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7265	}
7266	dirent->inode = fp->parent;
7267
7268	fp->done++;
7269	return DIRENT_ABORT | DIRENT_CHANGED;
7270}
7271
7272static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7273{
7274	ext2_filsys fs = ctx->fs;
7275	errcode_t       retval;
7276	struct fix_dotdot_struct fp;
7277	struct problem_context pctx;
7278
7279	fp.fs = fs;
7280	fp.parent = parent;
7281	fp.done = 0;
7282	fp.ctx = ctx;
7283
7284	retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7285				    0, fix_dotdot_proc, &fp);
7286	if (retval || !fp.done) {
7287		clear_problem_context(&pctx);
7288		pctx.ino = dir->ino;
7289		pctx.errcode = retval;
7290		fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7291			    PR_3_FIX_PARENT_NOFIND, &pctx);
7292		ext2fs_unmark_valid(fs);
7293	}
7294	dir->dotdot = parent;
7295}
7296
7297/*
7298 * These routines are responsible for expanding a /lost+found if it is
7299 * too small.
7300 */
7301
7302struct expand_dir_struct {
7303	int                     num;
7304	int                     guaranteed_size;
7305	int                     newblocks;
7306	int                     last_block;
7307	errcode_t               err;
7308	e2fsck_t                ctx;
7309};
7310
7311static int expand_dir_proc(ext2_filsys fs,
7312			   blk_t        *blocknr,
7313			   e2_blkcnt_t  blockcnt,
7314			   blk_t ref_block FSCK_ATTR((unused)),
7315			   int ref_offset FSCK_ATTR((unused)),
7316			   void *priv_data)
7317{
7318	struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7319	blk_t   new_blk;
7320	static blk_t    last_blk = 0;
7321	char            *block;
7322	errcode_t       retval;
7323	e2fsck_t        ctx;
7324
7325	ctx = es->ctx;
7326
7327	if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7328		return BLOCK_ABORT;
7329
7330	if (blockcnt > 0)
7331		es->last_block = blockcnt;
7332	if (*blocknr) {
7333		last_blk = *blocknr;
7334		return 0;
7335	}
7336	retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7337				  &new_blk);
7338	if (retval) {
7339		es->err = retval;
7340		return BLOCK_ABORT;
7341	}
7342	if (blockcnt > 0) {
7343		retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7344		if (retval) {
7345			es->err = retval;
7346			return BLOCK_ABORT;
7347		}
7348		es->num--;
7349		retval = ext2fs_write_dir_block(fs, new_blk, block);
7350	} else {
7351		retval = ext2fs_get_mem(fs->blocksize, &block);
7352		if (retval) {
7353			es->err = retval;
7354			return BLOCK_ABORT;
7355		}
7356		memset(block, 0, fs->blocksize);
7357		retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7358	}
7359	if (retval) {
7360		es->err = retval;
7361		return BLOCK_ABORT;
7362	}
7363	ext2fs_free_mem(&block);
7364	*blocknr = new_blk;
7365	ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7366	ext2fs_block_alloc_stats(fs, new_blk, +1);
7367	es->newblocks++;
7368
7369	if (es->num == 0)
7370		return (BLOCK_CHANGED | BLOCK_ABORT);
7371	else
7372		return BLOCK_CHANGED;
7373}
7374
7375errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7376				  int num, int guaranteed_size)
7377{
7378	ext2_filsys fs = ctx->fs;
7379	errcode_t       retval;
7380	struct expand_dir_struct es;
7381	struct ext2_inode       inode;
7382
7383	if (!(fs->flags & EXT2_FLAG_RW))
7384		return EXT2_ET_RO_FILSYS;
7385
7386	/*
7387	 * Read the inode and block bitmaps in; we'll be messing with
7388	 * them.
7389	 */
7390	e2fsck_read_bitmaps(ctx);
7391
7392	retval = ext2fs_check_directory(fs, dir);
7393	if (retval)
7394		return retval;
7395
7396	es.num = num;
7397	es.guaranteed_size = guaranteed_size;
7398	es.last_block = 0;
7399	es.err = 0;
7400	es.newblocks = 0;
7401	es.ctx = ctx;
7402
7403	retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7404				       0, expand_dir_proc, &es);
7405
7406	if (es.err)
7407		return es.err;
7408
7409	/*
7410	 * Update the size and block count fields in the inode.
7411	 */
7412	retval = ext2fs_read_inode(fs, dir, &inode);
7413	if (retval)
7414		return retval;
7415
7416	inode.i_size = (es.last_block + 1) * fs->blocksize;
7417	inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7418
7419	e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7420
7421	return 0;
7422}
7423
7424/*
7425 * pass4.c -- pass #4 of e2fsck: Check reference counts
7426 *
7427 * Pass 4 frees the following data structures:
7428 *      - A bitmap of which inodes are imagic inodes.   (inode_imagic_map)
7429 */
7430
7431/*
7432 * This routine is called when an inode is not connected to the
7433 * directory tree.
7434 *
7435 * This subroutine returns 1 then the caller shouldn't bother with the
7436 * rest of the pass 4 tests.
7437 */
7438static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7439{
7440	ext2_filsys fs = ctx->fs;
7441	struct ext2_inode       inode;
7442	struct problem_context  pctx;
7443
7444	e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7445	clear_problem_context(&pctx);
7446	pctx.ino = i;
7447	pctx.inode = &inode;
7448
7449	/*
7450	 * Offer to delete any zero-length files that does not have
7451	 * blocks.  If there is an EA block, it might have useful
7452	 * information, so we won't prompt to delete it, but let it be
7453	 * reconnected to lost+found.
7454	 */
7455	if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7456				LINUX_S_ISDIR(inode.i_mode))) {
7457		if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7458			ext2fs_icount_store(ctx->inode_link_info, i, 0);
7459			inode.i_links_count = 0;
7460			inode.i_dtime = time(0);
7461			e2fsck_write_inode(ctx, i, &inode,
7462					   "disconnect_inode");
7463			/*
7464			 * Fix up the bitmaps...
7465			 */
7466			e2fsck_read_bitmaps(ctx);
7467			ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7468			ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7469			ext2fs_inode_alloc_stats2(fs, i, -1,
7470						  LINUX_S_ISDIR(inode.i_mode));
7471			return 0;
7472		}
7473	}
7474
7475	/*
7476	 * Prompt to reconnect.
7477	 */
7478	if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7479		if (e2fsck_reconnect_file(ctx, i))
7480			ext2fs_unmark_valid(fs);
7481	} else {
7482		/*
7483		 * If we don't attach the inode, then skip the
7484		 * i_links_test since there's no point in trying to
7485		 * force i_links_count to zero.
7486		 */
7487		ext2fs_unmark_valid(fs);
7488		return 1;
7489	}
7490	return 0;
7491}
7492
7493
7494static void e2fsck_pass4(e2fsck_t ctx)
7495{
7496	ext2_filsys fs = ctx->fs;
7497	ext2_ino_t      i;
7498	struct ext2_inode       inode;
7499	struct problem_context  pctx;
7500	__u16   link_count, link_counted;
7501	char    *buf = 0;
7502	int     group, maxgroup;
7503
7504	/* Pass 4 */
7505
7506	clear_problem_context(&pctx);
7507
7508	if (!(ctx->options & E2F_OPT_PREEN))
7509		fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7510
7511	group = 0;
7512	maxgroup = fs->group_desc_count;
7513	if (ctx->progress)
7514		if ((ctx->progress)(ctx, 4, 0, maxgroup))
7515			return;
7516
7517	for (i=1; i <= fs->super->s_inodes_count; i++) {
7518		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7519			return;
7520		if ((i % fs->super->s_inodes_per_group) == 0) {
7521			group++;
7522			if (ctx->progress)
7523				if ((ctx->progress)(ctx, 4, group, maxgroup))
7524					return;
7525		}
7526		if (i == EXT2_BAD_INO ||
7527		    (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7528			continue;
7529		if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7530		    (ctx->inode_imagic_map &&
7531		     ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7532			continue;
7533		ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7534		ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7535		if (link_counted == 0) {
7536			if (!buf)
7537				buf = e2fsck_allocate_memory(ctx,
7538				     fs->blocksize, "bad_inode buffer");
7539			if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7540				continue;
7541			if (disconnect_inode(ctx, i))
7542				continue;
7543			ext2fs_icount_fetch(ctx->inode_link_info, i,
7544					    &link_count);
7545			ext2fs_icount_fetch(ctx->inode_count, i,
7546					    &link_counted);
7547		}
7548		if (link_counted != link_count) {
7549			e2fsck_read_inode(ctx, i, &inode, "pass4");
7550			pctx.ino = i;
7551			pctx.inode = &inode;
7552			if (link_count != inode.i_links_count) {
7553				pctx.num = link_count;
7554				fix_problem(ctx,
7555					    PR_4_INCONSISTENT_COUNT, &pctx);
7556			}
7557			pctx.num = link_counted;
7558			if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7559				inode.i_links_count = link_counted;
7560				e2fsck_write_inode(ctx, i, &inode, "pass4");
7561			}
7562		}
7563	}
7564	ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7565	ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7566	ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7567	ctx->inode_imagic_map = 0;
7568	ext2fs_free_mem(&buf);
7569}
7570
7571/*
7572 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7573 */
7574
7575#define NO_BLK ((blk_t) -1)
7576
7577static void print_bitmap_problem(e2fsck_t ctx, int problem,
7578			    struct problem_context *pctx)
7579{
7580	switch (problem) {
7581	case PR_5_BLOCK_UNUSED:
7582		if (pctx->blk == pctx->blk2)
7583			pctx->blk2 = 0;
7584		else
7585			problem = PR_5_BLOCK_RANGE_UNUSED;
7586		break;
7587	case PR_5_BLOCK_USED:
7588		if (pctx->blk == pctx->blk2)
7589			pctx->blk2 = 0;
7590		else
7591			problem = PR_5_BLOCK_RANGE_USED;
7592		break;
7593	case PR_5_INODE_UNUSED:
7594		if (pctx->ino == pctx->ino2)
7595			pctx->ino2 = 0;
7596		else
7597			problem = PR_5_INODE_RANGE_UNUSED;
7598		break;
7599	case PR_5_INODE_USED:
7600		if (pctx->ino == pctx->ino2)
7601			pctx->ino2 = 0;
7602		else
7603			problem = PR_5_INODE_RANGE_USED;
7604		break;
7605	}
7606	fix_problem(ctx, problem, pctx);
7607	pctx->blk = pctx->blk2 = NO_BLK;
7608	pctx->ino = pctx->ino2 = 0;
7609}
7610
7611static void check_block_bitmaps(e2fsck_t ctx)
7612{
7613	ext2_filsys fs = ctx->fs;
7614	blk_t   i;
7615	int     *free_array;
7616	int     group = 0;
7617	unsigned int    blocks = 0;
7618	unsigned int    free_blocks = 0;
7619	int     group_free = 0;
7620	int     actual, bitmap;
7621	struct problem_context  pctx;
7622	int     problem, save_problem, fixit, had_problem;
7623	errcode_t       retval;
7624
7625	clear_problem_context(&pctx);
7626	free_array = (int *) e2fsck_allocate_memory(ctx,
7627	    fs->group_desc_count * sizeof(int), "free block count array");
7628
7629	if ((fs->super->s_first_data_block <
7630	     ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7631	    (fs->super->s_blocks_count-1 >
7632	     ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7633		pctx.num = 1;
7634		pctx.blk = fs->super->s_first_data_block;
7635		pctx.blk2 = fs->super->s_blocks_count -1;
7636		pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7637		pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7638		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7639
7640		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7641		return;
7642	}
7643
7644	if ((fs->super->s_first_data_block <
7645	     ext2fs_get_block_bitmap_start(fs->block_map)) ||
7646	    (fs->super->s_blocks_count-1 >
7647	     ext2fs_get_block_bitmap_end(fs->block_map))) {
7648		pctx.num = 2;
7649		pctx.blk = fs->super->s_first_data_block;
7650		pctx.blk2 = fs->super->s_blocks_count -1;
7651		pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7652		pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7653		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7654
7655		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7656		return;
7657	}
7658
7659redo_counts:
7660	had_problem = 0;
7661	save_problem = 0;
7662	pctx.blk = pctx.blk2 = NO_BLK;
7663	for (i = fs->super->s_first_data_block;
7664	     i < fs->super->s_blocks_count;
7665	     i++) {
7666		actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7667		bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7668
7669		if (actual == bitmap)
7670			goto do_counts;
7671
7672		if (!actual && bitmap) {
7673			/*
7674			 * Block not used, but marked in use in the bitmap.
7675			 */
7676			problem = PR_5_BLOCK_UNUSED;
7677		} else {
7678			/*
7679			 * Block used, but not marked in use in the bitmap.
7680			 */
7681			problem = PR_5_BLOCK_USED;
7682		}
7683		if (pctx.blk == NO_BLK) {
7684			pctx.blk = pctx.blk2 = i;
7685			save_problem = problem;
7686		} else {
7687			if ((problem == save_problem) &&
7688			    (pctx.blk2 == i-1))
7689				pctx.blk2++;
7690			else {
7691				print_bitmap_problem(ctx, save_problem, &pctx);
7692				pctx.blk = pctx.blk2 = i;
7693				save_problem = problem;
7694			}
7695		}
7696		ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7697		had_problem++;
7698
7699	do_counts:
7700		if (!bitmap) {
7701			group_free++;
7702			free_blocks++;
7703		}
7704		blocks ++;
7705		if ((blocks == fs->super->s_blocks_per_group) ||
7706		    (i == fs->super->s_blocks_count-1)) {
7707			free_array[group] = group_free;
7708			group ++;
7709			blocks = 0;
7710			group_free = 0;
7711			if (ctx->progress)
7712				if ((ctx->progress)(ctx, 5, group,
7713						    fs->group_desc_count*2))
7714					return;
7715		}
7716	}
7717	if (pctx.blk != NO_BLK)
7718		print_bitmap_problem(ctx, save_problem, &pctx);
7719	if (had_problem)
7720		fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7721	else
7722		fixit = -1;
7723	ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7724
7725	if (fixit == 1) {
7726		ext2fs_free_block_bitmap(fs->block_map);
7727		retval = ext2fs_copy_bitmap(ctx->block_found_map,
7728						  &fs->block_map);
7729		if (retval) {
7730			clear_problem_context(&pctx);
7731			fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7732			ctx->flags |= E2F_FLAG_ABORT;
7733			return;
7734		}
7735		ext2fs_set_bitmap_padding(fs->block_map);
7736		ext2fs_mark_bb_dirty(fs);
7737
7738		/* Redo the counts */
7739		blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7740		memset(free_array, 0, fs->group_desc_count * sizeof(int));
7741		goto redo_counts;
7742	} else if (fixit == 0)
7743		ext2fs_unmark_valid(fs);
7744
7745	for (i = 0; i < fs->group_desc_count; i++) {
7746		if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7747			pctx.group = i;
7748			pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7749			pctx.blk2 = free_array[i];
7750
7751			if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7752					&pctx)) {
7753				fs->group_desc[i].bg_free_blocks_count =
7754					free_array[i];
7755				ext2fs_mark_super_dirty(fs);
7756			} else
7757				ext2fs_unmark_valid(fs);
7758		}
7759	}
7760	if (free_blocks != fs->super->s_free_blocks_count) {
7761		pctx.group = 0;
7762		pctx.blk = fs->super->s_free_blocks_count;
7763		pctx.blk2 = free_blocks;
7764
7765		if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7766			fs->super->s_free_blocks_count = free_blocks;
7767			ext2fs_mark_super_dirty(fs);
7768		} else
7769			ext2fs_unmark_valid(fs);
7770	}
7771	ext2fs_free_mem(&free_array);
7772}
7773
7774static void check_inode_bitmaps(e2fsck_t ctx)
7775{
7776	ext2_filsys fs = ctx->fs;
7777	ext2_ino_t      i;
7778	unsigned int    free_inodes = 0;
7779	int             group_free = 0;
7780	int             dirs_count = 0;
7781	int             group = 0;
7782	unsigned int    inodes = 0;
7783	int             *free_array;
7784	int             *dir_array;
7785	int             actual, bitmap;
7786	errcode_t       retval;
7787	struct problem_context  pctx;
7788	int             problem, save_problem, fixit, had_problem;
7789
7790	clear_problem_context(&pctx);
7791	free_array = (int *) e2fsck_allocate_memory(ctx,
7792	    fs->group_desc_count * sizeof(int), "free inode count array");
7793
7794	dir_array = (int *) e2fsck_allocate_memory(ctx,
7795	   fs->group_desc_count * sizeof(int), "directory count array");
7796
7797	if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7798	    (fs->super->s_inodes_count >
7799	     ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7800		pctx.num = 3;
7801		pctx.blk = 1;
7802		pctx.blk2 = fs->super->s_inodes_count;
7803		pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7804		pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7805		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7806
7807		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7808		return;
7809	}
7810	if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7811	    (fs->super->s_inodes_count >
7812	     ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7813		pctx.num = 4;
7814		pctx.blk = 1;
7815		pctx.blk2 = fs->super->s_inodes_count;
7816		pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7817		pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7818		fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7819
7820		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7821		return;
7822	}
7823
7824redo_counts:
7825	had_problem = 0;
7826	save_problem = 0;
7827	pctx.ino = pctx.ino2 = 0;
7828	for (i = 1; i <= fs->super->s_inodes_count; i++) {
7829		actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7830		bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7831
7832		if (actual == bitmap)
7833			goto do_counts;
7834
7835		if (!actual && bitmap) {
7836			/*
7837			 * Inode wasn't used, but marked in bitmap
7838			 */
7839			problem = PR_5_INODE_UNUSED;
7840		} else /* if (actual && !bitmap) */ {
7841			/*
7842			 * Inode used, but not in bitmap
7843			 */
7844			problem = PR_5_INODE_USED;
7845		}
7846		if (pctx.ino == 0) {
7847			pctx.ino = pctx.ino2 = i;
7848			save_problem = problem;
7849		} else {
7850			if ((problem == save_problem) &&
7851			    (pctx.ino2 == i-1))
7852				pctx.ino2++;
7853			else {
7854				print_bitmap_problem(ctx, save_problem, &pctx);
7855				pctx.ino = pctx.ino2 = i;
7856				save_problem = problem;
7857			}
7858		}
7859		ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7860		had_problem++;
7861
7862do_counts:
7863		if (!bitmap) {
7864			group_free++;
7865			free_inodes++;
7866		} else {
7867			if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7868				dirs_count++;
7869		}
7870		inodes++;
7871		if ((inodes == fs->super->s_inodes_per_group) ||
7872		    (i == fs->super->s_inodes_count)) {
7873			free_array[group] = group_free;
7874			dir_array[group] = dirs_count;
7875			group ++;
7876			inodes = 0;
7877			group_free = 0;
7878			dirs_count = 0;
7879			if (ctx->progress)
7880				if ((ctx->progress)(ctx, 5,
7881					    group + fs->group_desc_count,
7882					    fs->group_desc_count*2))
7883					return;
7884		}
7885	}
7886	if (pctx.ino)
7887		print_bitmap_problem(ctx, save_problem, &pctx);
7888
7889	if (had_problem)
7890		fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7891	else
7892		fixit = -1;
7893	ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7894
7895	if (fixit == 1) {
7896		ext2fs_free_inode_bitmap(fs->inode_map);
7897		retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7898						  &fs->inode_map);
7899		if (retval) {
7900			clear_problem_context(&pctx);
7901			fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7902			ctx->flags |= E2F_FLAG_ABORT;
7903			return;
7904		}
7905		ext2fs_set_bitmap_padding(fs->inode_map);
7906		ext2fs_mark_ib_dirty(fs);
7907
7908		/* redo counts */
7909		inodes = 0; free_inodes = 0; group_free = 0;
7910		dirs_count = 0; group = 0;
7911		memset(free_array, 0, fs->group_desc_count * sizeof(int));
7912		memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7913		goto redo_counts;
7914	} else if (fixit == 0)
7915		ext2fs_unmark_valid(fs);
7916
7917	for (i = 0; i < fs->group_desc_count; i++) {
7918		if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7919			pctx.group = i;
7920			pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7921			pctx.ino2 = free_array[i];
7922			if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7923					&pctx)) {
7924				fs->group_desc[i].bg_free_inodes_count =
7925					free_array[i];
7926				ext2fs_mark_super_dirty(fs);
7927			} else
7928				ext2fs_unmark_valid(fs);
7929		}
7930		if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7931			pctx.group = i;
7932			pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7933			pctx.ino2 = dir_array[i];
7934
7935			if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7936					&pctx)) {
7937				fs->group_desc[i].bg_used_dirs_count =
7938					dir_array[i];
7939				ext2fs_mark_super_dirty(fs);
7940			} else
7941				ext2fs_unmark_valid(fs);
7942		}
7943	}
7944	if (free_inodes != fs->super->s_free_inodes_count) {
7945		pctx.group = -1;
7946		pctx.ino = fs->super->s_free_inodes_count;
7947		pctx.ino2 = free_inodes;
7948
7949		if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
7950			fs->super->s_free_inodes_count = free_inodes;
7951			ext2fs_mark_super_dirty(fs);
7952		} else
7953			ext2fs_unmark_valid(fs);
7954	}
7955	ext2fs_free_mem(&free_array);
7956	ext2fs_free_mem(&dir_array);
7957}
7958
7959static void check_inode_end(e2fsck_t ctx)
7960{
7961	ext2_filsys fs = ctx->fs;
7962	ext2_ino_t      end, save_inodes_count, i;
7963	struct problem_context  pctx;
7964
7965	clear_problem_context(&pctx);
7966
7967	end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
7968	pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
7969						     &save_inodes_count);
7970	if (pctx.errcode) {
7971		pctx.num = 1;
7972		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
7973		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7974		return;
7975	}
7976	if (save_inodes_count == end)
7977		return;
7978
7979	for (i = save_inodes_count + 1; i <= end; i++) {
7980		if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
7981			if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
7982				for (i = save_inodes_count + 1; i <= end; i++)
7983					ext2fs_mark_inode_bitmap(fs->inode_map,
7984								 i);
7985				ext2fs_mark_ib_dirty(fs);
7986			} else
7987				ext2fs_unmark_valid(fs);
7988			break;
7989		}
7990	}
7991
7992	pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
7993						     save_inodes_count, 0);
7994	if (pctx.errcode) {
7995		pctx.num = 2;
7996		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
7997		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7998		return;
7999	}
8000}
8001
8002static void check_block_end(e2fsck_t ctx)
8003{
8004	ext2_filsys fs = ctx->fs;
8005	blk_t   end, save_blocks_count, i;
8006	struct problem_context  pctx;
8007
8008	clear_problem_context(&pctx);
8009
8010	end = fs->block_map->start +
8011		(EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8012	pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8013						     &save_blocks_count);
8014	if (pctx.errcode) {
8015		pctx.num = 3;
8016		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8017		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8018		return;
8019	}
8020	if (save_blocks_count == end)
8021		return;
8022
8023	for (i = save_blocks_count + 1; i <= end; i++) {
8024		if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8025			if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8026				for (i = save_blocks_count + 1; i <= end; i++)
8027					ext2fs_mark_block_bitmap(fs->block_map,
8028								 i);
8029				ext2fs_mark_bb_dirty(fs);
8030			} else
8031				ext2fs_unmark_valid(fs);
8032			break;
8033		}
8034	}
8035
8036	pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8037						     save_blocks_count, 0);
8038	if (pctx.errcode) {
8039		pctx.num = 4;
8040		fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8041		ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8042		return;
8043	}
8044}
8045
8046static void e2fsck_pass5(e2fsck_t ctx)
8047{
8048	struct problem_context  pctx;
8049
8050	/* Pass 5 */
8051
8052	clear_problem_context(&pctx);
8053
8054	if (!(ctx->options & E2F_OPT_PREEN))
8055		fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8056
8057	if (ctx->progress)
8058		if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8059			return;
8060
8061	e2fsck_read_bitmaps(ctx);
8062
8063	check_block_bitmaps(ctx);
8064	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8065		return;
8066	check_inode_bitmaps(ctx);
8067	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8068		return;
8069	check_inode_end(ctx);
8070	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8071		return;
8072	check_block_end(ctx);
8073	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8074		return;
8075
8076	ext2fs_free_inode_bitmap(ctx->inode_used_map);
8077	ctx->inode_used_map = 0;
8078	ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8079	ctx->inode_dir_map = 0;
8080	ext2fs_free_block_bitmap(ctx->block_found_map);
8081	ctx->block_found_map = 0;
8082}
8083
8084/*
8085 * problem.c --- report filesystem problems to the user
8086 */
8087
8088#define PR_PREEN_OK     0x000001 /* Don't need to do preenhalt */
8089#define PR_NO_OK        0x000002 /* If user answers no, don't make fs invalid */
8090#define PR_NO_DEFAULT   0x000004 /* Default to no */
8091#define PR_MSG_ONLY     0x000008 /* Print message only */
8092
8093/* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8094
8095#define PR_FATAL        0x001000 /* Fatal error */
8096#define PR_AFTER_CODE   0x002000 /* After asking the first question, */
8097				 /* ask another */
8098#define PR_PREEN_NOMSG  0x004000 /* Don't print a message if we're preening */
8099#define PR_NOCOLLATE    0x008000 /* Don't collate answers for this latch */
8100#define PR_NO_NOMSG     0x010000 /* Don't print a message if e2fsck -n */
8101#define PR_PREEN_NO     0x020000 /* Use No as an answer if preening */
8102#define PR_PREEN_NOHDR  0x040000 /* Don't print the preen header */
8103
8104
8105#define PROMPT_NONE     0
8106#define PROMPT_FIX      1
8107#define PROMPT_CLEAR    2
8108#define PROMPT_RELOCATE 3
8109#define PROMPT_ALLOCATE 4
8110#define PROMPT_EXPAND   5
8111#define PROMPT_CONNECT  6
8112#define PROMPT_CREATE   7
8113#define PROMPT_SALVAGE  8
8114#define PROMPT_TRUNCATE 9
8115#define PROMPT_CLEAR_INODE 10
8116#define PROMPT_ABORT    11
8117#define PROMPT_SPLIT    12
8118#define PROMPT_CONTINUE 13
8119#define PROMPT_CLONE    14
8120#define PROMPT_DELETE   15
8121#define PROMPT_SUPPRESS 16
8122#define PROMPT_UNLINK   17
8123#define PROMPT_CLEAR_HTREE 18
8124#define PROMPT_RECREATE 19
8125#define PROMPT_NULL     20
8126
8127struct e2fsck_problem {
8128	problem_t       e2p_code;
8129	const char *    e2p_description;
8130	char            prompt;
8131	int             flags;
8132	problem_t       second_code;
8133};
8134
8135struct latch_descr {
8136	int             latch_code;
8137	problem_t       question;
8138	problem_t       end_message;
8139	int             flags;
8140};
8141
8142/*
8143 * These are the prompts which are used to ask the user if they want
8144 * to fix a problem.
8145 */
8146static const char *const prompt[] = {
8147	N_("(no prompt)"),      /* 0 */
8148	N_("Fix"),              /* 1 */
8149	N_("Clear"),            /* 2 */
8150	N_("Relocate"),         /* 3 */
8151	N_("Allocate"),         /* 4 */
8152	N_("Expand"),           /* 5 */
8153	N_("Connect to /lost+found"), /* 6 */
8154	N_("Create"),           /* 7 */
8155	N_("Salvage"),          /* 8 */
8156	N_("Truncate"),         /* 9 */
8157	N_("Clear inode"),      /* 10 */
8158	N_("Abort"),            /* 11 */
8159	N_("Split"),            /* 12 */
8160	N_("Continue"),         /* 13 */
8161	N_("Clone multiply-claimed blocks"), /* 14 */
8162	N_("Delete file"),      /* 15 */
8163	N_("Suppress messages"),/* 16 */
8164	N_("Unlink"),           /* 17 */
8165	N_("Clear HTree index"),/* 18 */
8166	N_("Recreate"),         /* 19 */
8167	"",                     /* 20 */
8168};
8169
8170/*
8171 * These messages are printed when we are preen mode and we will be
8172 * automatically fixing the problem.
8173 */
8174static const char *const preen_msg[] = {
8175	N_("(NONE)"),           /* 0 */
8176	N_("FIXED"),            /* 1 */
8177	N_("CLEARED"),          /* 2 */
8178	N_("RELOCATED"),        /* 3 */
8179	N_("ALLOCATED"),        /* 4 */
8180	N_("EXPANDED"),         /* 5 */
8181	N_("RECONNECTED"),      /* 6 */
8182	N_("CREATED"),          /* 7 */
8183	N_("SALVAGED"),         /* 8 */
8184	N_("TRUNCATED"),        /* 9 */
8185	N_("INODE CLEARED"),    /* 10 */
8186	N_("ABORTED"),          /* 11 */
8187	N_("SPLIT"),            /* 12 */
8188	N_("CONTINUING"),       /* 13 */
8189	N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8190	N_("FILE DELETED"),     /* 15 */
8191	N_("SUPPRESSED"),       /* 16 */
8192	N_("UNLINKED"),         /* 17 */
8193	N_("HTREE INDEX CLEARED"),/* 18 */
8194	N_("WILL RECREATE"),    /* 19 */
8195	"",                     /* 20 */
8196};
8197
8198static const struct e2fsck_problem problem_table[] = {
8199
8200	/* Pre-Pass 1 errors */
8201
8202	/* Block bitmap not in group */
8203	{ PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g.  (@b %b)\n"),
8204	  PROMPT_RELOCATE, PR_LATCH_RELOC },
8205
8206	/* Inode bitmap not in group */
8207	{ PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g.  (@b %b)\n"),
8208	  PROMPT_RELOCATE, PR_LATCH_RELOC },
8209
8210	/* Inode table not in group */
8211	{ PR_0_ITABLE_NOT_GROUP,
8212	  N_("@i table for @g %g is not in @g.  (@b %b)\n"
8213	  "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8214	  PROMPT_RELOCATE, PR_LATCH_RELOC },
8215
8216	/* Superblock corrupt */
8217	{ PR_0_SB_CORRUPT,
8218	  N_("\nThe @S could not be read or does not describe a correct ext2\n"
8219	  "@f.  If the @v is valid and it really contains an ext2\n"
8220	  "@f (and not swap or ufs or something else), then the @S\n"
8221	  "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8222	  "    e2fsck -b %S <@v>\n\n"),
8223	  PROMPT_NONE, PR_FATAL },
8224
8225	/* Filesystem size is wrong */
8226	{ PR_0_FS_SIZE_WRONG,
8227	  N_("The @f size (according to the @S) is %b @bs\n"
8228	  "The physical size of the @v is %c @bs\n"
8229	  "Either the @S or the partition table is likely to be corrupt!\n"),
8230	  PROMPT_ABORT, 0 },
8231
8232	/* Fragments not supported */
8233	{ PR_0_NO_FRAGMENTS,
8234	  N_("@S @b_size = %b, fragsize = %c.\n"
8235	  "This version of e2fsck does not support fragment sizes different\n"
8236	  "from the @b size.\n"),
8237	  PROMPT_NONE, PR_FATAL },
8238
8239	  /* Bad blocks_per_group */
8240	{ PR_0_BLOCKS_PER_GROUP,
8241	  N_("@S @bs_per_group = %b, should have been %c\n"),
8242	  PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8243
8244	/* Bad first_data_block */
8245	{ PR_0_FIRST_DATA_BLOCK,
8246	  N_("@S first_data_@b = %b, should have been %c\n"),
8247	  PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8248
8249	/* Adding UUID to filesystem */
8250	{ PR_0_ADD_UUID,
8251	  N_("@f did not have a UUID; generating one.\n\n"),
8252	  PROMPT_NONE, 0 },
8253
8254	/* Relocate hint */
8255	{ PR_0_RELOCATE_HINT,
8256	  N_("Note: if several inode or block bitmap blocks or part\n"
8257	  "of the inode table require relocation, you may wish to try\n"
8258	  "running e2fsck with the '-b %S' option first.  The problem\n"
8259	  "may lie only with the primary block group descriptors, and\n"
8260	  "the backup block group descriptors may be OK.\n\n"),
8261	  PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8262
8263	/* Miscellaneous superblock corruption */
8264	{ PR_0_MISC_CORRUPT_SUPER,
8265	  N_("Corruption found in @S.  (%s = %N).\n"),
8266	  PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8267
8268	/* Error determing physical device size of filesystem */
8269	{ PR_0_GETSIZE_ERROR,
8270	  N_("Error determining size of the physical @v: %m\n"),
8271	  PROMPT_NONE, PR_FATAL },
8272
8273	/* Inode count in superblock is incorrect */
8274	{ PR_0_INODE_COUNT_WRONG,
8275	  N_("@i count in @S is %i, @s %j.\n"),
8276	  PROMPT_FIX, 0 },
8277
8278	{ PR_0_HURD_CLEAR_FILETYPE,
8279	  N_("The Hurd does not support the filetype feature.\n"),
8280	  PROMPT_CLEAR, 0 },
8281
8282	/* Journal inode is invalid */
8283	{ PR_0_JOURNAL_BAD_INODE,
8284	  N_("@S has an @n ext3 @j (@i %i).\n"),
8285	  PROMPT_CLEAR, PR_PREEN_OK },
8286
8287	/* The external journal has (unsupported) multiple filesystems */
8288	{ PR_0_JOURNAL_UNSUPP_MULTIFS,
8289	  N_("External @j has multiple @f users (unsupported).\n"),
8290	  PROMPT_NONE, PR_FATAL },
8291
8292	/* Can't find external journal */
8293	{ PR_0_CANT_FIND_JOURNAL,
8294	  N_("Can't find external @j\n"),
8295	  PROMPT_NONE, PR_FATAL },
8296
8297	/* External journal has bad superblock */
8298	{ PR_0_EXT_JOURNAL_BAD_SUPER,
8299	  N_("External @j has bad @S\n"),
8300	  PROMPT_NONE, PR_FATAL },
8301
8302	/* Superblock has a bad journal UUID */
8303	{ PR_0_JOURNAL_BAD_UUID,
8304	  N_("External @j does not support this @f\n"),
8305	  PROMPT_NONE, PR_FATAL },
8306
8307	/* Journal has an unknown superblock type */
8308	{ PR_0_JOURNAL_UNSUPP_SUPER,
8309	  N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8310	     "It is likely that your copy of e2fsck is old and/or doesn't "
8311	     "support this @j format.\n"
8312	     "It is also possible the @j @S is corrupt.\n"),
8313	  PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8314
8315	/* Journal superblock is corrupt */
8316	{ PR_0_JOURNAL_BAD_SUPER,
8317	  N_("Ext3 @j @S is corrupt.\n"),
8318	  PROMPT_FIX, PR_PREEN_OK },
8319
8320	/* Superblock flag should be cleared */
8321	{ PR_0_JOURNAL_HAS_JOURNAL,
8322	  N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8323	  PROMPT_CLEAR, PR_PREEN_OK },
8324
8325	/* Superblock flag is incorrect */
8326	{ PR_0_JOURNAL_RECOVER_SET,
8327	  N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8328	  PROMPT_CLEAR, PR_PREEN_OK },
8329
8330	/* Journal has data, but recovery flag is clear */
8331	{ PR_0_JOURNAL_RECOVERY_CLEAR,
8332	  N_("ext3 recovery flag is clear, but @j has data.\n"),
8333	  PROMPT_NONE, 0 },
8334
8335	/* Ask if we should clear the journal */
8336	{ PR_0_JOURNAL_RESET_JOURNAL,
8337	  N_("Clear @j"),
8338	  PROMPT_NULL, PR_PREEN_NOMSG },
8339
8340	/* Ask if we should run the journal anyway */
8341	{ PR_0_JOURNAL_RUN,
8342	  N_("Run @j anyway"),
8343	  PROMPT_NULL, 0 },
8344
8345	/* Run the journal by default */
8346	{ PR_0_JOURNAL_RUN_DEFAULT,
8347	  N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8348	  PROMPT_NONE, 0 },
8349
8350	/* Clearing orphan inode */
8351	{ PR_0_ORPHAN_CLEAR_INODE,
8352	  N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8353	  PROMPT_NONE, 0 },
8354
8355	/* Illegal block found in orphaned inode */
8356	{ PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8357	   N_("@I @b #%B (%b) found in @o @i %i.\n"),
8358	  PROMPT_NONE, 0 },
8359
8360	/* Already cleared block found in orphaned inode */
8361	{ PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8362	   N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8363	  PROMPT_NONE, 0 },
8364
8365	/* Illegal orphan inode in superblock */
8366	{ PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8367	  N_("@I @o @i %i in @S.\n"),
8368	  PROMPT_NONE, 0 },
8369
8370	/* Illegal inode in orphaned inode list */
8371	{ PR_0_ORPHAN_ILLEGAL_INODE,
8372	  N_("@I @i %i in @o @i list.\n"),
8373	  PROMPT_NONE, 0 },
8374
8375	/* Filesystem revision is 0, but feature flags are set */
8376	{ PR_0_FS_REV_LEVEL,
8377	  N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
8378	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8379
8380	/* Journal superblock has an unknown read-only feature flag set */
8381	{ PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8382	  N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8383	  PROMPT_ABORT, 0 },
8384
8385	/* Journal superblock has an unknown incompatible feature flag set */
8386	{ PR_0_JOURNAL_UNSUPP_INCOMPAT,
8387	  N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8388	  PROMPT_ABORT, 0 },
8389
8390	/* Journal has unsupported version number */
8391	{ PR_0_JOURNAL_UNSUPP_VERSION,
8392	  N_("@j version not supported by this e2fsck.\n"),
8393	  PROMPT_ABORT, 0 },
8394
8395	/* Moving journal to hidden file */
8396	{ PR_0_MOVE_JOURNAL,
8397	  N_("Moving @j from /%s to hidden @i.\n\n"),
8398	  PROMPT_NONE, 0 },
8399
8400	/* Error moving journal to hidden file */
8401	{ PR_0_ERR_MOVE_JOURNAL,
8402	  N_("Error moving @j: %m\n\n"),
8403	  PROMPT_NONE, 0 },
8404
8405	/* Clearing V2 journal superblock */
8406	{ PR_0_CLEAR_V2_JOURNAL,
8407	  N_("Found @n V2 @j @S fields (from V1 @j).\n"
8408	     "Clearing fields beyond the V1 @j @S...\n\n"),
8409	  PROMPT_NONE, 0 },
8410
8411	/* Backup journal inode blocks */
8412	{ PR_0_BACKUP_JNL,
8413	  N_("Backing up @j @i @b information.\n\n"),
8414	  PROMPT_NONE, 0 },
8415
8416	/* Reserved blocks w/o resize_inode */
8417	{ PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8418	  N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8419	     "is %N; @s zero.  "),
8420	  PROMPT_FIX, 0 },
8421
8422	/* Resize_inode not enabled, but resize inode is non-zero */
8423	{ PR_0_CLEAR_RESIZE_INODE,
8424	  N_("Resize_@i not enabled, but the resize @i is non-zero.  "),
8425	  PROMPT_CLEAR, 0 },
8426
8427	/* Resize inode invalid */
8428	{ PR_0_RESIZE_INODE_INVALID,
8429	  N_("Resize @i not valid.  "),
8430	  PROMPT_RECREATE, 0 },
8431
8432	/* Pass 1 errors */
8433
8434	/* Pass 1: Checking inodes, blocks, and sizes */
8435	{ PR_1_PASS_HEADER,
8436	  N_("Pass 1: Checking @is, @bs, and sizes\n"),
8437	  PROMPT_NONE, 0 },
8438
8439	/* Root directory is not an inode */
8440	{ PR_1_ROOT_NO_DIR, N_("@r is not a @d.  "),
8441	  PROMPT_CLEAR, 0 },
8442
8443	/* Root directory has dtime set */
8444	{ PR_1_ROOT_DTIME,
8445	  N_("@r has dtime set (probably due to old mke2fs).  "),
8446	  PROMPT_FIX, PR_PREEN_OK },
8447
8448	/* Reserved inode has bad mode */
8449	{ PR_1_RESERVED_BAD_MODE,
8450	  N_("Reserved @i %i (%Q) has @n mode.  "),
8451	  PROMPT_CLEAR, PR_PREEN_OK },
8452
8453	/* Deleted inode has zero dtime */
8454	{ PR_1_ZERO_DTIME,
8455	  N_("@D @i %i has zero dtime.  "),
8456	  PROMPT_FIX, PR_PREEN_OK },
8457
8458	/* Inode in use, but dtime set */
8459	{ PR_1_SET_DTIME,
8460	  N_("@i %i is in use, but has dtime set.  "),
8461	  PROMPT_FIX, PR_PREEN_OK },
8462
8463	/* Zero-length directory */
8464	{ PR_1_ZERO_LENGTH_DIR,
8465	  N_("@i %i is a @z @d.  "),
8466	  PROMPT_CLEAR, PR_PREEN_OK },
8467
8468	/* Block bitmap conflicts with some other fs block */
8469	{ PR_1_BB_CONFLICT,
8470	  N_("@g %g's @b @B at %b @C.\n"),
8471	  PROMPT_RELOCATE, 0 },
8472
8473	/* Inode bitmap conflicts with some other fs block */
8474	{ PR_1_IB_CONFLICT,
8475	  N_("@g %g's @i @B at %b @C.\n"),
8476	  PROMPT_RELOCATE, 0 },
8477
8478	/* Inode table conflicts with some other fs block */
8479	{ PR_1_ITABLE_CONFLICT,
8480	  N_("@g %g's @i table at %b @C.\n"),
8481	  PROMPT_RELOCATE, 0 },
8482
8483	/* Block bitmap is on a bad block */
8484	{ PR_1_BB_BAD_BLOCK,
8485	  N_("@g %g's @b @B (%b) is bad.  "),
8486	  PROMPT_RELOCATE, 0 },
8487
8488	/* Inode bitmap is on a bad block */
8489	{ PR_1_IB_BAD_BLOCK,
8490	  N_("@g %g's @i @B (%b) is bad.  "),
8491	  PROMPT_RELOCATE, 0 },
8492
8493	/* Inode has incorrect i_size */
8494	{ PR_1_BAD_I_SIZE,
8495	  N_("@i %i, i_size is %Is, @s %N.  "),
8496	  PROMPT_FIX, PR_PREEN_OK },
8497
8498	/* Inode has incorrect i_blocks */
8499	{ PR_1_BAD_I_BLOCKS,
8500	  N_("@i %i, i_@bs is %Ib, @s %N.  "),
8501	  PROMPT_FIX, PR_PREEN_OK },
8502
8503	/* Illegal blocknumber in inode */
8504	{ PR_1_ILLEGAL_BLOCK_NUM,
8505	  N_("@I @b #%B (%b) in @i %i.  "),
8506	  PROMPT_CLEAR, PR_LATCH_BLOCK },
8507
8508	/* Block number overlaps fs metadata */
8509	{ PR_1_BLOCK_OVERLAPS_METADATA,
8510	  N_("@b #%B (%b) overlaps @f metadata in @i %i.  "),
8511	  PROMPT_CLEAR, PR_LATCH_BLOCK },
8512
8513	/* Inode has illegal blocks (latch question) */
8514	{ PR_1_INODE_BLOCK_LATCH,
8515	  N_("@i %i has illegal @b(s).  "),
8516	  PROMPT_CLEAR, 0 },
8517
8518	/* Too many bad blocks in inode */
8519	{ PR_1_TOO_MANY_BAD_BLOCKS,
8520	  N_("Too many illegal @bs in @i %i.\n"),
8521	  PROMPT_CLEAR_INODE, PR_NO_OK },
8522
8523	/* Illegal block number in bad block inode */
8524	{ PR_1_BB_ILLEGAL_BLOCK_NUM,
8525	  N_("@I @b #%B (%b) in bad @b @i.  "),
8526	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
8527
8528	/* Bad block inode has illegal blocks (latch question) */
8529	{ PR_1_INODE_BBLOCK_LATCH,
8530	  N_("Bad @b @i has illegal @b(s).  "),
8531	  PROMPT_CLEAR, 0 },
8532
8533	/* Duplicate or bad blocks in use! */
8534	{ PR_1_DUP_BLOCKS_PREENSTOP,
8535	  N_("Duplicate or bad @b in use!\n"),
8536	  PROMPT_NONE, 0 },
8537
8538	/* Bad block used as bad block indirect block */
8539	{ PR_1_BBINODE_BAD_METABLOCK,
8540	  N_("Bad @b %b used as bad @b @i indirect @b.  "),
8541	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
8542
8543	/* Inconsistency can't be fixed prompt */
8544	{ PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8545	  N_("\nThe bad @b @i has probably been corrupted.  You probably\n"
8546	     "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8547	     "in the @f.\n"),
8548	  PROMPT_CONTINUE, PR_PREEN_NOMSG },
8549
8550	/* Bad primary block */
8551	{ PR_1_BAD_PRIMARY_BLOCK,
8552	  N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
8553	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8554
8555	/* Bad primary block prompt */
8556	{ PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8557	  N_("You can remove this @b from the bad @b list and hope\n"
8558	     "that the @b is really OK.  But there are no guarantees.\n\n"),
8559	  PROMPT_CLEAR, PR_PREEN_NOMSG },
8560
8561	/* Bad primary superblock */
8562	{ PR_1_BAD_PRIMARY_SUPERBLOCK,
8563	  N_("The primary @S (%b) is on the bad @b list.\n"),
8564	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8565
8566	/* Bad primary block group descriptors */
8567	{ PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8568	  N_("Block %b in the primary @g descriptors "
8569	  "is on the bad @b list\n"),
8570	  PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8571
8572	/* Bad superblock in group */
8573	{ PR_1_BAD_SUPERBLOCK,
8574	  N_("Warning: Group %g's @S (%b) is bad.\n"),
8575	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8576
8577	/* Bad block group descriptors in group */
8578	{ PR_1_BAD_GROUP_DESCRIPTORS,
8579	  N_("Warning: Group %g's copy of the @g descriptors has a bad "
8580	  "@b (%b).\n"),
8581	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8582
8583	/* Block claimed for no reason */
8584	{ PR_1_PROGERR_CLAIMED_BLOCK,
8585	  N_("Programming error?  @b #%b claimed for no reason in "
8586	  "process_bad_@b.\n"),
8587	  PROMPT_NONE, PR_PREEN_OK },
8588
8589	/* Error allocating blocks for relocating metadata */
8590	{ PR_1_RELOC_BLOCK_ALLOCATE,
8591	  N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8592	  PROMPT_NONE, PR_PREEN_OK },
8593
8594	/* Error allocating block buffer during relocation process */
8595	{ PR_1_RELOC_MEMORY_ALLOCATE,
8596	  N_("@A @b buffer for relocating %s\n"),
8597	  PROMPT_NONE, PR_PREEN_OK },
8598
8599	/* Relocating metadata group information from X to Y */
8600	{ PR_1_RELOC_FROM_TO,
8601	  N_("Relocating @g %g's %s from %b to %c...\n"),
8602	  PROMPT_NONE, PR_PREEN_OK },
8603
8604	/* Relocating metatdata group information to X */
8605	{ PR_1_RELOC_TO,
8606	  N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8607	  PROMPT_NONE, PR_PREEN_OK },
8608
8609	/* Block read error during relocation process */
8610	{ PR_1_RELOC_READ_ERR,
8611	  N_("Warning: could not read @b %b of %s: %m\n"),
8612	  PROMPT_NONE, PR_PREEN_OK },
8613
8614	/* Block write error during relocation process */
8615	{ PR_1_RELOC_WRITE_ERR,
8616	  N_("Warning: could not write @b %b for %s: %m\n"),
8617	  PROMPT_NONE, PR_PREEN_OK },
8618
8619	/* Error allocating inode bitmap */
8620	{ PR_1_ALLOCATE_IBITMAP_ERROR,
8621	  N_("@A @i @B (%N): %m\n"),
8622	  PROMPT_NONE, PR_FATAL },
8623
8624	/* Error allocating block bitmap */
8625	{ PR_1_ALLOCATE_BBITMAP_ERROR,
8626	  N_("@A @b @B (%N): %m\n"),
8627	  PROMPT_NONE, PR_FATAL },
8628
8629	/* Error allocating icount structure */
8630	{ PR_1_ALLOCATE_ICOUNT,
8631	  N_("@A icount link information: %m\n"),
8632	  PROMPT_NONE, PR_FATAL },
8633
8634	/* Error allocating dbcount */
8635	{ PR_1_ALLOCATE_DBCOUNT,
8636	  N_("@A @d @b array: %m\n"),
8637	  PROMPT_NONE, PR_FATAL },
8638
8639	/* Error while scanning inodes */
8640	{ PR_1_ISCAN_ERROR,
8641	  N_("Error while scanning @is (%i): %m\n"),
8642	  PROMPT_NONE, PR_FATAL },
8643
8644	/* Error while iterating over blocks */
8645	{ PR_1_BLOCK_ITERATE,
8646	  N_("Error while iterating over @bs in @i %i: %m\n"),
8647	  PROMPT_NONE, PR_FATAL },
8648
8649	/* Error while storing inode count information */
8650	{ PR_1_ICOUNT_STORE,
8651	  N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8652	  PROMPT_NONE, PR_FATAL },
8653
8654	/* Error while storing directory block information */
8655	{ PR_1_ADD_DBLOCK,
8656	  N_("Error storing @d @b information "
8657	  "(@i=%i, @b=%b, num=%N): %m\n"),
8658	  PROMPT_NONE, PR_FATAL },
8659
8660	/* Error while reading inode (for clearing) */
8661	{ PR_1_READ_INODE,
8662	  N_("Error reading @i %i: %m\n"),
8663	  PROMPT_NONE, PR_FATAL },
8664
8665	/* Suppress messages prompt */
8666	{ PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8667
8668	/* Imagic flag set on an inode when filesystem doesn't support it */
8669	{ PR_1_SET_IMAGIC,
8670	  N_("@i %i has imagic flag set.  "),
8671	  PROMPT_CLEAR, 0 },
8672
8673	/* Immutable flag set on a device or socket inode */
8674	{ PR_1_SET_IMMUTABLE,
8675	  N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8676	     "or append-only flag set.  "),
8677	  PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8678
8679	/* Compression flag set on an inode when filesystem doesn't support it */
8680	{ PR_1_COMPR_SET,
8681	  N_("@i %i has @cion flag set on @f without @cion support.  "),
8682	  PROMPT_CLEAR, 0 },
8683
8684	/* Non-zero size for device, fifo or socket inode */
8685	{ PR_1_SET_NONZSIZE,
8686	  N_("Special (@v/socket/fifo) @i %i has non-zero size.  "),
8687	  PROMPT_FIX, PR_PREEN_OK },
8688
8689	/* Filesystem revision is 0, but feature flags are set */
8690	{ PR_1_FS_REV_LEVEL,
8691	  N_("@f has feature flag(s) set, but is a revision 0 @f.  "),
8692	  PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8693
8694	/* Journal inode is not in use, but contains data */
8695	{ PR_1_JOURNAL_INODE_NOT_CLEAR,
8696	  N_("@j @i is not in use, but contains data.  "),
8697	  PROMPT_CLEAR, PR_PREEN_OK },
8698
8699	/* Journal has bad mode */
8700	{ PR_1_JOURNAL_BAD_MODE,
8701	  N_("@j is not regular file.  "),
8702	  PROMPT_FIX, PR_PREEN_OK },
8703
8704	/* Deal with inodes that were part of orphan linked list */
8705	{ PR_1_LOW_DTIME,
8706	  N_("@i %i was part of the @o @i list.  "),
8707	  PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8708
8709	/* Deal with inodes that were part of corrupted orphan linked
8710	   list (latch question) */
8711	{ PR_1_ORPHAN_LIST_REFUGEES,
8712	  N_("@is that were part of a corrupted orphan linked list found.  "),
8713	  PROMPT_FIX, 0 },
8714
8715	/* Error allocating refcount structure */
8716	{ PR_1_ALLOCATE_REFCOUNT,
8717	  N_("@A refcount structure (%N): %m\n"),
8718	  PROMPT_NONE, PR_FATAL },
8719
8720	/* Error reading extended attribute block */
8721	{ PR_1_READ_EA_BLOCK,
8722	  N_("Error reading @a @b %b for @i %i.  "),
8723	  PROMPT_CLEAR, 0 },
8724
8725	/* Invalid extended attribute block */
8726	{ PR_1_BAD_EA_BLOCK,
8727	  N_("@i %i has a bad @a @b %b.  "),
8728	  PROMPT_CLEAR, 0 },
8729
8730	/* Error reading Extended Attribute block while fixing refcount */
8731	{ PR_1_EXTATTR_READ_ABORT,
8732	  N_("Error reading @a @b %b (%m).  "),
8733	  PROMPT_ABORT, 0 },
8734
8735	/* Extended attribute reference count incorrect */
8736	{ PR_1_EXTATTR_REFCOUNT,
8737	  N_("@a @b %b has reference count %B, @s %N.  "),
8738	  PROMPT_FIX, 0 },
8739
8740	/* Error writing Extended Attribute block while fixing refcount */
8741	{ PR_1_EXTATTR_WRITE,
8742	  N_("Error writing @a @b %b (%m).  "),
8743	  PROMPT_ABORT, 0 },
8744
8745	/* Multiple EA blocks not supported */
8746	{ PR_1_EA_MULTI_BLOCK,
8747	  N_("@a @b %b has h_@bs > 1.  "),
8748	  PROMPT_CLEAR, 0},
8749
8750	/* Error allocating EA region allocation structure */
8751	{ PR_1_EA_ALLOC_REGION,
8752	  N_("@A @a @b %b.  "),
8753	  PROMPT_ABORT, 0},
8754
8755	/* Error EA allocation collision */
8756	{ PR_1_EA_ALLOC_COLLISION,
8757	  N_("@a @b %b is corrupt (allocation collision).  "),
8758	  PROMPT_CLEAR, 0},
8759
8760	/* Bad extended attribute name */
8761	{ PR_1_EA_BAD_NAME,
8762	  N_("@a @b %b is corrupt (@n name).  "),
8763	  PROMPT_CLEAR, 0},
8764
8765	/* Bad extended attribute value */
8766	{ PR_1_EA_BAD_VALUE,
8767	  N_("@a @b %b is corrupt (@n value).  "),
8768	  PROMPT_CLEAR, 0},
8769
8770	/* Inode too big (latch question) */
8771	{ PR_1_INODE_TOOBIG,
8772	  N_("@i %i is too big.  "), PROMPT_TRUNCATE, 0 },
8773
8774	/* Directory too big */
8775	{ PR_1_TOOBIG_DIR,
8776	  N_("@b #%B (%b) causes @d to be too big.  "),
8777	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
8778
8779	/* Regular file too big */
8780	{ PR_1_TOOBIG_REG,
8781	  N_("@b #%B (%b) causes file to be too big.  "),
8782	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
8783
8784	/* Symlink too big */
8785	{ PR_1_TOOBIG_SYMLINK,
8786	  N_("@b #%B (%b) causes symlink to be too big.  "),
8787	  PROMPT_CLEAR, PR_LATCH_TOOBIG },
8788
8789	/* INDEX_FL flag set on a non-HTREE filesystem */
8790	{ PR_1_HTREE_SET,
8791	  N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8792	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8793
8794	/* INDEX_FL flag set on a non-directory */
8795	{ PR_1_HTREE_NODIR,
8796	  N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8797	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8798
8799	/* Invalid root node in HTREE directory */
8800	{ PR_1_HTREE_BADROOT,
8801	  N_("@h %i has an @n root node.\n"),
8802	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8803
8804	/* Unsupported hash version in HTREE directory */
8805	{ PR_1_HTREE_HASHV,
8806	  N_("@h %i has an unsupported hash version (%N)\n"),
8807	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8808
8809	/* Incompatible flag in HTREE root node */
8810	{ PR_1_HTREE_INCOMPAT,
8811	  N_("@h %i uses an incompatible htree root node flag.\n"),
8812	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8813
8814	/* HTREE too deep */
8815	{ PR_1_HTREE_DEPTH,
8816	  N_("@h %i has a tree depth (%N) which is too big\n"),
8817	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8818
8819	/* Bad block has indirect block that conflicts with filesystem block */
8820	{ PR_1_BB_FS_BLOCK,
8821	  N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8822	     "@f metadata.  "),
8823	  PROMPT_CLEAR, PR_LATCH_BBLOCK },
8824
8825	/* Resize inode failed */
8826	{ PR_1_RESIZE_INODE_CREATE,
8827	  N_("Resize @i (re)creation failed: %m."),
8828	  PROMPT_ABORT, 0 },
8829
8830	/* invalid inode->i_extra_isize */
8831	{ PR_1_EXTRA_ISIZE,
8832	  N_("@i %i has a extra size (%IS) which is @n\n"),
8833	  PROMPT_FIX, PR_PREEN_OK },
8834
8835	/* invalid ea entry->e_name_len */
8836	{ PR_1_ATTR_NAME_LEN,
8837	  N_("@a in @i %i has a namelen (%N) which is @n\n"),
8838	  PROMPT_CLEAR, PR_PREEN_OK },
8839
8840	/* invalid ea entry->e_value_size */
8841	{ PR_1_ATTR_VALUE_SIZE,
8842	  N_("@a in @i %i has a value size (%N) which is @n\n"),
8843	  PROMPT_CLEAR, PR_PREEN_OK },
8844
8845	/* invalid ea entry->e_value_offs */
8846	{ PR_1_ATTR_VALUE_OFFSET,
8847	  N_("@a in @i %i has a value offset (%N) which is @n\n"),
8848	  PROMPT_CLEAR, PR_PREEN_OK },
8849
8850	/* invalid ea entry->e_value_block */
8851	{ PR_1_ATTR_VALUE_BLOCK,
8852	  N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8853	  PROMPT_CLEAR, PR_PREEN_OK },
8854
8855	/* invalid ea entry->e_hash */
8856	{ PR_1_ATTR_HASH,
8857	  N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8858	  PROMPT_CLEAR, PR_PREEN_OK },
8859
8860	/* Pass 1b errors */
8861
8862	/* Pass 1B: Rescan for duplicate/bad blocks */
8863	{ PR_1B_PASS_HEADER,
8864	  N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8865	  "Pass 1B: Rescanning for @m @bs\n"),
8866	  PROMPT_NONE, 0 },
8867
8868	/* Duplicate/bad block(s) header */
8869	{ PR_1B_DUP_BLOCK_HEADER,
8870	  N_("@m @b(s) in @i %i:"),
8871	  PROMPT_NONE, 0 },
8872
8873	/* Duplicate/bad block(s) in inode */
8874	{ PR_1B_DUP_BLOCK,
8875	  " %b",
8876	  PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8877
8878	/* Duplicate/bad block(s) end */
8879	{ PR_1B_DUP_BLOCK_END,
8880	  "\n",
8881	  PROMPT_NONE, PR_PREEN_NOHDR },
8882
8883	/* Error while scanning inodes */
8884	{ PR_1B_ISCAN_ERROR,
8885	  N_("Error while scanning inodes (%i): %m\n"),
8886	  PROMPT_NONE, PR_FATAL },
8887
8888	/* Error allocating inode bitmap */
8889	{ PR_1B_ALLOCATE_IBITMAP_ERROR,
8890	  N_("@A @i @B (@i_dup_map): %m\n"),
8891	  PROMPT_NONE, PR_FATAL },
8892
8893	/* Error while iterating over blocks */
8894	{ PR_1B_BLOCK_ITERATE,
8895	  N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8896	  PROMPT_NONE, 0 },
8897
8898	/* Error adjusting EA refcount */
8899	{ PR_1B_ADJ_EA_REFCOUNT,
8900	  N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8901	  PROMPT_NONE, 0 },
8902
8903
8904	/* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8905	{ PR_1C_PASS_HEADER,
8906	  N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8907	  PROMPT_NONE, 0 },
8908
8909
8910	/* Pass 1D: Reconciling multiply-claimed blocks */
8911	{ PR_1D_PASS_HEADER,
8912	  N_("Pass 1D: Reconciling @m @bs\n"),
8913	  PROMPT_NONE, 0 },
8914
8915	/* File has duplicate blocks */
8916	{ PR_1D_DUP_FILE,
8917	  N_("File %Q (@i #%i, mod time %IM)\n"
8918	  "  has %B @m @b(s), shared with %N file(s):\n"),
8919	  PROMPT_NONE, 0 },
8920
8921	/* List of files sharing duplicate blocks */
8922	{ PR_1D_DUP_FILE_LIST,
8923	  N_("\t%Q (@i #%i, mod time %IM)\n"),
8924	  PROMPT_NONE, 0 },
8925
8926	/* File sharing blocks with filesystem metadata  */
8927	{ PR_1D_SHARE_METADATA,
8928	  N_("\t<@f metadata>\n"),
8929	  PROMPT_NONE, 0 },
8930
8931	/* Report of how many duplicate/bad inodes */
8932	{ PR_1D_NUM_DUP_INODES,
8933	  N_("(There are %N @is containing @m @bs.)\n\n"),
8934	  PROMPT_NONE, 0 },
8935
8936	/* Duplicated blocks already reassigned or cloned. */
8937	{ PR_1D_DUP_BLOCKS_DEALT,
8938	  N_("@m @bs already reassigned or cloned.\n\n"),
8939	  PROMPT_NONE, 0 },
8940
8941	/* Clone duplicate/bad blocks? */
8942	{ PR_1D_CLONE_QUESTION,
8943	  "", PROMPT_CLONE, PR_NO_OK },
8944
8945	/* Delete file? */
8946	{ PR_1D_DELETE_QUESTION,
8947	  "", PROMPT_DELETE, 0 },
8948
8949	/* Couldn't clone file (error) */
8950	{ PR_1D_CLONE_ERROR,
8951	  N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
8952
8953	/* Pass 2 errors */
8954
8955	/* Pass 2: Checking directory structure */
8956	{ PR_2_PASS_HEADER,
8957	  N_("Pass 2: Checking @d structure\n"),
8958	  PROMPT_NONE, 0 },
8959
8960	/* Bad inode number for '.' */
8961	{ PR_2_BAD_INODE_DOT,
8962	  N_("@n @i number for '.' in @d @i %i.\n"),
8963	  PROMPT_FIX, 0 },
8964
8965	/* Directory entry has bad inode number */
8966	{ PR_2_BAD_INO,
8967	  N_("@E has @n @i #: %Di.\n"),
8968	  PROMPT_CLEAR, 0 },
8969
8970	/* Directory entry has deleted or unused inode */
8971	{ PR_2_UNUSED_INODE,
8972	  N_("@E has @D/unused @i %Di.  "),
8973	  PROMPT_CLEAR, PR_PREEN_OK },
8974
8975	/* Directry entry is link to '.' */
8976	{ PR_2_LINK_DOT,
8977	  N_("@E @L to '.'  "),
8978	  PROMPT_CLEAR, 0 },
8979
8980	/* Directory entry points to inode now located in a bad block */
8981	{ PR_2_BB_INODE,
8982	  N_("@E points to @i (%Di) located in a bad @b.\n"),
8983	  PROMPT_CLEAR, 0 },
8984
8985	/* Directory entry contains a link to a directory */
8986	{ PR_2_LINK_DIR,
8987	  N_("@E @L to @d %P (%Di).\n"),
8988	  PROMPT_CLEAR, 0 },
8989
8990	/* Directory entry contains a link to the root directry */
8991	{ PR_2_LINK_ROOT,
8992	  N_("@E @L to the @r.\n"),
8993	  PROMPT_CLEAR, 0 },
8994
8995	/* Directory entry has illegal characters in its name */
8996	{ PR_2_BAD_NAME,
8997	  N_("@E has illegal characters in its name.\n"),
8998	  PROMPT_FIX, 0 },
8999
9000	/* Missing '.' in directory inode */
9001	{ PR_2_MISSING_DOT,
9002	  N_("Missing '.' in @d @i %i.\n"),
9003	  PROMPT_FIX, 0 },
9004
9005	/* Missing '..' in directory inode */
9006	{ PR_2_MISSING_DOT_DOT,
9007	  N_("Missing '..' in @d @i %i.\n"),
9008	  PROMPT_FIX, 0 },
9009
9010	/* First entry in directory inode doesn't contain '.' */
9011	{ PR_2_1ST_NOT_DOT,
9012	  N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9013	  PROMPT_FIX, 0 },
9014
9015	/* Second entry in directory inode doesn't contain '..' */
9016	{ PR_2_2ND_NOT_DOT_DOT,
9017	  N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9018	  PROMPT_FIX, 0 },
9019
9020	/* i_faddr should be zero */
9021	{ PR_2_FADDR_ZERO,
9022	  N_("i_faddr @F %IF, @s zero.\n"),
9023	  PROMPT_CLEAR, 0 },
9024
9025	/* i_file_acl should be zero */
9026	{ PR_2_FILE_ACL_ZERO,
9027	  N_("i_file_acl @F %If, @s zero.\n"),
9028	  PROMPT_CLEAR, 0 },
9029
9030	/* i_dir_acl should be zero */
9031	{ PR_2_DIR_ACL_ZERO,
9032	  N_("i_dir_acl @F %Id, @s zero.\n"),
9033	  PROMPT_CLEAR, 0 },
9034
9035	/* i_frag should be zero */
9036	{ PR_2_FRAG_ZERO,
9037	  N_("i_frag @F %N, @s zero.\n"),
9038	  PROMPT_CLEAR, 0 },
9039
9040	/* i_fsize should be zero */
9041	{ PR_2_FSIZE_ZERO,
9042	  N_("i_fsize @F %N, @s zero.\n"),
9043	  PROMPT_CLEAR, 0 },
9044
9045	/* inode has bad mode */
9046	{ PR_2_BAD_MODE,
9047	  N_("@i %i (%Q) has @n mode (%Im).\n"),
9048	  PROMPT_CLEAR, 0 },
9049
9050	/* directory corrupted */
9051	{ PR_2_DIR_CORRUPTED,
9052	  N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9053	  PROMPT_SALVAGE, 0 },
9054
9055	/* filename too long */
9056	{ PR_2_FILENAME_LONG,
9057	  N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9058	  PROMPT_TRUNCATE, 0 },
9059
9060	/* Directory inode has a missing block (hole) */
9061	{ PR_2_DIRECTORY_HOLE,
9062	  N_("@d @i %i has an unallocated @b #%B.  "),
9063	  PROMPT_ALLOCATE, 0 },
9064
9065	/* '.' is not NULL terminated */
9066	{ PR_2_DOT_NULL_TERM,
9067	  N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9068	  PROMPT_FIX, 0 },
9069
9070	/* '..' is not NULL terminated */
9071	{ PR_2_DOT_DOT_NULL_TERM,
9072	  N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9073	  PROMPT_FIX, 0 },
9074
9075	/* Illegal character device inode */
9076	{ PR_2_BAD_CHAR_DEV,
9077	  N_("@i %i (%Q) is an @I character @v.\n"),
9078	  PROMPT_CLEAR, 0 },
9079
9080	/* Illegal block device inode */
9081	{ PR_2_BAD_BLOCK_DEV,
9082	  N_("@i %i (%Q) is an @I @b @v.\n"),
9083	  PROMPT_CLEAR, 0 },
9084
9085	/* Duplicate '.' entry */
9086	{ PR_2_DUP_DOT,
9087	  N_("@E is duplicate '.' @e.\n"),
9088	  PROMPT_FIX, 0 },
9089
9090	/* Duplicate '..' entry */
9091	{ PR_2_DUP_DOT_DOT,
9092	  N_("@E is duplicate '..' @e.\n"),
9093	  PROMPT_FIX, 0 },
9094
9095	/* Internal error: couldn't find dir_info */
9096	{ PR_2_NO_DIRINFO,
9097	  N_("Internal error: cannot find dir_info for %i.\n"),
9098	  PROMPT_NONE, PR_FATAL },
9099
9100	/* Final rec_len is wrong */
9101	{ PR_2_FINAL_RECLEN,
9102	  N_("@E has rec_len of %Dr, @s %N.\n"),
9103	  PROMPT_FIX, 0 },
9104
9105	/* Error allocating icount structure */
9106	{ PR_2_ALLOCATE_ICOUNT,
9107	  N_("@A icount structure: %m\n"),
9108	  PROMPT_NONE, PR_FATAL },
9109
9110	/* Error iterating over directory blocks */
9111	{ PR_2_DBLIST_ITERATE,
9112	  N_("Error iterating over @d @bs: %m\n"),
9113	  PROMPT_NONE, PR_FATAL },
9114
9115	/* Error reading directory block */
9116	{ PR_2_READ_DIRBLOCK,
9117	  N_("Error reading @d @b %b (@i %i): %m\n"),
9118	  PROMPT_CONTINUE, 0 },
9119
9120	/* Error writing directory block */
9121	{ PR_2_WRITE_DIRBLOCK,
9122	  N_("Error writing @d @b %b (@i %i): %m\n"),
9123	  PROMPT_CONTINUE, 0 },
9124
9125	/* Error allocating new directory block */
9126	{ PR_2_ALLOC_DIRBOCK,
9127	  N_("@A new @d @b for @i %i (%s): %m\n"),
9128	  PROMPT_NONE, 0 },
9129
9130	/* Error deallocating inode */
9131	{ PR_2_DEALLOC_INODE,
9132	  N_("Error deallocating @i %i: %m\n"),
9133	  PROMPT_NONE, PR_FATAL },
9134
9135	/* Directory entry for '.' is big.  Split? */
9136	{ PR_2_SPLIT_DOT,
9137	  N_("@d @e for '.' is big.  "),
9138	  PROMPT_SPLIT, PR_NO_OK },
9139
9140	/* Illegal FIFO inode */
9141	{ PR_2_BAD_FIFO,
9142	  N_("@i %i (%Q) is an @I FIFO.\n"),
9143	  PROMPT_CLEAR, 0 },
9144
9145	/* Illegal socket inode */
9146	{ PR_2_BAD_SOCKET,
9147	  N_("@i %i (%Q) is an @I socket.\n"),
9148	  PROMPT_CLEAR, 0 },
9149
9150	/* Directory filetype not set */
9151	{ PR_2_SET_FILETYPE,
9152	  N_("Setting filetype for @E to %N.\n"),
9153	  PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9154
9155	/* Directory filetype incorrect */
9156	{ PR_2_BAD_FILETYPE,
9157	  N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9158	  PROMPT_FIX, 0 },
9159
9160	/* Directory filetype set on filesystem */
9161	{ PR_2_CLEAR_FILETYPE,
9162	  N_("@E has filetype set.\n"),
9163	  PROMPT_CLEAR, PR_PREEN_OK },
9164
9165	/* Directory filename is null */
9166	{ PR_2_NULL_NAME,
9167	  N_("@E has a @z name.\n"),
9168	  PROMPT_CLEAR, 0 },
9169
9170	/* Invalid symlink */
9171	{ PR_2_INVALID_SYMLINK,
9172	  N_("Symlink %Q (@i #%i) is @n.\n"),
9173	  PROMPT_CLEAR, 0 },
9174
9175	/* i_file_acl (extended attribute block) is bad */
9176	{ PR_2_FILE_ACL_BAD,
9177	  N_("@a @b @F @n (%If).\n"),
9178	  PROMPT_CLEAR, 0 },
9179
9180	/* Filesystem contains large files, but has no such flag in sb */
9181	{ PR_2_FEATURE_LARGE_FILES,
9182	  N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9183	  PROMPT_FIX, 0 },
9184
9185	/* Node in HTREE directory not referenced */
9186	{ PR_2_HTREE_NOTREF,
9187	  N_("@p @h %d: node (%B) not referenced\n"),
9188	  PROMPT_NONE, 0 },
9189
9190	/* Node in HTREE directory referenced twice */
9191	{ PR_2_HTREE_DUPREF,
9192	  N_("@p @h %d: node (%B) referenced twice\n"),
9193	  PROMPT_NONE, 0 },
9194
9195	/* Node in HTREE directory has bad min hash */
9196	{ PR_2_HTREE_MIN_HASH,
9197	  N_("@p @h %d: node (%B) has bad min hash\n"),
9198	  PROMPT_NONE, 0 },
9199
9200	/* Node in HTREE directory has bad max hash */
9201	{ PR_2_HTREE_MAX_HASH,
9202	  N_("@p @h %d: node (%B) has bad max hash\n"),
9203	  PROMPT_NONE, 0 },
9204
9205	/* Clear invalid HTREE directory */
9206	{ PR_2_HTREE_CLEAR,
9207	  N_("@n @h %d (%q).  "), PROMPT_CLEAR, 0 },
9208
9209	/* Bad block in htree interior node */
9210	{ PR_2_HTREE_BADBLK,
9211	  N_("@p @h %d (%q): bad @b number %b.\n"),
9212	  PROMPT_CLEAR_HTREE, 0 },
9213
9214	/* Error adjusting EA refcount */
9215	{ PR_2_ADJ_EA_REFCOUNT,
9216	  N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9217	  PROMPT_NONE, PR_FATAL },
9218
9219	/* Invalid HTREE root node */
9220	{ PR_2_HTREE_BAD_ROOT,
9221	  N_("@p @h %d: root node is @n\n"),
9222	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9223
9224	/* Invalid HTREE limit */
9225	{ PR_2_HTREE_BAD_LIMIT,
9226	  N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9227	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9228
9229	/* Invalid HTREE count */
9230	{ PR_2_HTREE_BAD_COUNT,
9231	  N_("@p @h %d: node (%B) has @n count (%N)\n"),
9232	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9233
9234	/* HTREE interior node has out-of-order hashes in table */
9235	{ PR_2_HTREE_HASH_ORDER,
9236	  N_("@p @h %d: node (%B) has an unordered hash table\n"),
9237	  PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9238
9239	/* Node in HTREE directory has invalid depth */
9240	{ PR_2_HTREE_BAD_DEPTH,
9241	  N_("@p @h %d: node (%B) has @n depth\n"),
9242	  PROMPT_NONE, 0 },
9243
9244	/* Duplicate directory entry found */
9245	{ PR_2_DUPLICATE_DIRENT,
9246	  N_("Duplicate @E found.  "),
9247	  PROMPT_CLEAR, 0 },
9248
9249	/* Non-unique filename found */
9250	{ PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9251	  N_("@E has a non-unique filename.\nRename to %s"),
9252	  PROMPT_NULL, 0 },
9253
9254	/* Duplicate directory entry found */
9255	{ PR_2_REPORT_DUP_DIRENT,
9256	  N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9257	  PROMPT_NONE, 0 },
9258
9259	/* Pass 3 errors */
9260
9261	/* Pass 3: Checking directory connectivity */
9262	{ PR_3_PASS_HEADER,
9263	  N_("Pass 3: Checking @d connectivity\n"),
9264	  PROMPT_NONE, 0 },
9265
9266	/* Root inode not allocated */
9267	{ PR_3_NO_ROOT_INODE,
9268	  N_("@r not allocated.  "),
9269	  PROMPT_ALLOCATE, 0 },
9270
9271	/* No room in lost+found */
9272	{ PR_3_EXPAND_LF_DIR,
9273	  N_("No room in @l @d.  "),
9274	  PROMPT_EXPAND, 0 },
9275
9276	/* Unconnected directory inode */
9277	{ PR_3_UNCONNECTED_DIR,
9278	  N_("Unconnected @d @i %i (%p)\n"),
9279	  PROMPT_CONNECT, 0 },
9280
9281	/* /lost+found not found */
9282	{ PR_3_NO_LF_DIR,
9283	  N_("/@l not found.  "),
9284	  PROMPT_CREATE, PR_PREEN_OK },
9285
9286	/* .. entry is incorrect */
9287	{ PR_3_BAD_DOT_DOT,
9288	  N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9289	  PROMPT_FIX, 0 },
9290
9291	/* Bad or non-existent /lost+found.  Cannot reconnect */
9292	{ PR_3_NO_LPF,
9293	  N_("Bad or non-existent /@l.  Cannot reconnect.\n"),
9294	  PROMPT_NONE, 0 },
9295
9296	/* Could not expand /lost+found */
9297	{ PR_3_CANT_EXPAND_LPF,
9298	  N_("Could not expand /@l: %m\n"),
9299	  PROMPT_NONE, 0 },
9300
9301	/* Could not reconnect inode */
9302	{ PR_3_CANT_RECONNECT,
9303	  N_("Could not reconnect %i: %m\n"),
9304	  PROMPT_NONE, 0 },
9305
9306	/* Error while trying to find /lost+found */
9307	{ PR_3_ERR_FIND_LPF,
9308	  N_("Error while trying to find /@l: %m\n"),
9309	  PROMPT_NONE, 0 },
9310
9311	/* Error in ext2fs_new_block while creating /lost+found */
9312	{ PR_3_ERR_LPF_NEW_BLOCK,
9313	  N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9314	  PROMPT_NONE, 0 },
9315
9316	/* Error in ext2fs_new_inode while creating /lost+found */
9317	{ PR_3_ERR_LPF_NEW_INODE,
9318	  N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9319	  PROMPT_NONE, 0 },
9320
9321	/* Error in ext2fs_new_dir_block while creating /lost+found */
9322	{ PR_3_ERR_LPF_NEW_DIR_BLOCK,
9323	  N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9324	  PROMPT_NONE, 0 },
9325
9326	/* Error while writing directory block for /lost+found */
9327	{ PR_3_ERR_LPF_WRITE_BLOCK,
9328	  N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9329	  PROMPT_NONE, 0 },
9330
9331	/* Error while adjusting inode count */
9332	{ PR_3_ADJUST_INODE,
9333	  N_("Error while adjusting @i count on @i %i\n"),
9334	  PROMPT_NONE, 0 },
9335
9336	/* Couldn't fix parent directory -- error */
9337	{ PR_3_FIX_PARENT_ERR,
9338	  N_("Couldn't fix parent of @i %i: %m\n\n"),
9339	  PROMPT_NONE, 0 },
9340
9341	/* Couldn't fix parent directory -- couldn't find it */
9342	{ PR_3_FIX_PARENT_NOFIND,
9343	  N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9344	  PROMPT_NONE, 0 },
9345
9346	/* Error allocating inode bitmap */
9347	{ PR_3_ALLOCATE_IBITMAP_ERROR,
9348	  N_("@A @i @B (%N): %m\n"),
9349	  PROMPT_NONE, PR_FATAL },
9350
9351	/* Error creating root directory */
9352	{ PR_3_CREATE_ROOT_ERROR,
9353	  N_("Error creating root @d (%s): %m\n"),
9354	  PROMPT_NONE, PR_FATAL },
9355
9356	/* Error creating lost and found directory */
9357	{ PR_3_CREATE_LPF_ERROR,
9358	  N_("Error creating /@l @d (%s): %m\n"),
9359	  PROMPT_NONE, PR_FATAL },
9360
9361	/* Root inode is not directory; aborting */
9362	{ PR_3_ROOT_NOT_DIR_ABORT,
9363	  N_("@r is not a @d; aborting.\n"),
9364	  PROMPT_NONE, PR_FATAL },
9365
9366	/* Cannot proceed without a root inode. */
9367	{ PR_3_NO_ROOT_INODE_ABORT,
9368	  N_("Cannot proceed without a @r.\n"),
9369	  PROMPT_NONE, PR_FATAL },
9370
9371	/* Internal error: couldn't find dir_info */
9372	{ PR_3_NO_DIRINFO,
9373	  N_("Internal error: cannot find dir_info for %i.\n"),
9374	  PROMPT_NONE, PR_FATAL },
9375
9376	/* Lost+found not a directory */
9377	{ PR_3_LPF_NOTDIR,
9378	  N_("/@l is not a @d (ino=%i)\n"),
9379	  PROMPT_UNLINK, 0 },
9380
9381	/* Pass 3A Directory Optimization       */
9382
9383	/* Pass 3A: Optimizing directories */
9384	{ PR_3A_PASS_HEADER,
9385	  N_("Pass 3A: Optimizing directories\n"),
9386	  PROMPT_NONE, PR_PREEN_NOMSG },
9387
9388	/* Error iterating over directories */
9389	{ PR_3A_OPTIMIZE_ITER,
9390	  N_("Failed to create dirs_to_hash iterator: %m"),
9391	  PROMPT_NONE, 0 },
9392
9393	/* Error rehash directory */
9394	{ PR_3A_OPTIMIZE_DIR_ERR,
9395	  N_("Failed to optimize directory %q (%d): %m"),
9396	  PROMPT_NONE, 0 },
9397
9398	/* Rehashing dir header */
9399	{ PR_3A_OPTIMIZE_DIR_HEADER,
9400	  N_("Optimizing directories: "),
9401	  PROMPT_NONE, PR_MSG_ONLY },
9402
9403	/* Rehashing directory %d */
9404	{ PR_3A_OPTIMIZE_DIR,
9405	  " %d",
9406	  PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9407
9408	/* Rehashing dir end */
9409	{ PR_3A_OPTIMIZE_DIR_END,
9410	  "\n",
9411	  PROMPT_NONE, PR_PREEN_NOHDR },
9412
9413	/* Pass 4 errors */
9414
9415	/* Pass 4: Checking reference counts */
9416	{ PR_4_PASS_HEADER,
9417	  N_("Pass 4: Checking reference counts\n"),
9418	  PROMPT_NONE, 0 },
9419
9420	/* Unattached zero-length inode */
9421	{ PR_4_ZERO_LEN_INODE,
9422	  N_("@u @z @i %i.  "),
9423	  PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9424
9425	/* Unattached inode */
9426	{ PR_4_UNATTACHED_INODE,
9427	  N_("@u @i %i\n"),
9428	  PROMPT_CONNECT, 0 },
9429
9430	/* Inode ref count wrong */
9431	{ PR_4_BAD_REF_COUNT,
9432	  N_("@i %i ref count is %Il, @s %N.  "),
9433	  PROMPT_FIX, PR_PREEN_OK },
9434
9435	{ PR_4_INCONSISTENT_COUNT,
9436	  N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9437	  "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9438	  "@i_link_info[%i] is %N, @i.i_links_count is %Il.  "
9439	  "They @s the same!\n"),
9440	  PROMPT_NONE, 0 },
9441
9442	/* Pass 5 errors */
9443
9444	/* Pass 5: Checking group summary information */
9445	{ PR_5_PASS_HEADER,
9446	  N_("Pass 5: Checking @g summary information\n"),
9447	  PROMPT_NONE, 0 },
9448
9449	/* Padding at end of inode bitmap is not set. */
9450	{ PR_5_INODE_BMAP_PADDING,
9451	  N_("Padding at end of @i @B is not set. "),
9452	  PROMPT_FIX, PR_PREEN_OK },
9453
9454	/* Padding at end of block bitmap is not set. */
9455	{ PR_5_BLOCK_BMAP_PADDING,
9456	  N_("Padding at end of @b @B is not set. "),
9457	  PROMPT_FIX, PR_PREEN_OK },
9458
9459	/* Block bitmap differences header */
9460	{ PR_5_BLOCK_BITMAP_HEADER,
9461	  N_("@b @B differences: "),
9462	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9463
9464	/* Block not used, but marked in bitmap */
9465	{ PR_5_BLOCK_UNUSED,
9466	  " -%b",
9467	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9468
9469	/* Block used, but not marked used in bitmap */
9470	{ PR_5_BLOCK_USED,
9471	  " +%b",
9472	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9473
9474	/* Block bitmap differences end */
9475	{ PR_5_BLOCK_BITMAP_END,
9476	  "\n",
9477	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9478
9479	/* Inode bitmap differences header */
9480	{ PR_5_INODE_BITMAP_HEADER,
9481	  N_("@i @B differences: "),
9482	  PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9483
9484	/* Inode not used, but marked in bitmap */
9485	{ PR_5_INODE_UNUSED,
9486	  " -%i",
9487	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9488
9489	/* Inode used, but not marked used in bitmap */
9490	{ PR_5_INODE_USED,
9491	  " +%i",
9492	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9493
9494	/* Inode bitmap differences end */
9495	{ PR_5_INODE_BITMAP_END,
9496	  "\n",
9497	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9498
9499	/* Free inodes count for group wrong */
9500	{ PR_5_FREE_INODE_COUNT_GROUP,
9501	  N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9502	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9503
9504	/* Directories count for group wrong */
9505	{ PR_5_FREE_DIR_COUNT_GROUP,
9506	  N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9507	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9508
9509	/* Free inodes count wrong */
9510	{ PR_5_FREE_INODE_COUNT,
9511	  N_("Free @is count wrong (%i, counted=%j).\n"),
9512	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9513
9514	/* Free blocks count for group wrong */
9515	{ PR_5_FREE_BLOCK_COUNT_GROUP,
9516	  N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9517	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9518
9519	/* Free blocks count wrong */
9520	{ PR_5_FREE_BLOCK_COUNT,
9521	  N_("Free @bs count wrong (%b, counted=%c).\n"),
9522	  PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9523
9524	/* Programming error: bitmap endpoints don't match */
9525	{ PR_5_BMAP_ENDPOINTS,
9526	  N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9527	  "match calculated @B endpoints (%i, %j)\n"),
9528	  PROMPT_NONE, PR_FATAL },
9529
9530	/* Internal error: fudging end of bitmap */
9531	{ PR_5_FUDGE_BITMAP_ERROR,
9532	  N_("Internal error: fudging end of bitmap (%N)\n"),
9533	  PROMPT_NONE, PR_FATAL },
9534
9535	/* Error copying in replacement inode bitmap */
9536	{ PR_5_COPY_IBITMAP_ERROR,
9537	  N_("Error copying in replacement @i @B: %m\n"),
9538	  PROMPT_NONE, PR_FATAL },
9539
9540	/* Error copying in replacement block bitmap */
9541	{ PR_5_COPY_BBITMAP_ERROR,
9542	  N_("Error copying in replacement @b @B: %m\n"),
9543	  PROMPT_NONE, PR_FATAL },
9544
9545	/* Block range not used, but marked in bitmap */
9546	{ PR_5_BLOCK_RANGE_UNUSED,
9547	  " -(%b--%c)",
9548	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9549
9550	/* Block range used, but not marked used in bitmap */
9551	{ PR_5_BLOCK_RANGE_USED,
9552	  " +(%b--%c)",
9553	  PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9554
9555	/* Inode range not used, but marked in bitmap */
9556	{ PR_5_INODE_RANGE_UNUSED,
9557	  " -(%i--%j)",
9558	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9559
9560	/* Inode range used, but not marked used in bitmap */
9561	{ PR_5_INODE_RANGE_USED,
9562	  " +(%i--%j)",
9563	  PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9564
9565	{ 0 }
9566};
9567
9568/*
9569 * This is the latch flags register.  It allows several problems to be
9570 * "latched" together.  This means that the user has to answer but one
9571 * question for the set of problems, and all of the associated
9572 * problems will be either fixed or not fixed.
9573 */
9574static struct latch_descr pr_latch_info[] = {
9575	{ PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9576	{ PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9577	{ PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9578	{ PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9579	{ PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9580	{ PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9581	{ PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9582	{ PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9583	{ PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9584	{ -1, 0, 0 },
9585};
9586
9587static const struct e2fsck_problem *find_problem(problem_t code)
9588{
9589	int     i;
9590
9591	for (i=0; problem_table[i].e2p_code; i++) {
9592		if (problem_table[i].e2p_code == code)
9593			return &problem_table[i];
9594	}
9595	return 0;
9596}
9597
9598static struct latch_descr *find_latch(int code)
9599{
9600	int     i;
9601
9602	for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9603		if (pr_latch_info[i].latch_code == code)
9604			return &pr_latch_info[i];
9605	}
9606	return 0;
9607}
9608
9609int end_problem_latch(e2fsck_t ctx, int mask)
9610{
9611	struct latch_descr *ldesc;
9612	struct problem_context pctx;
9613	int answer = -1;
9614
9615	ldesc = find_latch(mask);
9616	if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9617		clear_problem_context(&pctx);
9618		answer = fix_problem(ctx, ldesc->end_message, &pctx);
9619	}
9620	ldesc->flags &= ~(PRL_VARIABLE);
9621	return answer;
9622}
9623
9624int set_latch_flags(int mask, int setflags, int clearflags)
9625{
9626	struct latch_descr *ldesc;
9627
9628	ldesc = find_latch(mask);
9629	if (!ldesc)
9630		return -1;
9631	ldesc->flags |= setflags;
9632	ldesc->flags &= ~clearflags;
9633	return 0;
9634}
9635
9636void clear_problem_context(struct problem_context *ctx)
9637{
9638	memset(ctx, 0, sizeof(struct problem_context));
9639	ctx->blkcount = -1;
9640	ctx->group = -1;
9641}
9642
9643int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9644{
9645	ext2_filsys fs = ctx->fs;
9646	const struct e2fsck_problem *ptr;
9647	struct latch_descr *ldesc = 0;
9648	const char *message;
9649	int             def_yn, answer, ans;
9650	int             print_answer = 0;
9651	int             suppress = 0;
9652
9653	ptr = find_problem(code);
9654	if (!ptr) {
9655		printf(_("Unhandled error code (0x%x)!\n"), code);
9656		return 0;
9657	}
9658	def_yn = 1;
9659	if ((ptr->flags & PR_NO_DEFAULT) ||
9660	    ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9661	    (ctx->options & E2F_OPT_NO))
9662		def_yn= 0;
9663
9664	/*
9665	 * Do special latch processing.  This is where we ask the
9666	 * latch question, if it exists
9667	 */
9668	if (ptr->flags & PR_LATCH_MASK) {
9669		ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9670		if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9671			ans = fix_problem(ctx, ldesc->question, pctx);
9672			if (ans == 1)
9673				ldesc->flags |= PRL_YES;
9674			if (ans == 0)
9675				ldesc->flags |= PRL_NO;
9676			ldesc->flags |= PRL_LATCHED;
9677		}
9678		if (ldesc->flags & PRL_SUPPRESS)
9679			suppress++;
9680	}
9681	if ((ptr->flags & PR_PREEN_NOMSG) &&
9682	    (ctx->options & E2F_OPT_PREEN))
9683		suppress++;
9684	if ((ptr->flags & PR_NO_NOMSG) &&
9685	    (ctx->options & E2F_OPT_NO))
9686		suppress++;
9687	if (!suppress) {
9688		message = ptr->e2p_description;
9689		if ((ctx->options & E2F_OPT_PREEN) &&
9690		    !(ptr->flags & PR_PREEN_NOHDR)) {
9691			printf("%s: ", ctx->device_name ?
9692			       ctx->device_name : ctx->filesystem_name);
9693		}
9694		if (*message)
9695			print_e2fsck_message(ctx, _(message), pctx, 1);
9696	}
9697	if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9698		preenhalt(ctx);
9699
9700	if (ptr->flags & PR_FATAL)
9701		bb_error_msg_and_die(0);
9702
9703	if (ptr->prompt == PROMPT_NONE) {
9704		if (ptr->flags & PR_NOCOLLATE)
9705			answer = -1;
9706		else
9707			answer = def_yn;
9708	} else {
9709		if (ctx->options & E2F_OPT_PREEN) {
9710			answer = def_yn;
9711			if (!(ptr->flags & PR_PREEN_NOMSG))
9712				print_answer = 1;
9713		} else if ((ptr->flags & PR_LATCH_MASK) &&
9714			   (ldesc->flags & (PRL_YES | PRL_NO))) {
9715			if (!suppress)
9716				print_answer = 1;
9717			if (ldesc->flags & PRL_YES)
9718				answer = 1;
9719			else
9720				answer = 0;
9721		} else
9722			answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9723		if (!answer && !(ptr->flags & PR_NO_OK))
9724			ext2fs_unmark_valid(fs);
9725
9726		if (print_answer)
9727			printf("%s.\n", answer ?
9728			       _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9729
9730	}
9731
9732	if ((ptr->prompt == PROMPT_ABORT) && answer)
9733		bb_error_msg_and_die(0);
9734
9735	if (ptr->flags & PR_AFTER_CODE)
9736		answer = fix_problem(ctx, ptr->second_code, pctx);
9737
9738	return answer;
9739}
9740
9741/*
9742 * linux/fs/recovery.c
9743 *
9744 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9745 */
9746
9747/*
9748 * Maintain information about the progress of the recovery job, so that
9749 * the different passes can carry information between them.
9750 */
9751struct recovery_info
9752{
9753	tid_t           start_transaction;
9754	tid_t           end_transaction;
9755
9756	int             nr_replays;
9757	int             nr_revokes;
9758	int             nr_revoke_hits;
9759};
9760
9761enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9762static int do_one_pass(journal_t *journal,
9763				struct recovery_info *info, enum passtype pass);
9764static int scan_revoke_records(journal_t *, struct buffer_head *,
9765				tid_t, struct recovery_info *);
9766
9767/*
9768 * Read a block from the journal
9769 */
9770
9771static int jread(struct buffer_head **bhp, journal_t *journal,
9772		 unsigned int offset)
9773{
9774	int err;
9775	unsigned long blocknr;
9776	struct buffer_head *bh;
9777
9778	*bhp = NULL;
9779
9780	err = journal_bmap(journal, offset, &blocknr);
9781
9782	if (err) {
9783		printf("JBD: bad block at offset %u\n", offset);
9784		return err;
9785	}
9786
9787	bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9788	if (!bh)
9789		return -ENOMEM;
9790
9791	if (!buffer_uptodate(bh)) {
9792		/* If this is a brand new buffer, start readahead.
9793		   Otherwise, we assume we are already reading it.  */
9794		if (!buffer_req(bh))
9795			do_readahead(journal, offset);
9796		wait_on_buffer(bh);
9797	}
9798
9799	if (!buffer_uptodate(bh)) {
9800		printf("JBD: Failed to read block at offset %u\n", offset);
9801		brelse(bh);
9802		return -EIO;
9803	}
9804
9805	*bhp = bh;
9806	return 0;
9807}
9808
9809
9810/*
9811 * Count the number of in-use tags in a journal descriptor block.
9812 */
9813
9814static int count_tags(struct buffer_head *bh, int size)
9815{
9816	char *                  tagp;
9817	journal_block_tag_t *   tag;
9818	int                     nr = 0;
9819
9820	tagp = &bh->b_data[sizeof(journal_header_t)];
9821
9822	while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9823		tag = (journal_block_tag_t *) tagp;
9824
9825		nr++;
9826		tagp += sizeof(journal_block_tag_t);
9827		if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9828			tagp += 16;
9829
9830		if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9831			break;
9832	}
9833
9834	return nr;
9835}
9836
9837
9838/* Make sure we wrap around the log correctly! */
9839#define wrap(journal, var)					      \
9840do {					                            \
9841	if (var >= (journal)->j_last)                                   \
9842		var -= ((journal)->j_last - (journal)->j_first);        \
9843} while (0)
9844
9845/**
9846 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9847 * @journal: the journal to recover
9848 *
9849 * The primary function for recovering the log contents when mounting a
9850 * journaled device.
9851 *
9852 * Recovery is done in three passes.  In the first pass, we look for the
9853 * end of the log.  In the second, we assemble the list of revoke
9854 * blocks.  In the third and final pass, we replay any un-revoked blocks
9855 * in the log.
9856 */
9857int journal_recover(journal_t *journal)
9858{
9859	int                     err;
9860	journal_superblock_t *  sb;
9861
9862	struct recovery_info    info;
9863
9864	memset(&info, 0, sizeof(info));
9865	sb = journal->j_superblock;
9866
9867	/*
9868	 * The journal superblock's s_start field (the current log head)
9869	 * is always zero if, and only if, the journal was cleanly
9870	 * unmounted.
9871	 */
9872
9873	if (!sb->s_start) {
9874		journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9875		return 0;
9876	}
9877
9878	err = do_one_pass(journal, &info, PASS_SCAN);
9879	if (!err)
9880		err = do_one_pass(journal, &info, PASS_REVOKE);
9881	if (!err)
9882		err = do_one_pass(journal, &info, PASS_REPLAY);
9883
9884	/* Restart the log at the next transaction ID, thus invalidating
9885	 * any existing commit records in the log. */
9886	journal->j_transaction_sequence = ++info.end_transaction;
9887
9888	journal_clear_revoke(journal);
9889	sync_blockdev(journal->j_fs_dev);
9890	return err;
9891}
9892
9893static int do_one_pass(journal_t *journal,
9894			struct recovery_info *info, enum passtype pass)
9895{
9896	unsigned int            first_commit_ID, next_commit_ID;
9897	unsigned long           next_log_block;
9898	int                     err, success = 0;
9899	journal_superblock_t *  sb;
9900	journal_header_t *      tmp;
9901	struct buffer_head *    bh;
9902	unsigned int            sequence;
9903	int                     blocktype;
9904
9905	/* Precompute the maximum metadata descriptors in a descriptor block */
9906	int                     MAX_BLOCKS_PER_DESC;
9907	MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9908			       / sizeof(journal_block_tag_t));
9909
9910	/*
9911	 * First thing is to establish what we expect to find in the log
9912	 * (in terms of transaction IDs), and where (in terms of log
9913	 * block offsets): query the superblock.
9914	 */
9915
9916	sb = journal->j_superblock;
9917	next_commit_ID = ntohl(sb->s_sequence);
9918	next_log_block = ntohl(sb->s_start);
9919
9920	first_commit_ID = next_commit_ID;
9921	if (pass == PASS_SCAN)
9922		info->start_transaction = first_commit_ID;
9923
9924	/*
9925	 * Now we walk through the log, transaction by transaction,
9926	 * making sure that each transaction has a commit block in the
9927	 * expected place.  Each complete transaction gets replayed back
9928	 * into the main filesystem.
9929	 */
9930
9931	while (1) {
9932		int                     flags;
9933		char *                  tagp;
9934		journal_block_tag_t *   tag;
9935		struct buffer_head *    obh;
9936		struct buffer_head *    nbh;
9937
9938		/* If we already know where to stop the log traversal,
9939		 * check right now that we haven't gone past the end of
9940		 * the log. */
9941
9942		if (pass != PASS_SCAN)
9943			if (tid_geq(next_commit_ID, info->end_transaction))
9944				break;
9945
9946		/* Skip over each chunk of the transaction looking
9947		 * either the next descriptor block or the final commit
9948		 * record. */
9949
9950		err = jread(&bh, journal, next_log_block);
9951		if (err)
9952			goto failed;
9953
9954		next_log_block++;
9955		wrap(journal, next_log_block);
9956
9957		/* What kind of buffer is it?
9958		 *
9959		 * If it is a descriptor block, check that it has the
9960		 * expected sequence number.  Otherwise, we're all done
9961		 * here. */
9962
9963		tmp = (journal_header_t *)bh->b_data;
9964
9965		if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
9966			brelse(bh);
9967			break;
9968		}
9969
9970		blocktype = ntohl(tmp->h_blocktype);
9971		sequence = ntohl(tmp->h_sequence);
9972
9973		if (sequence != next_commit_ID) {
9974			brelse(bh);
9975			break;
9976		}
9977
9978		/* OK, we have a valid descriptor block which matches
9979		 * all of the sequence number checks.  What are we going
9980		 * to do with it?  That depends on the pass... */
9981
9982		switch(blocktype) {
9983		case JFS_DESCRIPTOR_BLOCK:
9984			/* If it is a valid descriptor block, replay it
9985			 * in pass REPLAY; otherwise, just skip over the
9986			 * blocks it describes. */
9987			if (pass != PASS_REPLAY) {
9988				next_log_block +=
9989					count_tags(bh, journal->j_blocksize);
9990				wrap(journal, next_log_block);
9991				brelse(bh);
9992				continue;
9993			}
9994
9995			/* A descriptor block: we can now write all of
9996			 * the data blocks.  Yay, useful work is finally
9997			 * getting done here! */
9998
9999			tagp = &bh->b_data[sizeof(journal_header_t)];
10000			while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10001			       <= journal->j_blocksize) {
10002				unsigned long io_block;
10003
10004				tag = (journal_block_tag_t *) tagp;
10005				flags = ntohl(tag->t_flags);
10006
10007				io_block = next_log_block++;
10008				wrap(journal, next_log_block);
10009				err = jread(&obh, journal, io_block);
10010				if (err) {
10011					/* Recover what we can, but
10012					 * report failure at the end. */
10013					success = err;
10014					printf("JBD: IO error %d recovering "
10015						"block %ld in log\n",
10016						err, io_block);
10017				} else {
10018					unsigned long blocknr;
10019
10020					blocknr = ntohl(tag->t_blocknr);
10021
10022					/* If the block has been
10023					 * revoked, then we're all done
10024					 * here. */
10025					if (journal_test_revoke
10026					    (journal, blocknr,
10027					     next_commit_ID)) {
10028						brelse(obh);
10029						++info->nr_revoke_hits;
10030						goto skip_write;
10031					}
10032
10033					/* Find a buffer for the new
10034					 * data being restored */
10035					nbh = getblk(journal->j_fs_dev,
10036						       blocknr,
10037						     journal->j_blocksize);
10038					if (nbh == NULL) {
10039						printf("JBD: Out of memory "
10040						       "during recovery.\n");
10041						err = -ENOMEM;
10042						brelse(bh);
10043						brelse(obh);
10044						goto failed;
10045					}
10046
10047					lock_buffer(nbh);
10048					memcpy(nbh->b_data, obh->b_data,
10049							journal->j_blocksize);
10050					if (flags & JFS_FLAG_ESCAPE) {
10051						*((unsigned int *)bh->b_data) =
10052							htonl(JFS_MAGIC_NUMBER);
10053					}
10054
10055					mark_buffer_uptodate(nbh, 1);
10056					mark_buffer_dirty(nbh);
10057					++info->nr_replays;
10058					/* ll_rw_block(WRITE, 1, &nbh); */
10059					unlock_buffer(nbh);
10060					brelse(obh);
10061					brelse(nbh);
10062				}
10063
10064			skip_write:
10065				tagp += sizeof(journal_block_tag_t);
10066				if (!(flags & JFS_FLAG_SAME_UUID))
10067					tagp += 16;
10068
10069				if (flags & JFS_FLAG_LAST_TAG)
10070					break;
10071			}
10072
10073			brelse(bh);
10074			continue;
10075
10076		case JFS_COMMIT_BLOCK:
10077			/* Found an expected commit block: not much to
10078			 * do other than move on to the next sequence
10079			 * number. */
10080			brelse(bh);
10081			next_commit_ID++;
10082			continue;
10083
10084		case JFS_REVOKE_BLOCK:
10085			/* If we aren't in the REVOKE pass, then we can
10086			 * just skip over this block. */
10087			if (pass != PASS_REVOKE) {
10088				brelse(bh);
10089				continue;
10090			}
10091
10092			err = scan_revoke_records(journal, bh,
10093						  next_commit_ID, info);
10094			brelse(bh);
10095			if (err)
10096				goto failed;
10097			continue;
10098
10099		default:
10100			goto done;
10101		}
10102	}
10103
10104 done:
10105	/*
10106	 * We broke out of the log scan loop: either we came to the
10107	 * known end of the log or we found an unexpected block in the
10108	 * log.  If the latter happened, then we know that the "current"
10109	 * transaction marks the end of the valid log.
10110	 */
10111
10112	if (pass == PASS_SCAN)
10113		info->end_transaction = next_commit_ID;
10114	else {
10115		/* It's really bad news if different passes end up at
10116		 * different places (but possible due to IO errors). */
10117		if (info->end_transaction != next_commit_ID) {
10118			printf("JBD: recovery pass %d ended at "
10119				"transaction %u, expected %u\n",
10120				pass, next_commit_ID, info->end_transaction);
10121			if (!success)
10122				success = -EIO;
10123		}
10124	}
10125
10126	return success;
10127
10128 failed:
10129	return err;
10130}
10131
10132
10133/* Scan a revoke record, marking all blocks mentioned as revoked. */
10134
10135static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10136			       tid_t sequence, struct recovery_info *info)
10137{
10138	journal_revoke_header_t *header;
10139	int offset, max;
10140
10141	header = (journal_revoke_header_t *) bh->b_data;
10142	offset = sizeof(journal_revoke_header_t);
10143	max = ntohl(header->r_count);
10144
10145	while (offset < max) {
10146		unsigned long blocknr;
10147		int err;
10148
10149		blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10150		offset += 4;
10151		err = journal_set_revoke(journal, blocknr, sequence);
10152		if (err)
10153			return err;
10154		++info->nr_revokes;
10155	}
10156	return 0;
10157}
10158
10159
10160/*
10161 * rehash.c --- rebuild hash tree directories
10162 *
10163 * This algorithm is designed for simplicity of implementation and to
10164 * pack the directory as much as possible.  It however requires twice
10165 * as much memory as the size of the directory.  The maximum size
10166 * directory supported using a 4k blocksize is roughly a gigabyte, and
10167 * so there may very well be problems with machines that don't have
10168 * virtual memory, and obscenely large directories.
10169 *
10170 * An alternate algorithm which is much more disk intensive could be
10171 * written, and probably will need to be written in the future.  The
10172 * design goals of such an algorithm are: (a) use (roughly) constant
10173 * amounts of memory, no matter how large the directory, (b) the
10174 * directory must be safe at all times, even if e2fsck is interrupted
10175 * in the middle, (c) we must use minimal amounts of extra disk
10176 * blocks.  This pretty much requires an incremental approach, where
10177 * we are reading from one part of the directory, and inserting into
10178 * the front half.  So the algorithm will have to keep track of a
10179 * moving block boundary between the new tree and the old tree, and
10180 * files will need to be moved from the old directory and inserted
10181 * into the new tree.  If the new directory requires space which isn't
10182 * yet available, blocks from the beginning part of the old directory
10183 * may need to be moved to the end of the directory to make room for
10184 * the new tree:
10185 *
10186 *    --------------------------------------------------------
10187 *    |  new tree   |        | old tree                      |
10188 *    --------------------------------------------------------
10189 *                  ^ ptr    ^ptr
10190 *                tail new   head old
10191 *
10192 * This is going to be a pain in the tuckus to implement, and will
10193 * require a lot more disk accesses.  So I'm going to skip it for now;
10194 * it's only really going to be an issue for really, really big
10195 * filesystems (when we reach the level of tens of millions of files
10196 * in a single directory).  It will probably be easier to simply
10197 * require that e2fsck use VM first.
10198 */
10199
10200struct fill_dir_struct {
10201	char *buf;
10202	struct ext2_inode *inode;
10203	int err;
10204	e2fsck_t ctx;
10205	struct hash_entry *harray;
10206	int max_array, num_array;
10207	int dir_size;
10208	int compress;
10209	ino_t parent;
10210};
10211
10212struct hash_entry {
10213	ext2_dirhash_t  hash;
10214	ext2_dirhash_t  minor_hash;
10215	struct ext2_dir_entry   *dir;
10216};
10217
10218struct out_dir {
10219	int             num;
10220	int             max;
10221	char            *buf;
10222	ext2_dirhash_t  *hashes;
10223};
10224
10225static int fill_dir_block(ext2_filsys fs,
10226			  blk_t *block_nr,
10227			  e2_blkcnt_t blockcnt,
10228			  blk_t ref_block FSCK_ATTR((unused)),
10229			  int ref_offset FSCK_ATTR((unused)),
10230			  void *priv_data)
10231{
10232	struct fill_dir_struct  *fd = (struct fill_dir_struct *) priv_data;
10233	struct hash_entry       *new_array, *ent;
10234	struct ext2_dir_entry   *dirent;
10235	char                    *dir;
10236	unsigned int            offset, dir_offset;
10237
10238	if (blockcnt < 0)
10239		return 0;
10240
10241	offset = blockcnt * fs->blocksize;
10242	if (offset + fs->blocksize > fd->inode->i_size) {
10243		fd->err = EXT2_ET_DIR_CORRUPTED;
10244		return BLOCK_ABORT;
10245	}
10246	dir = (fd->buf+offset);
10247	if (HOLE_BLKADDR(*block_nr)) {
10248		memset(dir, 0, fs->blocksize);
10249		dirent = (struct ext2_dir_entry *) dir;
10250		dirent->rec_len = fs->blocksize;
10251	} else {
10252		fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10253		if (fd->err)
10254			return BLOCK_ABORT;
10255	}
10256	/* While the directory block is "hot", index it. */
10257	dir_offset = 0;
10258	while (dir_offset < fs->blocksize) {
10259		dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10260		if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10261		    (dirent->rec_len < 8) ||
10262		    ((dirent->rec_len % 4) != 0) ||
10263		    (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10264			fd->err = EXT2_ET_DIR_CORRUPTED;
10265			return BLOCK_ABORT;
10266		}
10267		dir_offset += dirent->rec_len;
10268		if (dirent->inode == 0)
10269			continue;
10270		if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10271		    (dirent->name[0] == '.'))
10272			continue;
10273		if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10274		    (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10275			fd->parent = dirent->inode;
10276			continue;
10277		}
10278		if (fd->num_array >= fd->max_array) {
10279			new_array = realloc(fd->harray,
10280			    sizeof(struct hash_entry) * (fd->max_array+500));
10281			if (!new_array) {
10282				fd->err = ENOMEM;
10283				return BLOCK_ABORT;
10284			}
10285			fd->harray = new_array;
10286			fd->max_array += 500;
10287		}
10288		ent = fd->harray + fd->num_array++;
10289		ent->dir = dirent;
10290		fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10291		if (fd->compress)
10292			ent->hash = ent->minor_hash = 0;
10293		else {
10294			fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10295						 dirent->name,
10296						 dirent->name_len & 0xFF,
10297						 fs->super->s_hash_seed,
10298						 &ent->hash, &ent->minor_hash);
10299			if (fd->err)
10300				return BLOCK_ABORT;
10301		}
10302	}
10303
10304	return 0;
10305}
10306
10307/* Used for sorting the hash entry */
10308static int name_cmp(const void *a, const void *b)
10309{
10310	const struct hash_entry *he_a = (const struct hash_entry *) a;
10311	const struct hash_entry *he_b = (const struct hash_entry *) b;
10312	int     ret;
10313	int     min_len;
10314
10315	min_len = he_a->dir->name_len;
10316	if (min_len > he_b->dir->name_len)
10317		min_len = he_b->dir->name_len;
10318
10319	ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10320	if (ret == 0) {
10321		if (he_a->dir->name_len > he_b->dir->name_len)
10322			ret = 1;
10323		else if (he_a->dir->name_len < he_b->dir->name_len)
10324			ret = -1;
10325		else
10326			ret = he_b->dir->inode - he_a->dir->inode;
10327	}
10328	return ret;
10329}
10330
10331/* Used for sorting the hash entry */
10332static int hash_cmp(const void *a, const void *b)
10333{
10334	const struct hash_entry *he_a = (const struct hash_entry *) a;
10335	const struct hash_entry *he_b = (const struct hash_entry *) b;
10336	int     ret;
10337
10338	if (he_a->hash > he_b->hash)
10339		ret = 1;
10340	else if (he_a->hash < he_b->hash)
10341		ret = -1;
10342	else {
10343		if (he_a->minor_hash > he_b->minor_hash)
10344			ret = 1;
10345		else if (he_a->minor_hash < he_b->minor_hash)
10346			ret = -1;
10347		else
10348			ret = name_cmp(a, b);
10349	}
10350	return ret;
10351}
10352
10353static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10354				int blocks)
10355{
10356	void                    *new_mem;
10357
10358	if (outdir->max) {
10359		new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10360		if (!new_mem)
10361			return ENOMEM;
10362		outdir->buf = new_mem;
10363		new_mem = realloc(outdir->hashes,
10364				  blocks * sizeof(ext2_dirhash_t));
10365		if (!new_mem)
10366			return ENOMEM;
10367		outdir->hashes = new_mem;
10368	} else {
10369		outdir->buf = malloc(blocks * fs->blocksize);
10370		outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10371		outdir->num = 0;
10372	}
10373	outdir->max = blocks;
10374	return 0;
10375}
10376
10377static void free_out_dir(struct out_dir *outdir)
10378{
10379	free(outdir->buf);
10380	free(outdir->hashes);
10381	outdir->max = 0;
10382	outdir->num =0;
10383}
10384
10385static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10386			 char ** ret)
10387{
10388	errcode_t       retval;
10389
10390	if (outdir->num >= outdir->max) {
10391		retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10392		if (retval)
10393			return retval;
10394	}
10395	*ret = outdir->buf + (outdir->num++ * fs->blocksize);
10396	memset(*ret, 0, fs->blocksize);
10397	return 0;
10398}
10399
10400/*
10401 * This function is used to make a unique filename.  We do this by
10402 * appending ~0, and then incrementing the number.  However, we cannot
10403 * expand the length of the filename beyond the padding available in
10404 * the directory entry.
10405 */
10406static void mutate_name(char *str, __u16 *len)
10407{
10408	int     i;
10409	__u16   l = *len & 0xFF, h = *len & 0xff00;
10410
10411	/*
10412	 * First check to see if it looks the name has been mutated
10413	 * already
10414	 */
10415	for (i = l-1; i > 0; i--) {
10416		if (!isdigit(str[i]))
10417			break;
10418	}
10419	if ((i == l-1) || (str[i] != '~')) {
10420		if (((l-1) & 3) < 2)
10421			l += 2;
10422		else
10423			l = (l+3) & ~3;
10424		str[l-2] = '~';
10425		str[l-1] = '0';
10426		*len = l | h;
10427		return;
10428	}
10429	for (i = l-1; i >= 0; i--) {
10430		if (isdigit(str[i])) {
10431			if (str[i] == '9')
10432				str[i] = '0';
10433			else {
10434				str[i]++;
10435				return;
10436			}
10437			continue;
10438		}
10439		if (i == 1) {
10440			if (str[0] == 'z')
10441				str[0] = 'A';
10442			else if (str[0] == 'Z') {
10443				str[0] = '~';
10444				str[1] = '0';
10445			} else
10446				str[0]++;
10447		} else if (i > 0) {
10448			str[i] = '1';
10449			str[i-1] = '~';
10450		} else {
10451			if (str[0] == '~')
10452				str[0] = 'a';
10453			else
10454				str[0]++;
10455		}
10456		break;
10457	}
10458}
10459
10460static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10461				    ext2_ino_t ino,
10462				    struct fill_dir_struct *fd)
10463{
10464	struct problem_context  pctx;
10465	struct hash_entry       *ent, *prev;
10466	int                     i, j;
10467	int                     fixed = 0;
10468	char                    new_name[256];
10469	__u16                   new_len;
10470
10471	clear_problem_context(&pctx);
10472	pctx.ino = ino;
10473
10474	for (i=1; i < fd->num_array; i++) {
10475		ent = fd->harray + i;
10476		prev = ent - 1;
10477		if (!ent->dir->inode ||
10478		    ((ent->dir->name_len & 0xFF) !=
10479		     (prev->dir->name_len & 0xFF)) ||
10480		    (strncmp(ent->dir->name, prev->dir->name,
10481			     ent->dir->name_len & 0xFF)))
10482			continue;
10483		pctx.dirent = ent->dir;
10484		if ((ent->dir->inode == prev->dir->inode) &&
10485		    fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10486			e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10487			ent->dir->inode = 0;
10488			fixed++;
10489			continue;
10490		}
10491		memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10492		new_len = ent->dir->name_len;
10493		mutate_name(new_name, &new_len);
10494		for (j=0; j < fd->num_array; j++) {
10495			if ((i==j) ||
10496			    ((ent->dir->name_len & 0xFF) !=
10497			     (fd->harray[j].dir->name_len & 0xFF)) ||
10498			    (strncmp(new_name, fd->harray[j].dir->name,
10499				     new_len & 0xFF)))
10500				continue;
10501			mutate_name(new_name, &new_len);
10502
10503			j = -1;
10504		}
10505		new_name[new_len & 0xFF] = 0;
10506		pctx.str = new_name;
10507		if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10508			memcpy(ent->dir->name, new_name, new_len & 0xFF);
10509			ent->dir->name_len = new_len;
10510			ext2fs_dirhash(fs->super->s_def_hash_version,
10511				       ent->dir->name,
10512				       ent->dir->name_len & 0xFF,
10513				       fs->super->s_hash_seed,
10514				       &ent->hash, &ent->minor_hash);
10515			fixed++;
10516		}
10517	}
10518	return fixed;
10519}
10520
10521
10522static errcode_t copy_dir_entries(ext2_filsys fs,
10523				  struct fill_dir_struct *fd,
10524				  struct out_dir *outdir)
10525{
10526	errcode_t               retval;
10527	char                    *block_start;
10528	struct hash_entry       *ent;
10529	struct ext2_dir_entry   *dirent;
10530	int                     i, rec_len, left;
10531	ext2_dirhash_t          prev_hash;
10532	int                     offset;
10533
10534	outdir->max = 0;
10535	retval = alloc_size_dir(fs, outdir,
10536				(fd->dir_size / fs->blocksize) + 2);
10537	if (retval)
10538		return retval;
10539	outdir->num = fd->compress ? 0 : 1;
10540	offset = 0;
10541	outdir->hashes[0] = 0;
10542	prev_hash = 1;
10543	if ((retval = get_next_block(fs, outdir, &block_start)))
10544		return retval;
10545	dirent = (struct ext2_dir_entry *) block_start;
10546	left = fs->blocksize;
10547	for (i=0; i < fd->num_array; i++) {
10548		ent = fd->harray + i;
10549		if (ent->dir->inode == 0)
10550			continue;
10551		rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10552		if (rec_len > left) {
10553			if (left)
10554				dirent->rec_len += left;
10555			if ((retval = get_next_block(fs, outdir,
10556						      &block_start)))
10557				return retval;
10558			offset = 0;
10559		}
10560		left = fs->blocksize - offset;
10561		dirent = (struct ext2_dir_entry *) (block_start + offset);
10562		if (offset == 0) {
10563			if (ent->hash == prev_hash)
10564				outdir->hashes[outdir->num-1] = ent->hash | 1;
10565			else
10566				outdir->hashes[outdir->num-1] = ent->hash;
10567		}
10568		dirent->inode = ent->dir->inode;
10569		dirent->name_len = ent->dir->name_len;
10570		dirent->rec_len = rec_len;
10571		memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10572		offset += rec_len;
10573		left -= rec_len;
10574		if (left < 12) {
10575			dirent->rec_len += left;
10576			offset += left;
10577			left = 0;
10578		}
10579		prev_hash = ent->hash;
10580	}
10581	if (left)
10582		dirent->rec_len += left;
10583
10584	return 0;
10585}
10586
10587
10588static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10589				    ext2_ino_t ino, ext2_ino_t parent)
10590{
10591	struct ext2_dir_entry           *dir;
10592	struct ext2_dx_root_info        *root;
10593	struct ext2_dx_countlimit       *limits;
10594	int                             filetype = 0;
10595
10596	if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10597		filetype = EXT2_FT_DIR << 8;
10598
10599	memset(buf, 0, fs->blocksize);
10600	dir = (struct ext2_dir_entry *) buf;
10601	dir->inode = ino;
10602	dir->name[0] = '.';
10603	dir->name_len = 1 | filetype;
10604	dir->rec_len = 12;
10605	dir = (struct ext2_dir_entry *) (buf + 12);
10606	dir->inode = parent;
10607	dir->name[0] = '.';
10608	dir->name[1] = '.';
10609	dir->name_len = 2 | filetype;
10610	dir->rec_len = fs->blocksize - 12;
10611
10612	root = (struct ext2_dx_root_info *) (buf+24);
10613	root->reserved_zero = 0;
10614	root->hash_version = fs->super->s_def_hash_version;
10615	root->info_length = 8;
10616	root->indirect_levels = 0;
10617	root->unused_flags = 0;
10618
10619	limits = (struct ext2_dx_countlimit *) (buf+32);
10620	limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10621	limits->count = 0;
10622
10623	return root;
10624}
10625
10626
10627static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10628{
10629	struct ext2_dir_entry           *dir;
10630	struct ext2_dx_countlimit       *limits;
10631
10632	memset(buf, 0, fs->blocksize);
10633	dir = (struct ext2_dir_entry *) buf;
10634	dir->inode = 0;
10635	dir->rec_len = fs->blocksize;
10636
10637	limits = (struct ext2_dx_countlimit *) (buf+8);
10638	limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10639	limits->count = 0;
10640
10641	return (struct ext2_dx_entry *) limits;
10642}
10643
10644/*
10645 * This function takes the leaf nodes which have been written in
10646 * outdir, and populates the root node and any necessary interior nodes.
10647 */
10648static errcode_t calculate_tree(ext2_filsys fs,
10649				struct out_dir *outdir,
10650				ext2_ino_t ino,
10651				ext2_ino_t parent)
10652{
10653	struct ext2_dx_root_info        *root_info;
10654	struct ext2_dx_entry            *root, *dx_ent = 0;
10655	struct ext2_dx_countlimit       *root_limit, *limit;
10656	errcode_t                       retval;
10657	char                            * block_start;
10658	int                             i, c1, c2, nblks;
10659	int                             limit_offset, root_offset;
10660
10661	root_info = set_root_node(fs, outdir->buf, ino, parent);
10662	root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10663		root_info->info_length;
10664	root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10665	c1 = root_limit->limit;
10666	nblks = outdir->num;
10667
10668	/* Write out the pointer blocks */
10669	if (nblks-1 <= c1) {
10670		/* Just write out the root block, and we're done */
10671		root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10672		for (i=1; i < nblks; i++) {
10673			root->block = ext2fs_cpu_to_le32(i);
10674			if (i != 1)
10675				root->hash =
10676					ext2fs_cpu_to_le32(outdir->hashes[i]);
10677			root++;
10678			c1--;
10679		}
10680	} else {
10681		c2 = 0;
10682		limit = 0;
10683		root_info->indirect_levels = 1;
10684		for (i=1; i < nblks; i++) {
10685			if (c1 == 0)
10686				return ENOSPC;
10687			if (c2 == 0) {
10688				if (limit)
10689					limit->limit = limit->count =
10690		ext2fs_cpu_to_le16(limit->limit);
10691				root = (struct ext2_dx_entry *)
10692					(outdir->buf + root_offset);
10693				root->block = ext2fs_cpu_to_le32(outdir->num);
10694				if (i != 1)
10695					root->hash =
10696			ext2fs_cpu_to_le32(outdir->hashes[i]);
10697				if ((retval =  get_next_block(fs, outdir,
10698							      &block_start)))
10699					return retval;
10700				dx_ent = set_int_node(fs, block_start);
10701				limit = (struct ext2_dx_countlimit *) dx_ent;
10702				c2 = limit->limit;
10703				root_offset += sizeof(struct ext2_dx_entry);
10704				c1--;
10705			}
10706			dx_ent->block = ext2fs_cpu_to_le32(i);
10707			if (c2 != limit->limit)
10708				dx_ent->hash =
10709					ext2fs_cpu_to_le32(outdir->hashes[i]);
10710			dx_ent++;
10711			c2--;
10712		}
10713		limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10714		limit->limit = ext2fs_cpu_to_le16(limit->limit);
10715	}
10716	root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10717	root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10718	root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10719
10720	return 0;
10721}
10722
10723struct write_dir_struct {
10724	struct out_dir *outdir;
10725	errcode_t       err;
10726	e2fsck_t        ctx;
10727	int             cleared;
10728};
10729
10730/*
10731 * Helper function which writes out a directory block.
10732 */
10733static int write_dir_block(ext2_filsys fs,
10734			   blk_t        *block_nr,
10735			   e2_blkcnt_t blockcnt,
10736			   blk_t ref_block FSCK_ATTR((unused)),
10737			   int ref_offset FSCK_ATTR((unused)),
10738			   void *priv_data)
10739{
10740	struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10741	blk_t   blk;
10742	char    *dir;
10743
10744	if (*block_nr == 0)
10745		return 0;
10746	if (blockcnt >= wd->outdir->num) {
10747		e2fsck_read_bitmaps(wd->ctx);
10748		blk = *block_nr;
10749		ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10750		ext2fs_block_alloc_stats(fs, blk, -1);
10751		*block_nr = 0;
10752		wd->cleared++;
10753		return BLOCK_CHANGED;
10754	}
10755	if (blockcnt < 0)
10756		return 0;
10757
10758	dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10759	wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10760	if (wd->err)
10761		return BLOCK_ABORT;
10762	return 0;
10763}
10764
10765static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10766				 struct out_dir *outdir,
10767				 ext2_ino_t ino, int compress)
10768{
10769	struct write_dir_struct wd;
10770	errcode_t       retval;
10771	struct ext2_inode       inode;
10772
10773	retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10774	if (retval)
10775		return retval;
10776
10777	wd.outdir = outdir;
10778	wd.err = 0;
10779	wd.ctx = ctx;
10780	wd.cleared = 0;
10781
10782	retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10783				       write_dir_block, &wd);
10784	if (retval)
10785		return retval;
10786	if (wd.err)
10787		return wd.err;
10788
10789	e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10790	if (compress)
10791		inode.i_flags &= ~EXT2_INDEX_FL;
10792	else
10793		inode.i_flags |= EXT2_INDEX_FL;
10794	inode.i_size = outdir->num * fs->blocksize;
10795	inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10796	e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10797
10798	return 0;
10799}
10800
10801static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10802{
10803	ext2_filsys             fs = ctx->fs;
10804	errcode_t               retval;
10805	struct ext2_inode       inode;
10806	char                    *dir_buf = 0;
10807	struct fill_dir_struct  fd;
10808	struct out_dir          outdir;
10809
10810	outdir.max = outdir.num = 0;
10811	outdir.buf = 0;
10812	outdir.hashes = 0;
10813	e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10814
10815	retval = ENOMEM;
10816	fd.harray = 0;
10817	dir_buf = malloc(inode.i_size);
10818	if (!dir_buf)
10819		goto errout;
10820
10821	fd.max_array = inode.i_size / 32;
10822	fd.num_array = 0;
10823	fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
10824	if (!fd.harray)
10825		goto errout;
10826
10827	fd.ctx = ctx;
10828	fd.buf = dir_buf;
10829	fd.inode = &inode;
10830	fd.err = 0;
10831	fd.dir_size = 0;
10832	fd.compress = 0;
10833	if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10834	    (inode.i_size / fs->blocksize) < 2)
10835		fd.compress = 1;
10836	fd.parent = 0;
10837
10838	/* Read in the entire directory into memory */
10839	retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10840				       fill_dir_block, &fd);
10841	if (fd.err) {
10842		retval = fd.err;
10843		goto errout;
10844	}
10845
10846	/* Sort the list */
10847resort:
10848	if (fd.compress)
10849		qsort(fd.harray+2, fd.num_array-2,
10850		      sizeof(struct hash_entry), name_cmp);
10851	else
10852		qsort(fd.harray, fd.num_array,
10853		      sizeof(struct hash_entry), hash_cmp);
10854
10855	/*
10856	 * Look for duplicates
10857	 */
10858	if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10859		goto resort;
10860
10861	if (ctx->options & E2F_OPT_NO) {
10862		retval = 0;
10863		goto errout;
10864	}
10865
10866	/*
10867	 * Copy the directory entries.  In a htree directory these
10868	 * will become the leaf nodes.
10869	 */
10870	retval = copy_dir_entries(fs, &fd, &outdir);
10871	if (retval)
10872		goto errout;
10873
10874	free(dir_buf); dir_buf = 0;
10875
10876	if (!fd.compress) {
10877		/* Calculate the interior nodes */
10878		retval = calculate_tree(fs, &outdir, ino, fd.parent);
10879		if (retval)
10880			goto errout;
10881	}
10882
10883	retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10884
10885errout:
10886	free(dir_buf);
10887	free(fd.harray);
10888
10889	free_out_dir(&outdir);
10890	return retval;
10891}
10892
10893void e2fsck_rehash_directories(e2fsck_t ctx)
10894{
10895	struct problem_context  pctx;
10896	struct dir_info         *dir;
10897	ext2_u32_iterate        iter;
10898	ext2_ino_t              ino;
10899	errcode_t               retval;
10900	int                     i, cur, max, all_dirs, dir_index, first = 1;
10901
10902	all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10903
10904	if (!ctx->dirs_to_hash && !all_dirs)
10905		return;
10906
10907	e2fsck_get_lost_and_found(ctx, 0);
10908
10909	clear_problem_context(&pctx);
10910
10911	dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10912	cur = 0;
10913	if (all_dirs) {
10914		i = 0;
10915		max = e2fsck_get_num_dirinfo(ctx);
10916	} else {
10917		retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10918						       &iter);
10919		if (retval) {
10920			pctx.errcode = retval;
10921			fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10922			return;
10923		}
10924		max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10925	}
10926	while (1) {
10927		if (all_dirs) {
10928			if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10929				break;
10930			ino = dir->ino;
10931		} else {
10932			if (!ext2fs_u32_list_iterate(iter, &ino))
10933				break;
10934		}
10935		if (ino == ctx->lost_and_found)
10936			continue;
10937		pctx.dir = ino;
10938		if (first) {
10939			fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
10940			first = 0;
10941		}
10942		pctx.errcode = e2fsck_rehash_dir(ctx, ino);
10943		if (pctx.errcode) {
10944			end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10945			fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
10946		}
10947		if (ctx->progress && !ctx->progress_fd)
10948			e2fsck_simple_progress(ctx, "Rebuilding directory",
10949			       100.0 * (float) (++cur) / (float) max, ino);
10950	}
10951	end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10952	if (!all_dirs)
10953		ext2fs_u32_list_iterate_end(iter);
10954
10955	ext2fs_u32_list_free(ctx->dirs_to_hash);
10956	ctx->dirs_to_hash = 0;
10957}
10958
10959/*
10960 * linux/fs/revoke.c
10961 *
10962 * Journal revoke routines for the generic filesystem journaling code;
10963 * part of the ext2fs journaling system.
10964 *
10965 * Revoke is the mechanism used to prevent old log records for deleted
10966 * metadata from being replayed on top of newer data using the same
10967 * blocks.  The revoke mechanism is used in two separate places:
10968 *
10969 * + Commit: during commit we write the entire list of the current
10970 *   transaction's revoked blocks to the journal
10971 *
10972 * + Recovery: during recovery we record the transaction ID of all
10973 *   revoked blocks.  If there are multiple revoke records in the log
10974 *   for a single block, only the last one counts, and if there is a log
10975 *   entry for a block beyond the last revoke, then that log entry still
10976 *   gets replayed.
10977 *
10978 * We can get interactions between revokes and new log data within a
10979 * single transaction:
10980 *
10981 * Block is revoked and then journaled:
10982 *   The desired end result is the journaling of the new block, so we
10983 *   cancel the revoke before the transaction commits.
10984 *
10985 * Block is journaled and then revoked:
10986 *   The revoke must take precedence over the write of the block, so we
10987 *   need either to cancel the journal entry or to write the revoke
10988 *   later in the log than the log block.  In this case, we choose the
10989 *   latter: journaling a block cancels any revoke record for that block
10990 *   in the current transaction, so any revoke for that block in the
10991 *   transaction must have happened after the block was journaled and so
10992 *   the revoke must take precedence.
10993 *
10994 * Block is revoked and then written as data:
10995 *   The data write is allowed to succeed, but the revoke is _not_
10996 *   cancelled.  We still need to prevent old log records from
10997 *   overwriting the new data.  We don't even need to clear the revoke
10998 *   bit here.
10999 *
11000 * Revoke information on buffers is a tri-state value:
11001 *
11002 * RevokeValid clear:   no cached revoke status, need to look it up
11003 * RevokeValid set, Revoked clear:
11004 *                      buffer has not been revoked, and cancel_revoke
11005 *                      need do nothing.
11006 * RevokeValid set, Revoked set:
11007 *                      buffer has been revoked.
11008 */
11009
11010static kmem_cache_t *revoke_record_cache;
11011static kmem_cache_t *revoke_table_cache;
11012
11013/* Each revoke record represents one single revoked block.  During
11014   journal replay, this involves recording the transaction ID of the
11015   last transaction to revoke this block. */
11016
11017struct jbd_revoke_record_s
11018{
11019	struct list_head  hash;
11020	tid_t             sequence;     /* Used for recovery only */
11021	unsigned long     blocknr;
11022};
11023
11024
11025/* The revoke table is just a simple hash table of revoke records. */
11026struct jbd_revoke_table_s
11027{
11028	/* It is conceivable that we might want a larger hash table
11029	 * for recovery.  Must be a power of two. */
11030	int               hash_size;
11031	int               hash_shift;
11032	struct list_head *hash_table;
11033};
11034
11035
11036/* Utility functions to maintain the revoke table */
11037
11038/* Borrowed from buffer.c: this is a tried and tested block hash function */
11039static int hash(journal_t *journal, unsigned long block)
11040{
11041	struct jbd_revoke_table_s *table = journal->j_revoke;
11042	int hash_shift = table->hash_shift;
11043
11044	return ((block << (hash_shift - 6)) ^
11045		(block >> 13) ^
11046		(block << (hash_shift - 12))) & (table->hash_size - 1);
11047}
11048
11049static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11050			      tid_t seq)
11051{
11052	struct list_head *hash_list;
11053	struct jbd_revoke_record_s *record;
11054
11055	record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11056	if (!record)
11057		goto oom;
11058
11059	record->sequence = seq;
11060	record->blocknr = blocknr;
11061	hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11062	list_add(&record->hash, hash_list);
11063	return 0;
11064
11065oom:
11066	return -ENOMEM;
11067}
11068
11069/* Find a revoke record in the journal's hash table. */
11070
11071static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11072						      unsigned long blocknr)
11073{
11074	struct list_head *hash_list;
11075	struct jbd_revoke_record_s *record;
11076
11077	hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11078
11079	record = (struct jbd_revoke_record_s *) hash_list->next;
11080	while (&(record->hash) != hash_list) {
11081		if (record->blocknr == blocknr)
11082			return record;
11083		record = (struct jbd_revoke_record_s *) record->hash.next;
11084	}
11085	return NULL;
11086}
11087
11088int journal_init_revoke_caches(void)
11089{
11090	revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11091	if (revoke_record_cache == 0)
11092		return -ENOMEM;
11093
11094	revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11095	if (revoke_table_cache == 0) {
11096		do_cache_destroy(revoke_record_cache);
11097		revoke_record_cache = NULL;
11098		return -ENOMEM;
11099	}
11100	return 0;
11101}
11102
11103void journal_destroy_revoke_caches(void)
11104{
11105	do_cache_destroy(revoke_record_cache);
11106	revoke_record_cache = 0;
11107	do_cache_destroy(revoke_table_cache);
11108	revoke_table_cache = 0;
11109}
11110
11111/* Initialise the revoke table for a given journal to a given size. */
11112
11113int journal_init_revoke(journal_t *journal, int hash_size)
11114{
11115	int shift, tmp;
11116
11117	journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11118	if (!journal->j_revoke)
11119		return -ENOMEM;
11120
11121	/* Check that the hash_size is a power of two */
11122	journal->j_revoke->hash_size = hash_size;
11123
11124	shift = 0;
11125	tmp = hash_size;
11126	while((tmp >>= 1UL) != 0UL)
11127		shift++;
11128	journal->j_revoke->hash_shift = shift;
11129
11130	journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11131	if (!journal->j_revoke->hash_table) {
11132		free(journal->j_revoke);
11133		journal->j_revoke = NULL;
11134		return -ENOMEM;
11135	}
11136
11137	for (tmp = 0; tmp < hash_size; tmp++)
11138		INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11139
11140	return 0;
11141}
11142
11143/* Destoy a journal's revoke table.  The table must already be empty! */
11144
11145void journal_destroy_revoke(journal_t *journal)
11146{
11147	struct jbd_revoke_table_s *table;
11148	struct list_head *hash_list;
11149	int i;
11150
11151	table = journal->j_revoke;
11152	if (!table)
11153		return;
11154
11155	for (i=0; i<table->hash_size; i++) {
11156		hash_list = &table->hash_table[i];
11157	}
11158
11159	free(table->hash_table);
11160	free(table);
11161	journal->j_revoke = NULL;
11162}
11163
11164/*
11165 * Revoke support for recovery.
11166 *
11167 * Recovery needs to be able to:
11168 *
11169 *  record all revoke records, including the tid of the latest instance
11170 *  of each revoke in the journal
11171 *
11172 *  check whether a given block in a given transaction should be replayed
11173 *  (ie. has not been revoked by a revoke record in that or a subsequent
11174 *  transaction)
11175 *
11176 *  empty the revoke table after recovery.
11177 */
11178
11179/*
11180 * First, setting revoke records.  We create a new revoke record for
11181 * every block ever revoked in the log as we scan it for recovery, and
11182 * we update the existing records if we find multiple revokes for a
11183 * single block.
11184 */
11185
11186int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11187		       tid_t sequence)
11188{
11189	struct jbd_revoke_record_s *record;
11190
11191	record = find_revoke_record(journal, blocknr);
11192	if (record) {
11193		/* If we have multiple occurences, only record the
11194		 * latest sequence number in the hashed record */
11195		if (tid_gt(sequence, record->sequence))
11196			record->sequence = sequence;
11197		return 0;
11198	}
11199	return insert_revoke_hash(journal, blocknr, sequence);
11200}
11201
11202/*
11203 * Test revoke records.  For a given block referenced in the log, has
11204 * that block been revoked?  A revoke record with a given transaction
11205 * sequence number revokes all blocks in that transaction and earlier
11206 * ones, but later transactions still need replayed.
11207 */
11208
11209int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11210			tid_t sequence)
11211{
11212	struct jbd_revoke_record_s *record;
11213
11214	record = find_revoke_record(journal, blocknr);
11215	if (!record)
11216		return 0;
11217	if (tid_gt(sequence, record->sequence))
11218		return 0;
11219	return 1;
11220}
11221
11222/*
11223 * Finally, once recovery is over, we need to clear the revoke table so
11224 * that it can be reused by the running filesystem.
11225 */
11226
11227void journal_clear_revoke(journal_t *journal)
11228{
11229	int i;
11230	struct list_head *hash_list;
11231	struct jbd_revoke_record_s *record;
11232	struct jbd_revoke_table_s *revoke_var;
11233
11234	revoke_var = journal->j_revoke;
11235
11236	for (i = 0; i < revoke_var->hash_size; i++) {
11237		hash_list = &revoke_var->hash_table[i];
11238		while (!list_empty(hash_list)) {
11239			record = (struct jbd_revoke_record_s*) hash_list->next;
11240			list_del(&record->hash);
11241			free(record);
11242		}
11243	}
11244}
11245
11246/*
11247 * e2fsck.c - superblock checks
11248 */
11249
11250#define MIN_CHECK 1
11251#define MAX_CHECK 2
11252
11253static void check_super_value(e2fsck_t ctx, const char *descr,
11254			      unsigned long value, int flags,
11255			      unsigned long min_val, unsigned long max_val)
11256{
11257	struct          problem_context pctx;
11258
11259	if (((flags & MIN_CHECK) && (value < min_val)) ||
11260	    ((flags & MAX_CHECK) && (value > max_val))) {
11261		clear_problem_context(&pctx);
11262		pctx.num = value;
11263		pctx.str = descr;
11264		fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11265		ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11266	}
11267}
11268
11269/*
11270 * This routine may get stubbed out in special compilations of the
11271 * e2fsck code..
11272 */
11273#ifndef EXT2_SPECIAL_DEVICE_SIZE
11274static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11275{
11276	return (ext2fs_get_device_size(ctx->filesystem_name,
11277				       EXT2_BLOCK_SIZE(ctx->fs->super),
11278				       &ctx->num_blocks));
11279}
11280#endif
11281
11282/*
11283 * helper function to release an inode
11284 */
11285struct process_block_struct {
11286	e2fsck_t        ctx;
11287	char            *buf;
11288	struct problem_context *pctx;
11289	int             truncating;
11290	int             truncate_offset;
11291	e2_blkcnt_t     truncate_block;
11292	int             truncated_blocks;
11293	int             abort;
11294	errcode_t       errcode;
11295};
11296
11297static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11298			       e2_blkcnt_t blockcnt,
11299			       blk_t    ref_blk FSCK_ATTR((unused)),
11300			       int      ref_offset FSCK_ATTR((unused)),
11301			       void *priv_data)
11302{
11303	struct process_block_struct *pb;
11304	e2fsck_t                ctx;
11305	struct problem_context  *pctx;
11306	blk_t                   blk = *block_nr;
11307	int                     retval = 0;
11308
11309	pb = (struct process_block_struct *) priv_data;
11310	ctx = pb->ctx;
11311	pctx = pb->pctx;
11312
11313	pctx->blk = blk;
11314	pctx->blkcount = blockcnt;
11315
11316	if (HOLE_BLKADDR(blk))
11317		return 0;
11318
11319	if ((blk < fs->super->s_first_data_block) ||
11320	    (blk >= fs->super->s_blocks_count)) {
11321		fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11322	return_abort:
11323		pb->abort = 1;
11324		return BLOCK_ABORT;
11325	}
11326
11327	if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11328		fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11329		goto return_abort;
11330	}
11331
11332	/*
11333	 * If we are deleting an orphan, then we leave the fields alone.
11334	 * If we are truncating an orphan, then update the inode fields
11335	 * and clean up any partial block data.
11336	 */
11337	if (pb->truncating) {
11338		/*
11339		 * We only remove indirect blocks if they are
11340		 * completely empty.
11341		 */
11342		if (blockcnt < 0) {
11343			int     i, limit;
11344			blk_t   *bp;
11345
11346			pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11347							pb->buf);
11348			if (pb->errcode)
11349				goto return_abort;
11350
11351			limit = fs->blocksize >> 2;
11352			for (i = 0, bp = (blk_t *) pb->buf;
11353			     i < limit;  i++, bp++)
11354				if (*bp)
11355					return 0;
11356		}
11357		/*
11358		 * We don't remove direct blocks until we've reached
11359		 * the truncation block.
11360		 */
11361		if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11362			return 0;
11363		/*
11364		 * If part of the last block needs truncating, we do
11365		 * it here.
11366		 */
11367		if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11368			pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11369							pb->buf);
11370			if (pb->errcode)
11371				goto return_abort;
11372			memset(pb->buf + pb->truncate_offset, 0,
11373			       fs->blocksize - pb->truncate_offset);
11374			pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11375							 pb->buf);
11376			if (pb->errcode)
11377				goto return_abort;
11378		}
11379		pb->truncated_blocks++;
11380		*block_nr = 0;
11381		retval |= BLOCK_CHANGED;
11382	}
11383
11384	ext2fs_block_alloc_stats(fs, blk, -1);
11385	return retval;
11386}
11387
11388/*
11389 * This function releases an inode.  Returns 1 if an inconsistency was
11390 * found.  If the inode has a link count, then it is being truncated and
11391 * not deleted.
11392 */
11393static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11394				struct ext2_inode *inode, char *block_buf,
11395				struct problem_context *pctx)
11396{
11397	struct process_block_struct     pb;
11398	ext2_filsys                     fs = ctx->fs;
11399	errcode_t                       retval;
11400	__u32                           count;
11401
11402	if (!ext2fs_inode_has_valid_blocks(inode))
11403		return 0;
11404
11405	pb.buf = block_buf + 3 * ctx->fs->blocksize;
11406	pb.ctx = ctx;
11407	pb.abort = 0;
11408	pb.errcode = 0;
11409	pb.pctx = pctx;
11410	if (inode->i_links_count) {
11411		pb.truncating = 1;
11412		pb.truncate_block = (e2_blkcnt_t)
11413			((((long long)inode->i_size_high << 32) +
11414			  inode->i_size + fs->blocksize - 1) /
11415			 fs->blocksize);
11416		pb.truncate_offset = inode->i_size % fs->blocksize;
11417	} else {
11418		pb.truncating = 0;
11419		pb.truncate_block = 0;
11420		pb.truncate_offset = 0;
11421	}
11422	pb.truncated_blocks = 0;
11423	retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11424				      block_buf, release_inode_block, &pb);
11425	if (retval) {
11426		bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11427			ino);
11428		return 1;
11429	}
11430	if (pb.abort)
11431		return 1;
11432
11433	/* Refresh the inode since ext2fs_block_iterate may have changed it */
11434	e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11435
11436	if (pb.truncated_blocks)
11437		inode->i_blocks -= pb.truncated_blocks *
11438			(fs->blocksize / 512);
11439
11440	if (inode->i_file_acl) {
11441		retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11442						   block_buf, -1, &count);
11443		if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11444			retval = 0;
11445			count = 1;
11446		}
11447		if (retval) {
11448			bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11449				ino);
11450			return 1;
11451		}
11452		if (count == 0)
11453			ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11454		inode->i_file_acl = 0;
11455	}
11456	return 0;
11457}
11458
11459/*
11460 * This function releases all of the orphan inodes.  It returns 1 if
11461 * it hit some error, and 0 on success.
11462 */
11463static int release_orphan_inodes(e2fsck_t ctx)
11464{
11465	ext2_filsys fs = ctx->fs;
11466	ext2_ino_t      ino, next_ino;
11467	struct ext2_inode inode;
11468	struct problem_context pctx;
11469	char *block_buf;
11470
11471	if ((ino = fs->super->s_last_orphan) == 0)
11472		return 0;
11473
11474	/*
11475	 * Win or lose, we won't be using the head of the orphan inode
11476	 * list again.
11477	 */
11478	fs->super->s_last_orphan = 0;
11479	ext2fs_mark_super_dirty(fs);
11480
11481	/*
11482	 * If the filesystem contains errors, don't run the orphan
11483	 * list, since the orphan list can't be trusted; and we're
11484	 * going to be running a full e2fsck run anyway...
11485	 */
11486	if (fs->super->s_state & EXT2_ERROR_FS)
11487		return 0;
11488
11489	if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11490	    (ino > fs->super->s_inodes_count)) {
11491		clear_problem_context(&pctx);
11492		pctx.ino = ino;
11493		fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11494		return 1;
11495	}
11496
11497	block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11498						    "block iterate buffer");
11499	e2fsck_read_bitmaps(ctx);
11500
11501	while (ino) {
11502		e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11503		clear_problem_context(&pctx);
11504		pctx.ino = ino;
11505		pctx.inode = &inode;
11506		pctx.str = inode.i_links_count ? _("Truncating") :
11507			_("Clearing");
11508
11509		fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11510
11511		next_ino = inode.i_dtime;
11512		if (next_ino &&
11513		    ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11514		     (next_ino > fs->super->s_inodes_count))) {
11515			pctx.ino = next_ino;
11516			fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11517			goto return_abort;
11518		}
11519
11520		if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11521			goto return_abort;
11522
11523		if (!inode.i_links_count) {
11524			ext2fs_inode_alloc_stats2(fs, ino, -1,
11525						  LINUX_S_ISDIR(inode.i_mode));
11526			inode.i_dtime = time(0);
11527		} else {
11528			inode.i_dtime = 0;
11529		}
11530		e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11531		ino = next_ino;
11532	}
11533	ext2fs_free_mem(&block_buf);
11534	return 0;
11535return_abort:
11536	ext2fs_free_mem(&block_buf);
11537	return 1;
11538}
11539
11540/*
11541 * Check the resize inode to make sure it is sane.  We check both for
11542 * the case where on-line resizing is not enabled (in which case the
11543 * resize inode should be cleared) as well as the case where on-line
11544 * resizing is enabled.
11545 */
11546static void check_resize_inode(e2fsck_t ctx)
11547{
11548	ext2_filsys fs = ctx->fs;
11549	struct ext2_inode inode;
11550	struct problem_context  pctx;
11551	int             i, j, gdt_off, ind_off;
11552	blk_t           blk, pblk, expect;
11553	__u32           *dind_buf = 0, *ind_buf;
11554	errcode_t       retval;
11555
11556	clear_problem_context(&pctx);
11557
11558	/*
11559	 * If the resize inode feature isn't set, then
11560	 * s_reserved_gdt_blocks must be zero.
11561	 */
11562	if (!(fs->super->s_feature_compat &
11563	      EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11564		if (fs->super->s_reserved_gdt_blocks) {
11565			pctx.num = fs->super->s_reserved_gdt_blocks;
11566			if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11567					&pctx)) {
11568				fs->super->s_reserved_gdt_blocks = 0;
11569				ext2fs_mark_super_dirty(fs);
11570			}
11571		}
11572	}
11573
11574	/* Read the resize inode */
11575	pctx.ino = EXT2_RESIZE_INO;
11576	retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11577	if (retval) {
11578		if (fs->super->s_feature_compat &
11579		    EXT2_FEATURE_COMPAT_RESIZE_INODE)
11580			ctx->flags |= E2F_FLAG_RESIZE_INODE;
11581		return;
11582	}
11583
11584	/*
11585	 * If the resize inode feature isn't set, check to make sure
11586	 * the resize inode is cleared; then we're done.
11587	 */
11588	if (!(fs->super->s_feature_compat &
11589	      EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11590		for (i=0; i < EXT2_N_BLOCKS; i++) {
11591			if (inode.i_block[i])
11592				break;
11593		}
11594		if ((i < EXT2_N_BLOCKS) &&
11595		    fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11596			memset(&inode, 0, sizeof(inode));
11597			e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11598					   "clear_resize");
11599		}
11600		return;
11601	}
11602
11603	/*
11604	 * The resize inode feature is enabled; check to make sure the
11605	 * only block in use is the double indirect block
11606	 */
11607	blk = inode.i_block[EXT2_DIND_BLOCK];
11608	for (i=0; i < EXT2_N_BLOCKS; i++) {
11609		if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11610			break;
11611	}
11612	if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11613	    !(inode.i_mode & LINUX_S_IFREG) ||
11614	    (blk < fs->super->s_first_data_block ||
11615	     blk >= fs->super->s_blocks_count)) {
11616	resize_inode_invalid:
11617		if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11618			memset(&inode, 0, sizeof(inode));
11619			e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11620					   "clear_resize");
11621			ctx->flags |= E2F_FLAG_RESIZE_INODE;
11622		}
11623		if (!(ctx->options & E2F_OPT_READONLY)) {
11624			fs->super->s_state &= ~EXT2_VALID_FS;
11625			ext2fs_mark_super_dirty(fs);
11626		}
11627		goto cleanup;
11628	}
11629	dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11630						    "resize dind buffer");
11631	ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11632
11633	retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11634	if (retval)
11635		goto resize_inode_invalid;
11636
11637	gdt_off = fs->desc_blocks;
11638	pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11639	for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11640	     i++, gdt_off++, pblk++) {
11641		gdt_off %= fs->blocksize/4;
11642		if (dind_buf[gdt_off] != pblk)
11643			goto resize_inode_invalid;
11644		retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11645		if (retval)
11646			goto resize_inode_invalid;
11647		ind_off = 0;
11648		for (j = 1; j < fs->group_desc_count; j++) {
11649			if (!ext2fs_bg_has_super(fs, j))
11650				continue;
11651			expect = pblk + (j * fs->super->s_blocks_per_group);
11652			if (ind_buf[ind_off] != expect)
11653				goto resize_inode_invalid;
11654			ind_off++;
11655		}
11656	}
11657
11658cleanup:
11659	ext2fs_free_mem(&dind_buf);
11660
11661 }
11662
11663static void check_super_block(e2fsck_t ctx)
11664{
11665	ext2_filsys fs = ctx->fs;
11666	blk_t   first_block, last_block;
11667	struct ext2_super_block *sb = fs->super;
11668	struct ext2_group_desc *gd;
11669	blk_t   blocks_per_group = fs->super->s_blocks_per_group;
11670	blk_t   bpg_max;
11671	int     inodes_per_block;
11672	int     ipg_max;
11673	int     inode_size;
11674	dgrp_t  i;
11675	blk_t   should_be;
11676	struct problem_context  pctx;
11677	__u32   free_blocks = 0, free_inodes = 0;
11678
11679	inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11680	ipg_max = inodes_per_block * (blocks_per_group - 4);
11681	if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11682		ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11683	bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11684	if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11685		bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11686
11687	ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11688		 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11689	ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11690		 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11691	ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11692		sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11693
11694	clear_problem_context(&pctx);
11695
11696	/*
11697	 * Verify the super block constants...
11698	 */
11699	check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11700			  MIN_CHECK, 1, 0);
11701	check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11702			  MIN_CHECK, 1, 0);
11703	check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11704			  MAX_CHECK, 0, sb->s_blocks_count);
11705	check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11706			  MIN_CHECK | MAX_CHECK, 0,
11707			  EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11708	check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11709			  MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11710	check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11711			  MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11712			  bpg_max);
11713	check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11714			  MIN_CHECK | MAX_CHECK, 8, bpg_max);
11715	check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11716			  MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11717	check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11718			  MAX_CHECK, 0, sb->s_blocks_count / 2);
11719	check_super_value(ctx, "reserved_gdt_blocks",
11720			  sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11721			  fs->blocksize/4);
11722	inode_size = EXT2_INODE_SIZE(sb);
11723	check_super_value(ctx, "inode_size",
11724			  inode_size, MIN_CHECK | MAX_CHECK,
11725			  EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11726	if (inode_size & (inode_size - 1)) {
11727		pctx.num = inode_size;
11728		pctx.str = "inode_size";
11729		fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11730		ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11731		return;
11732	}
11733
11734	if (!ctx->num_blocks) {
11735		pctx.errcode = e2fsck_get_device_size(ctx);
11736		if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11737			fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11738			ctx->flags |= E2F_FLAG_ABORT;
11739			return;
11740		}
11741		if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11742		    (ctx->num_blocks < sb->s_blocks_count)) {
11743			pctx.blk = sb->s_blocks_count;
11744			pctx.blk2 = ctx->num_blocks;
11745			if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11746				ctx->flags |= E2F_FLAG_ABORT;
11747				return;
11748			}
11749		}
11750	}
11751
11752	if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11753		pctx.blk = EXT2_BLOCK_SIZE(sb);
11754		pctx.blk2 = EXT2_FRAG_SIZE(sb);
11755		fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11756		ctx->flags |= E2F_FLAG_ABORT;
11757		return;
11758	}
11759
11760	should_be = sb->s_frags_per_group >>
11761		(sb->s_log_block_size - sb->s_log_frag_size);
11762	if (sb->s_blocks_per_group != should_be) {
11763		pctx.blk = sb->s_blocks_per_group;
11764		pctx.blk2 = should_be;
11765		fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11766		ctx->flags |= E2F_FLAG_ABORT;
11767		return;
11768	}
11769
11770	should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11771	if (sb->s_first_data_block != should_be) {
11772		pctx.blk = sb->s_first_data_block;
11773		pctx.blk2 = should_be;
11774		fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11775		ctx->flags |= E2F_FLAG_ABORT;
11776		return;
11777	}
11778
11779	should_be = sb->s_inodes_per_group * fs->group_desc_count;
11780	if (sb->s_inodes_count != should_be) {
11781		pctx.ino = sb->s_inodes_count;
11782		pctx.ino2 = should_be;
11783		if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11784			sb->s_inodes_count = should_be;
11785			ext2fs_mark_super_dirty(fs);
11786		}
11787	}
11788
11789	/*
11790	 * Verify the group descriptors....
11791	 */
11792	first_block =  sb->s_first_data_block;
11793	last_block = first_block + blocks_per_group;
11794
11795	for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11796		pctx.group = i;
11797
11798		if (i == fs->group_desc_count - 1)
11799			last_block = sb->s_blocks_count;
11800		if ((gd->bg_block_bitmap < first_block) ||
11801		    (gd->bg_block_bitmap >= last_block)) {
11802			pctx.blk = gd->bg_block_bitmap;
11803			if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11804				gd->bg_block_bitmap = 0;
11805		}
11806		if (gd->bg_block_bitmap == 0) {
11807			ctx->invalid_block_bitmap_flag[i]++;
11808			ctx->invalid_bitmaps++;
11809		}
11810		if ((gd->bg_inode_bitmap < first_block) ||
11811		    (gd->bg_inode_bitmap >= last_block)) {
11812			pctx.blk = gd->bg_inode_bitmap;
11813			if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11814				gd->bg_inode_bitmap = 0;
11815		}
11816		if (gd->bg_inode_bitmap == 0) {
11817			ctx->invalid_inode_bitmap_flag[i]++;
11818			ctx->invalid_bitmaps++;
11819		}
11820		if ((gd->bg_inode_table < first_block) ||
11821		    ((gd->bg_inode_table +
11822		      fs->inode_blocks_per_group - 1) >= last_block)) {
11823			pctx.blk = gd->bg_inode_table;
11824			if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11825				gd->bg_inode_table = 0;
11826		}
11827		if (gd->bg_inode_table == 0) {
11828			ctx->invalid_inode_table_flag[i]++;
11829			ctx->invalid_bitmaps++;
11830		}
11831		free_blocks += gd->bg_free_blocks_count;
11832		free_inodes += gd->bg_free_inodes_count;
11833		first_block += sb->s_blocks_per_group;
11834		last_block += sb->s_blocks_per_group;
11835
11836		if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11837		    (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11838		    (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11839			ext2fs_unmark_valid(fs);
11840
11841	}
11842
11843	/*
11844	 * Update the global counts from the block group counts.  This
11845	 * is needed for an experimental patch which eliminates
11846	 * locking the entire filesystem when allocating blocks or
11847	 * inodes; if the filesystem is not unmounted cleanly, the
11848	 * global counts may not be accurate.
11849	 */
11850	if ((free_blocks != sb->s_free_blocks_count) ||
11851	    (free_inodes != sb->s_free_inodes_count)) {
11852		if (ctx->options & E2F_OPT_READONLY)
11853			ext2fs_unmark_valid(fs);
11854		else {
11855			sb->s_free_blocks_count = free_blocks;
11856			sb->s_free_inodes_count = free_inodes;
11857			ext2fs_mark_super_dirty(fs);
11858		}
11859	}
11860
11861	if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11862	    (sb->s_free_inodes_count > sb->s_inodes_count))
11863		ext2fs_unmark_valid(fs);
11864
11865
11866	/*
11867	 * If we have invalid bitmaps, set the error state of the
11868	 * filesystem.
11869	 */
11870	if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11871		sb->s_state &= ~EXT2_VALID_FS;
11872		ext2fs_mark_super_dirty(fs);
11873	}
11874
11875	clear_problem_context(&pctx);
11876
11877	/*
11878	 * If the UUID field isn't assigned, assign it.
11879	 */
11880	if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11881		if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11882			uuid_generate(sb->s_uuid);
11883			ext2fs_mark_super_dirty(fs);
11884			fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11885		}
11886	}
11887
11888	if (!(ctx->options & E2F_OPT_READONLY) &&
11889	    fs->super->s_creator_os == EXT2_OS_HURD &&
11890	    (fs->super->s_feature_incompat &
11891	     EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11892		if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11893			fs->super->s_feature_incompat &=
11894				~EXT2_FEATURE_INCOMPAT_FILETYPE;
11895			ext2fs_mark_super_dirty(fs);
11896
11897		}
11898	}
11899
11900	/*
11901	 * If we have any of the compatibility flags set, we need to have a
11902	 * revision 1 filesystem.  Most kernels will not check the flags on
11903	 * a rev 0 filesystem and we may have corruption issues because of
11904	 * the incompatible changes to the filesystem.
11905	 */
11906	if (!(ctx->options & E2F_OPT_READONLY) &&
11907	    fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11908	    (fs->super->s_feature_compat ||
11909	     fs->super->s_feature_ro_compat ||
11910	     fs->super->s_feature_incompat) &&
11911	    fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11912		ext2fs_update_dynamic_rev(fs);
11913		ext2fs_mark_super_dirty(fs);
11914	}
11915
11916	check_resize_inode(ctx);
11917
11918	/*
11919	 * Clean up any orphan inodes, if present.
11920	 */
11921	if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11922		fs->super->s_state &= ~EXT2_VALID_FS;
11923		ext2fs_mark_super_dirty(fs);
11924	}
11925
11926	/*
11927	 * Move the ext3 journal file, if necessary.
11928	 */
11929	e2fsck_move_ext3_journal(ctx);
11930}
11931
11932/*
11933 * swapfs.c --- byte-swap an ext2 filesystem
11934 */
11935
11936#ifdef ENABLE_SWAPFS
11937
11938struct swap_block_struct {
11939	ext2_ino_t      ino;
11940	int             isdir;
11941	errcode_t       errcode;
11942	char            *dir_buf;
11943	struct ext2_inode *inode;
11944};
11945
11946/*
11947 * This is a helper function for block_iterate.  We mark all of the
11948 * indirect and direct blocks as changed, so that block_iterate will
11949 * write them out.
11950 */
11951static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
11952		      void *priv_data)
11953{
11954	errcode_t       retval;
11955
11956	struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
11957
11958	if (sb->isdir && (blockcnt >= 0) && *block_nr) {
11959		retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
11960		if (retval) {
11961			sb->errcode = retval;
11962			return BLOCK_ABORT;
11963		}
11964		retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
11965		if (retval) {
11966			sb->errcode = retval;
11967			return BLOCK_ABORT;
11968		}
11969	}
11970	if (blockcnt >= 0) {
11971		if (blockcnt < EXT2_NDIR_BLOCKS)
11972			return 0;
11973		return BLOCK_CHANGED;
11974	}
11975	if (blockcnt == BLOCK_COUNT_IND) {
11976		if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
11977			return 0;
11978		return BLOCK_CHANGED;
11979	}
11980	if (blockcnt == BLOCK_COUNT_DIND) {
11981		if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
11982			return 0;
11983		return BLOCK_CHANGED;
11984	}
11985	if (blockcnt == BLOCK_COUNT_TIND) {
11986		if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
11987			return 0;
11988		return BLOCK_CHANGED;
11989	}
11990	return BLOCK_CHANGED;
11991}
11992
11993/*
11994 * This function is responsible for byte-swapping all of the indirect,
11995 * block pointers.  It is also responsible for byte-swapping directories.
11996 */
11997static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
11998			      struct ext2_inode *inode)
11999{
12000	errcode_t                       retval;
12001	struct swap_block_struct        sb;
12002
12003	sb.ino = ino;
12004	sb.inode = inode;
12005	sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12006	sb.errcode = 0;
12007	sb.isdir = 0;
12008	if (LINUX_S_ISDIR(inode->i_mode))
12009		sb.isdir = 1;
12010
12011	retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12012				      swap_block, &sb);
12013	if (retval) {
12014		bb_error_msg(_("while calling ext2fs_block_iterate"));
12015		ctx->flags |= E2F_FLAG_ABORT;
12016		return;
12017	}
12018	if (sb.errcode) {
12019		bb_error_msg(_("while calling iterator function"));
12020		ctx->flags |= E2F_FLAG_ABORT;
12021		return;
12022	}
12023}
12024
12025static void swap_inodes(e2fsck_t ctx)
12026{
12027	ext2_filsys fs = ctx->fs;
12028	dgrp_t                  group;
12029	unsigned int            i;
12030	ext2_ino_t              ino = 1;
12031	char                    *buf, *block_buf;
12032	errcode_t               retval;
12033	struct ext2_inode *     inode;
12034
12035	e2fsck_use_inode_shortcuts(ctx, 1);
12036
12037	retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12038				&buf);
12039	if (retval) {
12040		bb_error_msg(_("while allocating inode buffer"));
12041		ctx->flags |= E2F_FLAG_ABORT;
12042		return;
12043	}
12044	block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12045						    "block interate buffer");
12046	for (group = 0; group < fs->group_desc_count; group++) {
12047		retval = io_channel_read_blk(fs->io,
12048		      fs->group_desc[group].bg_inode_table,
12049		      fs->inode_blocks_per_group, buf);
12050		if (retval) {
12051			bb_error_msg(_("while reading inode table (group %d)"),
12052				group);
12053			ctx->flags |= E2F_FLAG_ABORT;
12054			return;
12055		}
12056		inode = (struct ext2_inode *) buf;
12057		for (i=0; i < fs->super->s_inodes_per_group;
12058		     i++, ino++, inode++) {
12059			ctx->stashed_ino = ino;
12060			ctx->stashed_inode = inode;
12061
12062			if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12063				ext2fs_swap_inode(fs, inode, inode, 0);
12064
12065			/*
12066			 * Skip deleted files.
12067			 */
12068			if (inode->i_links_count == 0)
12069				continue;
12070
12071			if (LINUX_S_ISDIR(inode->i_mode) ||
12072			    ((inode->i_block[EXT2_IND_BLOCK] ||
12073			      inode->i_block[EXT2_DIND_BLOCK] ||
12074			      inode->i_block[EXT2_TIND_BLOCK]) &&
12075			     ext2fs_inode_has_valid_blocks(inode)))
12076				swap_inode_blocks(ctx, ino, block_buf, inode);
12077
12078			if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12079				return;
12080
12081			if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12082				ext2fs_swap_inode(fs, inode, inode, 1);
12083		}
12084		retval = io_channel_write_blk(fs->io,
12085		      fs->group_desc[group].bg_inode_table,
12086		      fs->inode_blocks_per_group, buf);
12087		if (retval) {
12088			bb_error_msg(_("while writing inode table (group %d)"),
12089				group);
12090			ctx->flags |= E2F_FLAG_ABORT;
12091			return;
12092		}
12093	}
12094	ext2fs_free_mem(&buf);
12095	ext2fs_free_mem(&block_buf);
12096	e2fsck_use_inode_shortcuts(ctx, 0);
12097	ext2fs_flush_icache(fs);
12098}
12099
12100#if defined(__powerpc__) && BB_BIG_ENDIAN
12101/*
12102 * On the PowerPC, the big-endian variant of the ext2 filesystem
12103 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12104 * of each word.  Thus a bitmap with only bit 0 set would be, as
12105 * a string of bytes, 00 00 00 01 00 ...
12106 * To cope with this, we byte-reverse each word of a bitmap if
12107 * we have a big-endian filesystem, that is, if we are *not*
12108 * byte-swapping other word-sized numbers.
12109 */
12110#define EXT2_BIG_ENDIAN_BITMAPS
12111#endif
12112
12113#ifdef EXT2_BIG_ENDIAN_BITMAPS
12114static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12115{
12116	__u32 *p = (__u32 *) bmap->bitmap;
12117	int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12118
12119	for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12120		*p = ext2fs_swab32(*p);
12121}
12122#endif
12123
12124
12125#ifdef ENABLE_SWAPFS
12126static void swap_filesys(e2fsck_t ctx)
12127{
12128	ext2_filsys fs = ctx->fs;
12129	if (!(ctx->options & E2F_OPT_PREEN))
12130		printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12131
12132	/* Byte swap */
12133
12134	if (fs->super->s_mnt_count) {
12135		fprintf(stderr, _("%s: the filesystem must be freshly "
12136			"checked using fsck\n"
12137			"and not mounted before trying to "
12138			"byte-swap it.\n"), ctx->device_name);
12139		ctx->flags |= E2F_FLAG_ABORT;
12140		return;
12141	}
12142	if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12143		fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12144			       EXT2_FLAG_SWAP_BYTES_WRITE);
12145		fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12146	} else {
12147		fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12148		fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12149	}
12150	swap_inodes(ctx);
12151	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12152		return;
12153	if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12154		fs->flags |= EXT2_FLAG_SWAP_BYTES;
12155	fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12156		       EXT2_FLAG_SWAP_BYTES_WRITE);
12157
12158#ifdef EXT2_BIG_ENDIAN_BITMAPS
12159	e2fsck_read_bitmaps(ctx);
12160	ext2fs_swap_bitmap(fs->inode_map);
12161	ext2fs_swap_bitmap(fs->block_map);
12162	fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12163#endif
12164	fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12165	ext2fs_flush(fs);
12166	fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12167}
12168#endif  /* ENABLE_SWAPFS */
12169
12170#endif
12171
12172/*
12173 * util.c --- miscellaneous utilities
12174 */
12175
12176
12177void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12178			     const char *description)
12179{
12180	void *ret;
12181	char buf[256];
12182
12183	ret = malloc(size);
12184	if (!ret) {
12185		sprintf(buf, "Can't allocate %s\n", description);
12186		bb_error_msg_and_die(buf);
12187	}
12188	memset(ret, 0, size);
12189	return ret;
12190}
12191
12192static char *string_copy(const char *str, int len)
12193{
12194	char    *ret;
12195
12196	if (!str)
12197		return NULL;
12198	if (!len)
12199		len = strlen(str);
12200	ret = malloc(len+1);
12201	if (ret) {
12202		strncpy(ret, str, len);
12203		ret[len] = 0;
12204	}
12205	return ret;
12206}
12207
12208#ifndef HAVE_CONIO_H
12209static int read_a_char(void)
12210{
12211	char    c;
12212	int     r;
12213	int     fail = 0;
12214
12215	while(1) {
12216		if (e2fsck_global_ctx &&
12217		    (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12218			return 3;
12219		}
12220		r = read(0, &c, 1);
12221		if (r == 1)
12222			return c;
12223		if (fail++ > 100)
12224			break;
12225	}
12226	return EOF;
12227}
12228#endif
12229
12230static int ask_yn(const char * string, int def)
12231{
12232	int             c;
12233	const char      *defstr;
12234	static const char short_yes[] = "yY";
12235	static const char short_no[] = "nN";
12236
12237#ifdef HAVE_TERMIOS_H
12238	struct termios  termios, tmp;
12239
12240	tcgetattr (0, &termios);
12241	tmp = termios;
12242	tmp.c_lflag &= ~(ICANON | ECHO);
12243	tmp.c_cc[VMIN] = 1;
12244	tmp.c_cc[VTIME] = 0;
12245	tcsetattr (0, TCSANOW, &tmp);
12246#endif
12247
12248	if (def == 1)
12249		defstr = "<y>";
12250	else if (def == 0)
12251		defstr = "<n>";
12252	else
12253		defstr = " (y/n)";
12254	printf("%s%s? ", string, defstr);
12255	while (1) {
12256		fflush (stdout);
12257		if ((c = read_a_char()) == EOF)
12258			break;
12259		if (c == 3) {
12260#ifdef HAVE_TERMIOS_H
12261			tcsetattr (0, TCSANOW, &termios);
12262#endif
12263			if (e2fsck_global_ctx &&
12264			    e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12265				puts("\n");
12266				longjmp(e2fsck_global_ctx->abort_loc, 1);
12267			}
12268			puts(_("cancelled!\n"));
12269			return 0;
12270		}
12271		if (strchr(short_yes, (char) c)) {
12272			def = 1;
12273			break;
12274		}
12275		else if (strchr(short_no, (char) c)) {
12276			def = 0;
12277			break;
12278		}
12279		else if ((c == ' ' || c == '\n') && (def != -1))
12280			break;
12281	}
12282	if (def)
12283		puts("yes\n");
12284	else
12285		puts ("no\n");
12286#ifdef HAVE_TERMIOS_H
12287	tcsetattr (0, TCSANOW, &termios);
12288#endif
12289	return def;
12290}
12291
12292int ask (e2fsck_t ctx, const char * string, int def)
12293{
12294	if (ctx->options & E2F_OPT_NO) {
12295		printf(_("%s? no\n\n"), string);
12296		return 0;
12297	}
12298	if (ctx->options & E2F_OPT_YES) {
12299		printf(_("%s? yes\n\n"), string);
12300		return 1;
12301	}
12302	if (ctx->options & E2F_OPT_PREEN) {
12303		printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
12304		return def;
12305	}
12306	return ask_yn(string, def);
12307}
12308
12309void e2fsck_read_bitmaps(e2fsck_t ctx)
12310{
12311	ext2_filsys fs = ctx->fs;
12312	errcode_t       retval;
12313
12314	if (ctx->invalid_bitmaps) {
12315		bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12316			ctx->device_name);
12317		bb_error_msg_and_die(0);
12318	}
12319
12320	ehandler_operation(_("reading inode and block bitmaps"));
12321	retval = ext2fs_read_bitmaps(fs);
12322	ehandler_operation(0);
12323	if (retval) {
12324		bb_error_msg(_("while retrying to read bitmaps for %s"),
12325			ctx->device_name);
12326		bb_error_msg_and_die(0);
12327	}
12328}
12329
12330static void e2fsck_write_bitmaps(e2fsck_t ctx)
12331{
12332	ext2_filsys fs = ctx->fs;
12333	errcode_t       retval;
12334
12335	if (ext2fs_test_bb_dirty(fs)) {
12336		ehandler_operation(_("writing block bitmaps"));
12337		retval = ext2fs_write_block_bitmap(fs);
12338		ehandler_operation(0);
12339		if (retval) {
12340			bb_error_msg(_("while retrying to write block bitmaps for %s"),
12341				ctx->device_name);
12342			bb_error_msg_and_die(0);
12343		}
12344	}
12345
12346	if (ext2fs_test_ib_dirty(fs)) {
12347		ehandler_operation(_("writing inode bitmaps"));
12348		retval = ext2fs_write_inode_bitmap(fs);
12349		ehandler_operation(0);
12350		if (retval) {
12351			bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12352				ctx->device_name);
12353			bb_error_msg_and_die(0);
12354		}
12355	}
12356}
12357
12358void preenhalt(e2fsck_t ctx)
12359{
12360	ext2_filsys fs = ctx->fs;
12361
12362	if (!(ctx->options & E2F_OPT_PREEN))
12363		return;
12364	fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12365		"RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12366	       ctx->device_name);
12367	if (fs != NULL) {
12368		fs->super->s_state |= EXT2_ERROR_FS;
12369		ext2fs_mark_super_dirty(fs);
12370		ext2fs_close(fs);
12371	}
12372	exit(EXIT_UNCORRECTED);
12373}
12374
12375void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12376			      struct ext2_inode * inode, const char *proc)
12377{
12378	int retval;
12379
12380	retval = ext2fs_read_inode(ctx->fs, ino, inode);
12381	if (retval) {
12382		bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12383		bb_error_msg_and_die(0);
12384	}
12385}
12386
12387extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12388			       struct ext2_inode * inode, int bufsize,
12389			       const char *proc)
12390{
12391	int retval;
12392
12393	retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12394	if (retval) {
12395		bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12396		bb_error_msg_and_die(0);
12397	}
12398}
12399
12400extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12401			       struct ext2_inode * inode, const char *proc)
12402{
12403	int retval;
12404
12405	retval = ext2fs_write_inode(ctx->fs, ino, inode);
12406	if (retval) {
12407		bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12408		bb_error_msg_and_die(0);
12409	}
12410}
12411
12412blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12413		   io_manager manager)
12414{
12415	struct ext2_super_block *sb;
12416	io_channel              io = NULL;
12417	void                    *buf = NULL;
12418	int                     blocksize;
12419	blk_t                   superblock, ret_sb = 8193;
12420
12421	if (fs && fs->super) {
12422		ret_sb = (fs->super->s_blocks_per_group +
12423			  fs->super->s_first_data_block);
12424		if (ctx) {
12425			ctx->superblock = ret_sb;
12426			ctx->blocksize = fs->blocksize;
12427		}
12428		return ret_sb;
12429	}
12430
12431	if (ctx) {
12432		if (ctx->blocksize) {
12433			ret_sb = ctx->blocksize * 8;
12434			if (ctx->blocksize == 1024)
12435				ret_sb++;
12436			ctx->superblock = ret_sb;
12437			return ret_sb;
12438		}
12439		ctx->superblock = ret_sb;
12440		ctx->blocksize = 1024;
12441	}
12442
12443	if (!name || !manager)
12444		goto cleanup;
12445
12446	if (manager->open(name, 0, &io) != 0)
12447		goto cleanup;
12448
12449	if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12450		goto cleanup;
12451	sb = (struct ext2_super_block *) buf;
12452
12453	for (blocksize = EXT2_MIN_BLOCK_SIZE;
12454	     blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
12455		superblock = blocksize*8;
12456		if (blocksize == 1024)
12457			superblock++;
12458		io_channel_set_blksize(io, blocksize);
12459		if (io_channel_read_blk(io, superblock,
12460					-SUPERBLOCK_SIZE, buf))
12461			continue;
12462#if BB_BIG_ENDIAN
12463		if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12464			ext2fs_swap_super(sb);
12465#endif
12466		if (sb->s_magic == EXT2_SUPER_MAGIC) {
12467			ret_sb = superblock;
12468			if (ctx) {
12469				ctx->superblock = superblock;
12470				ctx->blocksize = blocksize;
12471			}
12472			break;
12473		}
12474	}
12475
12476cleanup:
12477	if (io)
12478		io_channel_close(io);
12479	ext2fs_free_mem(&buf);
12480	return ret_sb;
12481}
12482
12483
12484/*
12485 * This function runs through the e2fsck passes and calls them all,
12486 * returning restart, abort, or cancel as necessary...
12487 */
12488typedef void (*pass_t)(e2fsck_t ctx);
12489
12490static const pass_t e2fsck_passes[] = {
12491	e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12492	e2fsck_pass5, 0 };
12493
12494#define E2F_FLAG_RUN_RETURN     (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12495
12496static int e2fsck_run(e2fsck_t ctx)
12497{
12498	int     i;
12499	pass_t  e2fsck_pass;
12500
12501	if (setjmp(ctx->abort_loc)) {
12502		ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12503		return (ctx->flags & E2F_FLAG_RUN_RETURN);
12504	}
12505	ctx->flags |= E2F_FLAG_SETJMP_OK;
12506
12507	for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12508		if (ctx->flags & E2F_FLAG_RUN_RETURN)
12509			break;
12510		e2fsck_pass(ctx);
12511		if (ctx->progress)
12512			(void) (ctx->progress)(ctx, 0, 0, 0);
12513	}
12514	ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12515
12516	if (ctx->flags & E2F_FLAG_RUN_RETURN)
12517		return (ctx->flags & E2F_FLAG_RUN_RETURN);
12518	return 0;
12519}
12520
12521
12522/*
12523 * unix.c - The unix-specific code for e2fsck
12524 */
12525
12526
12527/* Command line options */
12528static int swapfs;
12529#ifdef ENABLE_SWAPFS
12530static int normalize_swapfs;
12531#endif
12532static int cflag;               /* check disk */
12533static int show_version_only;
12534static int verbose;
12535
12536#define P_E2(singular, plural, n)       n, ((n) == 1 ? singular : plural)
12537
12538static void show_stats(e2fsck_t ctx)
12539{
12540	ext2_filsys fs = ctx->fs;
12541	int inodes, inodes_used, blocks, blocks_used;
12542	int dir_links;
12543	int num_files, num_links;
12544	int frag_percent;
12545
12546	dir_links = 2 * ctx->fs_directory_count - 1;
12547	num_files = ctx->fs_total_count - dir_links;
12548	num_links = ctx->fs_links_count - dir_links;
12549	inodes = fs->super->s_inodes_count;
12550	inodes_used = (fs->super->s_inodes_count -
12551		       fs->super->s_free_inodes_count);
12552	blocks = fs->super->s_blocks_count;
12553	blocks_used = (fs->super->s_blocks_count -
12554		       fs->super->s_free_blocks_count);
12555
12556	frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12557	frag_percent = (frag_percent + 5) / 10;
12558
12559	if (!verbose) {
12560		printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12561		       ctx->device_name, inodes_used, inodes,
12562		       frag_percent / 10, frag_percent % 10,
12563		       blocks_used, blocks);
12564		return;
12565	}
12566	printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12567		100 * inodes_used / inodes);
12568	printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12569		P_E2("", "s", ctx->fs_fragmented),
12570		frag_percent / 10, frag_percent % 10);
12571	printf(_("         # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12572		ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12573	printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12574		(int) ((long long) 100 * blocks_used / blocks));
12575	printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12576	printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12577	printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12578	printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12579	printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12580	printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12581	printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12582	printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12583	printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12584	printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12585	printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12586}
12587
12588static void check_mount(e2fsck_t ctx)
12589{
12590	errcode_t       retval;
12591	int             cont;
12592
12593	retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12594					 &ctx->mount_flags);
12595	if (retval) {
12596		bb_error_msg(_("while determining whether %s is mounted."),
12597			ctx->filesystem_name);
12598		return;
12599	}
12600
12601	/*
12602	 * If the filesystem isn't mounted, or it's the root filesystem
12603	 * and it's mounted read-only, then everything's fine.
12604	 */
12605	if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12606	    ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12607	     (ctx->mount_flags & EXT2_MF_READONLY)))
12608		return;
12609
12610	if (ctx->options & E2F_OPT_READONLY) {
12611		printf(_("Warning!  %s is mounted.\n"), ctx->filesystem_name);
12612		return;
12613	}
12614
12615	printf(_("%s is mounted.  "), ctx->filesystem_name);
12616	if (!ctx->interactive)
12617		bb_error_msg_and_die(_("Cannot continue, aborting."));
12618	printf(_("\n\n\007\007\007\007WARNING!!!  "
12619	       "Running e2fsck on a mounted filesystem may cause\n"
12620	       "SEVERE filesystem damage.\007\007\007\n\n"));
12621	cont = ask_yn(_("Do you really want to continue"), -1);
12622	if (!cont) {
12623		printf(_("check aborted.\n"));
12624		exit(0);
12625	}
12626}
12627
12628static int is_on_batt(void)
12629{
12630	FILE    *f;
12631	DIR     *d;
12632	char    tmp[80], tmp2[80], fname[80];
12633	unsigned int    acflag;
12634	struct dirent*  de;
12635
12636	f = fopen("/proc/apm", "r");
12637	if (f) {
12638		if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12639			acflag = 1;
12640		fclose(f);
12641		return (acflag != 1);
12642	}
12643	d = opendir("/proc/acpi/ac_adapter");
12644	if (d) {
12645		while ((de=readdir(d)) != NULL) {
12646			if (!strncmp(".", de->d_name, 1))
12647				continue;
12648			snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12649				 de->d_name);
12650			f = fopen(fname, "r");
12651			if (!f)
12652				continue;
12653			if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12654				tmp[0] = 0;
12655			fclose(f);
12656			if (strncmp(tmp, "off-line", 8) == 0) {
12657				closedir(d);
12658				return 1;
12659			}
12660		}
12661		closedir(d);
12662	}
12663	return 0;
12664}
12665
12666/*
12667 * This routine checks to see if a filesystem can be skipped; if so,
12668 * it will exit with EXIT_OK.  Under some conditions it will print a
12669 * message explaining why a check is being forced.
12670 */
12671static void check_if_skip(e2fsck_t ctx)
12672{
12673	ext2_filsys fs = ctx->fs;
12674	const char *reason = NULL;
12675	unsigned int reason_arg = 0;
12676	long next_check;
12677	int batt = is_on_batt();
12678	time_t now = time(0);
12679
12680	if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12681		return;
12682
12683	if ((fs->super->s_state & EXT2_ERROR_FS) ||
12684	    !ext2fs_test_valid(fs))
12685		reason = _(" contains a file system with errors");
12686	else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12687		reason = _(" was not cleanly unmounted");
12688	else if ((fs->super->s_max_mnt_count > 0) &&
12689		 (fs->super->s_mnt_count >=
12690		  (unsigned) fs->super->s_max_mnt_count)) {
12691		reason = _(" has been mounted %u times without being checked");
12692		reason_arg = fs->super->s_mnt_count;
12693		if (batt && (fs->super->s_mnt_count <
12694			     (unsigned) fs->super->s_max_mnt_count*2))
12695			reason = 0;
12696	} else if (fs->super->s_checkinterval &&
12697		   ((now - fs->super->s_lastcheck) >=
12698		    fs->super->s_checkinterval)) {
12699		reason = _(" has gone %u days without being checked");
12700		reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12701		if (batt && ((now - fs->super->s_lastcheck) <
12702			     fs->super->s_checkinterval*2))
12703			reason = 0;
12704	}
12705	if (reason) {
12706		fputs(ctx->device_name, stdout);
12707		printf(reason, reason_arg);
12708		fputs(_(", check forced.\n"), stdout);
12709		return;
12710	}
12711	printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12712	       fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12713	       fs->super->s_inodes_count,
12714	       fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12715	       fs->super->s_blocks_count);
12716	next_check = 100000;
12717	if (fs->super->s_max_mnt_count > 0) {
12718		next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12719		if (next_check <= 0)
12720			next_check = 1;
12721	}
12722	if (fs->super->s_checkinterval &&
12723	    ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12724		next_check = 1;
12725	if (next_check <= 5) {
12726		if (next_check == 1)
12727			fputs(_(" (check after next mount)"), stdout);
12728		else
12729			printf(_(" (check in %ld mounts)"), next_check);
12730	}
12731	fputc('\n', stdout);
12732	ext2fs_close(fs);
12733	ctx->fs = NULL;
12734	e2fsck_free_context(ctx);
12735	exit(EXIT_OK);
12736}
12737
12738/*
12739 * For completion notice
12740 */
12741struct percent_tbl {
12742	int     max_pass;
12743	int     table[32];
12744};
12745static const struct percent_tbl e2fsck_tbl = {
12746	5, { 0, 70, 90, 92,  95, 100 }
12747};
12748
12749static char bar[128], spaces[128];
12750
12751static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12752			  int max)
12753{
12754	float   percent;
12755
12756	if (pass <= 0)
12757		return 0.0;
12758	if (pass > tbl->max_pass || max == 0)
12759		return 100.0;
12760	percent = ((float) curr) / ((float) max);
12761	return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12762		+ tbl->table[pass-1]);
12763}
12764
12765void e2fsck_clear_progbar(e2fsck_t ctx)
12766{
12767	if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12768		return;
12769
12770	printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12771	       ctx->stop_meta);
12772	fflush(stdout);
12773	ctx->flags &= ~E2F_FLAG_PROG_BAR;
12774}
12775
12776int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12777			   unsigned int dpynum)
12778{
12779	static const char spinner[] = "\\|/-";
12780	int     i;
12781	unsigned int    tick;
12782	struct timeval  tv;
12783	int dpywidth;
12784	int fixed_percent;
12785
12786	if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12787		return 0;
12788
12789	/*
12790	 * Calculate the new progress position.  If the
12791	 * percentage hasn't changed, then we skip out right
12792	 * away.
12793	 */
12794	fixed_percent = (int) ((10 * percent) + 0.5);
12795	if (ctx->progress_last_percent == fixed_percent)
12796		return 0;
12797	ctx->progress_last_percent = fixed_percent;
12798
12799	/*
12800	 * If we've already updated the spinner once within
12801	 * the last 1/8th of a second, no point doing it
12802	 * again.
12803	 */
12804	gettimeofday(&tv, NULL);
12805	tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12806	if ((tick == ctx->progress_last_time) &&
12807	    (fixed_percent != 0) && (fixed_percent != 1000))
12808		return 0;
12809	ctx->progress_last_time = tick;
12810
12811	/*
12812	 * Advance the spinner, and note that the progress bar
12813	 * will be on the screen
12814	 */
12815	ctx->progress_pos = (ctx->progress_pos+1) & 3;
12816	ctx->flags |= E2F_FLAG_PROG_BAR;
12817
12818	dpywidth = 66 - strlen(label);
12819	dpywidth = 8 * (dpywidth / 8);
12820	if (dpynum)
12821		dpywidth -= 8;
12822
12823	i = ((percent * dpywidth) + 50) / 100;
12824	printf("%s%s: |%s%s", ctx->start_meta, label,
12825	       bar + (sizeof(bar) - (i+1)),
12826	       spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12827	if (fixed_percent == 1000)
12828		fputc('|', stdout);
12829	else
12830		fputc(spinner[ctx->progress_pos & 3], stdout);
12831	printf(" %4.1f%%  ", percent);
12832	if (dpynum)
12833		printf("%u\r", dpynum);
12834	else
12835		fputs(" \r", stdout);
12836	fputs(ctx->stop_meta, stdout);
12837
12838	if (fixed_percent == 1000)
12839		e2fsck_clear_progbar(ctx);
12840	fflush(stdout);
12841
12842	return 0;
12843}
12844
12845static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12846				  unsigned long cur, unsigned long max)
12847{
12848	char buf[80];
12849	float percent;
12850
12851	if (pass == 0)
12852		return 0;
12853
12854	if (ctx->progress_fd) {
12855		sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12856		write(ctx->progress_fd, buf, strlen(buf));
12857	} else {
12858		percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12859		e2fsck_simple_progress(ctx, ctx->device_name,
12860				       percent, 0);
12861	}
12862	return 0;
12863}
12864
12865static void reserve_stdio_fds(void)
12866{
12867	int     fd;
12868
12869	while (1) {
12870		fd = open(bb_dev_null, O_RDWR);
12871		if (fd > 2)
12872			break;
12873		if (fd < 0) {
12874			fprintf(stderr, _("ERROR: Cannot open "
12875				"/dev/null (%s)\n"),
12876				strerror(errno));
12877			break;
12878		}
12879	}
12880	close(fd);
12881}
12882
12883static void signal_progress_on(int sig FSCK_ATTR((unused)))
12884{
12885	e2fsck_t ctx = e2fsck_global_ctx;
12886
12887	if (!ctx)
12888		return;
12889
12890	ctx->progress = e2fsck_update_progress;
12891	ctx->progress_fd = 0;
12892}
12893
12894static void signal_progress_off(int sig FSCK_ATTR((unused)))
12895{
12896	e2fsck_t ctx = e2fsck_global_ctx;
12897
12898	if (!ctx)
12899		return;
12900
12901	e2fsck_clear_progbar(ctx);
12902	ctx->progress = 0;
12903}
12904
12905static void signal_cancel(int sig FSCK_ATTR((unused)))
12906{
12907	e2fsck_t ctx = e2fsck_global_ctx;
12908
12909	if (!ctx)
12910		exit(FSCK_CANCELED);
12911
12912	ctx->flags |= E2F_FLAG_CANCEL;
12913}
12914
12915static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12916{
12917	char    *buf, *token, *next, *p, *arg;
12918	int     ea_ver;
12919	int     extended_usage = 0;
12920
12921	buf = string_copy(opts, 0);
12922	for (token = buf; token && *token; token = next) {
12923		p = strchr(token, ',');
12924		next = 0;
12925		if (p) {
12926			*p = 0;
12927			next = p+1;
12928		}
12929		arg = strchr(token, '=');
12930		if (arg) {
12931			*arg = 0;
12932			arg++;
12933		}
12934		if (strcmp(token, "ea_ver") == 0) {
12935			if (!arg) {
12936				extended_usage++;
12937				continue;
12938			}
12939			ea_ver = strtoul(arg, &p, 0);
12940			if (*p ||
12941			    ((ea_ver != 1) && (ea_ver != 2))) {
12942				fprintf(stderr,
12943					_("Invalid EA version.\n"));
12944				extended_usage++;
12945				continue;
12946			}
12947			ctx->ext_attr_ver = ea_ver;
12948		} else {
12949			fprintf(stderr, _("Unknown extended option: %s\n"),
12950				token);
12951			extended_usage++;
12952		}
12953	}
12954	if (extended_usage) {
12955		bb_error_msg_and_die(
12956			"Extended options are separated by commas, "
12957			"and may take an argument which\n"
12958			"is set off by an equals ('=') sign.  "
12959			"Valid extended options are:\n"
12960			"\tea_ver=<ea_version (1 or 2)>\n\n");
12961	}
12962}
12963
12964
12965static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx)
12966{
12967	int             flush = 0;
12968	int             c, fd;
12969	e2fsck_t        ctx;
12970	errcode_t       retval;
12971	struct sigaction        sa;
12972	char            *extended_opts = 0;
12973
12974	retval = e2fsck_allocate_context(&ctx);
12975	if (retval)
12976		return retval;
12977
12978	*ret_ctx = ctx;
12979
12980	setvbuf(stdout, NULL, _IONBF, BUFSIZ);
12981	setvbuf(stderr, NULL, _IONBF, BUFSIZ);
12982	if (isatty(0) && isatty(1)) {
12983		ctx->interactive = 1;
12984	} else {
12985		ctx->start_meta[0] = '\001';
12986		ctx->stop_meta[0] = '\002';
12987	}
12988	memset(bar, '=', sizeof(bar)-1);
12989	memset(spaces, ' ', sizeof(spaces)-1);
12990	blkid_get_cache(&ctx->blkid, NULL);
12991
12992	if (argc && *argv)
12993		ctx->program_name = *argv;
12994	else
12995		ctx->program_name = "e2fsck";
12996	while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
12997		switch (c) {
12998		case 'C':
12999			ctx->progress = e2fsck_update_progress;
13000			ctx->progress_fd = atoi(optarg);
13001			if (!ctx->progress_fd)
13002				break;
13003			/* Validate the file descriptor to avoid disasters */
13004			fd = dup(ctx->progress_fd);
13005			if (fd < 0) {
13006				fprintf(stderr,
13007				_("Error validating file descriptor %d: %s\n"),
13008					ctx->progress_fd,
13009					error_message(errno));
13010				bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13011			} else
13012				close(fd);
13013			break;
13014		case 'D':
13015			ctx->options |= E2F_OPT_COMPRESS_DIRS;
13016			break;
13017		case 'E':
13018			extended_opts = optarg;
13019			break;
13020		case 'p':
13021		case 'a':
13022			if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13023			conflict_opt:
13024				bb_error_msg_and_die(_("Only one the options -p/-a, -n or -y may be specified."));
13025			}
13026			ctx->options |= E2F_OPT_PREEN;
13027			break;
13028		case 'n':
13029			if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13030				goto conflict_opt;
13031			ctx->options |= E2F_OPT_NO;
13032			break;
13033		case 'y':
13034			if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13035				goto conflict_opt;
13036			ctx->options |= E2F_OPT_YES;
13037			break;
13038		case 't':
13039			fprintf(stderr, _("The -t option is not "
13040				"supported on this version of e2fsck.\n"));
13041			break;
13042		case 'c':
13043			if (cflag++)
13044				ctx->options |= E2F_OPT_WRITECHECK;
13045			ctx->options |= E2F_OPT_CHECKBLOCKS;
13046			break;
13047		case 'r':
13048			/* What we do by default, anyway! */
13049			break;
13050		case 'b':
13051			ctx->use_superblock = atoi(optarg);
13052			ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13053			break;
13054		case 'B':
13055			ctx->blocksize = atoi(optarg);
13056			break;
13057		case 'I':
13058			ctx->inode_buffer_blocks = atoi(optarg);
13059			break;
13060		case 'j':
13061			ctx->journal_name = string_copy(optarg, 0);
13062			break;
13063		case 'P':
13064			ctx->process_inode_size = atoi(optarg);
13065			break;
13066		case 'd':
13067			ctx->options |= E2F_OPT_DEBUG;
13068			break;
13069		case 'f':
13070			ctx->options |= E2F_OPT_FORCE;
13071			break;
13072		case 'F':
13073			flush = 1;
13074			break;
13075		case 'v':
13076			verbose = 1;
13077			break;
13078		case 'V':
13079			show_version_only = 1;
13080			break;
13081		case 'N':
13082			ctx->device_name = optarg;
13083			break;
13084#ifdef ENABLE_SWAPFS
13085		case 's':
13086			normalize_swapfs = 1;
13087		case 'S':
13088			swapfs = 1;
13089			break;
13090#else
13091		case 's':
13092		case 'S':
13093			fprintf(stderr, _("Byte-swapping filesystems "
13094					  "not compiled in this version "
13095					  "of e2fsck\n"));
13096			exit(1);
13097#endif
13098		default:
13099			bb_show_usage();
13100		}
13101	if (show_version_only)
13102		return 0;
13103	if (optind != argc - 1)
13104		bb_show_usage();
13105	if ((ctx->options & E2F_OPT_NO) &&
13106	    !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13107		ctx->options |= E2F_OPT_READONLY;
13108	ctx->io_options = strchr(argv[optind], '?');
13109	if (ctx->io_options)
13110		*ctx->io_options++ = 0;
13111	ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13112	if (!ctx->filesystem_name) {
13113		bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13114		bb_error_msg_and_die(0);
13115	}
13116	if (extended_opts)
13117		parse_extended_opts(ctx, extended_opts);
13118
13119	if (flush) {
13120		fd = open(ctx->filesystem_name, O_RDONLY, 0);
13121		if (fd < 0) {
13122			bb_error_msg(_("while opening %s for flushing"),
13123				ctx->filesystem_name);
13124			bb_error_msg_and_die(0);
13125		}
13126		if ((retval = ext2fs_sync_device(fd, 1))) {
13127			bb_error_msg(_("while trying to flush %s"),
13128				ctx->filesystem_name);
13129			bb_error_msg_and_die(0);
13130		}
13131		close(fd);
13132	}
13133#ifdef ENABLE_SWAPFS
13134	if (swapfs && cflag) {
13135			fprintf(stderr, _("Incompatible options not "
13136					  "allowed when byte-swapping.\n"));
13137			exit(EXIT_USAGE);
13138	}
13139#endif
13140	/*
13141	 * Set up signal action
13142	 */
13143	memset(&sa, 0, sizeof(struct sigaction));
13144	sa.sa_handler = signal_cancel;
13145	sigaction(SIGINT, &sa, 0);
13146	sigaction(SIGTERM, &sa, 0);
13147#ifdef SA_RESTART
13148	sa.sa_flags = SA_RESTART;
13149#endif
13150	e2fsck_global_ctx = ctx;
13151	sa.sa_handler = signal_progress_on;
13152	sigaction(SIGUSR1, &sa, 0);
13153	sa.sa_handler = signal_progress_off;
13154	sigaction(SIGUSR2, &sa, 0);
13155
13156	/* Update our PATH to include /sbin if we need to run badblocks  */
13157	if (cflag)
13158		e2fs_set_sbin_path();
13159	return 0;
13160}
13161
13162static const char my_ver_string[] = E2FSPROGS_VERSION;
13163static const char my_ver_date[] = E2FSPROGS_DATE;
13164
13165int e2fsck_main (int argc, char **argv);
13166int e2fsck_main (int argc, char **argv)
13167{
13168	errcode_t       retval;
13169	int             exit_value = EXIT_OK;
13170	ext2_filsys     fs = 0;
13171	io_manager      io_ptr;
13172	struct ext2_super_block *sb;
13173	const char      *lib_ver_date;
13174	int             my_ver, lib_ver;
13175	e2fsck_t        ctx;
13176	struct problem_context pctx;
13177	int flags, run_result;
13178
13179	clear_problem_context(&pctx);
13180
13181	my_ver = ext2fs_parse_version_string(my_ver_string);
13182	lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13183	if (my_ver > lib_ver) {
13184		fprintf( stderr, _("Error: ext2fs library version "
13185			"out of date!\n"));
13186		show_version_only++;
13187	}
13188
13189	retval = PRS(argc, argv, &ctx);
13190	if (retval) {
13191		bb_error_msg(_("while trying to initialize program"));
13192		exit(EXIT_ERROR);
13193	}
13194	reserve_stdio_fds();
13195
13196	if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13197		fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13198			 my_ver_date);
13199
13200	if (show_version_only) {
13201		fprintf(stderr, _("\tUsing %s, %s\n"),
13202			error_message(EXT2_ET_BASE), lib_ver_date);
13203		exit(EXIT_OK);
13204	}
13205
13206	check_mount(ctx);
13207
13208	if (!(ctx->options & E2F_OPT_PREEN) &&
13209	    !(ctx->options & E2F_OPT_NO) &&
13210	    !(ctx->options & E2F_OPT_YES)) {
13211		if (!ctx->interactive)
13212			bb_error_msg_and_die(_("need terminal for interactive repairs"));
13213	}
13214	ctx->superblock = ctx->use_superblock;
13215restart:
13216#ifdef CONFIG_TESTIO_DEBUG
13217	io_ptr = test_io_manager;
13218	test_io_backing_manager = unix_io_manager;
13219#else
13220	io_ptr = unix_io_manager;
13221#endif
13222	flags = 0;
13223	if ((ctx->options & E2F_OPT_READONLY) == 0)
13224		flags |= EXT2_FLAG_RW;
13225
13226	if (ctx->superblock && ctx->blocksize) {
13227		retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13228				      flags, ctx->superblock, ctx->blocksize,
13229				      io_ptr, &fs);
13230	} else if (ctx->superblock) {
13231		int blocksize;
13232		for (blocksize = EXT2_MIN_BLOCK_SIZE;
13233		     blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13234			retval = ext2fs_open2(ctx->filesystem_name,
13235					      ctx->io_options, flags,
13236					      ctx->superblock, blocksize,
13237					      io_ptr, &fs);
13238			if (!retval)
13239				break;
13240		}
13241	} else
13242		retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13243				      flags, 0, 0, io_ptr, &fs);
13244	if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13245	    !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13246	    ((retval == EXT2_ET_BAD_MAGIC) ||
13247	     ((retval == 0) && ext2fs_check_desc(fs)))) {
13248		if (!fs || (fs->group_desc_count > 1)) {
13249			printf(_("%s trying backup blocks...\n"),
13250			       retval ? _("Couldn't find ext2 superblock,") :
13251			       _("Group descriptors look bad..."));
13252			get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13253			if (fs)
13254				ext2fs_close(fs);
13255			goto restart;
13256		}
13257	}
13258	if (retval) {
13259		bb_error_msg(_("while trying to open %s"),
13260			ctx->filesystem_name);
13261		if (retval == EXT2_ET_REV_TOO_HIGH) {
13262			printf(_("The filesystem revision is apparently "
13263			       "too high for this version of e2fsck.\n"
13264			       "(Or the filesystem superblock "
13265			       "is corrupt)\n\n"));
13266			fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13267		} else if (retval == EXT2_ET_SHORT_READ)
13268			printf(_("Could this be a zero-length partition?\n"));
13269		else if ((retval == EPERM) || (retval == EACCES))
13270			printf(_("You must have %s access to the "
13271			       "filesystem or be root\n"),
13272			       (ctx->options & E2F_OPT_READONLY) ?
13273			       "r/o" : "r/w");
13274		else if (retval == ENXIO)
13275			printf(_("Possibly non-existent or swap device?\n"));
13276#ifdef EROFS
13277		else if (retval == EROFS)
13278			printf(_("Disk write-protected; use the -n option "
13279			       "to do a read-only\n"
13280			       "check of the device.\n"));
13281#endif
13282		else
13283			fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13284		bb_error_msg_and_die(0);
13285	}
13286	ctx->fs = fs;
13287	fs->priv_data = ctx;
13288	sb = fs->super;
13289	if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13290		bb_error_msg(_("while trying to open %s"),
13291			ctx->filesystem_name);
13292	get_newer:
13293		bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13294	}
13295
13296	/*
13297	 * Set the device name, which is used whenever we print error
13298	 * or informational messages to the user.
13299	 */
13300	if (ctx->device_name == 0 &&
13301	    (sb->s_volume_name[0] != 0)) {
13302		ctx->device_name = string_copy(sb->s_volume_name,
13303					       sizeof(sb->s_volume_name));
13304	}
13305	if (ctx->device_name == 0)
13306		ctx->device_name = ctx->filesystem_name;
13307
13308	/*
13309	 * Make sure the ext3 superblock fields are consistent.
13310	 */
13311	retval = e2fsck_check_ext3_journal(ctx);
13312	if (retval) {
13313		bb_error_msg(_("while checking ext3 journal for %s"),
13314			ctx->device_name);
13315		bb_error_msg_and_die(0);
13316	}
13317
13318	/*
13319	 * Check to see if we need to do ext3-style recovery.  If so,
13320	 * do it, and then restart the fsck.
13321	 */
13322	if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13323		if (ctx->options & E2F_OPT_READONLY) {
13324			printf(_("Warning: skipping journal recovery "
13325				 "because doing a read-only filesystem "
13326				 "check.\n"));
13327			io_channel_flush(ctx->fs->io);
13328		} else {
13329			if (ctx->flags & E2F_FLAG_RESTARTED) {
13330				/*
13331				 * Whoops, we attempted to run the
13332				 * journal twice.  This should never
13333				 * happen, unless the hardware or
13334				 * device driver is being bogus.
13335				 */
13336				bb_error_msg(_("cannot set superblock flags on %s"), ctx->device_name);
13337				bb_error_msg_and_die(0);
13338			}
13339			retval = e2fsck_run_ext3_journal(ctx);
13340			if (retval) {
13341				bb_error_msg(_("while recovering ext3 journal of %s"),
13342					ctx->device_name);
13343				bb_error_msg_and_die(0);
13344			}
13345			ext2fs_close(ctx->fs);
13346			ctx->fs = 0;
13347			ctx->flags |= E2F_FLAG_RESTARTED;
13348			goto restart;
13349		}
13350	}
13351
13352	/*
13353	 * Check for compatibility with the feature sets.  We need to
13354	 * be more stringent than ext2fs_open().
13355	 */
13356	if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13357	    (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13358		bb_error_msg("(%s)", ctx->device_name);
13359		goto get_newer;
13360	}
13361	if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13362		bb_error_msg("(%s)", ctx->device_name);
13363		goto get_newer;
13364	}
13365#ifdef ENABLE_COMPRESSION
13366	if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13367		bb_error_msg(_("Warning: compression support is experimental."));
13368#endif
13369#ifndef ENABLE_HTREE
13370	if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13371		bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13372			  "but filesystem %s has HTREE directories."),
13373			ctx->device_name);
13374		goto get_newer;
13375	}
13376#endif
13377
13378	/*
13379	 * If the user specified a specific superblock, presumably the
13380	 * master superblock has been trashed.  So we mark the
13381	 * superblock as dirty, so it can be written out.
13382	 */
13383	if (ctx->superblock &&
13384	    !(ctx->options & E2F_OPT_READONLY))
13385		ext2fs_mark_super_dirty(fs);
13386
13387	/*
13388	 * We only update the master superblock because (a) paranoia;
13389	 * we don't want to corrupt the backup superblocks, and (b) we
13390	 * don't need to update the mount count and last checked
13391	 * fields in the backup superblock (the kernel doesn't
13392	 * update the backup superblocks anyway).
13393	 */
13394	fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13395
13396	ehandler_init(fs->io);
13397
13398	if (ctx->superblock)
13399		set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13400	ext2fs_mark_valid(fs);
13401	check_super_block(ctx);
13402	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13403		bb_error_msg_and_die(0);
13404	check_if_skip(ctx);
13405	if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13406		bb_error_msg_and_die(0);
13407#ifdef ENABLE_SWAPFS
13408
13409#ifdef WORDS_BIGENDIAN
13410#define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13411#else
13412#define NATIVE_FLAG 0
13413#endif
13414
13415
13416	if (normalize_swapfs) {
13417		if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13418			fprintf(stderr, _("%s: Filesystem byte order "
13419				"already normalized.\n"), ctx->device_name);
13420			bb_error_msg_and_die(0);
13421		}
13422	}
13423	if (swapfs) {
13424		swap_filesys(ctx);
13425		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13426			bb_error_msg_and_die(0);
13427	}
13428#endif
13429
13430	/*
13431	 * Mark the system as valid, 'til proven otherwise
13432	 */
13433	ext2fs_mark_valid(fs);
13434
13435	retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13436	if (retval) {
13437		bb_error_msg(_("while reading bad blocks inode"));
13438		preenhalt(ctx);
13439		printf(_("This doesn't bode well,"
13440			 " but we'll try to go on...\n"));
13441	}
13442
13443	run_result = e2fsck_run(ctx);
13444	e2fsck_clear_progbar(ctx);
13445	if (run_result == E2F_FLAG_RESTART) {
13446		printf(_("Restarting e2fsck from the beginning...\n"));
13447		retval = e2fsck_reset_context(ctx);
13448		if (retval) {
13449			bb_error_msg(_("while resetting context"));
13450			bb_error_msg_and_die(0);
13451		}
13452		ext2fs_close(fs);
13453		goto restart;
13454	}
13455	if (run_result & E2F_FLAG_CANCEL) {
13456		printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13457		       ctx->device_name : ctx->filesystem_name);
13458		exit_value |= FSCK_CANCELED;
13459	}
13460	if (run_result & E2F_FLAG_ABORT)
13461		bb_error_msg_and_die(_("aborted"));
13462
13463	/* Cleanup */
13464	if (ext2fs_test_changed(fs)) {
13465		exit_value |= EXIT_NONDESTRUCT;
13466		if (!(ctx->options & E2F_OPT_PREEN))
13467		    printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13468			       ctx->device_name);
13469		if (ctx->mount_flags & EXT2_MF_ISROOT) {
13470			printf(_("%s: ***** REBOOT LINUX *****\n"),
13471			       ctx->device_name);
13472			exit_value |= EXIT_DESTRUCT;
13473		}
13474	}
13475	if (!ext2fs_test_valid(fs)) {
13476		printf(_("\n%s: ********** WARNING: Filesystem still has "
13477			 "errors **********\n\n"), ctx->device_name);
13478		exit_value |= EXIT_UNCORRECTED;
13479		exit_value &= ~EXIT_NONDESTRUCT;
13480	}
13481	if (exit_value & FSCK_CANCELED)
13482		exit_value &= ~EXIT_NONDESTRUCT;
13483	else {
13484		show_stats(ctx);
13485		if (!(ctx->options & E2F_OPT_READONLY)) {
13486			if (ext2fs_test_valid(fs)) {
13487				if (!(sb->s_state & EXT2_VALID_FS))
13488					exit_value |= EXIT_NONDESTRUCT;
13489				sb->s_state = EXT2_VALID_FS;
13490			} else
13491				sb->s_state &= ~EXT2_VALID_FS;
13492			sb->s_mnt_count = 0;
13493			sb->s_lastcheck = time(NULL);
13494			ext2fs_mark_super_dirty(fs);
13495		}
13496	}
13497
13498	e2fsck_write_bitmaps(ctx);
13499
13500	ext2fs_close(fs);
13501	ctx->fs = NULL;
13502	free(ctx->filesystem_name);
13503	free(ctx->journal_name);
13504	e2fsck_free_context(ctx);
13505
13506	return exit_value;
13507}
13508