1 /* vi: set sw=4 ts=4: */
5 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6 * Copyright (C) 2006 Garrett Kajmowicz
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.
21 * linux/fs/recovery and linux/fs/revoke
22 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
24 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
26 * Journal recovery routines for the generic filesystem journaling code;
27 * part of the ext2fs journaling system.
29 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
32 //usage:#define e2fsck_trivial_usage
33 //usage: "[-panyrcdfvstDFSV] [-b superblock] [-B blocksize] "
34 //usage: "[-I inode_buffer_blocks] [-P process_inode_size] "
35 //usage: "[-l|-L bad_blocks_file] [-C fd] [-j external_journal] "
36 //usage: "[-E extended-options] device"
37 //usage:#define e2fsck_full_usage "\n\n"
38 //usage: "Check ext2/ext3 file system\n"
39 //usage: "\n -p Automatic repair (no questions)"
40 //usage: "\n -n Make no changes to the filesystem"
41 //usage: "\n -y Assume 'yes' to all questions"
42 //usage: "\n -c Check for bad blocks and add them to the badblock list"
43 //usage: "\n -f Force checking even if filesystem is marked clean"
44 //usage: "\n -v Verbose"
45 //usage: "\n -b superblock Use alternative superblock"
46 //usage: "\n -B blocksize Force blocksize when looking for superblock"
47 //usage: "\n -j journal Set location of the external journal"
48 //usage: "\n -l file Add to badblocks list"
49 //usage: "\n -L file Set badblocks list"
51 //usage:#define fsck_ext2_trivial_usage NOUSAGE_STR
52 //usage:#define fsck_ext2_full_usage ""
54 //usage:#define fsck_ext3_trivial_usage NOUSAGE_STR
55 //usage:#define fsck_ext3_full_usage ""
57 #include "e2fsck.h" /*Put all of our defines here to clean things up*/
63 * Procedure declarations
66 static void e2fsck_pass1_dupblocks(e2fsck_t ctx
, char *block_buf
);
69 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx
, int fl_bool
);
72 static int e2fsck_process_bad_inode(e2fsck_t ctx
, ext2_ino_t dir
,
73 ext2_ino_t ino
, char *buf
);
76 static int e2fsck_reconnect_file(e2fsck_t ctx
, ext2_ino_t inode
);
77 static errcode_t
e2fsck_expand_directory(e2fsck_t ctx
, ext2_ino_t dir
,
78 int num
, int gauranteed_size
);
79 static ext2_ino_t
e2fsck_get_lost_and_found(e2fsck_t ctx
, int fix
);
80 static errcode_t
e2fsck_adjust_inode_count(e2fsck_t ctx
, ext2_ino_t ino
,
84 static void e2fsck_rehash_directories(e2fsck_t ctx
);
87 static void *e2fsck_allocate_memory(e2fsck_t ctx
, unsigned int size
,
88 const char *description
);
89 static int ask(e2fsck_t ctx
, const char * string
, int def
);
90 static void e2fsck_read_bitmaps(e2fsck_t ctx
);
91 static void preenhalt(e2fsck_t ctx
);
92 static void e2fsck_read_inode(e2fsck_t ctx
, unsigned long ino
,
93 struct ext2_inode
* inode
, const char * proc
);
94 static void e2fsck_write_inode(e2fsck_t ctx
, unsigned long ino
,
95 struct ext2_inode
* inode
, const char * proc
);
96 static blk_t
get_backup_sb(e2fsck_t ctx
, ext2_filsys fs
,
97 const char *name
, io_manager manager
);
100 static void e2fsck_clear_progbar(e2fsck_t ctx
);
101 static int e2fsck_simple_progress(e2fsck_t ctx
, const char *label
,
102 float percent
, unsigned int dpynum
);
106 * problem.h --- e2fsck problem error codes
109 typedef __u32 problem_t
;
111 struct problem_context
{
113 ext2_ino_t ino
, ino2
, dir
;
114 struct ext2_inode
*inode
;
115 struct ext2_dir_entry
*dirent
;
117 e2_blkcnt_t blkcount
;
125 * Function declarations
127 static int fix_problem(e2fsck_t ctx
, problem_t code
, struct problem_context
*pctx
);
128 static int end_problem_latch(e2fsck_t ctx
, int mask
);
129 static int set_latch_flags(int mask
, int setflags
, int clearflags
);
130 static void clear_problem_context(struct problem_context
*ctx
);
133 * Dictionary Abstract Data Type
134 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
136 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
144 * Blurb for inclusion into C++ translation units
147 typedef unsigned long dictcount_t
;
148 #define DICTCOUNT_T_MAX ULONG_MAX
151 * The dictionary is implemented as a red-black tree
154 typedef enum { dnode_red
, dnode_black
} dnode_color_t
;
156 typedef struct dnode_t
{
157 struct dnode_t
*dict_left
;
158 struct dnode_t
*dict_right
;
159 struct dnode_t
*dict_parent
;
160 dnode_color_t dict_color
;
161 const void *dict_key
;
165 typedef int (*dict_comp_t
)(const void *, const void *);
166 typedef void (*dnode_free_t
)(dnode_t
*);
168 typedef struct dict_t
{
169 dnode_t dict_nilnode
;
170 dictcount_t dict_nodecount
;
171 dictcount_t dict_maxcount
;
172 dict_comp_t dict_compare
;
173 dnode_free_t dict_freenode
;
177 typedef void (*dnode_process_t
)(dict_t
*, dnode_t
*, void *);
179 typedef struct dict_load_t
{
180 dict_t
*dict_dictptr
;
181 dnode_t dict_nilnode
;
184 #define dict_count(D) ((D)->dict_nodecount)
185 #define dnode_get(N) ((N)->dict_data)
186 #define dnode_getkey(N) ((N)->dict_key)
191 * Compatibility header file for e2fsck which should be included
192 * instead of linux/jfs.h
194 * Copyright (C) 2000 Stephen C. Tweedie
198 * Pull in the definition of the e2fsck context structure
214 #define K_DEV_JOURNAL 2
216 #define lock_buffer(bh) do {} while (0)
217 #define unlock_buffer(bh) do {} while (0)
218 #define buffer_req(bh) 1
219 #define do_readahead(journal, start) do {} while (0)
221 static e2fsck_t e2fsck_global_ctx
; /* Try your very best not to use this! */
227 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
230 * We use the standard libext2fs portability tricks for inline
234 static kmem_cache_t
* do_cache_create(int len
)
236 kmem_cache_t
*new_cache
;
238 new_cache
= xmalloc(sizeof(*new_cache
));
239 new_cache
->object_length
= len
;
243 static void do_cache_destroy(kmem_cache_t
*cache
)
250 * Dictionary Abstract Data Type
255 * These macros provide short convenient names for structure members,
256 * which are embellished with dict_ prefixes so that they are
257 * properly confined to the documented namespace. It's legal for a
258 * program which uses dict to define, for instance, a macro called ``parent''.
259 * Such a macro would interfere with the dnode_t struct definition.
260 * In general, highly portable and reusable C modules which expose their
261 * structures need to confine structure member names to well-defined spaces.
262 * The resulting identifiers aren't necessarily convenient to use, nor
263 * readable, in the implementation, however!
266 #define left dict_left
267 #define right dict_right
268 #define parent dict_parent
269 #define color dict_color
271 #define data dict_data
273 #define nilnode dict_nilnode
274 #define maxcount dict_maxcount
275 #define compare dict_compare
276 #define dupes dict_dupes
278 #define dict_root(D) ((D)->nilnode.left)
279 #define dict_nil(D) (&(D)->nilnode)
281 static void dnode_free(dnode_t
*node
);
284 * Perform a ``left rotation'' adjustment on the tree. The given node P and
285 * its right child C are rearranged so that the P instead becomes the left
286 * child of C. The left subtree of C is inherited as the new right subtree
287 * for P. The ordering of the keys within the tree is thus preserved.
290 static void rotate_left(dnode_t
*upper
)
292 dnode_t
*lower
, *lowleft
, *upparent
;
294 lower
= upper
->right
;
295 upper
->right
= lowleft
= lower
->left
;
296 lowleft
->parent
= upper
;
298 lower
->parent
= upparent
= upper
->parent
;
300 /* don't need to check for root node here because root->parent is
301 the sentinel nil node, and root->parent->left points back to root */
303 if (upper
== upparent
->left
) {
304 upparent
->left
= lower
;
306 assert (upper
== upparent
->right
);
307 upparent
->right
= lower
;
311 upper
->parent
= lower
;
315 * This operation is the ``mirror'' image of rotate_left. It is
316 * the same procedure, but with left and right interchanged.
319 static void rotate_right(dnode_t
*upper
)
321 dnode_t
*lower
, *lowright
, *upparent
;
324 upper
->left
= lowright
= lower
->right
;
325 lowright
->parent
= upper
;
327 lower
->parent
= upparent
= upper
->parent
;
329 if (upper
== upparent
->right
) {
330 upparent
->right
= lower
;
332 assert (upper
== upparent
->left
);
333 upparent
->left
= lower
;
336 lower
->right
= upper
;
337 upper
->parent
= lower
;
341 * Do a postorder traversal of the tree rooted at the specified
342 * node and free everything under it. Used by dict_free().
345 static void free_nodes(dict_t
*dict
, dnode_t
*node
, dnode_t
*nil
)
349 free_nodes(dict
, node
->left
, nil
);
350 free_nodes(dict
, node
->right
, nil
);
351 dict
->dict_freenode(node
);
355 * Verify that the tree contains the given node. This is done by
356 * traversing all of the nodes and comparing their pointers to the
357 * given pointer. Returns 1 if the node is found, otherwise
358 * returns zero. It is intended for debugging purposes.
361 static int verify_dict_has_node(dnode_t
*nil
, dnode_t
*root
, dnode_t
*node
)
365 || verify_dict_has_node(nil
, root
->left
, node
)
366 || verify_dict_has_node(nil
, root
->right
, node
);
373 * Select a different set of node allocator routines.
376 static void dict_set_allocator(dict_t
*dict
, dnode_free_t fr
)
378 assert(dict_count(dict
) == 0);
379 dict
->dict_freenode
= fr
;
383 * Free all the nodes in the dictionary by using the dictionary's
384 * installed free routine. The dictionary is emptied.
387 static void dict_free_nodes(dict_t
*dict
)
389 dnode_t
*nil
= dict_nil(dict
), *root
= dict_root(dict
);
390 free_nodes(dict
, root
, nil
);
391 dict
->dict_nodecount
= 0;
392 dict
->nilnode
.left
= &dict
->nilnode
;
393 dict
->nilnode
.right
= &dict
->nilnode
;
397 * Initialize a user-supplied dictionary object.
400 static dict_t
*dict_init(dict_t
*dict
, dictcount_t maxcount
, dict_comp_t comp
)
402 dict
->compare
= comp
;
403 dict
->dict_freenode
= dnode_free
;
404 dict
->dict_nodecount
= 0;
405 dict
->maxcount
= maxcount
;
406 dict
->nilnode
.left
= &dict
->nilnode
;
407 dict
->nilnode
.right
= &dict
->nilnode
;
408 dict
->nilnode
.parent
= &dict
->nilnode
;
409 dict
->nilnode
.color
= dnode_black
;
415 * Locate a node in the dictionary having the given key.
416 * If the node is not found, a null a pointer is returned (rather than
417 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
418 * located node is returned.
421 static dnode_t
*dict_lookup(dict_t
*dict
, const void *key
)
423 dnode_t
*root
= dict_root(dict
);
424 dnode_t
*nil
= dict_nil(dict
);
428 /* simple binary search adapted for trees that contain duplicate keys */
430 while (root
!= nil
) {
431 result
= dict
->compare(key
, root
->key
);
437 if (!dict
->dupes
) { /* no duplicates, return match */
439 } else { /* could be dupes, find leftmost one */
443 while (root
!= nil
&& dict
->compare(key
, root
->key
))
445 } while (root
!= nil
);
455 * Insert a node into the dictionary. The node should have been
456 * initialized with a data field. All other fields are ignored.
457 * The behavior is undefined if the user attempts to insert into
458 * a dictionary that is already full (for which the dict_isfull()
459 * function returns true).
462 static void dict_insert(dict_t
*dict
, dnode_t
*node
, const void *key
)
464 dnode_t
*where
= dict_root(dict
), *nil
= dict_nil(dict
);
465 dnode_t
*parent
= nil
, *uncle
, *grandpa
;
470 /* basic binary tree insert */
472 while (where
!= nil
) {
474 result
= dict
->compare(key
, where
->key
);
475 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
476 assert(dict
->dupes
|| result
!= 0);
480 where
= where
->right
;
483 assert(where
== nil
);
488 parent
->right
= node
;
490 node
->parent
= parent
;
494 dict
->dict_nodecount
++;
496 /* red black adjustments */
498 node
->color
= dnode_red
;
500 while (parent
->color
== dnode_red
) {
501 grandpa
= parent
->parent
;
502 if (parent
== grandpa
->left
) {
503 uncle
= grandpa
->right
;
504 if (uncle
->color
== dnode_red
) { /* red parent, red uncle */
505 parent
->color
= dnode_black
;
506 uncle
->color
= dnode_black
;
507 grandpa
->color
= dnode_red
;
509 parent
= grandpa
->parent
;
510 } else { /* red parent, black uncle */
511 if (node
== parent
->right
) {
514 assert (grandpa
== parent
->parent
);
515 /* rotation between parent and child preserves grandpa */
517 parent
->color
= dnode_black
;
518 grandpa
->color
= dnode_red
;
519 rotate_right(grandpa
);
522 } else { /* symmetric cases: parent == parent->parent->right */
523 uncle
= grandpa
->left
;
524 if (uncle
->color
== dnode_red
) {
525 parent
->color
= dnode_black
;
526 uncle
->color
= dnode_black
;
527 grandpa
->color
= dnode_red
;
529 parent
= grandpa
->parent
;
531 if (node
== parent
->left
) {
532 rotate_right(parent
);
534 assert (grandpa
== parent
->parent
);
536 parent
->color
= dnode_black
;
537 grandpa
->color
= dnode_red
;
538 rotate_left(grandpa
);
544 dict_root(dict
)->color
= dnode_black
;
548 * Allocate a node using the dictionary's allocator routine, give it
552 static dnode_t
*dnode_init(dnode_t
*dnode
, void *data
)
555 dnode
->parent
= NULL
;
561 static int dict_alloc_insert(dict_t
*dict
, const void *key
, void *data
)
563 dnode_t
*node
= xmalloc(sizeof(dnode_t
));
565 dnode_init(node
, data
);
566 dict_insert(dict
, node
, key
);
571 * Return the node with the lowest (leftmost) key. If the dictionary is empty
572 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
575 static dnode_t
*dict_first(dict_t
*dict
)
577 dnode_t
*nil
= dict_nil(dict
), *root
= dict_root(dict
), *left
;
580 while ((left
= root
->left
) != nil
)
583 return (root
== nil
) ? NULL
: root
;
587 * Return the given node's successor node---the node which has the
588 * next key in the left to right ordering. If the node has
589 * no successor, a null pointer is returned rather than a pointer to
593 static dnode_t
*dict_next(dict_t
*dict
, dnode_t
*curr
)
595 dnode_t
*nil
= dict_nil(dict
), *parent
, *left
;
597 if (curr
->right
!= nil
) {
599 while ((left
= curr
->left
) != nil
)
604 parent
= curr
->parent
;
606 while (parent
!= nil
&& curr
== parent
->right
) {
608 parent
= curr
->parent
;
611 return (parent
== nil
) ? NULL
: parent
;
615 static void dnode_free(dnode_t
*node
)
635 * dirinfo.c --- maintains the directory information table for e2fsck.
639 * This subroutine is called during pass1 to create a directory info
640 * entry. During pass1, the passed-in parent is 0; it will get filled
643 static void e2fsck_add_dir_info(e2fsck_t ctx
, ext2_ino_t ino
, ext2_ino_t parent
)
645 struct dir_info
*dir
;
649 unsigned long old_size
;
651 if (!ctx
->dir_info
) {
652 ctx
->dir_info_count
= 0;
653 retval
= ext2fs_get_num_dirs(ctx
->fs
, &num_dirs
);
655 num_dirs
= 1024; /* Guess */
656 ctx
->dir_info_size
= num_dirs
+ 10;
657 ctx
->dir_info
= (struct dir_info
*)
658 e2fsck_allocate_memory(ctx
, ctx
->dir_info_size
659 * sizeof (struct dir_info
),
663 if (ctx
->dir_info_count
>= ctx
->dir_info_size
) {
664 old_size
= ctx
->dir_info_size
* sizeof(struct dir_info
);
665 ctx
->dir_info_size
+= 10;
666 retval
= ext2fs_resize_mem(old_size
, ctx
->dir_info_size
*
667 sizeof(struct dir_info
),
670 ctx
->dir_info_size
-= 10;
676 * Normally, add_dir_info is called with each inode in
677 * sequential order; but once in a while (like when pass 3
678 * needs to recreate the root directory or lost+found
679 * directory) it is called out of order. In those cases, we
680 * need to move the dir_info entries down to make room, since
681 * the dir_info array needs to be sorted by inode number for
682 * get_dir_info()'s sake.
684 if (ctx
->dir_info_count
&&
685 ctx
->dir_info
[ctx
->dir_info_count
-1].ino
>= ino
) {
686 for (i
= ctx
->dir_info_count
-1; i
> 0; i
--)
687 if (ctx
->dir_info
[i
-1].ino
< ino
)
689 dir
= &ctx
->dir_info
[i
];
691 for (j
= ctx
->dir_info_count
++; j
> i
; j
--)
692 ctx
->dir_info
[j
] = ctx
->dir_info
[j
-1];
694 dir
= &ctx
->dir_info
[ctx
->dir_info_count
++];
697 dir
->dotdot
= parent
;
698 dir
->parent
= parent
;
702 * get_dir_info() --- given an inode number, try to find the directory
703 * information entry for it.
705 static struct dir_info
*e2fsck_get_dir_info(e2fsck_t ctx
, ext2_ino_t ino
)
710 high
= ctx
->dir_info_count
-1;
713 if (ino
== ctx
->dir_info
[low
].ino
)
714 return &ctx
->dir_info
[low
];
715 if (ino
== ctx
->dir_info
[high
].ino
)
716 return &ctx
->dir_info
[high
];
720 if (mid
== low
|| mid
== high
)
722 if (ino
== ctx
->dir_info
[mid
].ino
)
723 return &ctx
->dir_info
[mid
];
724 if (ino
< ctx
->dir_info
[mid
].ino
)
733 * Free the dir_info structure when it isn't needed any more.
735 static void e2fsck_free_dir_info(e2fsck_t ctx
)
737 ext2fs_free_mem(&ctx
->dir_info
);
738 ctx
->dir_info_size
= 0;
739 ctx
->dir_info_count
= 0;
743 * Return the count of number of directories in the dir_info structure
745 static int e2fsck_get_num_dirinfo(e2fsck_t ctx
)
747 return ctx
->dir_info_count
;
751 * A simple interator function
753 static struct dir_info
*e2fsck_dir_info_iter(e2fsck_t ctx
, int *control
)
755 if (*control
>= ctx
->dir_info_count
)
758 return ctx
->dir_info
+ (*control
)++;
762 * dirinfo.c --- maintains the directory information table for e2fsck.
769 * This subroutine is called during pass1 to create a directory info
770 * entry. During pass1, the passed-in parent is 0; it will get filled
773 static void e2fsck_add_dx_dir(e2fsck_t ctx
, ext2_ino_t ino
, int num_blocks
)
775 struct dx_dir_info
*dir
;
778 unsigned long old_size
;
780 if (!ctx
->dx_dir_info
) {
781 ctx
->dx_dir_info_count
= 0;
782 ctx
->dx_dir_info_size
= 100; /* Guess */
783 ctx
->dx_dir_info
= (struct dx_dir_info
*)
784 e2fsck_allocate_memory(ctx
, ctx
->dx_dir_info_size
785 * sizeof (struct dx_dir_info
),
789 if (ctx
->dx_dir_info_count
>= ctx
->dx_dir_info_size
) {
790 old_size
= ctx
->dx_dir_info_size
* sizeof(struct dx_dir_info
);
791 ctx
->dx_dir_info_size
+= 10;
792 retval
= ext2fs_resize_mem(old_size
, ctx
->dx_dir_info_size
*
793 sizeof(struct dx_dir_info
),
796 ctx
->dx_dir_info_size
-= 10;
802 * Normally, add_dx_dir_info is called with each inode in
803 * sequential order; but once in a while (like when pass 3
804 * needs to recreate the root directory or lost+found
805 * directory) it is called out of order. In those cases, we
806 * need to move the dx_dir_info entries down to make room, since
807 * the dx_dir_info array needs to be sorted by inode number for
808 * get_dx_dir_info()'s sake.
810 if (ctx
->dx_dir_info_count
&&
811 ctx
->dx_dir_info
[ctx
->dx_dir_info_count
-1].ino
>= ino
) {
812 for (i
= ctx
->dx_dir_info_count
-1; i
> 0; i
--)
813 if (ctx
->dx_dir_info
[i
-1].ino
< ino
)
815 dir
= &ctx
->dx_dir_info
[i
];
817 for (j
= ctx
->dx_dir_info_count
++; j
> i
; j
--)
818 ctx
->dx_dir_info
[j
] = ctx
->dx_dir_info
[j
-1];
820 dir
= &ctx
->dx_dir_info
[ctx
->dx_dir_info_count
++];
823 dir
->numblocks
= num_blocks
;
824 dir
->hashversion
= 0;
825 dir
->dx_block
= e2fsck_allocate_memory(ctx
, num_blocks
826 * sizeof (struct dx_dirblock_info
),
827 "dx_block info array");
831 * get_dx_dir_info() --- given an inode number, try to find the directory
832 * information entry for it.
834 static struct dx_dir_info
*e2fsck_get_dx_dir_info(e2fsck_t ctx
, ext2_ino_t ino
)
839 high
= ctx
->dx_dir_info_count
-1;
840 if (!ctx
->dx_dir_info
)
842 if (ino
== ctx
->dx_dir_info
[low
].ino
)
843 return &ctx
->dx_dir_info
[low
];
844 if (ino
== ctx
->dx_dir_info
[high
].ino
)
845 return &ctx
->dx_dir_info
[high
];
849 if (mid
== low
|| mid
== high
)
851 if (ino
== ctx
->dx_dir_info
[mid
].ino
)
852 return &ctx
->dx_dir_info
[mid
];
853 if (ino
< ctx
->dx_dir_info
[mid
].ino
)
862 * Free the dx_dir_info structure when it isn't needed any more.
864 static void e2fsck_free_dx_dir_info(e2fsck_t ctx
)
867 struct dx_dir_info
*dir
;
869 if (ctx
->dx_dir_info
) {
870 dir
= ctx
->dx_dir_info
;
871 for (i
=0; i
< ctx
->dx_dir_info_count
; i
++) {
872 ext2fs_free_mem(&dir
->dx_block
);
874 ext2fs_free_mem(&ctx
->dx_dir_info
);
876 ctx
->dx_dir_info_size
= 0;
877 ctx
->dx_dir_info_count
= 0;
881 * A simple interator function
883 static struct dx_dir_info
*e2fsck_dx_dir_info_iter(e2fsck_t ctx
, int *control
)
885 if (*control
>= ctx
->dx_dir_info_count
)
888 return ctx
->dx_dir_info
+ (*control
)++;
891 #endif /* ENABLE_HTREE */
893 * e2fsck.c - a consistency checker for the new extended file system.
898 * This function allocates an e2fsck context
900 static errcode_t
e2fsck_allocate_context(e2fsck_t
*ret
)
905 retval
= ext2fs_get_mem(sizeof(struct e2fsck_struct
), &context
);
909 memset(context
, 0, sizeof(struct e2fsck_struct
));
911 context
->process_inode_size
= 256;
912 context
->ext_attr_ver
= 2;
918 struct ea_refcount_el
{
927 struct ea_refcount_el
*list
;
930 static void ea_refcount_free(ext2_refcount_t refcount
)
935 ext2fs_free_mem(&refcount
->list
);
936 ext2fs_free_mem(&refcount
);
940 * This function resets an e2fsck context; it is called when e2fsck
941 * needs to be restarted.
943 static errcode_t
e2fsck_reset_context(e2fsck_t ctx
)
946 ctx
->lost_and_found
= 0;
947 ctx
->bad_lost_and_found
= 0;
948 ext2fs_free_inode_bitmap(ctx
->inode_used_map
);
949 ctx
->inode_used_map
= 0;
950 ext2fs_free_inode_bitmap(ctx
->inode_dir_map
);
951 ctx
->inode_dir_map
= 0;
952 ext2fs_free_inode_bitmap(ctx
->inode_reg_map
);
953 ctx
->inode_reg_map
= 0;
954 ext2fs_free_block_bitmap(ctx
->block_found_map
);
955 ctx
->block_found_map
= 0;
956 ext2fs_free_icount(ctx
->inode_link_info
);
957 ctx
->inode_link_info
= 0;
958 if (ctx
->journal_io
) {
959 if (ctx
->fs
&& ctx
->fs
->io
!= ctx
->journal_io
)
960 io_channel_close(ctx
->journal_io
);
964 ext2fs_free_dblist(ctx
->fs
->dblist
);
967 e2fsck_free_dir_info(ctx
);
969 e2fsck_free_dx_dir_info(ctx
);
971 ea_refcount_free(ctx
->refcount
);
973 ea_refcount_free(ctx
->refcount_extra
);
974 ctx
->refcount_extra
= 0;
975 ext2fs_free_block_bitmap(ctx
->block_dup_map
);
976 ctx
->block_dup_map
= 0;
977 ext2fs_free_block_bitmap(ctx
->block_ea_map
);
978 ctx
->block_ea_map
= 0;
979 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
980 ctx
->inode_bad_map
= 0;
981 ext2fs_free_inode_bitmap(ctx
->inode_imagic_map
);
982 ctx
->inode_imagic_map
= 0;
983 ext2fs_u32_list_free(ctx
->dirs_to_hash
);
984 ctx
->dirs_to_hash
= 0;
987 * Clear the array of invalid meta-data flags
989 ext2fs_free_mem(&ctx
->invalid_inode_bitmap_flag
);
990 ext2fs_free_mem(&ctx
->invalid_block_bitmap_flag
);
991 ext2fs_free_mem(&ctx
->invalid_inode_table_flag
);
993 /* Clear statistic counters */
994 ctx
->fs_directory_count
= 0;
995 ctx
->fs_regular_count
= 0;
996 ctx
->fs_blockdev_count
= 0;
997 ctx
->fs_chardev_count
= 0;
998 ctx
->fs_links_count
= 0;
999 ctx
->fs_symlinks_count
= 0;
1000 ctx
->fs_fast_symlinks_count
= 0;
1001 ctx
->fs_fifo_count
= 0;
1002 ctx
->fs_total_count
= 0;
1003 ctx
->fs_sockets_count
= 0;
1004 ctx
->fs_ind_count
= 0;
1005 ctx
->fs_dind_count
= 0;
1006 ctx
->fs_tind_count
= 0;
1007 ctx
->fs_fragmented
= 0;
1008 ctx
->large_files
= 0;
1010 /* Reset the superblock to the user's requested value */
1011 ctx
->superblock
= ctx
->use_superblock
;
1016 static void e2fsck_free_context(e2fsck_t ctx
)
1021 e2fsck_reset_context(ctx
);
1023 ext2fs_free_mem(&ctx
);
1031 * The strategy we use for keeping track of EA refcounts is as
1032 * follows. We keep a sorted array of first EA blocks and its
1033 * reference counts. Once the refcount has dropped to zero, it is
1034 * removed from the array to save memory space. Once the EA block is
1035 * checked, its bit is set in the block_ea_map bitmap.
1039 static errcode_t
ea_refcount_create(int size
, ext2_refcount_t
*ret
)
1041 ext2_refcount_t refcount
;
1045 retval
= ext2fs_get_mem(sizeof(struct ea_refcount
), &refcount
);
1048 memset(refcount
, 0, sizeof(struct ea_refcount
));
1052 refcount
->size
= size
;
1053 bytes
= (size_t) (size
* sizeof(struct ea_refcount_el
));
1055 printf("Refcount allocated %d entries, %d bytes.\n",
1056 refcount
->size
, bytes
);
1058 retval
= ext2fs_get_mem(bytes
, &refcount
->list
);
1061 memset(refcount
->list
, 0, bytes
);
1063 refcount
->count
= 0;
1064 refcount
->cursor
= 0;
1070 ea_refcount_free(refcount
);
1075 * collapse_refcount() --- go through the refcount array, and get rid
1076 * of any count == zero entries
1078 static void refcount_collapse(ext2_refcount_t refcount
)
1081 struct ea_refcount_el
*list
;
1083 list
= refcount
->list
;
1084 for (i
= 0, j
= 0; i
< refcount
->count
; i
++) {
1085 if (list
[i
].ea_count
) {
1091 #if defined(DEBUG) || defined(TEST_PROGRAM)
1092 printf("Refcount_collapse: size was %d, now %d\n",
1093 refcount
->count
, j
);
1095 refcount
->count
= j
;
1100 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1101 * specified position.
1103 static struct ea_refcount_el
*insert_refcount_el(ext2_refcount_t refcount
,
1106 struct ea_refcount_el
*el
;
1111 if (refcount
->count
>= refcount
->size
) {
1112 new_size
= refcount
->size
+ 100;
1114 printf("Reallocating refcount %d entries...\n", new_size
);
1116 retval
= ext2fs_resize_mem((size_t) refcount
->size
*
1117 sizeof(struct ea_refcount_el
),
1119 sizeof(struct ea_refcount_el
),
1123 refcount
->size
= new_size
;
1125 num
= (int) refcount
->count
- pos
;
1127 return 0; /* should never happen */
1129 memmove(&refcount
->list
[pos
+1], &refcount
->list
[pos
],
1130 sizeof(struct ea_refcount_el
) * num
);
1133 el
= &refcount
->list
[pos
];
1141 * get_refcount_el() --- given an block number, try to find refcount
1142 * information in the sorted list. If the create flag is set,
1143 * and we can't find an entry, create one in the sorted list.
1145 static struct ea_refcount_el
*get_refcount_el(ext2_refcount_t refcount
,
1146 blk_t blk
, int create
)
1150 blk_t lowval
, highval
;
1152 if (!refcount
|| !refcount
->list
)
1156 high
= (int) refcount
->count
-1;
1157 if (create
&& ((refcount
->count
== 0) ||
1158 (blk
> refcount
->list
[high
].ea_blk
))) {
1159 if (refcount
->count
>= refcount
->size
)
1160 refcount_collapse(refcount
);
1162 return insert_refcount_el(refcount
, blk
,
1163 (unsigned) refcount
->count
);
1165 if (refcount
->count
== 0)
1168 if (refcount
->cursor
>= refcount
->count
)
1169 refcount
->cursor
= 0;
1170 if (blk
== refcount
->list
[refcount
->cursor
].ea_blk
)
1171 return &refcount
->list
[refcount
->cursor
++];
1173 printf("Non-cursor get_refcount_el: %u\n", blk
);
1175 while (low
<= high
) {
1179 /* Interpolate for efficiency */
1180 lowval
= refcount
->list
[low
].ea_blk
;
1181 highval
= refcount
->list
[high
].ea_blk
;
1185 else if (blk
> highval
)
1188 range
= ((float) (blk
- lowval
)) /
1190 mid
= low
+ ((int) (range
* (high
-low
)));
1193 if (blk
== refcount
->list
[mid
].ea_blk
) {
1194 refcount
->cursor
= mid
+1;
1195 return &refcount
->list
[mid
];
1197 if (blk
< refcount
->list
[mid
].ea_blk
)
1203 * If we need to create a new entry, it should be right at
1204 * low (where high will be left at low-1).
1207 if (refcount
->count
>= refcount
->size
) {
1208 refcount_collapse(refcount
);
1209 if (refcount
->count
< refcount
->size
)
1212 return insert_refcount_el(refcount
, blk
, low
);
1218 ea_refcount_increment(ext2_refcount_t refcount
, blk_t blk
, int *ret
)
1220 struct ea_refcount_el
*el
;
1222 el
= get_refcount_el(refcount
, blk
, 1);
1224 return EXT2_ET_NO_MEMORY
;
1228 *ret
= el
->ea_count
;
1233 ea_refcount_decrement(ext2_refcount_t refcount
, blk_t blk
, int *ret
)
1235 struct ea_refcount_el
*el
;
1237 el
= get_refcount_el(refcount
, blk
, 0);
1238 if (!el
|| el
->ea_count
== 0)
1239 return EXT2_ET_INVALID_ARGUMENT
;
1244 *ret
= el
->ea_count
;
1249 ea_refcount_store(ext2_refcount_t refcount
, blk_t blk
, int count
)
1251 struct ea_refcount_el
*el
;
1254 * Get the refcount element
1256 el
= get_refcount_el(refcount
, blk
, count
? 1 : 0);
1258 return count
? EXT2_ET_NO_MEMORY
: 0;
1259 el
->ea_count
= count
;
1263 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount
)
1265 refcount
->cursor
= 0;
1269 static blk_t
ea_refcount_intr_next(ext2_refcount_t refcount
, int *ret
)
1271 struct ea_refcount_el
*list
;
1274 if (refcount
->cursor
>= refcount
->count
)
1276 list
= refcount
->list
;
1277 if (list
[refcount
->cursor
].ea_count
) {
1279 *ret
= list
[refcount
->cursor
].ea_count
;
1280 return list
[refcount
->cursor
++].ea_blk
;
1288 * ehandler.c --- handle bad block errors which come up during the
1289 * course of an e2fsck session.
1293 static const char *operation
;
1296 e2fsck_handle_read_error(io_channel channel
, unsigned long block
, int count
,
1297 void *data
, size_t size
FSCK_ATTR((unused
)),
1298 int actual
FSCK_ATTR((unused
)), errcode_t error
)
1302 ext2_filsys fs
= (ext2_filsys
) channel
->app_data
;
1305 ctx
= (e2fsck_t
) fs
->priv_data
;
1308 * If more than one block was read, try reading each block
1309 * separately. We could use the actual bytes read to figure
1310 * out where to start, but we don't bother.
1314 for (i
=0; i
< count
; i
++, p
+= channel
->block_size
, block
++) {
1315 error
= io_channel_read_blk(channel
, block
,
1323 printf(_("Error reading block %lu (%s) while %s. "), block
,
1324 error_message(error
), operation
);
1326 printf(_("Error reading block %lu (%s). "), block
,
1327 error_message(error
));
1329 if (ask(ctx
, _("Ignore error"), 1)) {
1330 if (ask(ctx
, _("Force rewrite"), 1))
1331 io_channel_write_blk(channel
, block
, 1, data
);
1339 e2fsck_handle_write_error(io_channel channel
, unsigned long block
, int count
,
1340 const void *data
, size_t size
FSCK_ATTR((unused
)),
1341 int actual
FSCK_ATTR((unused
)), errcode_t error
)
1345 ext2_filsys fs
= (ext2_filsys
) channel
->app_data
;
1348 ctx
= (e2fsck_t
) fs
->priv_data
;
1351 * If more than one block was written, try writing each block
1352 * separately. We could use the actual bytes read to figure
1353 * out where to start, but we don't bother.
1356 p
= (const char *) data
;
1357 for (i
=0; i
< count
; i
++, p
+= channel
->block_size
, block
++) {
1358 error
= io_channel_write_blk(channel
, block
,
1367 printf(_("Error writing block %lu (%s) while %s. "), block
,
1368 error_message(error
), operation
);
1370 printf(_("Error writing block %lu (%s). "), block
,
1371 error_message(error
));
1373 if (ask(ctx
, _("Ignore error"), 1))
1379 static const char *ehandler_operation(const char *op
)
1381 const char *ret
= operation
;
1387 static void ehandler_init(io_channel channel
)
1389 channel
->read_error
= e2fsck_handle_read_error
;
1390 channel
->write_error
= e2fsck_handle_write_error
;
1394 * journal.c --- code for handling the "ext3" journal
1396 * Copyright (C) 2000 Andreas Dilger
1397 * Copyright (C) 2000 Theodore Ts'o
1399 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1400 * Copyright (C) 1999 Red Hat Software
1402 * This file may be redistributed under the terms of the
1403 * GNU General Public License version 2 or at your discretion
1404 * any later version.
1408 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1409 * This creates a larger static binary, and a smaller binary using
1410 * shared libraries. It's also probably slightly less CPU-efficient,
1411 * which is why it's not on by default. But, it's a good way of
1412 * testing the functions in inode_io.c and fileio.c.
1416 /* Kernel compatibility functions for handling the journal. These allow us
1417 * to use the recovery.c file virtually unchanged from the kernel, so we
1418 * don't have to do much to keep kernel and user recovery in sync.
1420 static int journal_bmap(journal_t
*journal
, blk_t block
, unsigned long *phys
)
1426 struct inode
*inode
= journal
->j_inode
;
1435 retval
= ext2fs_bmap(inode
->i_ctx
->fs
, inode
->i_ino
,
1436 &inode
->i_ext2
, NULL
, 0, block
, &pblk
);
1442 static struct buffer_head
*getblk(kdev_t kdev
, blk_t blocknr
, int blocksize
)
1444 struct buffer_head
*bh
;
1446 bh
= e2fsck_allocate_memory(kdev
->k_ctx
, sizeof(*bh
), "block buffer");
1450 bh
->b_ctx
= kdev
->k_ctx
;
1451 if (kdev
->k_dev
== K_DEV_FS
)
1452 bh
->b_io
= kdev
->k_ctx
->fs
->io
;
1454 bh
->b_io
= kdev
->k_ctx
->journal_io
;
1455 bh
->b_size
= blocksize
;
1456 bh
->b_blocknr
= blocknr
;
1461 static void sync_blockdev(kdev_t kdev
)
1465 if (kdev
->k_dev
== K_DEV_FS
)
1466 io
= kdev
->k_ctx
->fs
->io
;
1468 io
= kdev
->k_ctx
->journal_io
;
1470 io_channel_flush(io
);
1473 static void ll_rw_block(int rw
, int nr
, struct buffer_head
*bhp
[])
1476 struct buffer_head
*bh
;
1478 for (; nr
> 0; --nr
) {
1480 if (rw
== READ
&& !bh
->b_uptodate
) {
1481 retval
= io_channel_read_blk(bh
->b_io
,
1485 bb_error_msg("while reading block %lu",
1486 (unsigned long) bh
->b_blocknr
);
1491 } else if (rw
== WRITE
&& bh
->b_dirty
) {
1492 retval
= io_channel_write_blk(bh
->b_io
,
1496 bb_error_msg("while writing block %lu",
1497 (unsigned long) bh
->b_blocknr
);
1507 static void mark_buffer_dirty(struct buffer_head
*bh
)
1512 static inline void mark_buffer_clean(struct buffer_head
* bh
)
1517 static void brelse(struct buffer_head
*bh
)
1520 ll_rw_block(WRITE
, 1, &bh
);
1521 ext2fs_free_mem(&bh
);
1524 static int buffer_uptodate(struct buffer_head
*bh
)
1526 return bh
->b_uptodate
;
1529 static inline void mark_buffer_uptodate(struct buffer_head
*bh
, int val
)
1531 bh
->b_uptodate
= val
;
1534 static void wait_on_buffer(struct buffer_head
*bh
)
1536 if (!bh
->b_uptodate
)
1537 ll_rw_block(READ
, 1, &bh
);
1541 static void e2fsck_clear_recover(e2fsck_t ctx
, int error
)
1543 ctx
->fs
->super
->s_feature_incompat
&= ~EXT3_FEATURE_INCOMPAT_RECOVER
;
1545 /* if we had an error doing journal recovery, we need a full fsck */
1547 ctx
->fs
->super
->s_state
&= ~EXT2_VALID_FS
;
1548 ext2fs_mark_super_dirty(ctx
->fs
);
1551 static errcode_t
e2fsck_get_journal(e2fsck_t ctx
, journal_t
**ret_journal
)
1553 struct ext2_super_block
*sb
= ctx
->fs
->super
;
1554 struct ext2_super_block jsuper
;
1555 struct problem_context pctx
;
1556 struct buffer_head
*bh
;
1557 struct inode
*j_inode
= NULL
;
1558 struct kdev_s
*dev_fs
= NULL
, *dev_journal
;
1559 const char *journal_name
= NULL
;
1560 journal_t
*journal
= NULL
;
1561 errcode_t retval
= 0;
1562 io_manager io_ptr
= 0;
1563 unsigned long start
= 0;
1565 int ext_journal
= 0;
1566 int tried_backup_jnl
= 0;
1569 clear_problem_context(&pctx
);
1571 journal
= e2fsck_allocate_memory(ctx
, sizeof(journal_t
), "journal");
1573 return EXT2_ET_NO_MEMORY
;
1576 dev_fs
= e2fsck_allocate_memory(ctx
, 2*sizeof(struct kdev_s
), "kdev");
1578 retval
= EXT2_ET_NO_MEMORY
;
1581 dev_journal
= dev_fs
+1;
1583 dev_fs
->k_ctx
= dev_journal
->k_ctx
= ctx
;
1584 dev_fs
->k_dev
= K_DEV_FS
;
1585 dev_journal
->k_dev
= K_DEV_JOURNAL
;
1587 journal
->j_dev
= dev_journal
;
1588 journal
->j_fs_dev
= dev_fs
;
1589 journal
->j_inode
= NULL
;
1590 journal
->j_blocksize
= ctx
->fs
->blocksize
;
1592 if (uuid_is_null(sb
->s_journal_uuid
)) {
1593 if (!sb
->s_journal_inum
)
1594 return EXT2_ET_BAD_INODE_NUM
;
1595 j_inode
= e2fsck_allocate_memory(ctx
, sizeof(*j_inode
),
1598 retval
= EXT2_ET_NO_MEMORY
;
1602 j_inode
->i_ctx
= ctx
;
1603 j_inode
->i_ino
= sb
->s_journal_inum
;
1605 if ((retval
= ext2fs_read_inode(ctx
->fs
,
1607 &j_inode
->i_ext2
))) {
1609 if (sb
->s_jnl_backup_type
!= EXT3_JNL_BACKUP_BLOCKS
||
1612 memset(&j_inode
->i_ext2
, 0, sizeof(struct ext2_inode
));
1613 memcpy(&j_inode
->i_ext2
.i_block
[0], sb
->s_jnl_blocks
,
1615 j_inode
->i_ext2
.i_size
= sb
->s_jnl_blocks
[16];
1616 j_inode
->i_ext2
.i_links_count
= 1;
1617 j_inode
->i_ext2
.i_mode
= LINUX_S_IFREG
| 0600;
1620 if (!j_inode
->i_ext2
.i_links_count
||
1621 !LINUX_S_ISREG(j_inode
->i_ext2
.i_mode
)) {
1622 retval
= EXT2_ET_NO_JOURNAL
;
1623 goto try_backup_journal
;
1625 if (j_inode
->i_ext2
.i_size
/ journal
->j_blocksize
<
1626 JFS_MIN_JOURNAL_BLOCKS
) {
1627 retval
= EXT2_ET_JOURNAL_TOO_SMALL
;
1628 goto try_backup_journal
;
1630 for (i
=0; i
< EXT2_N_BLOCKS
; i
++) {
1631 blk
= j_inode
->i_ext2
.i_block
[i
];
1633 if (i
< EXT2_NDIR_BLOCKS
) {
1634 retval
= EXT2_ET_JOURNAL_TOO_SMALL
;
1635 goto try_backup_journal
;
1639 if (blk
< sb
->s_first_data_block
||
1640 blk
>= sb
->s_blocks_count
) {
1641 retval
= EXT2_ET_BAD_BLOCK_NUM
;
1642 goto try_backup_journal
;
1645 journal
->j_maxlen
= j_inode
->i_ext2
.i_size
/ journal
->j_blocksize
;
1648 retval
= ext2fs_inode_io_intern2(ctx
->fs
, sb
->s_journal_inum
,
1654 io_ptr
= inode_io_manager
;
1656 journal
->j_inode
= j_inode
;
1657 ctx
->journal_io
= ctx
->fs
->io
;
1658 if ((retval
= journal_bmap(journal
, 0, &start
)) != 0)
1663 if (!ctx
->journal_name
) {
1666 unparse_uuid(sb
->s_journal_uuid
, uuid
);
1667 ctx
->journal_name
= get_devname_from_uuid(uuid
);
1668 if (!ctx
->journal_name
)
1669 ctx
->journal_name
= get_devname_from_device(sb
->s_journal_dev
);
1671 journal_name
= ctx
->journal_name
;
1673 if (!journal_name
) {
1674 fix_problem(ctx
, PR_0_CANT_FIND_JOURNAL
, &pctx
);
1675 return EXT2_ET_LOAD_EXT_JOURNAL
;
1678 io_ptr
= unix_io_manager
;
1681 #ifndef USE_INODE_IO
1684 retval
= io_ptr
->open(journal_name
, IO_FLAG_RW
,
1689 io_channel_set_blksize(ctx
->journal_io
, ctx
->fs
->blocksize
);
1692 if (ctx
->fs
->blocksize
== 1024)
1694 bh
= getblk(dev_journal
, start
, ctx
->fs
->blocksize
);
1696 retval
= EXT2_ET_NO_MEMORY
;
1699 ll_rw_block(READ
, 1, &bh
);
1700 if ((retval
= bh
->b_err
) != 0)
1702 memcpy(&jsuper
, start
? bh
->b_data
: bh
->b_data
+ 1024,
1706 if (jsuper
.s_magic
== ext2fs_swab16(EXT2_SUPER_MAGIC
))
1707 ext2fs_swap_super(&jsuper
);
1709 if (jsuper
.s_magic
!= EXT2_SUPER_MAGIC
||
1710 !(jsuper
.s_feature_incompat
& EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
)) {
1711 fix_problem(ctx
, PR_0_EXT_JOURNAL_BAD_SUPER
, &pctx
);
1712 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
1715 /* Make sure the journal UUID is correct */
1716 if (memcmp(jsuper
.s_uuid
, ctx
->fs
->super
->s_journal_uuid
,
1717 sizeof(jsuper
.s_uuid
))) {
1718 fix_problem(ctx
, PR_0_JOURNAL_BAD_UUID
, &pctx
);
1719 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
1723 journal
->j_maxlen
= jsuper
.s_blocks_count
;
1727 if (!(bh
= getblk(dev_journal
, start
, journal
->j_blocksize
))) {
1728 retval
= EXT2_ET_NO_MEMORY
;
1732 journal
->j_sb_buffer
= bh
;
1733 journal
->j_superblock
= (journal_superblock_t
*)bh
->b_data
;
1736 ext2fs_free_mem(&j_inode
);
1739 *ret_journal
= journal
;
1743 ext2fs_free_mem(&dev_fs
);
1744 ext2fs_free_mem(&j_inode
);
1745 ext2fs_free_mem(&journal
);
1749 static errcode_t
e2fsck_journal_fix_bad_inode(e2fsck_t ctx
,
1750 struct problem_context
*pctx
)
1752 struct ext2_super_block
*sb
= ctx
->fs
->super
;
1753 int recover
= ctx
->fs
->super
->s_feature_incompat
&
1754 EXT3_FEATURE_INCOMPAT_RECOVER
;
1755 int has_journal
= ctx
->fs
->super
->s_feature_compat
&
1756 EXT3_FEATURE_COMPAT_HAS_JOURNAL
;
1758 if (has_journal
|| sb
->s_journal_inum
) {
1759 /* The journal inode is bogus, remove and force full fsck */
1760 pctx
->ino
= sb
->s_journal_inum
;
1761 if (fix_problem(ctx
, PR_0_JOURNAL_BAD_INODE
, pctx
)) {
1762 if (has_journal
&& sb
->s_journal_inum
)
1763 printf("*** ext3 journal has been deleted - "
1764 "filesystem is now ext2 only ***\n\n");
1765 sb
->s_feature_compat
&= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL
;
1766 sb
->s_journal_inum
= 0;
1767 ctx
->flags
|= E2F_FLAG_JOURNAL_INODE
; /* FIXME: todo */
1768 e2fsck_clear_recover(ctx
, 1);
1771 return EXT2_ET_BAD_INODE_NUM
;
1772 } else if (recover
) {
1773 if (fix_problem(ctx
, PR_0_JOURNAL_RECOVER_SET
, pctx
)) {
1774 e2fsck_clear_recover(ctx
, 1);
1777 return EXT2_ET_UNSUPP_FEATURE
;
1782 #define V1_SB_SIZE 0x0024
1783 static void clear_v2_journal_fields(journal_t
*journal
)
1785 e2fsck_t ctx
= journal
->j_dev
->k_ctx
;
1786 struct problem_context pctx
;
1788 clear_problem_context(&pctx
);
1790 if (!fix_problem(ctx
, PR_0_CLEAR_V2_JOURNAL
, &pctx
))
1793 memset(((char *) journal
->j_superblock
) + V1_SB_SIZE
, 0,
1794 ctx
->fs
->blocksize
-V1_SB_SIZE
);
1795 mark_buffer_dirty(journal
->j_sb_buffer
);
1799 static errcode_t
e2fsck_journal_load(journal_t
*journal
)
1801 e2fsck_t ctx
= journal
->j_dev
->k_ctx
;
1802 journal_superblock_t
*jsb
;
1803 struct buffer_head
*jbh
= journal
->j_sb_buffer
;
1804 struct problem_context pctx
;
1806 clear_problem_context(&pctx
);
1808 ll_rw_block(READ
, 1, &jbh
);
1810 bb_error_msg(_("reading journal superblock"));
1814 jsb
= journal
->j_superblock
;
1815 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1816 if (jsb
->s_header
.h_magic
!= htonl(JFS_MAGIC_NUMBER
))
1817 return e2fsck_journal_fix_bad_inode(ctx
, &pctx
);
1819 switch (ntohl(jsb
->s_header
.h_blocktype
)) {
1820 case JFS_SUPERBLOCK_V1
:
1821 journal
->j_format_version
= 1;
1822 if (jsb
->s_feature_compat
||
1823 jsb
->s_feature_incompat
||
1824 jsb
->s_feature_ro_compat
||
1826 clear_v2_journal_fields(journal
);
1829 case JFS_SUPERBLOCK_V2
:
1830 journal
->j_format_version
= 2;
1831 if (ntohl(jsb
->s_nr_users
) > 1 &&
1832 uuid_is_null(ctx
->fs
->super
->s_journal_uuid
))
1833 clear_v2_journal_fields(journal
);
1834 if (ntohl(jsb
->s_nr_users
) > 1) {
1835 fix_problem(ctx
, PR_0_JOURNAL_UNSUPP_MULTIFS
, &pctx
);
1836 return EXT2_ET_JOURNAL_UNSUPP_VERSION
;
1841 * These should never appear in a journal super block, so if
1842 * they do, the journal is badly corrupted.
1844 case JFS_DESCRIPTOR_BLOCK
:
1845 case JFS_COMMIT_BLOCK
:
1846 case JFS_REVOKE_BLOCK
:
1847 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1849 /* If we don't understand the superblock major type, but there
1850 * is a magic number, then it is likely to be a new format we
1851 * just don't understand, so leave it alone. */
1853 return EXT2_ET_JOURNAL_UNSUPP_VERSION
;
1856 if (JFS_HAS_INCOMPAT_FEATURE(journal
, ~JFS_KNOWN_INCOMPAT_FEATURES
))
1857 return EXT2_ET_UNSUPP_FEATURE
;
1859 if (JFS_HAS_RO_COMPAT_FEATURE(journal
, ~JFS_KNOWN_ROCOMPAT_FEATURES
))
1860 return EXT2_ET_RO_UNSUPP_FEATURE
;
1862 /* We have now checked whether we know enough about the journal
1863 * format to be able to proceed safely, so any other checks that
1864 * fail we should attempt to recover from. */
1865 if (jsb
->s_blocksize
!= htonl(journal
->j_blocksize
)) {
1866 bb_error_msg(_("%s: no valid journal superblock found"),
1868 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1871 if (ntohl(jsb
->s_maxlen
) < journal
->j_maxlen
)
1872 journal
->j_maxlen
= ntohl(jsb
->s_maxlen
);
1873 else if (ntohl(jsb
->s_maxlen
) > journal
->j_maxlen
) {
1874 bb_error_msg(_("%s: journal too short"),
1876 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1879 journal
->j_tail_sequence
= ntohl(jsb
->s_sequence
);
1880 journal
->j_transaction_sequence
= journal
->j_tail_sequence
;
1881 journal
->j_tail
= ntohl(jsb
->s_start
);
1882 journal
->j_first
= ntohl(jsb
->s_first
);
1883 journal
->j_last
= ntohl(jsb
->s_maxlen
);
1888 static void e2fsck_journal_reset_super(e2fsck_t ctx
, journal_superblock_t
*jsb
,
1899 /* Leave a valid existing V1 superblock signature alone.
1900 * Anything unrecognizable we overwrite with a new V2
1903 if (jsb
->s_header
.h_magic
!= htonl(JFS_MAGIC_NUMBER
) ||
1904 jsb
->s_header
.h_blocktype
!= htonl(JFS_SUPERBLOCK_V1
)) {
1905 jsb
->s_header
.h_magic
= htonl(JFS_MAGIC_NUMBER
);
1906 jsb
->s_header
.h_blocktype
= htonl(JFS_SUPERBLOCK_V2
);
1909 /* Zero out everything else beyond the superblock header */
1911 p
= ((char *) jsb
) + sizeof(journal_header_t
);
1912 memset (p
, 0, ctx
->fs
->blocksize
-sizeof(journal_header_t
));
1914 jsb
->s_blocksize
= htonl(ctx
->fs
->blocksize
);
1915 jsb
->s_maxlen
= htonl(journal
->j_maxlen
);
1916 jsb
->s_first
= htonl(1);
1918 /* Initialize the journal sequence number so that there is "no"
1919 * chance we will find old "valid" transactions in the journal.
1920 * This avoids the need to zero the whole journal (slow to do,
1921 * and risky when we are just recovering the filesystem).
1923 generate_uuid(u
.uuid
);
1924 for (i
= 0; i
< 4; i
++)
1925 new_seq
^= u
.val
[i
];
1926 jsb
->s_sequence
= htonl(new_seq
);
1928 mark_buffer_dirty(journal
->j_sb_buffer
);
1929 ll_rw_block(WRITE
, 1, &journal
->j_sb_buffer
);
1932 static errcode_t
e2fsck_journal_fix_corrupt_super(e2fsck_t ctx
,
1934 struct problem_context
*pctx
)
1936 struct ext2_super_block
*sb
= ctx
->fs
->super
;
1937 int recover
= ctx
->fs
->super
->s_feature_incompat
&
1938 EXT3_FEATURE_INCOMPAT_RECOVER
;
1940 if (sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
) {
1941 if (fix_problem(ctx
, PR_0_JOURNAL_BAD_SUPER
, pctx
)) {
1942 e2fsck_journal_reset_super(ctx
, journal
->j_superblock
,
1944 journal
->j_transaction_sequence
= 1;
1945 e2fsck_clear_recover(ctx
, recover
);
1948 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1949 } else if (e2fsck_journal_fix_bad_inode(ctx
, pctx
))
1950 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1955 static void e2fsck_journal_release(e2fsck_t ctx
, journal_t
*journal
,
1956 int reset
, int drop
)
1958 journal_superblock_t
*jsb
;
1961 mark_buffer_clean(journal
->j_sb_buffer
);
1962 else if (!(ctx
->options
& E2F_OPT_READONLY
)) {
1963 jsb
= journal
->j_superblock
;
1964 jsb
->s_sequence
= htonl(journal
->j_transaction_sequence
);
1966 jsb
->s_start
= 0; /* this marks the journal as empty */
1967 mark_buffer_dirty(journal
->j_sb_buffer
);
1969 brelse(journal
->j_sb_buffer
);
1971 if (ctx
->journal_io
) {
1972 if (ctx
->fs
&& ctx
->fs
->io
!= ctx
->journal_io
)
1973 io_channel_close(ctx
->journal_io
);
1974 ctx
->journal_io
= 0;
1977 #ifndef USE_INODE_IO
1978 ext2fs_free_mem(&journal
->j_inode
);
1980 ext2fs_free_mem(&journal
->j_fs_dev
);
1981 ext2fs_free_mem(&journal
);
1985 * This function makes sure that the superblock fields regarding the
1986 * journal are consistent.
1988 static int e2fsck_check_ext3_journal(e2fsck_t ctx
)
1990 struct ext2_super_block
*sb
= ctx
->fs
->super
;
1992 int recover
= ctx
->fs
->super
->s_feature_incompat
&
1993 EXT3_FEATURE_INCOMPAT_RECOVER
;
1994 struct problem_context pctx
;
1996 int reset
= 0, force_fsck
= 0;
1999 /* If we don't have any journal features, don't do anything more */
2000 if (!(sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
) &&
2001 !recover
&& sb
->s_journal_inum
== 0 && sb
->s_journal_dev
== 0 &&
2002 uuid_is_null(sb
->s_journal_uuid
))
2005 clear_problem_context(&pctx
);
2006 pctx
.num
= sb
->s_journal_inum
;
2008 retval
= e2fsck_get_journal(ctx
, &journal
);
2010 if ((retval
== EXT2_ET_BAD_INODE_NUM
) ||
2011 (retval
== EXT2_ET_BAD_BLOCK_NUM
) ||
2012 (retval
== EXT2_ET_JOURNAL_TOO_SMALL
) ||
2013 (retval
== EXT2_ET_NO_JOURNAL
))
2014 return e2fsck_journal_fix_bad_inode(ctx
, &pctx
);
2018 retval
= e2fsck_journal_load(journal
);
2020 if ((retval
== EXT2_ET_CORRUPT_SUPERBLOCK
) ||
2021 ((retval
== EXT2_ET_UNSUPP_FEATURE
) &&
2022 (!fix_problem(ctx
, PR_0_JOURNAL_UNSUPP_INCOMPAT
,
2024 ((retval
== EXT2_ET_RO_UNSUPP_FEATURE
) &&
2025 (!fix_problem(ctx
, PR_0_JOURNAL_UNSUPP_ROCOMPAT
,
2027 ((retval
== EXT2_ET_JOURNAL_UNSUPP_VERSION
) &&
2028 (!fix_problem(ctx
, PR_0_JOURNAL_UNSUPP_VERSION
, &pctx
))))
2029 retval
= e2fsck_journal_fix_corrupt_super(ctx
, journal
,
2031 e2fsck_journal_release(ctx
, journal
, 0, 1);
2036 * We want to make the flags consistent here. We will not leave with
2037 * needs_recovery set but has_journal clear. We can't get in a loop
2038 * with -y, -n, or -p, only if a user isn't making up their mind.
2041 if (!(sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
)) {
2042 recover
= sb
->s_feature_incompat
& EXT3_FEATURE_INCOMPAT_RECOVER
;
2044 if (fix_problem(ctx
, PR_0_JOURNAL_HAS_JOURNAL
, &pctx
)) {
2046 !fix_problem(ctx
, PR_0_JOURNAL_RECOVER_SET
, &pctx
))
2047 goto no_has_journal
;
2049 * Need a full fsck if we are releasing a
2050 * journal stored on a reserved inode.
2052 force_fsck
= recover
||
2053 (sb
->s_journal_inum
< EXT2_FIRST_INODE(sb
));
2054 /* Clear all of the journal fields */
2055 sb
->s_journal_inum
= 0;
2056 sb
->s_journal_dev
= 0;
2057 memset(sb
->s_journal_uuid
, 0,
2058 sizeof(sb
->s_journal_uuid
));
2059 e2fsck_clear_recover(ctx
, force_fsck
);
2060 } else if (!(ctx
->options
& E2F_OPT_READONLY
)) {
2061 sb
->s_feature_compat
|= EXT3_FEATURE_COMPAT_HAS_JOURNAL
;
2062 ext2fs_mark_super_dirty(ctx
->fs
);
2066 if (sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
&&
2067 !(sb
->s_feature_incompat
& EXT3_FEATURE_INCOMPAT_RECOVER
) &&
2068 journal
->j_superblock
->s_start
!= 0) {
2069 /* Print status information */
2070 fix_problem(ctx
, PR_0_JOURNAL_RECOVERY_CLEAR
, &pctx
);
2071 if (ctx
->superblock
)
2072 problem
= PR_0_JOURNAL_RUN_DEFAULT
;
2074 problem
= PR_0_JOURNAL_RUN
;
2075 if (fix_problem(ctx
, problem
, &pctx
)) {
2076 ctx
->options
|= E2F_OPT_FORCE
;
2077 sb
->s_feature_incompat
|=
2078 EXT3_FEATURE_INCOMPAT_RECOVER
;
2079 ext2fs_mark_super_dirty(ctx
->fs
);
2080 } else if (fix_problem(ctx
,
2081 PR_0_JOURNAL_RESET_JOURNAL
, &pctx
)) {
2083 sb
->s_state
&= ~EXT2_VALID_FS
;
2084 ext2fs_mark_super_dirty(ctx
->fs
);
2087 * If the user answers no to the above question, we
2088 * ignore the fact that journal apparently has data;
2089 * accidentally replaying over valid data would be far
2090 * worse than skipping a questionable recovery.
2092 * XXX should we abort with a fatal error here? What
2093 * will the ext3 kernel code do if a filesystem with
2094 * !NEEDS_RECOVERY but with a non-zero
2095 * journal->j_superblock->s_start is mounted?
2099 e2fsck_journal_release(ctx
, journal
, reset
, 0);
2103 static errcode_t
recover_ext3_journal(e2fsck_t ctx
)
2108 journal_init_revoke_caches();
2109 retval
= e2fsck_get_journal(ctx
, &journal
);
2113 retval
= e2fsck_journal_load(journal
);
2117 retval
= journal_init_revoke(journal
, 1024);
2121 retval
= -journal_recover(journal
);
2125 if (journal
->j_superblock
->s_errno
) {
2126 ctx
->fs
->super
->s_state
|= EXT2_ERROR_FS
;
2127 ext2fs_mark_super_dirty(ctx
->fs
);
2128 journal
->j_superblock
->s_errno
= 0;
2129 mark_buffer_dirty(journal
->j_sb_buffer
);
2133 journal_destroy_revoke(journal
);
2134 journal_destroy_revoke_caches();
2135 e2fsck_journal_release(ctx
, journal
, 1, 0);
2139 static int e2fsck_run_ext3_journal(e2fsck_t ctx
)
2141 io_manager io_ptr
= ctx
->fs
->io
->manager
;
2142 int blocksize
= ctx
->fs
->blocksize
;
2143 errcode_t retval
, recover_retval
;
2145 printf(_("%s: recovering journal\n"), ctx
->device_name
);
2146 if (ctx
->options
& E2F_OPT_READONLY
) {
2147 printf(_("%s: won't do journal recovery while read-only\n"),
2149 return EXT2_ET_FILE_RO
;
2152 if (ctx
->fs
->flags
& EXT2_FLAG_DIRTY
)
2153 ext2fs_flush(ctx
->fs
); /* Force out any modifications */
2155 recover_retval
= recover_ext3_journal(ctx
);
2158 * Reload the filesystem context to get up-to-date data from disk
2159 * because journal recovery will change the filesystem under us.
2161 ext2fs_close(ctx
->fs
);
2162 retval
= ext2fs_open(ctx
->filesystem_name
, EXT2_FLAG_RW
,
2163 ctx
->superblock
, blocksize
, io_ptr
,
2167 bb_error_msg(_("while trying to re-open %s"),
2169 bb_error_msg_and_die(0);
2171 ctx
->fs
->priv_data
= ctx
;
2173 /* Set the superblock flags */
2174 e2fsck_clear_recover(ctx
, recover_retval
);
2175 return recover_retval
;
2179 * This function will move the journal inode from a visible file in
2180 * the filesystem directory hierarchy to the reserved inode if necessary.
2182 static const char *const journal_names
[] = {
2183 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2185 static void e2fsck_move_ext3_journal(e2fsck_t ctx
)
2187 struct ext2_super_block
*sb
= ctx
->fs
->super
;
2188 struct problem_context pctx
;
2189 struct ext2_inode inode
;
2190 ext2_filsys fs
= ctx
->fs
;
2193 const char *const * cpp
;
2194 int group
, mount_flags
;
2196 clear_problem_context(&pctx
);
2199 * If the filesystem is opened read-only, or there is no
2200 * journal, then do nothing.
2202 if ((ctx
->options
& E2F_OPT_READONLY
) ||
2203 (sb
->s_journal_inum
== 0) ||
2204 !(sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
))
2208 * Read in the journal inode
2210 if (ext2fs_read_inode(fs
, sb
->s_journal_inum
, &inode
) != 0)
2214 * If it's necessary to backup the journal inode, do so.
2216 if ((sb
->s_jnl_backup_type
== 0) ||
2217 ((sb
->s_jnl_backup_type
== EXT3_JNL_BACKUP_BLOCKS
) &&
2218 memcmp(inode
.i_block
, sb
->s_jnl_blocks
, EXT2_N_BLOCKS
*4))) {
2219 if (fix_problem(ctx
, PR_0_BACKUP_JNL
, &pctx
)) {
2220 memcpy(sb
->s_jnl_blocks
, inode
.i_block
,
2222 sb
->s_jnl_blocks
[16] = inode
.i_size
;
2223 sb
->s_jnl_backup_type
= EXT3_JNL_BACKUP_BLOCKS
;
2224 ext2fs_mark_super_dirty(fs
);
2225 fs
->flags
&= ~EXT2_FLAG_MASTER_SB_ONLY
;
2230 * If the journal is already the hidden inode, then do nothing
2232 if (sb
->s_journal_inum
== EXT2_JOURNAL_INO
)
2236 * The journal inode had better have only one link and not be readable.
2238 if (inode
.i_links_count
!= 1)
2242 * If the filesystem is mounted, or we can't tell whether
2243 * or not it's mounted, do nothing.
2245 retval
= ext2fs_check_if_mounted(ctx
->filesystem_name
, &mount_flags
);
2246 if (retval
|| (mount_flags
& EXT2_MF_MOUNTED
))
2250 * If we can't find the name of the journal inode, then do
2253 for (cpp
= journal_names
; *cpp
; cpp
++) {
2254 retval
= ext2fs_lookup(fs
, EXT2_ROOT_INO
, *cpp
,
2255 strlen(*cpp
), 0, &ino
);
2256 if ((retval
== 0) && (ino
== sb
->s_journal_inum
))
2262 /* We need the inode bitmap to be loaded */
2263 retval
= ext2fs_read_bitmaps(fs
);
2268 if (!fix_problem(ctx
, PR_0_MOVE_JOURNAL
, &pctx
))
2272 * OK, we've done all the checks, let's actually move the
2273 * journal inode. Errors at this point mean we need to force
2274 * an ext2 filesystem check.
2276 if ((retval
= ext2fs_unlink(fs
, EXT2_ROOT_INO
, *cpp
, ino
, 0)) != 0)
2278 if ((retval
= ext2fs_write_inode(fs
, EXT2_JOURNAL_INO
, &inode
)) != 0)
2280 sb
->s_journal_inum
= EXT2_JOURNAL_INO
;
2281 ext2fs_mark_super_dirty(fs
);
2282 fs
->flags
&= ~EXT2_FLAG_MASTER_SB_ONLY
;
2283 inode
.i_links_count
= 0;
2284 inode
.i_dtime
= time(NULL
);
2285 if ((retval
= ext2fs_write_inode(fs
, ino
, &inode
)) != 0)
2288 group
= ext2fs_group_of_ino(fs
, ino
);
2289 ext2fs_unmark_inode_bitmap(fs
->inode_map
, ino
);
2290 ext2fs_mark_ib_dirty(fs
);
2291 fs
->group_desc
[group
].bg_free_inodes_count
++;
2292 fs
->super
->s_free_inodes_count
++;
2296 pctx
.errcode
= retval
;
2297 fix_problem(ctx
, PR_0_ERR_MOVE_JOURNAL
, &pctx
);
2298 fs
->super
->s_state
&= ~EXT2_VALID_FS
;
2299 ext2fs_mark_super_dirty(fs
);
2303 * message.c --- print e2fsck messages (with compression)
2305 * print_e2fsck_message() prints a message to the user, using
2306 * compression techniques and expansions of abbreviations.
2308 * The following % expansions are supported:
2310 * %b <blk> block number
2311 * %B <blkcount> integer
2312 * %c <blk2> block number
2313 * %Di <dirent>->ino inode number
2314 * %Dn <dirent>->name string
2315 * %Dr <dirent>->rec_len
2316 * %Dl <dirent>->name_len
2317 * %Dt <dirent>->filetype
2318 * %d <dir> inode number
2319 * %g <group> integer
2320 * %i <ino> inode number
2321 * %Is <inode> -> i_size
2322 * %IS <inode> -> i_extra_isize
2323 * %Ib <inode> -> i_blocks
2324 * %Il <inode> -> i_links_count
2325 * %Im <inode> -> i_mode
2326 * %IM <inode> -> i_mtime
2327 * %IF <inode> -> i_faddr
2328 * %If <inode> -> i_file_acl
2329 * %Id <inode> -> i_dir_acl
2330 * %Iu <inode> -> i_uid
2331 * %Ig <inode> -> i_gid
2332 * %j <ino2> inode number
2333 * %m <com_err error message>
2335 * %p ext2fs_get_pathname of directory <ino>
2336 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2337 * the containing directory. (If dirent is NULL
2338 * then return the pathname of directory <ino2>)
2339 * %q ext2fs_get_pathname of directory <dir>
2340 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2341 * the containing directory.
2342 * %s <str> miscellaneous string
2343 * %S backup superblock
2344 * %X <num> hexadecimal format
2346 * The following '@' expansions are supported:
2348 * @a extended attribute
2349 * @A error allocating
2353 * @C conflicts with some other fs block
2357 * @E Entry '%Dn' in %p (%i)
2359 * @F for @i %i (%Q) is
2361 * @h HTREE directory inode
2367 * @m multiply-claimed
2381 * This structure defines the abbreviations used by the text strings
2382 * below. The first character in the string is the index letter. An
2383 * abbreviation of the form '@<i>' is expanded by looking up the index
2384 * letter <i> in the table below.
2386 static const char *const abbrevs
[] = {
2387 N_("aextended attribute"),
2388 N_("Aerror allocating"),
2392 N_("Cconflicts with some other fs @b"),
2399 N_("E@e '%Dn' in %p (%i)"),
2401 N_("Ffor @i %i (%Q) is"),
2406 N_("mmultiply-claimed"),
2421 * Give more user friendly names to the "special" inodes.
2423 #define num_special_inodes 11
2424 static const char *const special_inode_name
[] =
2426 N_("<The NULL inode>"), /* 0 */
2427 N_("<The bad blocks inode>"), /* 1 */
2429 N_("<The ACL index inode>"), /* 3 */
2430 N_("<The ACL data inode>"), /* 4 */
2431 N_("<The boot loader inode>"), /* 5 */
2432 N_("<The undelete directory inode>"), /* 6 */
2433 N_("<The group descriptor inode>"), /* 7 */
2434 N_("<The journal inode>"), /* 8 */
2435 N_("<Reserved inode 9>"), /* 9 */
2436 N_("<Reserved inode 10>"), /* 10 */
2440 * This function does "safe" printing. It will convert non-printable
2441 * ASCII characters using '^' and M- notation.
2443 static void safe_print(const char *cp
, int len
)
2453 fputs("M-", stdout
);
2456 if ((ch
< 32) || (ch
== 0x7f)) {
2458 ch
^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2466 * This function prints a pathname, using the ext2fs_get_pathname
2469 static void print_pathname(ext2_filsys fs
, ext2_ino_t dir
, ext2_ino_t ino
)
2474 if (!dir
&& (ino
< num_special_inodes
)) {
2475 fputs(_(special_inode_name
[ino
]), stdout
);
2479 retval
= ext2fs_get_pathname(fs
, dir
, ino
, &path
);
2481 fputs("???", stdout
);
2483 safe_print(path
, -1);
2484 ext2fs_free_mem(&path
);
2488 static void print_e2fsck_message(e2fsck_t ctx
, const char *msg
,
2489 struct problem_context
*pctx
, int first
);
2491 * This function handles the '@' expansion. We allow recursive
2492 * expansion; an @ expression can contain further '@' and '%'
2495 static void expand_at_expression(e2fsck_t ctx
, char ch
,
2496 struct problem_context
*pctx
,
2499 const char *const *cpp
;
2502 /* Search for the abbreviation */
2503 for (cpp
= abbrevs
; *cpp
; cpp
++) {
2509 if (*first
&& islower(*str
)) {
2511 bb_putchar(toupper(*str
++));
2513 print_e2fsck_message(ctx
, str
, pctx
, *first
);
2519 * This function expands '%IX' expressions
2521 static void expand_inode_expression(char ch
,
2522 struct problem_context
*ctx
)
2524 struct ext2_inode
*inode
;
2525 struct ext2_inode_large
*large_inode
;
2530 if (!ctx
|| !ctx
->inode
)
2534 large_inode
= (struct ext2_inode_large
*) inode
;
2538 if (LINUX_S_ISDIR(inode
->i_mode
))
2539 printf("%u", inode
->i_size
);
2541 printf("%"PRIu64
, (inode
->i_size
|
2542 ((uint64_t) inode
->i_size_high
<< 32)));
2546 printf("%u", large_inode
->i_extra_isize
);
2549 printf("%u", inode
->i_blocks
);
2552 printf("%d", inode
->i_links_count
);
2555 printf("0%o", inode
->i_mode
);
2558 /* The diet libc doesn't respect the TZ environemnt variable */
2560 time_str
= getenv("TZ");
2562 time_str
= (char *)"";
2563 do_gmt
= !strcmp(time_str
, "GMT");
2566 time_str
= asctime(do_gmt
? gmtime(&t
) : localtime(&t
));
2567 printf("%.24s", time_str
);
2570 printf("%u", inode
->i_faddr
);
2573 printf("%u", inode
->i_file_acl
);
2576 printf("%u", (LINUX_S_ISDIR(inode
->i_mode
) ?
2577 inode
->i_dir_acl
: 0));
2580 printf("%d", (inode
->i_uid
|
2581 (inode
->osd2
.linux2
.l_i_uid_high
<< 16)));
2584 printf("%d", (inode
->i_gid
|
2585 (inode
->osd2
.linux2
.l_i_gid_high
<< 16)));
2589 printf("%%I%c", ch
);
2595 * This function expands '%dX' expressions
2597 static void expand_dirent_expression(char ch
,
2598 struct problem_context
*ctx
)
2600 struct ext2_dir_entry
*dirent
;
2603 if (!ctx
|| !ctx
->dirent
)
2606 dirent
= ctx
->dirent
;
2610 printf("%u", dirent
->inode
);
2613 len
= dirent
->name_len
& 0xFF;
2614 if (len
> EXT2_NAME_LEN
)
2615 len
= EXT2_NAME_LEN
;
2616 if (len
> dirent
->rec_len
)
2617 len
= dirent
->rec_len
;
2618 safe_print(dirent
->name
, len
);
2621 printf("%u", dirent
->rec_len
);
2624 printf("%u", dirent
->name_len
& 0xFF);
2627 printf("%u", dirent
->name_len
>> 8);
2631 printf("%%D%c", ch
);
2636 static void expand_percent_expression(ext2_filsys fs
, char ch
,
2637 struct problem_context
*ctx
)
2647 printf("%u", ctx
->blk
);
2650 printf("%"PRIi64
, ctx
->blkcount
);
2653 printf("%u", ctx
->blk2
);
2656 printf("%u", ctx
->dir
);
2659 printf("%d", ctx
->group
);
2662 printf("%u", ctx
->ino
);
2665 printf("%u", ctx
->ino2
);
2668 fputs(error_message(ctx
->errcode
), stdout
);
2671 printf("%"PRIi64
, ctx
->num
);
2674 print_pathname(fs
, ctx
->ino
, 0);
2677 print_pathname(fs
, ctx
->ino2
,
2678 ctx
->dirent
? ctx
->dirent
->inode
: 0);
2681 print_pathname(fs
, ctx
->dir
, 0);
2684 print_pathname(fs
, ctx
->dir
, ctx
->ino
);
2687 printf("%d", get_backup_sb(NULL
, fs
, NULL
, NULL
));
2690 fputs((ctx
->str
? ctx
->str
: "NULL"), stdout
);
2693 printf("0x%"PRIi64
, ctx
->num
);
2703 static void print_e2fsck_message(e2fsck_t ctx
, const char *msg
,
2704 struct problem_context
*pctx
, int first
)
2706 ext2_filsys fs
= ctx
->fs
;
2710 e2fsck_clear_progbar(ctx
);
2711 for (cp
= msg
; *cp
; cp
++) {
2714 expand_at_expression(ctx
, *cp
, pctx
, &first
);
2715 } else if (cp
[0] == '%' && cp
[1] == 'I') {
2717 expand_inode_expression(*cp
, pctx
);
2718 } else if (cp
[0] == '%' && cp
[1] == 'D') {
2720 expand_dirent_expression(*cp
, pctx
);
2721 } else if ((cp
[0] == '%')) {
2723 expand_percent_expression(fs
, *cp
, pctx
);
2725 for (i
=0; cp
[i
]; i
++)
2726 if ((cp
[i
] == '@') || cp
[i
] == '%')
2728 printf("%.*s", i
, cp
);
2737 * region.c --- code which manages allocations within a region.
2741 region_addr_t start
;
2743 struct region_el
*next
;
2746 struct region_struct
{
2749 struct region_el
*allocated
;
2752 static region_t
region_create(region_addr_t min
, region_addr_t max
)
2756 region
= xzalloc(sizeof(struct region_struct
));
2762 static void region_free(region_t region
)
2764 struct region_el
*r
, *next
;
2766 for (r
= region
->allocated
; r
; r
= next
) {
2770 memset(region
, 0, sizeof(struct region_struct
));
2774 static int region_allocate(region_t region
, region_addr_t start
, int n
)
2776 struct region_el
*r
, *new_region
, *prev
, *next
;
2780 if ((start
< region
->min
) || (end
> region
->max
))
2786 * Search through the linked list. If we find that it
2787 * conflicts witih something that's already allocated, return
2788 * 1; if we can find an existing region which we can grow, do
2789 * so. Otherwise, stop when we find the appropriate place
2790 * insert a new region element into the linked list.
2792 for (r
= region
->allocated
, prev
=NULL
; r
; prev
= r
, r
= r
->next
) {
2793 if (((start
>= r
->start
) && (start
< r
->end
)) ||
2794 ((end
> r
->start
) && (end
<= r
->end
)) ||
2795 ((start
<= r
->start
) && (end
>= r
->end
)))
2797 if (end
== r
->start
) {
2801 if (start
== r
->end
) {
2802 if ((next
= r
->next
)) {
2803 if (end
> next
->start
)
2805 if (end
== next
->start
) {
2807 r
->next
= next
->next
;
2815 if (start
< r
->start
)
2819 * Insert a new region element structure into the linked list
2821 new_region
= xmalloc(sizeof(struct region_el
));
2822 new_region
->start
= start
;
2823 new_region
->end
= start
+ n
;
2824 new_region
->next
= r
;
2826 prev
->next
= new_region
;
2828 region
->allocated
= new_region
;
2833 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2835 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2836 * and applies the following tests to each inode:
2838 * - The mode field of the inode must be legal.
2839 * - The size and block count fields of the inode are correct.
2840 * - A data block must not be used by another inode
2842 * Pass 1 also gathers the collects the following information:
2844 * - A bitmap of which inodes are in use. (inode_used_map)
2845 * - A bitmap of which inodes are directories. (inode_dir_map)
2846 * - A bitmap of which inodes are regular files. (inode_reg_map)
2847 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2848 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2849 * - A bitmap of which blocks are in use. (block_found_map)
2850 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2851 * - The data blocks of the directory inodes. (dir_map)
2853 * Pass 1 is designed to stash away enough information so that the
2854 * other passes should not need to read in the inode information
2855 * during the normal course of a filesystem check. (Althogh if an
2856 * inconsistency is detected, other passes may need to read in an
2859 * Note that pass 1B will be invoked if there are any duplicate blocks
2864 static int process_block(ext2_filsys fs
, blk_t
*blocknr
,
2865 e2_blkcnt_t blockcnt
, blk_t ref_blk
,
2866 int ref_offset
, void *priv_data
);
2867 static int process_bad_block(ext2_filsys fs
, blk_t
*block_nr
,
2868 e2_blkcnt_t blockcnt
, blk_t ref_blk
,
2869 int ref_offset
, void *priv_data
);
2870 static void check_blocks(e2fsck_t ctx
, struct problem_context
*pctx
,
2872 static void mark_table_blocks(e2fsck_t ctx
);
2873 static void alloc_imagic_map(e2fsck_t ctx
);
2874 static void mark_inode_bad(e2fsck_t ctx
, ino_t ino
);
2875 static void handle_fs_bad_blocks(e2fsck_t ctx
);
2876 static void process_inodes(e2fsck_t ctx
, char *block_buf
);
2877 static int process_inode_cmp(const void *a
, const void *b
);
2878 static errcode_t
scan_callback(ext2_filsys fs
,
2879 dgrp_t group
, void * priv_data
);
2880 static void adjust_extattr_refcount(e2fsck_t ctx
, ext2_refcount_t refcount
,
2881 char *block_buf
, int adjust_sign
);
2882 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2884 static void e2fsck_write_inode_full(e2fsck_t ctx
, unsigned long ino
,
2885 struct ext2_inode
* inode
, int bufsize
,
2888 struct process_block_struct_1
{
2890 unsigned is_dir
:1, is_reg
:1, clear
:1, suppress
:1,
2891 fragmented
:1, compressed
:1, bbcheck
:1;
2894 e2_blkcnt_t last_block
;
2895 int num_illegal_blocks
;
2896 blk_t previous_block
;
2897 struct ext2_inode
*inode
;
2898 struct problem_context
*pctx
;
2899 ext2fs_block_bitmap fs_meta_blocks
;
2903 struct process_inode_block
{
2905 struct ext2_inode inode
;
2908 struct scan_callback_struct
{
2914 * For the inodes to process list.
2916 static struct process_inode_block
*inodes_to_process
;
2917 static int process_inode_count
;
2919 static __u64 ext2_max_sizes
[EXT2_MAX_BLOCK_LOG_SIZE
-
2920 EXT2_MIN_BLOCK_LOG_SIZE
+ 1];
2923 * Free all memory allocated by pass1 in preparation for restarting
2926 static void unwind_pass1(void)
2928 ext2fs_free_mem(&inodes_to_process
);
2932 * Check to make sure a device inode is real. Returns 1 if the device
2933 * checks out, 0 if not.
2935 * Note: this routine is now also used to check FIFO's and Sockets,
2936 * since they have the same requirement; the i_block fields should be
2940 e2fsck_pass1_check_device_inode(ext2_filsys fs
, struct ext2_inode
*inode
)
2945 * If i_blocks is non-zero, or the index flag is set, then
2946 * this is a bogus device/fifo/socket
2948 if ((ext2fs_inode_data_blocks(fs
, inode
) != 0) ||
2949 (inode
->i_flags
& EXT2_INDEX_FL
))
2953 * We should be able to do the test below all the time, but
2954 * because the kernel doesn't forcibly clear the device
2955 * inode's additional i_block fields, there are some rare
2956 * occasions when a legitimate device inode will have non-zero
2957 * additional i_block fields. So for now, we only complain
2958 * when the immutable flag is set, which should never happen
2959 * for devices. (And that's when the problem is caused, since
2960 * you can't set or clear immutable flags for devices.) Once
2961 * the kernel has been fixed we can change this...
2963 if (inode
->i_flags
& (EXT2_IMMUTABLE_FL
| EXT2_APPEND_FL
)) {
2964 for (i
=4; i
< EXT2_N_BLOCKS
; i
++)
2965 if (inode
->i_block
[i
])
2972 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2973 * checks out, 0 if not.
2976 e2fsck_pass1_check_symlink(ext2_filsys fs
, struct ext2_inode
*inode
, char *buf
)
2982 if ((inode
->i_size_high
|| inode
->i_size
== 0) ||
2983 (inode
->i_flags
& EXT2_INDEX_FL
))
2986 blocks
= ext2fs_inode_data_blocks(fs
, inode
);
2988 if ((inode
->i_size
>= fs
->blocksize
) ||
2989 (blocks
!= fs
->blocksize
>> 9) ||
2990 (inode
->i_block
[0] < fs
->super
->s_first_data_block
) ||
2991 (inode
->i_block
[0] >= fs
->super
->s_blocks_count
))
2994 for (i
= 1; i
< EXT2_N_BLOCKS
; i
++)
2995 if (inode
->i_block
[i
])
2998 if (io_channel_read_blk(fs
->io
, inode
->i_block
[0], 1, buf
))
3001 len
= strnlen(buf
, fs
->blocksize
);
3002 if (len
== fs
->blocksize
)
3005 if (inode
->i_size
>= sizeof(inode
->i_block
))
3008 len
= strnlen((char *)inode
->i_block
, sizeof(inode
->i_block
));
3009 if (len
== sizeof(inode
->i_block
))
3012 if (len
!= inode
->i_size
)
3018 * If the immutable (or append-only) flag is set on the inode, offer
3021 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3022 static void check_immutable(e2fsck_t ctx
, struct problem_context
*pctx
)
3024 if (!(pctx
->inode
->i_flags
& BAD_SPECIAL_FLAGS
))
3027 if (!fix_problem(ctx
, PR_1_SET_IMMUTABLE
, pctx
))
3030 pctx
->inode
->i_flags
&= ~BAD_SPECIAL_FLAGS
;
3031 e2fsck_write_inode(ctx
, pctx
->ino
, pctx
->inode
, "pass1");
3035 * If device, fifo or socket, check size is zero -- if not offer to
3038 static void check_size(e2fsck_t ctx
, struct problem_context
*pctx
)
3040 struct ext2_inode
*inode
= pctx
->inode
;
3042 if ((inode
->i_size
== 0) && (inode
->i_size_high
== 0))
3045 if (!fix_problem(ctx
, PR_1_SET_NONZSIZE
, pctx
))
3049 inode
->i_size_high
= 0;
3050 e2fsck_write_inode(ctx
, pctx
->ino
, pctx
->inode
, "pass1");
3053 static void check_ea_in_inode(e2fsck_t ctx
, struct problem_context
*pctx
)
3055 struct ext2_super_block
*sb
= ctx
->fs
->super
;
3056 struct ext2_inode_large
*inode
;
3057 struct ext2_ext_attr_entry
*entry
;
3059 int storage_size
, remain
, offs
;
3062 inode
= (struct ext2_inode_large
*) pctx
->inode
;
3063 storage_size
= EXT2_INODE_SIZE(ctx
->fs
->super
) - EXT2_GOOD_OLD_INODE_SIZE
-
3064 inode
->i_extra_isize
;
3065 start
= ((char *) inode
) + EXT2_GOOD_OLD_INODE_SIZE
+
3066 inode
->i_extra_isize
+ sizeof(__u32
);
3067 end
= (char *) inode
+ EXT2_INODE_SIZE(ctx
->fs
->super
);
3068 entry
= (struct ext2_ext_attr_entry
*) start
;
3070 /* scan all entry's headers first */
3072 /* take finish entry 0UL into account */
3073 remain
= storage_size
- sizeof(__u32
);
3076 while (!EXT2_EXT_IS_LAST_ENTRY(entry
)) {
3078 /* header eats this space */
3079 remain
-= sizeof(struct ext2_ext_attr_entry
);
3081 /* is attribute name valid? */
3082 if (EXT2_EXT_ATTR_SIZE(entry
->e_name_len
) > remain
) {
3083 pctx
->num
= entry
->e_name_len
;
3084 problem
= PR_1_ATTR_NAME_LEN
;
3088 /* attribute len eats this space */
3089 remain
-= EXT2_EXT_ATTR_SIZE(entry
->e_name_len
);
3091 /* check value size */
3092 if (entry
->e_value_size
== 0 || entry
->e_value_size
> remain
) {
3093 pctx
->num
= entry
->e_value_size
;
3094 problem
= PR_1_ATTR_VALUE_SIZE
;
3098 /* check value placement */
3099 if (entry
->e_value_offs
+
3100 EXT2_XATTR_SIZE(entry
->e_value_size
) != offs
) {
3101 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry
->e_value_offs
+ entry
->e_value_size
, offs
);
3102 pctx
->num
= entry
->e_value_offs
;
3103 problem
= PR_1_ATTR_VALUE_OFFSET
;
3107 /* e_value_block must be 0 in inode's ea */
3108 if (entry
->e_value_block
!= 0) {
3109 pctx
->num
= entry
->e_value_block
;
3110 problem
= PR_1_ATTR_VALUE_BLOCK
;
3114 /* e_hash must be 0 in inode's ea */
3115 if (entry
->e_hash
!= 0) {
3116 pctx
->num
= entry
->e_hash
;
3117 problem
= PR_1_ATTR_HASH
;
3121 remain
-= entry
->e_value_size
;
3122 offs
-= EXT2_XATTR_SIZE(entry
->e_value_size
);
3124 entry
= EXT2_EXT_ATTR_NEXT(entry
);
3128 * it seems like a corruption. it's very unlikely we could repair
3129 * EA(s) in automatic fashion -bzzz
3131 if (problem
== 0 || !fix_problem(ctx
, problem
, pctx
))
3134 /* simple remove all possible EA(s) */
3135 *((__u32
*)start
) = 0UL;
3136 e2fsck_write_inode_full(ctx
, pctx
->ino
, (struct ext2_inode
*)inode
,
3137 EXT2_INODE_SIZE(sb
), "pass1");
3140 static void check_inode_extra_space(e2fsck_t ctx
, struct problem_context
*pctx
)
3142 struct ext2_super_block
*sb
= ctx
->fs
->super
;
3143 struct ext2_inode_large
*inode
;
3147 inode
= (struct ext2_inode_large
*) pctx
->inode
;
3148 if (EXT2_INODE_SIZE(sb
) == EXT2_GOOD_OLD_INODE_SIZE
) {
3149 /* this isn't large inode. so, nothing to check */
3153 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3154 min
= sizeof(inode
->i_extra_isize
) + sizeof(inode
->i_pad1
);
3155 max
= EXT2_INODE_SIZE(sb
) - EXT2_GOOD_OLD_INODE_SIZE
;
3157 * For now we will allow i_extra_isize to be 0, but really
3158 * implementations should never allow i_extra_isize to be 0
3160 if (inode
->i_extra_isize
&&
3161 (inode
->i_extra_isize
< min
|| inode
->i_extra_isize
> max
)) {
3162 if (!fix_problem(ctx
, PR_1_EXTRA_ISIZE
, pctx
))
3164 inode
->i_extra_isize
= min
;
3165 e2fsck_write_inode_full(ctx
, pctx
->ino
, pctx
->inode
,
3166 EXT2_INODE_SIZE(sb
), "pass1");
3170 eamagic
= (__u32
*) (((char *) inode
) + EXT2_GOOD_OLD_INODE_SIZE
+
3171 inode
->i_extra_isize
);
3172 if (*eamagic
== EXT2_EXT_ATTR_MAGIC
) {
3173 /* it seems inode has an extended attribute(s) in body */
3174 check_ea_in_inode(ctx
, pctx
);
3178 static void e2fsck_pass1(e2fsck_t ctx
)
3182 ext2_filsys fs
= ctx
->fs
;
3184 struct ext2_inode
*inode
;
3185 ext2_inode_scan scan
;
3187 unsigned char frag
, fsize
;
3188 struct problem_context pctx
;
3189 struct scan_callback_struct scan_struct
;
3190 struct ext2_super_block
*sb
= ctx
->fs
->super
;
3192 int busted_fs_time
= 0;
3195 clear_problem_context(&pctx
);
3197 if (!(ctx
->options
& E2F_OPT_PREEN
))
3198 fix_problem(ctx
, PR_1_PASS_HEADER
, &pctx
);
3200 if ((fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
) &&
3201 !(ctx
->options
& E2F_OPT_NO
)) {
3202 if (ext2fs_u32_list_create(&ctx
->dirs_to_hash
, 50))
3203 ctx
->dirs_to_hash
= 0;
3208 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3210 for (i
= EXT2_MIN_BLOCK_LOG_SIZE
; i
<= EXT2_MAX_BLOCK_LOG_SIZE
; i
++) {
3211 max_sizes
= EXT2_NDIR_BLOCKS
+ EXT2_BPP(i
);
3212 max_sizes
= max_sizes
+ EXT2_BPP(i
) * EXT2_BPP(i
);
3213 max_sizes
= max_sizes
+ EXT2_BPP(i
) * EXT2_BPP(i
) * EXT2_BPP(i
);
3214 max_sizes
= (max_sizes
* (1UL << i
)) - 1;
3215 ext2_max_sizes
[i
- EXT2_MIN_BLOCK_LOG_SIZE
] = max_sizes
;
3219 imagic_fs
= (sb
->s_feature_compat
& EXT2_FEATURE_COMPAT_IMAGIC_INODES
);
3222 * Allocate bitmaps structures
3224 pctx
.errcode
= ext2fs_allocate_inode_bitmap(fs
, _("in-use inode map"),
3225 &ctx
->inode_used_map
);
3228 fix_problem(ctx
, PR_1_ALLOCATE_IBITMAP_ERROR
, &pctx
);
3229 ctx
->flags
|= E2F_FLAG_ABORT
;
3232 pctx
.errcode
= ext2fs_allocate_inode_bitmap(fs
,
3233 _("directory inode map"), &ctx
->inode_dir_map
);
3236 fix_problem(ctx
, PR_1_ALLOCATE_IBITMAP_ERROR
, &pctx
);
3237 ctx
->flags
|= E2F_FLAG_ABORT
;
3240 pctx
.errcode
= ext2fs_allocate_inode_bitmap(fs
,
3241 _("regular file inode map"), &ctx
->inode_reg_map
);
3244 fix_problem(ctx
, PR_1_ALLOCATE_IBITMAP_ERROR
, &pctx
);
3245 ctx
->flags
|= E2F_FLAG_ABORT
;
3248 pctx
.errcode
= ext2fs_allocate_block_bitmap(fs
, _("in-use block map"),
3249 &ctx
->block_found_map
);
3252 fix_problem(ctx
, PR_1_ALLOCATE_BBITMAP_ERROR
, &pctx
);
3253 ctx
->flags
|= E2F_FLAG_ABORT
;
3256 pctx
.errcode
= ext2fs_create_icount2(fs
, 0, 0, 0,
3257 &ctx
->inode_link_info
);
3259 fix_problem(ctx
, PR_1_ALLOCATE_ICOUNT
, &pctx
);
3260 ctx
->flags
|= E2F_FLAG_ABORT
;
3263 inode_size
= EXT2_INODE_SIZE(fs
->super
);
3264 inode
= (struct ext2_inode
*)
3265 e2fsck_allocate_memory(ctx
, inode_size
, "scratch inode");
3267 inodes_to_process
= (struct process_inode_block
*)
3268 e2fsck_allocate_memory(ctx
,
3269 (ctx
->process_inode_size
*
3270 sizeof(struct process_inode_block
)),
3271 "array of inodes to process");
3272 process_inode_count
= 0;
3274 pctx
.errcode
= ext2fs_init_dblist(fs
, 0);
3276 fix_problem(ctx
, PR_1_ALLOCATE_DBCOUNT
, &pctx
);
3277 ctx
->flags
|= E2F_FLAG_ABORT
;
3282 * If the last orphan field is set, clear it, since the pass1
3283 * processing will automatically find and clear the orphans.
3284 * In the future, we may want to try using the last_orphan
3285 * linked list ourselves, but for now, we clear it so that the
3286 * ext3 mount code won't get confused.
3288 if (!(ctx
->options
& E2F_OPT_READONLY
)) {
3289 if (fs
->super
->s_last_orphan
) {
3290 fs
->super
->s_last_orphan
= 0;
3291 ext2fs_mark_super_dirty(fs
);
3295 mark_table_blocks(ctx
);
3296 block_buf
= (char *) e2fsck_allocate_memory(ctx
, fs
->blocksize
* 3,
3297 "block interate buffer");
3298 e2fsck_use_inode_shortcuts(ctx
, 1);
3299 ehandler_operation(_("doing inode scan"));
3300 pctx
.errcode
= ext2fs_open_inode_scan(fs
, ctx
->inode_buffer_blocks
,
3303 fix_problem(ctx
, PR_1_ISCAN_ERROR
, &pctx
);
3304 ctx
->flags
|= E2F_FLAG_ABORT
;
3307 ext2fs_inode_scan_flags(scan
, EXT2_SF_SKIP_MISSING_ITABLE
, 0);
3308 ctx
->stashed_inode
= inode
;
3309 scan_struct
.ctx
= ctx
;
3310 scan_struct
.block_buf
= block_buf
;
3311 ext2fs_set_inode_callback(scan
, scan_callback
, &scan_struct
);
3313 if ((ctx
->progress
)(ctx
, 1, 0, ctx
->fs
->group_desc_count
))
3315 if ((fs
->super
->s_wtime
< fs
->super
->s_inodes_count
) ||
3316 (fs
->super
->s_mtime
< fs
->super
->s_inodes_count
))
3320 pctx
.errcode
= ext2fs_get_next_inode_full(scan
, &ino
,
3322 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
3324 if (pctx
.errcode
== EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
) {
3328 fix_problem(ctx
, PR_1_ISCAN_ERROR
, &pctx
);
3329 ctx
->flags
|= E2F_FLAG_ABORT
;
3336 ctx
->stashed_ino
= ino
;
3337 if (inode
->i_links_count
) {
3338 pctx
.errcode
= ext2fs_icount_store(ctx
->inode_link_info
,
3339 ino
, inode
->i_links_count
);
3341 pctx
.num
= inode
->i_links_count
;
3342 fix_problem(ctx
, PR_1_ICOUNT_STORE
, &pctx
);
3343 ctx
->flags
|= E2F_FLAG_ABORT
;
3347 if (ino
== EXT2_BAD_INO
) {
3348 struct process_block_struct_1 pb
;
3350 pctx
.errcode
= ext2fs_copy_bitmap(ctx
->block_found_map
,
3351 &pb
.fs_meta_blocks
);
3354 fix_problem(ctx
, PR_1_ALLOCATE_BBITMAP_ERROR
, &pctx
);
3355 ctx
->flags
|= E2F_FLAG_ABORT
;
3358 pb
.ino
= EXT2_BAD_INO
;
3359 pb
.num_blocks
= pb
.last_block
= 0;
3360 pb
.num_illegal_blocks
= 0;
3361 pb
.suppress
= 0; pb
.clear
= 0; pb
.is_dir
= 0;
3362 pb
.is_reg
= 0; pb
.fragmented
= 0; pb
.bbcheck
= 0;
3366 pctx
.errcode
= ext2fs_block_iterate2(fs
, ino
, 0,
3367 block_buf
, process_bad_block
, &pb
);
3368 ext2fs_free_block_bitmap(pb
.fs_meta_blocks
);
3370 fix_problem(ctx
, PR_1_BLOCK_ITERATE
, &pctx
);
3371 ctx
->flags
|= E2F_FLAG_ABORT
;
3375 if (!fix_problem(ctx
, PR_1_BBINODE_BAD_METABLOCK_PROMPT
, &pctx
)) {
3376 ctx
->flags
|= E2F_FLAG_ABORT
;
3379 ext2fs_mark_inode_bitmap(ctx
->inode_used_map
, ino
);
3380 clear_problem_context(&pctx
);
3382 } else if (ino
== EXT2_ROOT_INO
) {
3384 * Make sure the root inode is a directory; if
3385 * not, offer to clear it. It will be
3386 * regnerated in pass #3.
3388 if (!LINUX_S_ISDIR(inode
->i_mode
)) {
3389 if (fix_problem(ctx
, PR_1_ROOT_NO_DIR
, &pctx
)) {
3390 inode
->i_dtime
= time(NULL
);
3391 inode
->i_links_count
= 0;
3392 ext2fs_icount_store(ctx
->inode_link_info
,
3394 e2fsck_write_inode(ctx
, ino
, inode
,
3399 * If dtime is set, offer to clear it. mke2fs
3400 * version 0.2b created filesystems with the
3401 * dtime field set for the root and lost+found
3402 * directories. We won't worry about
3403 * /lost+found, since that can be regenerated
3404 * easily. But we will fix the root directory
3405 * as a special case.
3407 if (inode
->i_dtime
&& inode
->i_links_count
) {
3408 if (fix_problem(ctx
, PR_1_ROOT_DTIME
, &pctx
)) {
3410 e2fsck_write_inode(ctx
, ino
, inode
,
3414 } else if (ino
== EXT2_JOURNAL_INO
) {
3415 ext2fs_mark_inode_bitmap(ctx
->inode_used_map
, ino
);
3416 if (fs
->super
->s_journal_inum
== EXT2_JOURNAL_INO
) {
3417 if (!LINUX_S_ISREG(inode
->i_mode
) &&
3418 fix_problem(ctx
, PR_1_JOURNAL_BAD_MODE
,
3420 inode
->i_mode
= LINUX_S_IFREG
;
3421 e2fsck_write_inode(ctx
, ino
, inode
,
3424 check_blocks(ctx
, &pctx
, block_buf
);
3427 if ((inode
->i_links_count
|| inode
->i_blocks
||
3428 inode
->i_blocks
|| inode
->i_block
[0]) &&
3429 fix_problem(ctx
, PR_1_JOURNAL_INODE_NOT_CLEAR
,
3431 memset(inode
, 0, inode_size
);
3432 ext2fs_icount_store(ctx
->inode_link_info
,
3434 e2fsck_write_inode_full(ctx
, ino
, inode
,
3435 inode_size
, "pass1");
3437 } else if (ino
< EXT2_FIRST_INODE(fs
->super
)) {
3440 ext2fs_mark_inode_bitmap(ctx
->inode_used_map
, ino
);
3441 if (ino
== EXT2_BOOT_LOADER_INO
) {
3442 if (LINUX_S_ISDIR(inode
->i_mode
))
3443 problem
= PR_1_RESERVED_BAD_MODE
;
3444 } else if (ino
== EXT2_RESIZE_INO
) {
3445 if (inode
->i_mode
&&
3446 !LINUX_S_ISREG(inode
->i_mode
))
3447 problem
= PR_1_RESERVED_BAD_MODE
;
3449 if (inode
->i_mode
!= 0)
3450 problem
= PR_1_RESERVED_BAD_MODE
;
3453 if (fix_problem(ctx
, problem
, &pctx
)) {
3455 e2fsck_write_inode(ctx
, ino
, inode
,
3459 check_blocks(ctx
, &pctx
, block_buf
);
3463 * Check for inodes who might have been part of the
3464 * orphaned list linked list. They should have gotten
3465 * dealt with by now, unless the list had somehow been
3468 * FIXME: In the future, inodes which are still in use
3469 * (and which are therefore) pending truncation should
3470 * be handled specially. Right now we just clear the
3471 * dtime field, and the normal e2fsck handling of
3472 * inodes where i_size and the inode blocks are
3473 * inconsistent is to fix i_size, instead of releasing
3474 * the extra blocks. This won't catch the inodes that
3475 * was at the end of the orphan list, but it's better
3476 * than nothing. The right answer is that there
3477 * shouldn't be any bugs in the orphan list handling. :-)
3479 if (inode
->i_dtime
&& !busted_fs_time
&&
3480 inode
->i_dtime
< ctx
->fs
->super
->s_inodes_count
) {
3481 if (fix_problem(ctx
, PR_1_LOW_DTIME
, &pctx
)) {
3482 inode
->i_dtime
= inode
->i_links_count
?
3484 e2fsck_write_inode(ctx
, ino
, inode
,
3490 * This code assumes that deleted inodes have
3491 * i_links_count set to 0.
3493 if (!inode
->i_links_count
) {
3494 if (!inode
->i_dtime
&& inode
->i_mode
) {
3495 if (fix_problem(ctx
,
3496 PR_1_ZERO_DTIME
, &pctx
)) {
3497 inode
->i_dtime
= time(NULL
);
3498 e2fsck_write_inode(ctx
, ino
, inode
,
3505 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3506 * deleted files. Oops.
3508 * Since all new ext2 implementations get this right,
3509 * we now assume that the case of non-zero
3510 * i_links_count and non-zero dtime means that we
3511 * should keep the file, not delete it.
3514 if (inode
->i_dtime
) {
3515 if (fix_problem(ctx
, PR_1_SET_DTIME
, &pctx
)) {
3517 e2fsck_write_inode(ctx
, ino
, inode
, "pass1");
3521 ext2fs_mark_inode_bitmap(ctx
->inode_used_map
, ino
);
3522 switch (fs
->super
->s_creator_os
) {
3524 frag
= inode
->osd2
.linux2
.l_i_frag
;
3525 fsize
= inode
->osd2
.linux2
.l_i_fsize
;
3528 frag
= inode
->osd2
.hurd2
.h_i_frag
;
3529 fsize
= inode
->osd2
.hurd2
.h_i_fsize
;
3532 frag
= inode
->osd2
.masix2
.m_i_frag
;
3533 fsize
= inode
->osd2
.masix2
.m_i_fsize
;
3539 if (inode
->i_faddr
|| frag
|| fsize
||
3540 (LINUX_S_ISDIR(inode
->i_mode
) && inode
->i_dir_acl
))
3541 mark_inode_bad(ctx
, ino
);
3542 if (inode
->i_flags
& EXT2_IMAGIC_FL
) {
3544 if (!ctx
->inode_imagic_map
)
3545 alloc_imagic_map(ctx
);
3546 ext2fs_mark_inode_bitmap(ctx
->inode_imagic_map
,
3549 if (fix_problem(ctx
, PR_1_SET_IMAGIC
, &pctx
)) {
3550 inode
->i_flags
&= ~EXT2_IMAGIC_FL
;
3551 e2fsck_write_inode(ctx
, ino
,
3557 check_inode_extra_space(ctx
, &pctx
);
3559 if (LINUX_S_ISDIR(inode
->i_mode
)) {
3560 ext2fs_mark_inode_bitmap(ctx
->inode_dir_map
, ino
);
3561 e2fsck_add_dir_info(ctx
, ino
, 0);
3562 ctx
->fs_directory_count
++;
3563 } else if (LINUX_S_ISREG (inode
->i_mode
)) {
3564 ext2fs_mark_inode_bitmap(ctx
->inode_reg_map
, ino
);
3565 ctx
->fs_regular_count
++;
3566 } else if (LINUX_S_ISCHR (inode
->i_mode
) &&
3567 e2fsck_pass1_check_device_inode(fs
, inode
)) {
3568 check_immutable(ctx
, &pctx
);
3569 check_size(ctx
, &pctx
);
3570 ctx
->fs_chardev_count
++;
3571 } else if (LINUX_S_ISBLK (inode
->i_mode
) &&
3572 e2fsck_pass1_check_device_inode(fs
, inode
)) {
3573 check_immutable(ctx
, &pctx
);
3574 check_size(ctx
, &pctx
);
3575 ctx
->fs_blockdev_count
++;
3576 } else if (LINUX_S_ISLNK (inode
->i_mode
) &&
3577 e2fsck_pass1_check_symlink(fs
, inode
, block_buf
)) {
3578 check_immutable(ctx
, &pctx
);
3579 ctx
->fs_symlinks_count
++;
3580 if (ext2fs_inode_data_blocks(fs
, inode
) == 0) {
3581 ctx
->fs_fast_symlinks_count
++;
3582 check_blocks(ctx
, &pctx
, block_buf
);
3586 else if (LINUX_S_ISFIFO (inode
->i_mode
) &&
3587 e2fsck_pass1_check_device_inode(fs
, inode
)) {
3588 check_immutable(ctx
, &pctx
);
3589 check_size(ctx
, &pctx
);
3590 ctx
->fs_fifo_count
++;
3591 } else if ((LINUX_S_ISSOCK (inode
->i_mode
)) &&
3592 e2fsck_pass1_check_device_inode(fs
, inode
)) {
3593 check_immutable(ctx
, &pctx
);
3594 check_size(ctx
, &pctx
);
3595 ctx
->fs_sockets_count
++;
3597 mark_inode_bad(ctx
, ino
);
3598 if (inode
->i_block
[EXT2_IND_BLOCK
])
3599 ctx
->fs_ind_count
++;
3600 if (inode
->i_block
[EXT2_DIND_BLOCK
])
3601 ctx
->fs_dind_count
++;
3602 if (inode
->i_block
[EXT2_TIND_BLOCK
])
3603 ctx
->fs_tind_count
++;
3604 if (inode
->i_block
[EXT2_IND_BLOCK
] ||
3605 inode
->i_block
[EXT2_DIND_BLOCK
] ||
3606 inode
->i_block
[EXT2_TIND_BLOCK
] ||
3607 inode
->i_file_acl
) {
3608 inodes_to_process
[process_inode_count
].ino
= ino
;
3609 inodes_to_process
[process_inode_count
].inode
= *inode
;
3610 process_inode_count
++;
3612 check_blocks(ctx
, &pctx
, block_buf
);
3614 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
3617 if (process_inode_count
>= ctx
->process_inode_size
) {
3618 process_inodes(ctx
, block_buf
);
3620 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
3624 process_inodes(ctx
, block_buf
);
3625 ext2fs_close_inode_scan(scan
);
3626 ehandler_operation(0);
3629 * If any extended attribute blocks' reference counts need to
3630 * be adjusted, either up (ctx->refcount_extra), or down
3631 * (ctx->refcount), then fix them.
3633 if (ctx
->refcount
) {
3634 adjust_extattr_refcount(ctx
, ctx
->refcount
, block_buf
, -1);
3635 ea_refcount_free(ctx
->refcount
);
3638 if (ctx
->refcount_extra
) {
3639 adjust_extattr_refcount(ctx
, ctx
->refcount_extra
,
3641 ea_refcount_free(ctx
->refcount_extra
);
3642 ctx
->refcount_extra
= 0;
3645 if (ctx
->invalid_bitmaps
)
3646 handle_fs_bad_blocks(ctx
);
3648 /* We don't need the block_ea_map any more */
3649 ext2fs_free_block_bitmap(ctx
->block_ea_map
);
3650 ctx
->block_ea_map
= 0;
3652 if (ctx
->flags
& E2F_FLAG_RESIZE_INODE
) {
3653 ext2fs_block_bitmap save_bmap
;
3655 save_bmap
= fs
->block_map
;
3656 fs
->block_map
= ctx
->block_found_map
;
3657 clear_problem_context(&pctx
);
3658 pctx
.errcode
= ext2fs_create_resize_inode(fs
);
3660 fix_problem(ctx
, PR_1_RESIZE_INODE_CREATE
, &pctx
);
3661 /* Should never get here */
3662 ctx
->flags
|= E2F_FLAG_ABORT
;
3665 e2fsck_read_inode(ctx
, EXT2_RESIZE_INO
, inode
,
3667 inode
->i_mtime
= time(NULL
);
3668 e2fsck_write_inode(ctx
, EXT2_RESIZE_INO
, inode
,
3670 fs
->block_map
= save_bmap
;
3671 ctx
->flags
&= ~E2F_FLAG_RESIZE_INODE
;
3674 if (ctx
->flags
& E2F_FLAG_RESTART
) {
3676 * Only the master copy of the superblock and block
3677 * group descriptors are going to be written during a
3678 * restart, so set the superblock to be used to be the
3679 * master superblock.
3681 ctx
->use_superblock
= 0;
3686 if (ctx
->block_dup_map
) {
3687 if (ctx
->options
& E2F_OPT_PREEN
) {
3688 clear_problem_context(&pctx
);
3689 fix_problem(ctx
, PR_1_DUP_BLOCKS_PREENSTOP
, &pctx
);
3691 e2fsck_pass1_dupblocks(ctx
, block_buf
);
3693 ext2fs_free_mem(&inodes_to_process
);
3695 e2fsck_use_inode_shortcuts(ctx
, 0);
3697 ext2fs_free_mem(&block_buf
);
3698 ext2fs_free_mem(&inode
);
3702 * When the inode_scan routines call this callback at the end of the
3703 * glock group, call process_inodes.
3705 static errcode_t
scan_callback(ext2_filsys fs
,
3706 dgrp_t group
, void * priv_data
)
3708 struct scan_callback_struct
*scan_struct
;
3711 scan_struct
= (struct scan_callback_struct
*) priv_data
;
3712 ctx
= scan_struct
->ctx
;
3714 process_inodes((e2fsck_t
) fs
->priv_data
, scan_struct
->block_buf
);
3717 if ((ctx
->progress
)(ctx
, 1, group
+1,
3718 ctx
->fs
->group_desc_count
))
3719 return EXT2_ET_CANCEL_REQUESTED
;
3725 * Process the inodes in the "inodes to process" list.
3727 static void process_inodes(e2fsck_t ctx
, char *block_buf
)
3730 struct ext2_inode
*old_stashed_inode
;
3731 ext2_ino_t old_stashed_ino
;
3732 const char *old_operation
;
3734 struct problem_context pctx
;
3736 /* begin process_inodes */
3737 if (process_inode_count
== 0)
3739 old_operation
= ehandler_operation(0);
3740 old_stashed_inode
= ctx
->stashed_inode
;
3741 old_stashed_ino
= ctx
->stashed_ino
;
3742 qsort(inodes_to_process
, process_inode_count
,
3743 sizeof(struct process_inode_block
), process_inode_cmp
);
3744 clear_problem_context(&pctx
);
3745 for (i
=0; i
< process_inode_count
; i
++) {
3746 pctx
.inode
= ctx
->stashed_inode
= &inodes_to_process
[i
].inode
;
3747 pctx
.ino
= ctx
->stashed_ino
= inodes_to_process
[i
].ino
;
3748 sprintf(buf
, _("reading indirect blocks of inode %u"),
3750 ehandler_operation(buf
);
3751 check_blocks(ctx
, &pctx
, block_buf
);
3752 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
3755 ctx
->stashed_inode
= old_stashed_inode
;
3756 ctx
->stashed_ino
= old_stashed_ino
;
3757 process_inode_count
= 0;
3758 /* end process inodes */
3760 ehandler_operation(old_operation
);
3763 static int process_inode_cmp(const void *a
, const void *b
)
3765 const struct process_inode_block
*ib_a
=
3766 (const struct process_inode_block
*) a
;
3767 const struct process_inode_block
*ib_b
=
3768 (const struct process_inode_block
*) b
;
3771 ret
= (ib_a
->inode
.i_block
[EXT2_IND_BLOCK
] -
3772 ib_b
->inode
.i_block
[EXT2_IND_BLOCK
]);
3774 ret
= ib_a
->inode
.i_file_acl
- ib_b
->inode
.i_file_acl
;
3779 * Mark an inode as being bad in some what
3781 static void mark_inode_bad(e2fsck_t ctx
, ino_t ino
)
3783 struct problem_context pctx
;
3785 if (!ctx
->inode_bad_map
) {
3786 clear_problem_context(&pctx
);
3788 pctx
.errcode
= ext2fs_allocate_inode_bitmap(ctx
->fs
,
3789 _("bad inode map"), &ctx
->inode_bad_map
);
3792 fix_problem(ctx
, PR_1_ALLOCATE_IBITMAP_ERROR
, &pctx
);
3793 /* Should never get here */
3794 ctx
->flags
|= E2F_FLAG_ABORT
;
3798 ext2fs_mark_inode_bitmap(ctx
->inode_bad_map
, ino
);
3803 * This procedure will allocate the inode imagic table
3805 static void alloc_imagic_map(e2fsck_t ctx
)
3807 struct problem_context pctx
;
3809 clear_problem_context(&pctx
);
3810 pctx
.errcode
= ext2fs_allocate_inode_bitmap(ctx
->fs
,
3811 _("imagic inode map"),
3812 &ctx
->inode_imagic_map
);
3815 fix_problem(ctx
, PR_1_ALLOCATE_IBITMAP_ERROR
, &pctx
);
3816 /* Should never get here */
3817 ctx
->flags
|= E2F_FLAG_ABORT
;
3823 * Marks a block as in use, setting the dup_map if it's been set
3824 * already. Called by process_block and process_bad_block.
3826 * WARNING: Assumes checks have already been done to make sure block
3827 * is valid. This is true in both process_block and process_bad_block.
3829 static void mark_block_used(e2fsck_t ctx
, blk_t block
)
3831 struct problem_context pctx
;
3833 clear_problem_context(&pctx
);
3835 if (ext2fs_fast_test_block_bitmap(ctx
->block_found_map
, block
)) {
3836 if (!ctx
->block_dup_map
) {
3837 pctx
.errcode
= ext2fs_allocate_block_bitmap(ctx
->fs
,
3838 _("multiply claimed block map"),
3839 &ctx
->block_dup_map
);
3842 fix_problem(ctx
, PR_1_ALLOCATE_BBITMAP_ERROR
,
3844 /* Should never get here */
3845 ctx
->flags
|= E2F_FLAG_ABORT
;
3849 ext2fs_fast_mark_block_bitmap(ctx
->block_dup_map
, block
);
3851 ext2fs_fast_mark_block_bitmap(ctx
->block_found_map
, block
);
3856 * Adjust the extended attribute block's reference counts at the end
3857 * of pass 1, either by subtracting out references for EA blocks that
3858 * are still referenced in ctx->refcount, or by adding references for
3859 * EA blocks that had extra references as accounted for in
3860 * ctx->refcount_extra.
3862 static void adjust_extattr_refcount(e2fsck_t ctx
, ext2_refcount_t refcount
,
3863 char *block_buf
, int adjust_sign
)
3865 struct ext2_ext_attr_header
*header
;
3866 struct problem_context pctx
;
3867 ext2_filsys fs
= ctx
->fs
;
3872 clear_problem_context(&pctx
);
3874 ea_refcount_intr_begin(refcount
);
3876 if ((blk
= ea_refcount_intr_next(refcount
, &count
)) == 0)
3879 pctx
.errcode
= ext2fs_read_ext_attr(fs
, blk
, block_buf
);
3881 fix_problem(ctx
, PR_1_EXTATTR_READ_ABORT
, &pctx
);
3884 header
= (struct ext2_ext_attr_header
*) block_buf
;
3885 pctx
.blkcount
= header
->h_refcount
;
3886 should_be
= header
->h_refcount
+ adjust_sign
* count
;
3887 pctx
.num
= should_be
;
3888 if (fix_problem(ctx
, PR_1_EXTATTR_REFCOUNT
, &pctx
)) {
3889 header
->h_refcount
= should_be
;
3890 pctx
.errcode
= ext2fs_write_ext_attr(fs
, blk
,
3893 fix_problem(ctx
, PR_1_EXTATTR_WRITE
, &pctx
);
3901 * Handle processing the extended attribute blocks
3903 static int check_ext_attr(e2fsck_t ctx
, struct problem_context
*pctx
,
3906 ext2_filsys fs
= ctx
->fs
;
3907 ext2_ino_t ino
= pctx
->ino
;
3908 struct ext2_inode
*inode
= pctx
->inode
;
3911 struct ext2_ext_attr_header
*header
;
3912 struct ext2_ext_attr_entry
*entry
;
3916 blk
= inode
->i_file_acl
;
3921 * If the Extended attribute flag isn't set, then a non-zero
3922 * file acl means that the inode is corrupted.
3924 * Or if the extended attribute block is an invalid block,
3925 * then the inode is also corrupted.
3927 if (!(fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
) ||
3928 (blk
< fs
->super
->s_first_data_block
) ||
3929 (blk
>= fs
->super
->s_blocks_count
)) {
3930 mark_inode_bad(ctx
, ino
);
3934 /* If ea bitmap hasn't been allocated, create it */
3935 if (!ctx
->block_ea_map
) {
3936 pctx
->errcode
= ext2fs_allocate_block_bitmap(fs
,
3937 _("ext attr block map"),
3938 &ctx
->block_ea_map
);
3939 if (pctx
->errcode
) {
3941 fix_problem(ctx
, PR_1_ALLOCATE_BBITMAP_ERROR
, pctx
);
3942 ctx
->flags
|= E2F_FLAG_ABORT
;
3947 /* Create the EA refcount structure if necessary */
3948 if (!ctx
->refcount
) {
3949 pctx
->errcode
= ea_refcount_create(0, &ctx
->refcount
);
3950 if (pctx
->errcode
) {
3952 fix_problem(ctx
, PR_1_ALLOCATE_REFCOUNT
, pctx
);
3953 ctx
->flags
|= E2F_FLAG_ABORT
;
3958 /* Have we seen this EA block before? */
3959 if (ext2fs_fast_test_block_bitmap(ctx
->block_ea_map
, blk
)) {
3960 if (ea_refcount_decrement(ctx
->refcount
, blk
, 0) == 0)
3962 /* Ooops, this EA was referenced more than it stated */
3963 if (!ctx
->refcount_extra
) {
3964 pctx
->errcode
= ea_refcount_create(0,
3965 &ctx
->refcount_extra
);
3966 if (pctx
->errcode
) {
3968 fix_problem(ctx
, PR_1_ALLOCATE_REFCOUNT
, pctx
);
3969 ctx
->flags
|= E2F_FLAG_ABORT
;
3973 ea_refcount_increment(ctx
->refcount_extra
, blk
, 0);
3978 * OK, we haven't seen this EA block yet. So we need to
3982 pctx
->errcode
= ext2fs_read_ext_attr(fs
, blk
, block_buf
);
3983 if (pctx
->errcode
&& fix_problem(ctx
, PR_1_READ_EA_BLOCK
, pctx
))
3985 header
= (struct ext2_ext_attr_header
*) block_buf
;
3986 pctx
->blk
= inode
->i_file_acl
;
3987 if (((ctx
->ext_attr_ver
== 1) &&
3988 (header
->h_magic
!= EXT2_EXT_ATTR_MAGIC_v1
)) ||
3989 ((ctx
->ext_attr_ver
== 2) &&
3990 (header
->h_magic
!= EXT2_EXT_ATTR_MAGIC
))) {
3991 if (fix_problem(ctx
, PR_1_BAD_EA_BLOCK
, pctx
))
3995 if (header
->h_blocks
!= 1) {
3996 if (fix_problem(ctx
, PR_1_EA_MULTI_BLOCK
, pctx
))
4000 region
= region_create(0, fs
->blocksize
);
4002 fix_problem(ctx
, PR_1_EA_ALLOC_REGION
, pctx
);
4003 ctx
->flags
|= E2F_FLAG_ABORT
;
4006 if (region_allocate(region
, 0, sizeof(struct ext2_ext_attr_header
))) {
4007 if (fix_problem(ctx
, PR_1_EA_ALLOC_COLLISION
, pctx
))
4011 entry
= (struct ext2_ext_attr_entry
*)(header
+1);
4012 end
= block_buf
+ fs
->blocksize
;
4013 while ((char *)entry
< end
&& *(__u32
*)entry
) {
4014 if (region_allocate(region
, (char *)entry
- (char *)header
,
4015 EXT2_EXT_ATTR_LEN(entry
->e_name_len
))) {
4016 if (fix_problem(ctx
, PR_1_EA_ALLOC_COLLISION
, pctx
))
4019 if ((ctx
->ext_attr_ver
== 1 &&
4020 (entry
->e_name_len
== 0 || entry
->e_name_index
!= 0)) ||
4021 (ctx
->ext_attr_ver
== 2 &&
4022 entry
->e_name_index
== 0)) {
4023 if (fix_problem(ctx
, PR_1_EA_BAD_NAME
, pctx
))
4026 if (entry
->e_value_block
!= 0) {
4027 if (fix_problem(ctx
, PR_1_EA_BAD_VALUE
, pctx
))
4030 if (entry
->e_value_size
&&
4031 region_allocate(region
, entry
->e_value_offs
,
4032 EXT2_EXT_ATTR_SIZE(entry
->e_value_size
))) {
4033 if (fix_problem(ctx
, PR_1_EA_ALLOC_COLLISION
, pctx
))
4036 entry
= EXT2_EXT_ATTR_NEXT(entry
);
4038 if (region_allocate(region
, (char *)entry
- (char *)header
, 4)) {
4039 if (fix_problem(ctx
, PR_1_EA_ALLOC_COLLISION
, pctx
))
4042 region_free(region
);
4044 count
= header
->h_refcount
- 1;
4046 ea_refcount_store(ctx
->refcount
, blk
, count
);
4047 mark_block_used(ctx
, blk
);
4048 ext2fs_fast_mark_block_bitmap(ctx
->block_ea_map
, blk
);
4053 inode
->i_file_acl
= 0;
4054 e2fsck_write_inode(ctx
, ino
, inode
, "check_ext_attr");
4058 /* Returns 1 if bad htree, 0 if OK */
4059 static int handle_htree(e2fsck_t ctx
, struct problem_context
*pctx
,
4060 ext2_ino_t ino
FSCK_ATTR((unused
)),
4061 struct ext2_inode
*inode
,
4064 struct ext2_dx_root_info
*root
;
4065 ext2_filsys fs
= ctx
->fs
;
4069 if ((!LINUX_S_ISDIR(inode
->i_mode
) &&
4070 fix_problem(ctx
, PR_1_HTREE_NODIR
, pctx
)) ||
4071 (!(fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
) &&
4072 fix_problem(ctx
, PR_1_HTREE_SET
, pctx
)))
4075 blk
= inode
->i_block
[0];
4077 (blk
< fs
->super
->s_first_data_block
) ||
4078 (blk
>= fs
->super
->s_blocks_count
)) &&
4079 fix_problem(ctx
, PR_1_HTREE_BADROOT
, pctx
))
4082 retval
= io_channel_read_blk(fs
->io
, blk
, 1, block_buf
);
4083 if (retval
&& fix_problem(ctx
, PR_1_HTREE_BADROOT
, pctx
))
4086 /* XXX should check that beginning matches a directory */
4087 root
= (struct ext2_dx_root_info
*) (block_buf
+ 24);
4089 if ((root
->reserved_zero
|| root
->info_length
< 8) &&
4090 fix_problem(ctx
, PR_1_HTREE_BADROOT
, pctx
))
4093 pctx
->num
= root
->hash_version
;
4094 if ((root
->hash_version
!= EXT2_HASH_LEGACY
) &&
4095 (root
->hash_version
!= EXT2_HASH_HALF_MD4
) &&
4096 (root
->hash_version
!= EXT2_HASH_TEA
) &&
4097 fix_problem(ctx
, PR_1_HTREE_HASHV
, pctx
))
4100 if ((root
->unused_flags
& EXT2_HASH_FLAG_INCOMPAT
) &&
4101 fix_problem(ctx
, PR_1_HTREE_INCOMPAT
, pctx
))
4104 pctx
->num
= root
->indirect_levels
;
4105 if ((root
->indirect_levels
> 1) &&
4106 fix_problem(ctx
, PR_1_HTREE_DEPTH
, pctx
))
4113 * This subroutine is called on each inode to account for all of the
4114 * blocks used by that inode.
4116 static void check_blocks(e2fsck_t ctx
, struct problem_context
*pctx
,
4119 ext2_filsys fs
= ctx
->fs
;
4120 struct process_block_struct_1 pb
;
4121 ext2_ino_t ino
= pctx
->ino
;
4122 struct ext2_inode
*inode
= pctx
->inode
;
4124 int dirty_inode
= 0;
4130 pb
.num_illegal_blocks
= 0;
4131 pb
.suppress
= 0; pb
.clear
= 0;
4134 pb
.previous_block
= 0;
4135 pb
.is_dir
= LINUX_S_ISDIR(inode
->i_mode
);
4136 pb
.is_reg
= LINUX_S_ISREG(inode
->i_mode
);
4137 pb
.max_blocks
= 1 << (31 - fs
->super
->s_log_block_size
);
4144 if (inode
->i_flags
& EXT2_COMPRBLK_FL
) {
4145 if (fs
->super
->s_feature_incompat
&
4146 EXT2_FEATURE_INCOMPAT_COMPRESSION
)
4149 if (fix_problem(ctx
, PR_1_COMPR_SET
, pctx
)) {
4150 inode
->i_flags
&= ~EXT2_COMPRBLK_FL
;
4156 if (inode
->i_file_acl
&& check_ext_attr(ctx
, pctx
, block_buf
))
4159 if (ext2fs_inode_has_valid_blocks(inode
))
4160 pctx
->errcode
= ext2fs_block_iterate2(fs
, ino
,
4161 pb
.is_dir
? BLOCK_FLAG_HOLE
: 0,
4162 block_buf
, process_block
, &pb
);
4163 end_problem_latch(ctx
, PR_LATCH_BLOCK
);
4164 end_problem_latch(ctx
, PR_LATCH_TOOBIG
);
4165 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
4168 fix_problem(ctx
, PR_1_BLOCK_ITERATE
, pctx
);
4170 if (pb
.fragmented
&& pb
.num_blocks
< fs
->super
->s_blocks_per_group
)
4171 ctx
->fs_fragmented
++;
4174 inode
->i_links_count
= 0;
4175 ext2fs_icount_store(ctx
->inode_link_info
, ino
, 0);
4176 inode
->i_dtime
= time(NULL
);
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
);
4182 * The inode was probably partially accounted for
4183 * before processing was aborted, so we need to
4184 * restart the pass 1 scan.
4186 ctx
->flags
|= E2F_FLAG_RESTART
;
4190 if (inode
->i_flags
& EXT2_INDEX_FL
) {
4191 if (handle_htree(ctx
, pctx
, ino
, inode
, block_buf
)) {
4192 inode
->i_flags
&= ~EXT2_INDEX_FL
;
4196 e2fsck_add_dx_dir(ctx
, ino
, pb
.last_block
+1);
4200 if (ctx
->dirs_to_hash
&& pb
.is_dir
&&
4201 !(inode
->i_flags
& EXT2_INDEX_FL
) &&
4202 ((inode
->i_size
/ fs
->blocksize
) >= 3))
4203 ext2fs_u32_list_add(ctx
->dirs_to_hash
, ino
);
4205 if (!pb
.num_blocks
&& pb
.is_dir
) {
4206 if (fix_problem(ctx
, PR_1_ZERO_LENGTH_DIR
, pctx
)) {
4207 inode
->i_links_count
= 0;
4208 ext2fs_icount_store(ctx
->inode_link_info
, ino
, 0);
4209 inode
->i_dtime
= time(NULL
);
4211 ext2fs_unmark_inode_bitmap(ctx
->inode_dir_map
, ino
);
4212 ext2fs_unmark_inode_bitmap(ctx
->inode_reg_map
, ino
);
4213 ext2fs_unmark_inode_bitmap(ctx
->inode_used_map
, ino
);
4214 ctx
->fs_directory_count
--;
4219 pb
.num_blocks
*= (fs
->blocksize
/ 512);
4222 int nblock
= inode
->i_size
>> EXT2_BLOCK_SIZE_BITS(fs
->super
);
4223 if (nblock
> (pb
.last_block
+ 1))
4225 else if (nblock
< (pb
.last_block
+ 1)) {
4226 if (((pb
.last_block
+ 1) - nblock
) >
4227 fs
->super
->s_prealloc_dir_blocks
)
4231 size
= EXT2_I_SIZE(inode
);
4232 if ((pb
.last_block
>= 0) &&
4233 (size
< (__u64
) pb
.last_block
* fs
->blocksize
))
4235 else if (size
> ext2_max_sizes
[fs
->super
->s_log_block_size
])
4238 /* i_size for symlinks is checked elsewhere */
4239 if (bad_size
&& !LINUX_S_ISLNK(inode
->i_mode
)) {
4240 pctx
->num
= (pb
.last_block
+1) * fs
->blocksize
;
4241 if (fix_problem(ctx
, PR_1_BAD_I_SIZE
, pctx
)) {
4242 inode
->i_size
= pctx
->num
;
4243 if (!LINUX_S_ISDIR(inode
->i_mode
))
4244 inode
->i_size_high
= pctx
->num
>> 32;
4249 if (LINUX_S_ISREG(inode
->i_mode
) &&
4250 (inode
->i_size_high
|| inode
->i_size
& 0x80000000UL
))
4252 if (pb
.num_blocks
!= inode
->i_blocks
) {
4253 pctx
->num
= pb
.num_blocks
;
4254 if (fix_problem(ctx
, PR_1_BAD_I_BLOCKS
, pctx
)) {
4255 inode
->i_blocks
= pb
.num_blocks
;
4262 e2fsck_write_inode(ctx
, ino
, inode
, "check_blocks");
4267 * This is a helper function for check_blocks().
4269 static int process_block(ext2_filsys fs
,
4271 e2_blkcnt_t blockcnt
,
4272 blk_t ref_block
FSCK_ATTR((unused
)),
4273 int ref_offset
FSCK_ATTR((unused
)),
4276 struct process_block_struct_1
*p
;
4277 struct problem_context
*pctx
;
4278 blk_t blk
= *block_nr
;
4283 p
= (struct process_block_struct_1
*) priv_data
;
4287 if (p
->compressed
&& (blk
== EXT2FS_COMPRESSED_BLKADDR
)) {
4288 /* todo: Check that the comprblk_fl is high, that the
4289 blkaddr pattern looks right (all non-holes up to
4290 first EXT2FS_COMPRESSED_BLKADDR, then all
4291 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4292 that the feature_incompat bit is high, and that the
4293 inode is a regular file. If we're doing a "full
4294 check" (a concept introduced to e2fsck by e2compr,
4295 meaning that we look at data blocks as well as
4296 metadata) then call some library routine that
4297 checks the compressed data. I'll have to think
4298 about this, because one particularly important
4299 problem to be able to fix is to recalculate the
4300 cluster size if necessary. I think that perhaps
4301 we'd better do most/all e2compr-specific checks
4302 separately, after the non-e2compr checks. If not
4303 doing a full check, it may be useful to test that
4304 the personality is linux; e.g. if it isn't then
4305 perhaps this really is just an illegal block. */
4310 if (p
->is_dir
== 0) {
4312 * Should never happen, since only directories
4313 * get called with BLOCK_FLAG_HOLE
4316 printf("process_block() called with blk == 0, "
4317 "blockcnt=%d, inode %lu???\n",
4324 if (blockcnt
* fs
->blocksize
< p
->inode
->i_size
) {
4331 * Simplistic fragmentation check. We merely require that the
4332 * file be contiguous. (Which can never be true for really
4333 * big files that are greater than a block group.)
4335 if (!HOLE_BLKADDR(p
->previous_block
)) {
4336 if (p
->previous_block
+1 != blk
)
4339 p
->previous_block
= blk
;
4341 if (p
->is_dir
&& blockcnt
> (1 << (21 - fs
->super
->s_log_block_size
)))
4342 problem
= PR_1_TOOBIG_DIR
;
4343 if (p
->is_reg
&& p
->num_blocks
+1 >= p
->max_blocks
)
4344 problem
= PR_1_TOOBIG_REG
;
4345 if (!p
->is_dir
&& !p
->is_reg
&& blockcnt
> 0)
4346 problem
= PR_1_TOOBIG_SYMLINK
;
4348 if (blk
< fs
->super
->s_first_data_block
||
4349 blk
>= fs
->super
->s_blocks_count
)
4350 problem
= PR_1_ILLEGAL_BLOCK_NUM
;
4353 p
->num_illegal_blocks
++;
4354 if (!p
->suppress
&& (p
->num_illegal_blocks
% 12) == 0) {
4355 if (fix_problem(ctx
, PR_1_TOO_MANY_BAD_BLOCKS
, pctx
)) {
4359 if (fix_problem(ctx
, PR_1_SUPPRESS_MESSAGES
, pctx
)) {
4361 set_latch_flags(PR_LATCH_BLOCK
,
4366 pctx
->blkcount
= blockcnt
;
4367 if (fix_problem(ctx
, problem
, pctx
)) {
4368 blk
= *block_nr
= 0;
4369 ret_code
= BLOCK_CHANGED
;
4375 if (p
->ino
== EXT2_RESIZE_INO
) {
4377 * The resize inode has already be sanity checked
4378 * during pass #0 (the superblock checks). All we
4379 * have to do is mark the double indirect block as
4380 * being in use; all of the other blocks are handled
4381 * by mark_table_blocks()).
4383 if (blockcnt
== BLOCK_COUNT_DIND
)
4384 mark_block_used(ctx
, blk
);
4386 mark_block_used(ctx
, blk
);
4389 p
->last_block
= blockcnt
;
4391 if (p
->is_dir
&& (blockcnt
>= 0)) {
4392 pctx
->errcode
= ext2fs_add_dir_block(fs
->dblist
, p
->ino
,
4394 if (pctx
->errcode
) {
4396 pctx
->num
= blockcnt
;
4397 fix_problem(ctx
, PR_1_ADD_DBLOCK
, pctx
);
4398 /* Should never get here */
4399 ctx
->flags
|= E2F_FLAG_ABORT
;
4406 static int process_bad_block(ext2_filsys fs
FSCK_ATTR((unused
)),
4408 e2_blkcnt_t blockcnt
,
4409 blk_t ref_block
FSCK_ATTR((unused
)),
4410 int ref_offset
FSCK_ATTR((unused
)),
4411 void *priv_data
EXT2FS_ATTR((unused
)))
4414 * Note: This function processes blocks for the bad blocks
4415 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4418 printf("Unrecoverable Error: Found %"PRIi64
" bad blocks starting at block number: %u\n", blockcnt
, *block_nr
);
4423 * This routine gets called at the end of pass 1 if bad blocks are
4424 * detected in the superblock, group descriptors, inode_bitmaps, or
4425 * block bitmaps. At this point, all of the blocks have been mapped
4426 * out, so we can try to allocate new block(s) to replace the bad
4429 static void handle_fs_bad_blocks(e2fsck_t ctx
EXT2FS_ATTR((unused
)))
4431 printf("Bad blocks detected on your filesystem\n"
4432 "You should get your data off as the device will soon die\n");
4436 * This routine marks all blocks which are used by the superblock,
4437 * group descriptors, inode bitmaps, and block bitmaps.
4439 static void mark_table_blocks(e2fsck_t ctx
)
4441 ext2_filsys fs
= ctx
->fs
;
4445 struct problem_context pctx
;
4447 clear_problem_context(&pctx
);
4449 block
= fs
->super
->s_first_data_block
;
4450 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
4453 ext2fs_reserve_super_and_bgd(fs
, i
, ctx
->block_found_map
);
4456 * Mark the blocks used for the inode table
4458 if (fs
->group_desc
[i
].bg_inode_table
) {
4459 for (j
= 0, b
= fs
->group_desc
[i
].bg_inode_table
;
4460 j
< fs
->inode_blocks_per_group
;
4462 if (ext2fs_test_block_bitmap(ctx
->block_found_map
,
4465 if (fix_problem(ctx
,
4466 PR_1_ITABLE_CONFLICT
, &pctx
)) {
4467 ctx
->invalid_inode_table_flag
[i
]++;
4468 ctx
->invalid_bitmaps
++;
4471 ext2fs_mark_block_bitmap(ctx
->block_found_map
, b
);
4477 * Mark block used for the block bitmap
4479 if (fs
->group_desc
[i
].bg_block_bitmap
) {
4480 if (ext2fs_test_block_bitmap(ctx
->block_found_map
,
4481 fs
->group_desc
[i
].bg_block_bitmap
)) {
4482 pctx
.blk
= fs
->group_desc
[i
].bg_block_bitmap
;
4483 if (fix_problem(ctx
, PR_1_BB_CONFLICT
, &pctx
)) {
4484 ctx
->invalid_block_bitmap_flag
[i
]++;
4485 ctx
->invalid_bitmaps
++;
4488 ext2fs_mark_block_bitmap(ctx
->block_found_map
,
4489 fs
->group_desc
[i
].bg_block_bitmap
);
4493 * Mark block used for the inode bitmap
4495 if (fs
->group_desc
[i
].bg_inode_bitmap
) {
4496 if (ext2fs_test_block_bitmap(ctx
->block_found_map
,
4497 fs
->group_desc
[i
].bg_inode_bitmap
)) {
4498 pctx
.blk
= fs
->group_desc
[i
].bg_inode_bitmap
;
4499 if (fix_problem(ctx
, PR_1_IB_CONFLICT
, &pctx
)) {
4500 ctx
->invalid_inode_bitmap_flag
[i
]++;
4501 ctx
->invalid_bitmaps
++;
4504 ext2fs_mark_block_bitmap(ctx
->block_found_map
,
4505 fs
->group_desc
[i
].bg_inode_bitmap
);
4508 block
+= fs
->super
->s_blocks_per_group
;
4513 * Thes subroutines short circuits ext2fs_get_blocks and
4514 * ext2fs_check_directory; we use them since we already have the inode
4515 * structure, so there's no point in letting the ext2fs library read
4518 static errcode_t
pass1_get_blocks(ext2_filsys fs
, ext2_ino_t ino
,
4521 e2fsck_t ctx
= (e2fsck_t
) fs
->priv_data
;
4524 if ((ino
!= ctx
->stashed_ino
) || !ctx
->stashed_inode
)
4525 return EXT2_ET_CALLBACK_NOTHANDLED
;
4527 for (i
=0; i
< EXT2_N_BLOCKS
; i
++)
4528 blocks
[i
] = ctx
->stashed_inode
->i_block
[i
];
4532 static errcode_t
pass1_read_inode(ext2_filsys fs
, ext2_ino_t ino
,
4533 struct ext2_inode
*inode
)
4535 e2fsck_t ctx
= (e2fsck_t
) fs
->priv_data
;
4537 if ((ino
!= ctx
->stashed_ino
) || !ctx
->stashed_inode
)
4538 return EXT2_ET_CALLBACK_NOTHANDLED
;
4539 *inode
= *ctx
->stashed_inode
;
4543 static errcode_t
pass1_write_inode(ext2_filsys fs
, ext2_ino_t ino
,
4544 struct ext2_inode
*inode
)
4546 e2fsck_t ctx
= (e2fsck_t
) fs
->priv_data
;
4548 if ((ino
== ctx
->stashed_ino
) && ctx
->stashed_inode
)
4549 *ctx
->stashed_inode
= *inode
;
4550 return EXT2_ET_CALLBACK_NOTHANDLED
;
4553 static errcode_t
pass1_check_directory(ext2_filsys fs
, ext2_ino_t ino
)
4555 e2fsck_t ctx
= (e2fsck_t
) fs
->priv_data
;
4557 if ((ino
!= ctx
->stashed_ino
) || !ctx
->stashed_inode
)
4558 return EXT2_ET_CALLBACK_NOTHANDLED
;
4560 if (!LINUX_S_ISDIR(ctx
->stashed_inode
->i_mode
))
4561 return EXT2_ET_NO_DIRECTORY
;
4565 void e2fsck_use_inode_shortcuts(e2fsck_t ctx
, int fl_bool
)
4567 ext2_filsys fs
= ctx
->fs
;
4570 fs
->get_blocks
= pass1_get_blocks
;
4571 fs
->check_directory
= pass1_check_directory
;
4572 fs
->read_inode
= pass1_read_inode
;
4573 fs
->write_inode
= pass1_write_inode
;
4574 ctx
->stashed_ino
= 0;
4577 fs
->check_directory
= 0;
4579 fs
->write_inode
= 0;
4584 * pass1b.c --- Pass #1b of e2fsck
4586 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4587 * only invoked if pass 1 discovered blocks which are in use by more
4590 * Pass1B scans the data blocks of all the inodes again, generating a
4591 * complete list of duplicate blocks and which inodes have claimed
4594 * Pass1C does a tree-traversal of the filesystem, to determine the
4595 * parent directories of these inodes. This step is necessary so that
4596 * e2fsck can print out the pathnames of affected inodes.
4598 * Pass1D is a reconciliation pass. For each inode with duplicate
4599 * blocks, the user is prompted if s/he would like to clone the file
4600 * (so that the file gets a fresh copy of the duplicated blocks) or
4601 * simply to delete the file.
4606 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4607 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4608 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4610 /* Define an extension to the ext2 library's block count information */
4611 #define BLOCK_COUNT_EXTATTR (-5)
4615 struct block_el
*next
;
4620 struct inode_el
*next
;
4625 struct inode_el
*inode_list
;
4629 * This structure stores information about a particular inode which
4630 * is sharing blocks with other inodes. This information is collected
4631 * to display to the user, so that the user knows what files he or she
4632 * is dealing with, when trying to decide how to resolve the conflict
4633 * of multiply-claimed blocks.
4638 struct ext2_inode inode
;
4639 struct block_el
*block_list
;
4642 static int process_pass1b_block(ext2_filsys fs
, blk_t
*blocknr
,
4643 e2_blkcnt_t blockcnt
, blk_t ref_blk
,
4644 int ref_offset
, void *priv_data
);
4645 static void delete_file(e2fsck_t ctx
, ext2_ino_t ino
,
4646 struct dup_inode
*dp
, char *block_buf
);
4647 static int clone_file(e2fsck_t ctx
, ext2_ino_t ino
,
4648 struct dup_inode
*dp
, char* block_buf
);
4649 static int check_if_fs_block(e2fsck_t ctx
, blk_t test_blk
);
4651 static void pass1b(e2fsck_t ctx
, char *block_buf
);
4652 static void pass1c(e2fsck_t ctx
, char *block_buf
);
4653 static void pass1d(e2fsck_t ctx
, char *block_buf
);
4655 static int dup_inode_count
= 0;
4657 static dict_t blk_dict
, ino_dict
;
4659 static ext2fs_inode_bitmap inode_dup_map
;
4661 static int dict_int_cmp(const void *a
, const void *b
)
4672 * Add a duplicate block record
4674 static void add_dupe(e2fsck_t ctx
, ext2_ino_t ino
, blk_t blk
,
4675 struct ext2_inode
*inode
)
4678 struct dup_block
*db
;
4679 struct dup_inode
*di
;
4680 struct block_el
*blk_el
;
4681 struct inode_el
*ino_el
;
4683 n
= dict_lookup(&blk_dict
, INT_TO_VOIDPTR(blk
));
4685 db
= (struct dup_block
*) dnode_get(n
);
4687 db
= (struct dup_block
*) e2fsck_allocate_memory(ctx
,
4688 sizeof(struct dup_block
), "duplicate block header");
4691 dict_alloc_insert(&blk_dict
, INT_TO_VOIDPTR(blk
), db
);
4693 ino_el
= (struct inode_el
*) e2fsck_allocate_memory(ctx
,
4694 sizeof(struct inode_el
), "inode element");
4695 ino_el
->inode
= ino
;
4696 ino_el
->next
= db
->inode_list
;
4697 db
->inode_list
= ino_el
;
4700 n
= dict_lookup(&ino_dict
, INT_TO_VOIDPTR(ino
));
4702 di
= (struct dup_inode
*) dnode_get(n
);
4704 di
= (struct dup_inode
*) e2fsck_allocate_memory(ctx
,
4705 sizeof(struct dup_inode
), "duplicate inode header");
4706 di
->dir
= (ino
== EXT2_ROOT_INO
) ? EXT2_ROOT_INO
: 0;
4707 di
->num_dupblocks
= 0;
4710 dict_alloc_insert(&ino_dict
, INT_TO_VOIDPTR(ino
), di
);
4712 blk_el
= (struct block_el
*) e2fsck_allocate_memory(ctx
,
4713 sizeof(struct block_el
), "block element");
4714 blk_el
->block
= blk
;
4715 blk_el
->next
= di
->block_list
;
4716 di
->block_list
= blk_el
;
4717 di
->num_dupblocks
++;
4721 * Free a duplicate inode record
4723 static void inode_dnode_free(dnode_t
*node
)
4725 struct dup_inode
*di
;
4726 struct block_el
*p
, *next
;
4728 di
= (struct dup_inode
*) dnode_get(node
);
4729 for (p
= di
->block_list
; p
; p
= next
) {
4737 * Free a duplicate block record
4739 static void block_dnode_free(dnode_t
*node
)
4741 struct dup_block
*db
;
4742 struct inode_el
*p
, *next
;
4744 db
= (struct dup_block
*) dnode_get(node
);
4745 for (p
= db
->inode_list
; p
; p
= next
) {
4754 * Main procedure for handling duplicate blocks
4756 void e2fsck_pass1_dupblocks(e2fsck_t ctx
, char *block_buf
)
4758 ext2_filsys fs
= ctx
->fs
;
4759 struct problem_context pctx
;
4761 clear_problem_context(&pctx
);
4763 pctx
.errcode
= ext2fs_allocate_inode_bitmap(fs
,
4764 _("multiply claimed inode map"), &inode_dup_map
);
4766 fix_problem(ctx
, PR_1B_ALLOCATE_IBITMAP_ERROR
, &pctx
);
4767 ctx
->flags
|= E2F_FLAG_ABORT
;
4771 dict_init(&ino_dict
, DICTCOUNT_T_MAX
, dict_int_cmp
);
4772 dict_init(&blk_dict
, DICTCOUNT_T_MAX
, dict_int_cmp
);
4773 dict_set_allocator(&ino_dict
, inode_dnode_free
);
4774 dict_set_allocator(&blk_dict
, block_dnode_free
);
4776 pass1b(ctx
, block_buf
);
4777 pass1c(ctx
, block_buf
);
4778 pass1d(ctx
, block_buf
);
4781 * Time to free all of the accumulated data structures that we
4782 * don't need anymore.
4784 dict_free_nodes(&ino_dict
);
4785 dict_free_nodes(&blk_dict
);
4789 * Scan the inodes looking for inodes that contain duplicate blocks.
4791 struct process_block_struct_1b
{
4795 struct ext2_inode
*inode
;
4796 struct problem_context
*pctx
;
4799 static void pass1b(e2fsck_t ctx
, char *block_buf
)
4801 ext2_filsys fs
= ctx
->fs
;
4803 struct ext2_inode inode
;
4804 ext2_inode_scan scan
;
4805 struct process_block_struct_1b pb
;
4806 struct problem_context pctx
;
4808 clear_problem_context(&pctx
);
4810 if (!(ctx
->options
& E2F_OPT_PREEN
))
4811 fix_problem(ctx
, PR_1B_PASS_HEADER
, &pctx
);
4812 pctx
.errcode
= ext2fs_open_inode_scan(fs
, ctx
->inode_buffer_blocks
,
4815 fix_problem(ctx
, PR_1B_ISCAN_ERROR
, &pctx
);
4816 ctx
->flags
|= E2F_FLAG_ABORT
;
4819 ctx
->stashed_inode
= &inode
;
4822 pctx
.str
= "pass1b";
4824 pctx
.errcode
= ext2fs_get_next_inode(scan
, &ino
, &inode
);
4825 if (pctx
.errcode
== EXT2_ET_BAD_BLOCK_IN_INODE_TABLE
)
4828 fix_problem(ctx
, PR_1B_ISCAN_ERROR
, &pctx
);
4829 ctx
->flags
|= E2F_FLAG_ABORT
;
4834 pctx
.ino
= ctx
->stashed_ino
= ino
;
4835 if ((ino
!= EXT2_BAD_INO
) &&
4836 !ext2fs_test_inode_bitmap(ctx
->inode_used_map
, ino
))
4843 if (ext2fs_inode_has_valid_blocks(&inode
) ||
4844 (ino
== EXT2_BAD_INO
))
4845 pctx
.errcode
= ext2fs_block_iterate2(fs
, ino
,
4846 0, block_buf
, process_pass1b_block
, &pb
);
4847 if (inode
.i_file_acl
)
4848 process_pass1b_block(fs
, &inode
.i_file_acl
,
4849 BLOCK_COUNT_EXTATTR
, 0, 0, &pb
);
4850 if (pb
.dup_blocks
) {
4851 end_problem_latch(ctx
, PR_LATCH_DBLOCK
);
4852 if (ino
>= EXT2_FIRST_INODE(fs
->super
) ||
4853 ino
== EXT2_ROOT_INO
)
4857 fix_problem(ctx
, PR_1B_BLOCK_ITERATE
, &pctx
);
4859 ext2fs_close_inode_scan(scan
);
4860 e2fsck_use_inode_shortcuts(ctx
, 0);
4863 static int process_pass1b_block(ext2_filsys fs
FSCK_ATTR((unused
)),
4865 e2_blkcnt_t blockcnt
FSCK_ATTR((unused
)),
4866 blk_t ref_blk
FSCK_ATTR((unused
)),
4867 int ref_offset
FSCK_ATTR((unused
)),
4870 struct process_block_struct_1b
*p
;
4873 if (HOLE_BLKADDR(*block_nr
))
4875 p
= (struct process_block_struct_1b
*) priv_data
;
4878 if (!ext2fs_test_block_bitmap(ctx
->block_dup_map
, *block_nr
))
4881 /* OK, this is a duplicate block */
4882 if (p
->ino
!= EXT2_BAD_INO
) {
4883 p
->pctx
->blk
= *block_nr
;
4884 fix_problem(ctx
, PR_1B_DUP_BLOCK
, p
->pctx
);
4887 ext2fs_mark_inode_bitmap(inode_dup_map
, p
->ino
);
4889 add_dupe(ctx
, p
->ino
, *block_nr
, p
->inode
);
4895 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4896 * is used so that we can print pathnames when prompting the user for
4899 struct search_dir_struct
{
4901 ext2_ino_t first_inode
;
4902 ext2_ino_t max_inode
;
4905 static int search_dirent_proc(ext2_ino_t dir
, int entry
,
4906 struct ext2_dir_entry
*dirent
,
4907 int offset
FSCK_ATTR((unused
)),
4908 int blocksize
FSCK_ATTR((unused
)),
4909 char *buf
FSCK_ATTR((unused
)),
4912 struct search_dir_struct
*sd
;
4913 struct dup_inode
*p
;
4916 sd
= (struct search_dir_struct
*) priv_data
;
4918 if (dirent
->inode
> sd
->max_inode
)
4919 /* Should abort this inode, but not everything */
4922 if ((dirent
->inode
< sd
->first_inode
) || (entry
< DIRENT_OTHER_FILE
) ||
4923 !ext2fs_test_inode_bitmap(inode_dup_map
, dirent
->inode
))
4926 n
= dict_lookup(&ino_dict
, INT_TO_VOIDPTR(dirent
->inode
));
4929 p
= (struct dup_inode
*) dnode_get(n
);
4933 return sd
->count
? 0 : DIRENT_ABORT
;
4937 static void pass1c(e2fsck_t ctx
, char *block_buf
)
4939 ext2_filsys fs
= ctx
->fs
;
4940 struct search_dir_struct sd
;
4941 struct problem_context pctx
;
4943 clear_problem_context(&pctx
);
4945 if (!(ctx
->options
& E2F_OPT_PREEN
))
4946 fix_problem(ctx
, PR_1C_PASS_HEADER
, &pctx
);
4949 * Search through all directories to translate inodes to names
4950 * (by searching for the containing directory for that inode.)
4952 sd
.count
= dup_inode_count
;
4953 sd
.first_inode
= EXT2_FIRST_INODE(fs
->super
);
4954 sd
.max_inode
= fs
->super
->s_inodes_count
;
4955 ext2fs_dblist_dir_iterate(fs
->dblist
, 0, block_buf
,
4956 search_dirent_proc
, &sd
);
4959 static void pass1d(e2fsck_t ctx
, char *block_buf
)
4961 ext2_filsys fs
= ctx
->fs
;
4962 struct dup_inode
*p
, *t
;
4963 struct dup_block
*q
;
4964 ext2_ino_t
*shared
, ino
;
4969 struct problem_context pctx
;
4974 clear_problem_context(&pctx
);
4976 if (!(ctx
->options
& E2F_OPT_PREEN
))
4977 fix_problem(ctx
, PR_1D_PASS_HEADER
, &pctx
);
4978 e2fsck_read_bitmaps(ctx
);
4980 pctx
.num
= dup_inode_count
; /* dict_count(&ino_dict); */
4981 fix_problem(ctx
, PR_1D_NUM_DUP_INODES
, &pctx
);
4982 shared
= (ext2_ino_t
*) e2fsck_allocate_memory(ctx
,
4983 sizeof(ext2_ino_t
) * dict_count(&ino_dict
),
4984 "Shared inode list");
4985 for (n
= dict_first(&ino_dict
); n
; n
= dict_next(&ino_dict
, n
)) {
4986 p
= (struct dup_inode
*) dnode_get(n
);
4989 ino
= (ext2_ino_t
)VOIDPTR_TO_INT(dnode_getkey(n
));
4990 if (ino
== EXT2_BAD_INO
|| ino
== EXT2_RESIZE_INO
)
4994 * Find all of the inodes which share blocks with this
4995 * one. First we find all of the duplicate blocks
4996 * belonging to this inode, and then search each block
4997 * get the list of inodes, and merge them together.
4999 for (s
= p
->block_list
; s
; s
= s
->next
) {
5000 m
= dict_lookup(&blk_dict
, INT_TO_VOIDPTR(s
->block
));
5002 continue; /* Should never happen... */
5003 q
= (struct dup_block
*) dnode_get(m
);
5006 if (check_if_fs_block(ctx
, s
->block
)) {
5012 * Add all inodes used by this block to the
5013 * shared[] --- which is a unique list, so
5014 * if an inode is already in shared[], don't
5017 for (r
= q
->inode_list
; r
; r
= r
->next
) {
5018 if (r
->inode
== ino
)
5020 for (i
= 0; i
< shared_len
; i
++)
5021 if (shared
[i
] == r
->inode
)
5023 if (i
== shared_len
) {
5024 shared
[shared_len
++] = r
->inode
;
5030 * Report the inode that we are working on
5032 pctx
.inode
= &p
->inode
;
5035 pctx
.blkcount
= p
->num_dupblocks
;
5036 pctx
.num
= meta_data
? shared_len
+1 : shared_len
;
5037 fix_problem(ctx
, PR_1D_DUP_FILE
, &pctx
);
5042 fix_problem(ctx
, PR_1D_SHARE_METADATA
, &pctx
);
5044 for (i
= 0; i
< shared_len
; i
++) {
5045 m
= dict_lookup(&ino_dict
, INT_TO_VOIDPTR(shared
[i
]));
5047 continue; /* should never happen */
5048 t
= (struct dup_inode
*) dnode_get(m
);
5050 * Report the inode that we are sharing with
5052 pctx
.inode
= &t
->inode
;
5053 pctx
.ino
= shared
[i
];
5055 fix_problem(ctx
, PR_1D_DUP_FILE_LIST
, &pctx
);
5058 fix_problem(ctx
, PR_1D_DUP_BLOCKS_DEALT
, &pctx
);
5061 if (fix_problem(ctx
, PR_1D_CLONE_QUESTION
, &pctx
)) {
5062 pctx
.errcode
= clone_file(ctx
, ino
, p
, block_buf
);
5064 fix_problem(ctx
, PR_1D_CLONE_ERROR
, &pctx
);
5068 if (fix_problem(ctx
, PR_1D_DELETE_QUESTION
, &pctx
))
5069 delete_file(ctx
, ino
, p
, block_buf
);
5071 ext2fs_unmark_valid(fs
);
5073 ext2fs_free_mem(&shared
);
5077 * Drop the refcount on the dup_block structure, and clear the entry
5078 * in the block_dup_map if appropriate.
5080 static void decrement_badcount(e2fsck_t ctx
, blk_t block
, struct dup_block
*p
)
5083 if (p
->num_bad
<= 0 ||
5084 (p
->num_bad
== 1 && !check_if_fs_block(ctx
, block
)))
5085 ext2fs_unmark_block_bitmap(ctx
->block_dup_map
, block
);
5088 static int delete_file_block(ext2_filsys fs
,
5090 e2_blkcnt_t blockcnt
FSCK_ATTR((unused
)),
5091 blk_t ref_block
FSCK_ATTR((unused
)),
5092 int ref_offset
FSCK_ATTR((unused
)),
5095 struct process_block_struct_1b
*pb
;
5096 struct dup_block
*p
;
5100 pb
= (struct process_block_struct_1b
*) priv_data
;
5103 if (HOLE_BLKADDR(*block_nr
))
5106 if (ext2fs_test_block_bitmap(ctx
->block_dup_map
, *block_nr
)) {
5107 n
= dict_lookup(&blk_dict
, INT_TO_VOIDPTR(*block_nr
));
5109 p
= (struct dup_block
*) dnode_get(n
);
5110 decrement_badcount(ctx
, *block_nr
, p
);
5112 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5115 ext2fs_unmark_block_bitmap(ctx
->block_found_map
, *block_nr
);
5116 ext2fs_block_alloc_stats(fs
, *block_nr
, -1);
5122 static void delete_file(e2fsck_t ctx
, ext2_ino_t ino
,
5123 struct dup_inode
*dp
, char* block_buf
)
5125 ext2_filsys fs
= ctx
->fs
;
5126 struct process_block_struct_1b pb
;
5127 struct ext2_inode inode
;
5128 struct problem_context pctx
;
5131 clear_problem_context(&pctx
);
5132 pctx
.ino
= pb
.ino
= ino
;
5133 pb
.dup_blocks
= dp
->num_dupblocks
;
5135 pctx
.str
= "delete_file";
5137 e2fsck_read_inode(ctx
, ino
, &inode
, "delete_file");
5138 if (ext2fs_inode_has_valid_blocks(&inode
))
5139 pctx
.errcode
= ext2fs_block_iterate2(fs
, ino
, 0, block_buf
,
5140 delete_file_block
, &pb
);
5142 fix_problem(ctx
, PR_1B_BLOCK_ITERATE
, &pctx
);
5143 ext2fs_unmark_inode_bitmap(ctx
->inode_used_map
, ino
);
5144 ext2fs_unmark_inode_bitmap(ctx
->inode_dir_map
, ino
);
5145 if (ctx
->inode_bad_map
)
5146 ext2fs_unmark_inode_bitmap(ctx
->inode_bad_map
, ino
);
5147 ext2fs_inode_alloc_stats2(fs
, ino
, -1, LINUX_S_ISDIR(inode
.i_mode
));
5149 /* Inode may have changed by block_iterate, so reread it */
5150 e2fsck_read_inode(ctx
, ino
, &inode
, "delete_file");
5151 inode
.i_links_count
= 0;
5152 inode
.i_dtime
= time(NULL
);
5153 if (inode
.i_file_acl
&&
5154 (fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
)) {
5156 pctx
.errcode
= ext2fs_adjust_ea_refcount(fs
, inode
.i_file_acl
,
5157 block_buf
, -1, &count
);
5158 if (pctx
.errcode
== EXT2_ET_BAD_EA_BLOCK_NUM
) {
5163 pctx
.blk
= inode
.i_file_acl
;
5164 fix_problem(ctx
, PR_1B_ADJ_EA_REFCOUNT
, &pctx
);
5167 * If the count is zero, then arrange to have the
5168 * block deleted. If the block is in the block_dup_map,
5169 * also call delete_file_block since it will take care
5170 * of keeping the accounting straight.
5173 ext2fs_test_block_bitmap(ctx
->block_dup_map
,
5175 delete_file_block(fs
, &inode
.i_file_acl
,
5176 BLOCK_COUNT_EXTATTR
, 0, 0, &pb
);
5178 e2fsck_write_inode(ctx
, ino
, &inode
, "delete_file");
5181 struct clone_struct
{
5188 static int clone_file_block(ext2_filsys fs
,
5190 e2_blkcnt_t blockcnt
,
5191 blk_t ref_block
FSCK_ATTR((unused
)),
5192 int ref_offset
FSCK_ATTR((unused
)),
5195 struct dup_block
*p
;
5198 struct clone_struct
*cs
= (struct clone_struct
*) priv_data
;
5204 if (HOLE_BLKADDR(*block_nr
))
5207 if (ext2fs_test_block_bitmap(ctx
->block_dup_map
, *block_nr
)) {
5208 n
= dict_lookup(&blk_dict
, INT_TO_VOIDPTR(*block_nr
));
5210 p
= (struct dup_block
*) dnode_get(n
);
5211 retval
= ext2fs_new_block(fs
, 0, ctx
->block_found_map
,
5214 cs
->errcode
= retval
;
5217 if (cs
->dir
&& (blockcnt
>= 0)) {
5218 retval
= ext2fs_set_dir_block(fs
->dblist
,
5219 cs
->dir
, new_block
, blockcnt
);
5221 cs
->errcode
= retval
;
5226 retval
= io_channel_read_blk(fs
->io
, *block_nr
, 1,
5229 cs
->errcode
= retval
;
5232 retval
= io_channel_write_blk(fs
->io
, new_block
, 1,
5235 cs
->errcode
= retval
;
5238 decrement_badcount(ctx
, *block_nr
, p
);
5239 *block_nr
= new_block
;
5240 ext2fs_mark_block_bitmap(ctx
->block_found_map
,
5242 ext2fs_mark_block_bitmap(fs
->block_map
, new_block
);
5243 return BLOCK_CHANGED
;
5245 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5251 static int clone_file(e2fsck_t ctx
, ext2_ino_t ino
,
5252 struct dup_inode
*dp
, char* block_buf
)
5254 ext2_filsys fs
= ctx
->fs
;
5256 struct clone_struct cs
;
5257 struct problem_context pctx
;
5260 struct inode_el
*ino_el
;
5261 struct dup_block
*db
;
5262 struct dup_inode
*di
;
5264 clear_problem_context(&pctx
);
5268 retval
= ext2fs_get_mem(fs
->blocksize
, &cs
.buf
);
5272 if (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
, ino
))
5276 pctx
.str
= "clone_file";
5277 if (ext2fs_inode_has_valid_blocks(&dp
->inode
))
5278 pctx
.errcode
= ext2fs_block_iterate2(fs
, ino
, 0, block_buf
,
5279 clone_file_block
, &cs
);
5280 ext2fs_mark_bb_dirty(fs
);
5282 fix_problem(ctx
, PR_1B_BLOCK_ITERATE
, &pctx
);
5283 retval
= pctx
.errcode
;
5287 bb_error_msg(_("returned from clone_file_block"));
5288 retval
= cs
.errcode
;
5291 /* The inode may have changed on disk, so we have to re-read it */
5292 e2fsck_read_inode(ctx
, ino
, &dp
->inode
, "clone file EA");
5293 blk
= dp
->inode
.i_file_acl
;
5294 if (blk
&& (clone_file_block(fs
, &dp
->inode
.i_file_acl
,
5295 BLOCK_COUNT_EXTATTR
, 0, 0, &cs
) ==
5297 e2fsck_write_inode(ctx
, ino
, &dp
->inode
, "clone file EA");
5299 * If we cloned the EA block, find all other inodes
5300 * which refered to that EA block, and modify
5301 * them to point to the new EA block.
5303 n
= dict_lookup(&blk_dict
, INT_TO_VOIDPTR(blk
));
5304 db
= (struct dup_block
*) dnode_get(n
);
5305 for (ino_el
= db
->inode_list
; ino_el
; ino_el
= ino_el
->next
) {
5306 if (ino_el
->inode
== ino
)
5308 n
= dict_lookup(&ino_dict
, INT_TO_VOIDPTR(ino_el
->inode
));
5309 di
= (struct dup_inode
*) dnode_get(n
);
5310 if (di
->inode
.i_file_acl
== blk
) {
5311 di
->inode
.i_file_acl
= dp
->inode
.i_file_acl
;
5312 e2fsck_write_inode(ctx
, ino_el
->inode
,
5313 &di
->inode
, "clone file EA");
5314 decrement_badcount(ctx
, blk
, db
);
5320 ext2fs_free_mem(&cs
.buf
);
5325 * This routine returns 1 if a block overlaps with one of the superblocks,
5326 * group descriptors, inode bitmaps, or block bitmaps.
5328 static int check_if_fs_block(e2fsck_t ctx
, blk_t test_block
)
5330 ext2_filsys fs
= ctx
->fs
;
5334 block
= fs
->super
->s_first_data_block
;
5335 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
5337 /* Check superblocks/block group descriptros */
5338 if (ext2fs_bg_has_super(fs
, i
)) {
5339 if (test_block
>= block
&&
5340 (test_block
<= block
+ fs
->desc_blocks
))
5344 /* Check the inode table */
5345 if ((fs
->group_desc
[i
].bg_inode_table
) &&
5346 (test_block
>= fs
->group_desc
[i
].bg_inode_table
) &&
5347 (test_block
< (fs
->group_desc
[i
].bg_inode_table
+
5348 fs
->inode_blocks_per_group
)))
5351 /* Check the bitmap blocks */
5352 if ((test_block
== fs
->group_desc
[i
].bg_block_bitmap
) ||
5353 (test_block
== fs
->group_desc
[i
].bg_inode_bitmap
))
5356 block
+= fs
->super
->s_blocks_per_group
;
5361 * pass2.c --- check directory structure
5363 * Pass 2 of e2fsck iterates through all active directory inodes, and
5364 * applies to following tests to each directory entry in the directory
5365 * blocks in the inodes:
5367 * - The length of the directory entry (rec_len) should be at
5368 * least 8 bytes, and no more than the remaining space
5369 * left in the directory block.
5370 * - The length of the name in the directory entry (name_len)
5371 * should be less than (rec_len - 8).
5372 * - The inode number in the directory entry should be within
5374 * - The inode number should refer to a in-use inode.
5375 * - The first entry should be '.', and its inode should be
5376 * the inode of the directory.
5377 * - The second entry should be '..'.
5379 * To minimize disk seek time, the directory blocks are processed in
5380 * sorted order of block numbers.
5382 * Pass 2 also collects the following information:
5383 * - The inode numbers of the subdirectories for each directory.
5385 * Pass 2 relies on the following information from previous passes:
5386 * - The directory information collected in pass 1.
5387 * - The inode_used_map bitmap
5388 * - The inode_bad_map bitmap
5389 * - The inode_dir_map bitmap
5391 * Pass 2 frees the following data structures
5392 * - The inode_bad_map bitmap
5393 * - The inode_reg_map bitmap
5397 * Keeps track of how many times an inode is referenced.
5399 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
);
5400 static int check_dir_block(ext2_filsys fs
,
5401 struct ext2_db_entry
*dir_blocks_info
,
5403 static int allocate_dir_block(e2fsck_t ctx
, struct ext2_db_entry
*dir_blocks_info
,
5404 struct problem_context
*pctx
);
5405 static int update_dir_block(ext2_filsys fs
,
5407 e2_blkcnt_t blockcnt
,
5411 static void clear_htree(e2fsck_t ctx
, ext2_ino_t ino
);
5412 static int htree_depth(struct dx_dir_info
*dx_dir
,
5413 struct dx_dirblock_info
*dx_db
);
5414 static int special_dir_block_cmp(const void *a
, const void *b
);
5416 struct check_dir_struct
{
5418 struct problem_context pctx
;
5423 static void e2fsck_pass2(e2fsck_t ctx
)
5425 struct ext2_super_block
*sb
= ctx
->fs
->super
;
5426 struct problem_context pctx
;
5427 ext2_filsys fs
= ctx
->fs
;
5429 struct dir_info
*dir
;
5430 struct check_dir_struct cd
;
5431 struct dx_dir_info
*dx_dir
;
5432 struct dx_dirblock_info
*dx_db
, *dx_parent
;
5438 clear_problem_context(&cd
.pctx
);
5442 if (!(ctx
->options
& E2F_OPT_PREEN
))
5443 fix_problem(ctx
, PR_2_PASS_HEADER
, &cd
.pctx
);
5445 cd
.pctx
.errcode
= ext2fs_create_icount2(fs
, EXT2_ICOUNT_OPT_INCREMENT
,
5446 0, ctx
->inode_link_info
,
5448 if (cd
.pctx
.errcode
) {
5449 fix_problem(ctx
, PR_2_ALLOCATE_ICOUNT
, &cd
.pctx
);
5450 ctx
->flags
|= E2F_FLAG_ABORT
;
5453 buf
= (char *) e2fsck_allocate_memory(ctx
, 2*fs
->blocksize
,
5454 "directory scan buffer");
5457 * Set up the parent pointer for the root directory, if
5458 * present. (If the root directory is not present, we will
5459 * create it in pass 3.)
5461 dir
= e2fsck_get_dir_info(ctx
, EXT2_ROOT_INO
);
5463 dir
->parent
= EXT2_ROOT_INO
;
5468 cd
.max
= ext2fs_dblist_count(fs
->dblist
);
5471 (void) (ctx
->progress
)(ctx
, 2, 0, cd
.max
);
5473 if (fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
)
5474 ext2fs_dblist_sort(fs
->dblist
, special_dir_block_cmp
);
5476 cd
.pctx
.errcode
= ext2fs_dblist_iterate(fs
->dblist
, check_dir_block
,
5478 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
5480 if (cd
.pctx
.errcode
) {
5481 fix_problem(ctx
, PR_2_DBLIST_ITERATE
, &cd
.pctx
);
5482 ctx
->flags
|= E2F_FLAG_ABORT
;
5487 for (i
=0; (dx_dir
= e2fsck_dx_dir_info_iter(ctx
, &i
)) != 0;) {
5488 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
5490 if (dx_dir
->numblocks
== 0)
5492 clear_problem_context(&pctx
);
5494 pctx
.dir
= dx_dir
->ino
;
5495 dx_db
= dx_dir
->dx_block
;
5496 if (dx_db
->flags
& DX_FLAG_REFERENCED
)
5497 dx_db
->flags
|= DX_FLAG_DUP_REF
;
5499 dx_db
->flags
|= DX_FLAG_REFERENCED
;
5501 * Find all of the first and last leaf blocks, and
5502 * update their parent's min and max hash values
5504 for (b
=0, dx_db
= dx_dir
->dx_block
;
5505 b
< dx_dir
->numblocks
;
5507 if ((dx_db
->type
!= DX_DIRBLOCK_LEAF
) ||
5508 !(dx_db
->flags
& (DX_FLAG_FIRST
| DX_FLAG_LAST
)))
5510 dx_parent
= &dx_dir
->dx_block
[dx_db
->parent
];
5512 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5514 if (dx_db
->flags
& DX_FLAG_FIRST
)
5515 dx_parent
->min_hash
= dx_db
->min_hash
;
5517 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5519 if (dx_db
->flags
& DX_FLAG_LAST
)
5520 dx_parent
->max_hash
= dx_db
->max_hash
;
5523 for (b
=0, dx_db
= dx_dir
->dx_block
;
5524 b
< dx_dir
->numblocks
;
5527 pctx
.group
= dx_db
->parent
;
5529 if (!(dx_db
->flags
& DX_FLAG_FIRST
) &&
5530 (dx_db
->min_hash
< dx_db
->node_min_hash
)) {
5531 pctx
.blk
= dx_db
->min_hash
;
5532 pctx
.blk2
= dx_db
->node_min_hash
;
5533 code
= PR_2_HTREE_MIN_HASH
;
5534 fix_problem(ctx
, code
, &pctx
);
5537 if (dx_db
->type
== DX_DIRBLOCK_LEAF
) {
5538 depth
= htree_depth(dx_dir
, dx_db
);
5539 if (depth
!= dx_dir
->depth
) {
5540 code
= PR_2_HTREE_BAD_DEPTH
;
5541 fix_problem(ctx
, code
, &pctx
);
5546 * This test doesn't apply for the root block
5550 (dx_db
->max_hash
> dx_db
->node_max_hash
)) {
5551 pctx
.blk
= dx_db
->max_hash
;
5552 pctx
.blk2
= dx_db
->node_max_hash
;
5553 code
= PR_2_HTREE_MAX_HASH
;
5554 fix_problem(ctx
, code
, &pctx
);
5557 if (!(dx_db
->flags
& DX_FLAG_REFERENCED
)) {
5558 code
= PR_2_HTREE_NOTREF
;
5559 fix_problem(ctx
, code
, &pctx
);
5561 } else if (dx_db
->flags
& DX_FLAG_DUP_REF
) {
5562 code
= PR_2_HTREE_DUPREF
;
5563 fix_problem(ctx
, code
, &pctx
);
5569 if (bad_dir
&& fix_problem(ctx
, PR_2_HTREE_CLEAR
, &pctx
)) {
5570 clear_htree(ctx
, dx_dir
->ino
);
5571 dx_dir
->numblocks
= 0;
5575 ext2fs_free_mem(&buf
);
5576 ext2fs_free_dblist(fs
->dblist
);
5578 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
5579 ctx
->inode_bad_map
= 0;
5580 ext2fs_free_inode_bitmap(ctx
->inode_reg_map
);
5581 ctx
->inode_reg_map
= 0;
5583 clear_problem_context(&pctx
);
5584 if (ctx
->large_files
) {
5585 if (!(sb
->s_feature_ro_compat
&
5586 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
) &&
5587 fix_problem(ctx
, PR_2_FEATURE_LARGE_FILES
, &pctx
)) {
5588 sb
->s_feature_ro_compat
|=
5589 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
;
5590 ext2fs_mark_super_dirty(fs
);
5592 if (sb
->s_rev_level
== EXT2_GOOD_OLD_REV
&&
5593 fix_problem(ctx
, PR_1_FS_REV_LEVEL
, &pctx
)) {
5594 ext2fs_update_dynamic_rev(fs
);
5595 ext2fs_mark_super_dirty(fs
);
5597 } else if (!ctx
->large_files
&&
5598 (sb
->s_feature_ro_compat
&
5599 EXT2_FEATURE_RO_COMPAT_LARGE_FILE
)) {
5600 if (fs
->flags
& EXT2_FLAG_RW
) {
5601 sb
->s_feature_ro_compat
&=
5602 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE
;
5603 ext2fs_mark_super_dirty(fs
);
5608 #define MAX_DEPTH 32000
5609 static int htree_depth(struct dx_dir_info
*dx_dir
,
5610 struct dx_dirblock_info
*dx_db
)
5614 while (dx_db
->type
!= DX_DIRBLOCK_ROOT
&& depth
< MAX_DEPTH
) {
5615 dx_db
= &dx_dir
->dx_block
[dx_db
->parent
];
5621 static int dict_de_cmp(const void *a
, const void *b
)
5623 const struct ext2_dir_entry
*de_a
, *de_b
;
5626 de_a
= (const struct ext2_dir_entry
*) a
;
5627 a_len
= de_a
->name_len
& 0xFF;
5628 de_b
= (const struct ext2_dir_entry
*) b
;
5629 b_len
= de_b
->name_len
& 0xFF;
5632 return (a_len
- b_len
);
5634 return strncmp(de_a
->name
, de_b
->name
, a_len
);
5638 * This is special sort function that makes sure that directory blocks
5639 * with a dirblock of zero are sorted to the beginning of the list.
5640 * This guarantees that the root node of the htree directories are
5641 * processed first, so we know what hash version to use.
5643 static int special_dir_block_cmp(const void *a
, const void *b
)
5645 const struct ext2_db_entry
*db_a
=
5646 (const struct ext2_db_entry
*) a
;
5647 const struct ext2_db_entry
*db_b
=
5648 (const struct ext2_db_entry
*) b
;
5650 if (db_a
->blockcnt
&& !db_b
->blockcnt
)
5653 if (!db_a
->blockcnt
&& db_b
->blockcnt
)
5656 if (db_a
->blk
!= db_b
->blk
)
5657 return (int) (db_a
->blk
- db_b
->blk
);
5659 if (db_a
->ino
!= db_b
->ino
)
5660 return (int) (db_a
->ino
- db_b
->ino
);
5662 return (int) (db_a
->blockcnt
- db_b
->blockcnt
);
5667 * Make sure the first entry in the directory is '.', and that the
5668 * directory entry is sane.
5670 static int check_dot(e2fsck_t ctx
,
5671 struct ext2_dir_entry
*dirent
,
5672 ext2_ino_t ino
, struct problem_context
*pctx
)
5674 struct ext2_dir_entry
*nextdir
;
5681 problem
= PR_2_MISSING_DOT
;
5682 else if (((dirent
->name_len
& 0xFF) != 1) ||
5683 (dirent
->name
[0] != '.'))
5684 problem
= PR_2_1ST_NOT_DOT
;
5685 else if (dirent
->name
[1] != '\0')
5686 problem
= PR_2_DOT_NULL_TERM
;
5689 if (fix_problem(ctx
, problem
, pctx
)) {
5690 if (dirent
->rec_len
< 12)
5691 dirent
->rec_len
= 12;
5692 dirent
->inode
= ino
;
5693 dirent
->name_len
= 1;
5694 dirent
->name
[0] = '.';
5695 dirent
->name
[1] = '\0';
5700 if (dirent
->inode
!= ino
) {
5701 if (fix_problem(ctx
, PR_2_BAD_INODE_DOT
, pctx
)) {
5702 dirent
->inode
= ino
;
5706 if (dirent
->rec_len
> 12) {
5707 new_len
= dirent
->rec_len
- 12;
5710 fix_problem(ctx
, PR_2_SPLIT_DOT
, pctx
)) {
5711 nextdir
= (struct ext2_dir_entry
*)
5712 ((char *) dirent
+ 12);
5713 dirent
->rec_len
= 12;
5714 nextdir
->rec_len
= new_len
;
5716 nextdir
->name_len
= 0;
5725 * Make sure the second entry in the directory is '..', and that the
5726 * directory entry is sane. We do not check the inode number of '..'
5727 * here; this gets done in pass 3.
5729 static int check_dotdot(e2fsck_t ctx
,
5730 struct ext2_dir_entry
*dirent
,
5731 struct dir_info
*dir
, struct problem_context
*pctx
)
5736 problem
= PR_2_MISSING_DOT_DOT
;
5737 else if (((dirent
->name_len
& 0xFF) != 2) ||
5738 (dirent
->name
[0] != '.') ||
5739 (dirent
->name
[1] != '.'))
5740 problem
= PR_2_2ND_NOT_DOT_DOT
;
5741 else if (dirent
->name
[2] != '\0')
5742 problem
= PR_2_DOT_DOT_NULL_TERM
;
5745 if (fix_problem(ctx
, problem
, pctx
)) {
5746 if (dirent
->rec_len
< 12)
5747 dirent
->rec_len
= 12;
5749 * Note: we don't have the parent inode just
5750 * yet, so we will fill it in with the root
5751 * inode. This will get fixed in pass 3.
5753 dirent
->inode
= EXT2_ROOT_INO
;
5754 dirent
->name_len
= 2;
5755 dirent
->name
[0] = '.';
5756 dirent
->name
[1] = '.';
5757 dirent
->name
[2] = '\0';
5762 dir
->dotdot
= dirent
->inode
;
5767 * Check to make sure a directory entry doesn't contain any illegal
5770 static int check_name(e2fsck_t ctx
,
5771 struct ext2_dir_entry
*dirent
,
5772 struct problem_context
*pctx
)
5778 for ( i
= 0; i
< (dirent
->name_len
& 0xFF); i
++) {
5779 if (dirent
->name
[i
] == '/' || dirent
->name
[i
] == '\0') {
5781 fixup
= fix_problem(ctx
, PR_2_BAD_NAME
, pctx
);
5784 dirent
->name
[i
] = '.';
5793 * Check the directory filetype (if present)
5797 * Given a mode, return the ext2 file type
5799 static int ext2_file_type(unsigned int mode
)
5801 if (LINUX_S_ISREG(mode
))
5802 return EXT2_FT_REG_FILE
;
5804 if (LINUX_S_ISDIR(mode
))
5807 if (LINUX_S_ISCHR(mode
))
5808 return EXT2_FT_CHRDEV
;
5810 if (LINUX_S_ISBLK(mode
))
5811 return EXT2_FT_BLKDEV
;
5813 if (LINUX_S_ISLNK(mode
))
5814 return EXT2_FT_SYMLINK
;
5816 if (LINUX_S_ISFIFO(mode
))
5817 return EXT2_FT_FIFO
;
5819 if (LINUX_S_ISSOCK(mode
))
5820 return EXT2_FT_SOCK
;
5825 static int check_filetype(e2fsck_t ctx
,
5826 struct ext2_dir_entry
*dirent
,
5827 struct problem_context
*pctx
)
5829 int filetype
= dirent
->name_len
>> 8;
5830 int should_be
= EXT2_FT_UNKNOWN
;
5831 struct ext2_inode inode
;
5833 if (!(ctx
->fs
->super
->s_feature_incompat
&
5834 EXT2_FEATURE_INCOMPAT_FILETYPE
)) {
5835 if (filetype
== 0 ||
5836 !fix_problem(ctx
, PR_2_CLEAR_FILETYPE
, pctx
))
5838 dirent
->name_len
= dirent
->name_len
& 0xFF;
5842 if (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
, dirent
->inode
)) {
5843 should_be
= EXT2_FT_DIR
;
5844 } else if (ext2fs_test_inode_bitmap(ctx
->inode_reg_map
,
5846 should_be
= EXT2_FT_REG_FILE
;
5847 } else if (ctx
->inode_bad_map
&&
5848 ext2fs_test_inode_bitmap(ctx
->inode_bad_map
,
5852 e2fsck_read_inode(ctx
, dirent
->inode
, &inode
,
5854 should_be
= ext2_file_type(inode
.i_mode
);
5856 if (filetype
== should_be
)
5858 pctx
->num
= should_be
;
5860 if (fix_problem(ctx
, filetype
? PR_2_BAD_FILETYPE
: PR_2_SET_FILETYPE
,
5864 dirent
->name_len
= (dirent
->name_len
& 0xFF) | should_be
<< 8;
5869 static void parse_int_node(ext2_filsys fs
,
5870 struct ext2_db_entry
*db
,
5871 struct check_dir_struct
*cd
,
5872 struct dx_dir_info
*dx_dir
,
5875 struct ext2_dx_root_info
*root
;
5876 struct ext2_dx_entry
*ent
;
5877 struct ext2_dx_countlimit
*limit
;
5878 struct dx_dirblock_info
*dx_db
;
5879 int i
, expect_limit
, count
;
5881 ext2_dirhash_t min_hash
= 0xffffffff;
5882 ext2_dirhash_t max_hash
= 0;
5883 ext2_dirhash_t hash
= 0, prev_hash
;
5885 if (db
->blockcnt
== 0) {
5886 root
= (struct ext2_dx_root_info
*) (block_buf
+ 24);
5887 ent
= (struct ext2_dx_entry
*) (block_buf
+ 24 + root
->info_length
);
5889 ent
= (struct ext2_dx_entry
*) (block_buf
+8);
5891 limit
= (struct ext2_dx_countlimit
*) ent
;
5893 count
= ext2fs_le16_to_cpu(limit
->count
);
5894 expect_limit
= (fs
->blocksize
- ((char *) ent
- block_buf
)) /
5895 sizeof(struct ext2_dx_entry
);
5896 if (ext2fs_le16_to_cpu(limit
->limit
) != expect_limit
) {
5897 cd
->pctx
.num
= ext2fs_le16_to_cpu(limit
->limit
);
5898 if (fix_problem(cd
->ctx
, PR_2_HTREE_BAD_LIMIT
, &cd
->pctx
))
5899 goto clear_and_exit
;
5901 if (count
> expect_limit
) {
5902 cd
->pctx
.num
= count
;
5903 if (fix_problem(cd
->ctx
, PR_2_HTREE_BAD_COUNT
, &cd
->pctx
))
5904 goto clear_and_exit
;
5905 count
= expect_limit
;
5908 for (i
=0; i
< count
; i
++) {
5910 hash
= i
? (ext2fs_le32_to_cpu(ent
[i
].hash
) & ~1) : 0;
5911 blk
= ext2fs_le32_to_cpu(ent
[i
].block
) & 0x0ffffff;
5912 /* Check to make sure the block is valid */
5913 if (blk
> (blk_t
) dx_dir
->numblocks
) {
5915 if (fix_problem(cd
->ctx
, PR_2_HTREE_BADBLK
,
5917 goto clear_and_exit
;
5919 if (hash
< prev_hash
&&
5920 fix_problem(cd
->ctx
, PR_2_HTREE_HASH_ORDER
, &cd
->pctx
))
5921 goto clear_and_exit
;
5922 dx_db
= &dx_dir
->dx_block
[blk
];
5923 if (dx_db
->flags
& DX_FLAG_REFERENCED
) {
5924 dx_db
->flags
|= DX_FLAG_DUP_REF
;
5926 dx_db
->flags
|= DX_FLAG_REFERENCED
;
5927 dx_db
->parent
= db
->blockcnt
;
5929 if (hash
< min_hash
)
5931 if (hash
> max_hash
)
5933 dx_db
->node_min_hash
= hash
;
5935 dx_db
->node_max_hash
=
5936 ext2fs_le32_to_cpu(ent
[i
+1].hash
) & ~1;
5938 dx_db
->node_max_hash
= 0xfffffffe;
5939 dx_db
->flags
|= DX_FLAG_LAST
;
5942 dx_db
->flags
|= DX_FLAG_FIRST
;
5944 dx_db
= &dx_dir
->dx_block
[db
->blockcnt
];
5945 dx_db
->min_hash
= min_hash
;
5946 dx_db
->max_hash
= max_hash
;
5950 clear_htree(cd
->ctx
, cd
->pctx
.ino
);
5951 dx_dir
->numblocks
= 0;
5953 #endif /* ENABLE_HTREE */
5956 * Given a busted directory, try to salvage it somehow.
5959 static void salvage_directory(ext2_filsys fs
,
5960 struct ext2_dir_entry
*dirent
,
5961 struct ext2_dir_entry
*prev
,
5962 unsigned int *offset
)
5964 char *cp
= (char *) dirent
;
5965 int left
= fs
->blocksize
- *offset
- dirent
->rec_len
;
5966 int name_len
= dirent
->name_len
& 0xFF;
5969 * Special case of directory entry of size 8: copy what's left
5970 * of the directory block up to cover up the invalid hole.
5972 if ((left
>= 12) && (dirent
->rec_len
== 8)) {
5973 memmove(cp
, cp
+8, left
);
5974 memset(cp
+ left
, 0, 8);
5978 * If the directory entry overruns the end of the directory
5979 * block, and the name is small enough to fit, then adjust the
5983 (name_len
+ 8 <= dirent
->rec_len
+ left
) &&
5984 dirent
->inode
<= fs
->super
->s_inodes_count
&&
5985 strnlen(dirent
->name
, name_len
) == name_len
) {
5986 dirent
->rec_len
+= left
;
5990 * If the directory entry is a multiple of four, so it is
5991 * valid, let the previous directory entry absorb the invalid
5994 if (prev
&& dirent
->rec_len
&& (dirent
->rec_len
% 4) == 0) {
5995 prev
->rec_len
+= dirent
->rec_len
;
5996 *offset
+= dirent
->rec_len
;
6000 * Default salvage method --- kill all of the directory
6001 * entries for the rest of the block. We will either try to
6002 * absorb it into the previous directory entry, or create a
6003 * new empty directory entry the rest of the directory block.
6006 prev
->rec_len
+= fs
->blocksize
- *offset
;
6007 *offset
= fs
->blocksize
;
6009 dirent
->rec_len
= fs
->blocksize
- *offset
;
6010 dirent
->name_len
= 0;
6015 static int check_dir_block(ext2_filsys fs
,
6016 struct ext2_db_entry
*db
,
6019 struct dir_info
*subdir
, *dir
;
6020 struct dx_dir_info
*dx_dir
;
6022 struct dx_dirblock_info
*dx_db
= NULL
;
6023 #endif /* ENABLE_HTREE */
6024 struct ext2_dir_entry
*dirent
, *prev
;
6025 ext2_dirhash_t hash
;
6026 unsigned int offset
= 0;
6027 int dir_modified
= 0;
6029 blk_t block_nr
= db
->blk
;
6030 ext2_ino_t ino
= db
->ino
;
6032 struct check_dir_struct
*cd
;
6036 struct ext2_dx_root_info
*root
;
6037 struct ext2_dx_countlimit
*limit
;
6038 static dict_t de_dict
;
6039 struct problem_context pctx
;
6042 cd
= (struct check_dir_struct
*) priv_data
;
6046 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
6047 return DIRENT_ABORT
;
6049 if (ctx
->progress
&& (ctx
->progress
)(ctx
, 2, cd
->count
++, cd
->max
))
6050 return DIRENT_ABORT
;
6053 * Make sure the inode is still in use (could have been
6054 * deleted in the duplicate/bad blocks pass.
6056 if (!(ext2fs_test_inode_bitmap(ctx
->inode_used_map
, ino
)))
6060 cd
->pctx
.blk
= block_nr
;
6061 cd
->pctx
.blkcount
= db
->blockcnt
;
6063 cd
->pctx
.dirent
= 0;
6067 if (allocate_dir_block(ctx
, db
, &cd
->pctx
))
6077 if (ctx
->dirs_to_hash
&&
6078 ext2fs_u32_list_test(ctx
->dirs_to_hash
, ino
))
6081 cd
->pctx
.errcode
= ext2fs_read_dir_block(fs
, block_nr
, buf
);
6082 if (cd
->pctx
.errcode
== EXT2_ET_DIR_CORRUPTED
)
6083 cd
->pctx
.errcode
= 0; /* We'll handle this ourselves */
6084 if (cd
->pctx
.errcode
) {
6085 if (!fix_problem(ctx
, PR_2_READ_DIRBLOCK
, &cd
->pctx
)) {
6086 ctx
->flags
|= E2F_FLAG_ABORT
;
6087 return DIRENT_ABORT
;
6089 memset(buf
, 0, fs
->blocksize
);
6092 dx_dir
= e2fsck_get_dx_dir_info(ctx
, ino
);
6093 if (dx_dir
&& dx_dir
->numblocks
) {
6094 if (db
->blockcnt
>= dx_dir
->numblocks
) {
6095 printf("XXX should never happen!!!\n");
6098 dx_db
= &dx_dir
->dx_block
[db
->blockcnt
];
6099 dx_db
->type
= DX_DIRBLOCK_LEAF
;
6100 dx_db
->phys
= block_nr
;
6101 dx_db
->min_hash
= ~0;
6102 dx_db
->max_hash
= 0;
6104 dirent
= (struct ext2_dir_entry
*) buf
;
6105 limit
= (struct ext2_dx_countlimit
*) (buf
+8);
6106 if (db
->blockcnt
== 0) {
6107 root
= (struct ext2_dx_root_info
*) (buf
+ 24);
6108 dx_db
->type
= DX_DIRBLOCK_ROOT
;
6109 dx_db
->flags
|= DX_FLAG_FIRST
| DX_FLAG_LAST
;
6110 if ((root
->reserved_zero
||
6111 root
->info_length
< 8 ||
6112 root
->indirect_levels
> 1) &&
6113 fix_problem(ctx
, PR_2_HTREE_BAD_ROOT
, &cd
->pctx
)) {
6114 clear_htree(ctx
, ino
);
6115 dx_dir
->numblocks
= 0;
6118 dx_dir
->hashversion
= root
->hash_version
;
6119 dx_dir
->depth
= root
->indirect_levels
+ 1;
6120 } else if ((dirent
->inode
== 0) &&
6121 (dirent
->rec_len
== fs
->blocksize
) &&
6122 (dirent
->name_len
== 0) &&
6123 (ext2fs_le16_to_cpu(limit
->limit
) ==
6124 ((fs
->blocksize
-8) /
6125 sizeof(struct ext2_dx_entry
))))
6126 dx_db
->type
= DX_DIRBLOCK_NODE
;
6128 #endif /* ENABLE_HTREE */
6130 dict_init(&de_dict
, DICTCOUNT_T_MAX
, dict_de_cmp
);
6134 dirent
= (struct ext2_dir_entry
*) (buf
+ offset
);
6135 cd
->pctx
.dirent
= dirent
;
6136 cd
->pctx
.num
= offset
;
6137 if (((offset
+ dirent
->rec_len
) > fs
->blocksize
) ||
6138 (dirent
->rec_len
< 12) ||
6139 ((dirent
->rec_len
% 4) != 0) ||
6140 (((dirent
->name_len
& 0xFF)+8) > dirent
->rec_len
)) {
6141 if (fix_problem(ctx
, PR_2_DIR_CORRUPTED
, &cd
->pctx
)) {
6142 salvage_directory(fs
, dirent
, prev
, &offset
);
6146 goto abort_free_dict
;
6148 if ((dirent
->name_len
& 0xFF) > EXT2_NAME_LEN
) {
6149 if (fix_problem(ctx
, PR_2_FILENAME_LONG
, &cd
->pctx
)) {
6150 dirent
->name_len
= EXT2_NAME_LEN
;
6155 if (dot_state
== 0) {
6156 if (check_dot(ctx
, dirent
, ino
, &cd
->pctx
))
6158 } else if (dot_state
== 1) {
6159 dir
= e2fsck_get_dir_info(ctx
, ino
);
6161 fix_problem(ctx
, PR_2_NO_DIRINFO
, &cd
->pctx
);
6162 goto abort_free_dict
;
6164 if (check_dotdot(ctx
, dirent
, dir
, &cd
->pctx
))
6166 } else if (dirent
->inode
== ino
) {
6167 problem
= PR_2_LINK_DOT
;
6168 if (fix_problem(ctx
, PR_2_LINK_DOT
, &cd
->pctx
)) {
6178 * Make sure the inode listed is a legal one.
6180 if (((dirent
->inode
!= EXT2_ROOT_INO
) &&
6181 (dirent
->inode
< EXT2_FIRST_INODE(fs
->super
))) ||
6182 (dirent
->inode
> fs
->super
->s_inodes_count
)) {
6183 problem
= PR_2_BAD_INO
;
6184 } else if (!(ext2fs_test_inode_bitmap(ctx
->inode_used_map
,
6187 * If the inode is unused, offer to clear it.
6189 problem
= PR_2_UNUSED_INODE
;
6190 } else if ((dot_state
> 1) &&
6191 ((dirent
->name_len
& 0xFF) == 1) &&
6192 (dirent
->name
[0] == '.')) {
6194 * If there's a '.' entry in anything other
6195 * than the first directory entry, it's a
6196 * duplicate entry that should be removed.
6198 problem
= PR_2_DUP_DOT
;
6199 } else if ((dot_state
> 1) &&
6200 ((dirent
->name_len
& 0xFF) == 2) &&
6201 (dirent
->name
[0] == '.') &&
6202 (dirent
->name
[1] == '.')) {
6204 * If there's a '..' entry in anything other
6205 * than the second directory entry, it's a
6206 * duplicate entry that should be removed.
6208 problem
= PR_2_DUP_DOT_DOT
;
6209 } else if ((dot_state
> 1) &&
6210 (dirent
->inode
== EXT2_ROOT_INO
)) {
6212 * Don't allow links to the root directory.
6213 * We check this specially to make sure we
6214 * catch this error case even if the root
6215 * directory hasn't been created yet.
6217 problem
= PR_2_LINK_ROOT
;
6218 } else if ((dot_state
> 1) &&
6219 (dirent
->name_len
& 0xFF) == 0) {
6221 * Don't allow zero-length directory names.
6223 problem
= PR_2_NULL_NAME
;
6227 if (fix_problem(ctx
, problem
, &cd
->pctx
)) {
6232 ext2fs_unmark_valid(fs
);
6233 if (problem
== PR_2_BAD_INO
)
6239 * If the inode was marked as having bad fields in
6240 * pass1, process it and offer to fix/clear it.
6241 * (We wait until now so that we can display the
6242 * pathname to the user.)
6244 if (ctx
->inode_bad_map
&&
6245 ext2fs_test_inode_bitmap(ctx
->inode_bad_map
,
6247 if (e2fsck_process_bad_inode(ctx
, ino
,
6249 buf
+ fs
->blocksize
)) {
6254 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
6255 return DIRENT_ABORT
;
6258 if (check_name(ctx
, dirent
, &cd
->pctx
))
6261 if (check_filetype(ctx
, dirent
, &cd
->pctx
))
6266 ext2fs_dirhash(dx_dir
->hashversion
, dirent
->name
,
6267 (dirent
->name_len
& 0xFF),
6268 fs
->super
->s_hash_seed
, &hash
, 0);
6269 if (hash
< dx_db
->min_hash
)
6270 dx_db
->min_hash
= hash
;
6271 if (hash
> dx_db
->max_hash
)
6272 dx_db
->max_hash
= hash
;
6277 * If this is a directory, then mark its parent in its
6278 * dir_info structure. If the parent field is already
6279 * filled in, then this directory has more than one
6280 * hard link. We assume the first link is correct,
6281 * and ask the user if he/she wants to clear this one.
6283 if ((dot_state
> 1) &&
6284 (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
,
6286 subdir
= e2fsck_get_dir_info(ctx
, dirent
->inode
);
6288 cd
->pctx
.ino
= dirent
->inode
;
6289 fix_problem(ctx
, PR_2_NO_DIRINFO
, &cd
->pctx
);
6290 goto abort_free_dict
;
6292 if (subdir
->parent
) {
6293 cd
->pctx
.ino2
= subdir
->parent
;
6294 if (fix_problem(ctx
, PR_2_LINK_DIR
,
6302 subdir
->parent
= ino
;
6307 } else if (dict_lookup(&de_dict
, dirent
)) {
6308 clear_problem_context(&pctx
);
6310 pctx
.dirent
= dirent
;
6311 fix_problem(ctx
, PR_2_REPORT_DUP_DIRENT
, &pctx
);
6312 if (!ctx
->dirs_to_hash
)
6313 ext2fs_u32_list_create(&ctx
->dirs_to_hash
, 50);
6314 if (ctx
->dirs_to_hash
)
6315 ext2fs_u32_list_add(ctx
->dirs_to_hash
, ino
);
6318 dict_alloc_insert(&de_dict
, dirent
, dirent
);
6320 ext2fs_icount_increment(ctx
->inode_count
, dirent
->inode
,
6323 ctx
->fs_links_count
++;
6324 ctx
->fs_total_count
++;
6327 offset
+= dirent
->rec_len
;
6329 } while (offset
< fs
->blocksize
);
6332 cd
->pctx
.dir
= cd
->pctx
.ino
;
6333 if ((dx_db
->type
== DX_DIRBLOCK_ROOT
) ||
6334 (dx_db
->type
== DX_DIRBLOCK_NODE
))
6335 parse_int_node(fs
, db
, cd
, dx_dir
, buf
);
6337 #endif /* ENABLE_HTREE */
6338 if (offset
!= fs
->blocksize
) {
6339 cd
->pctx
.num
= dirent
->rec_len
- fs
->blocksize
+ offset
;
6340 if (fix_problem(ctx
, PR_2_FINAL_RECLEN
, &cd
->pctx
)) {
6341 dirent
->rec_len
= cd
->pctx
.num
;
6346 cd
->pctx
.errcode
= ext2fs_write_dir_block(fs
, block_nr
, buf
);
6347 if (cd
->pctx
.errcode
) {
6348 if (!fix_problem(ctx
, PR_2_WRITE_DIRBLOCK
,
6350 goto abort_free_dict
;
6352 ext2fs_mark_changed(fs
);
6354 dict_free_nodes(&de_dict
);
6357 dict_free_nodes(&de_dict
);
6358 ctx
->flags
|= E2F_FLAG_ABORT
;
6359 return DIRENT_ABORT
;
6363 * This function is called to deallocate a block, and is an interator
6364 * functioned called by deallocate inode via ext2fs_iterate_block().
6366 static int deallocate_inode_block(ext2_filsys fs
, blk_t
*block_nr
,
6367 e2_blkcnt_t blockcnt
FSCK_ATTR((unused
)),
6368 blk_t ref_block
FSCK_ATTR((unused
)),
6369 int ref_offset
FSCK_ATTR((unused
)),
6372 e2fsck_t ctx
= (e2fsck_t
) priv_data
;
6374 if (HOLE_BLKADDR(*block_nr
))
6376 if ((*block_nr
< fs
->super
->s_first_data_block
) ||
6377 (*block_nr
>= fs
->super
->s_blocks_count
))
6379 ext2fs_unmark_block_bitmap(ctx
->block_found_map
, *block_nr
);
6380 ext2fs_block_alloc_stats(fs
, *block_nr
, -1);
6385 * This fuction deallocates an inode
6387 static void deallocate_inode(e2fsck_t ctx
, ext2_ino_t ino
, char* block_buf
)
6389 ext2_filsys fs
= ctx
->fs
;
6390 struct ext2_inode inode
;
6391 struct problem_context pctx
;
6394 ext2fs_icount_store(ctx
->inode_link_info
, ino
, 0);
6395 e2fsck_read_inode(ctx
, ino
, &inode
, "deallocate_inode");
6396 inode
.i_links_count
= 0;
6397 inode
.i_dtime
= time(NULL
);
6398 e2fsck_write_inode(ctx
, ino
, &inode
, "deallocate_inode");
6399 clear_problem_context(&pctx
);
6403 * Fix up the bitmaps...
6405 e2fsck_read_bitmaps(ctx
);
6406 ext2fs_unmark_inode_bitmap(ctx
->inode_used_map
, ino
);
6407 ext2fs_unmark_inode_bitmap(ctx
->inode_dir_map
, ino
);
6408 if (ctx
->inode_bad_map
)
6409 ext2fs_unmark_inode_bitmap(ctx
->inode_bad_map
, ino
);
6410 ext2fs_inode_alloc_stats2(fs
, ino
, -1, LINUX_S_ISDIR(inode
.i_mode
));
6412 if (inode
.i_file_acl
&&
6413 (fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
)) {
6414 pctx
.errcode
= ext2fs_adjust_ea_refcount(fs
, inode
.i_file_acl
,
6415 block_buf
, -1, &count
);
6416 if (pctx
.errcode
== EXT2_ET_BAD_EA_BLOCK_NUM
) {
6421 pctx
.blk
= inode
.i_file_acl
;
6422 fix_problem(ctx
, PR_2_ADJ_EA_REFCOUNT
, &pctx
);
6423 ctx
->flags
|= E2F_FLAG_ABORT
;
6427 ext2fs_unmark_block_bitmap(ctx
->block_found_map
,
6429 ext2fs_block_alloc_stats(fs
, inode
.i_file_acl
, -1);
6431 inode
.i_file_acl
= 0;
6434 if (!ext2fs_inode_has_valid_blocks(&inode
))
6437 if (LINUX_S_ISREG(inode
.i_mode
) &&
6438 (inode
.i_size_high
|| inode
.i_size
& 0x80000000UL
))
6441 pctx
.errcode
= ext2fs_block_iterate2(fs
, ino
, 0, block_buf
,
6442 deallocate_inode_block
, ctx
);
6444 fix_problem(ctx
, PR_2_DEALLOC_INODE
, &pctx
);
6445 ctx
->flags
|= E2F_FLAG_ABORT
;
6451 * This fuction clears the htree flag on an inode
6453 static void clear_htree(e2fsck_t ctx
, ext2_ino_t ino
)
6455 struct ext2_inode inode
;
6457 e2fsck_read_inode(ctx
, ino
, &inode
, "clear_htree");
6458 inode
.i_flags
= inode
.i_flags
& ~EXT2_INDEX_FL
;
6459 e2fsck_write_inode(ctx
, ino
, &inode
, "clear_htree");
6460 if (ctx
->dirs_to_hash
)
6461 ext2fs_u32_list_add(ctx
->dirs_to_hash
, ino
);
6465 static int e2fsck_process_bad_inode(e2fsck_t ctx
, ext2_ino_t dir
,
6466 ext2_ino_t ino
, char *buf
)
6468 ext2_filsys fs
= ctx
->fs
;
6469 struct ext2_inode inode
;
6470 int inode_modified
= 0;
6472 unsigned char *frag
, *fsize
;
6473 struct problem_context pctx
;
6476 e2fsck_read_inode(ctx
, ino
, &inode
, "process_bad_inode");
6478 clear_problem_context(&pctx
);
6481 pctx
.inode
= &inode
;
6483 if (inode
.i_file_acl
&&
6484 !(fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_EXT_ATTR
) &&
6485 fix_problem(ctx
, PR_2_FILE_ACL_ZERO
, &pctx
)) {
6486 inode
.i_file_acl
= 0;
6489 * This is a special kludge to deal with long symlinks
6490 * on big endian systems. i_blocks had already been
6491 * decremented earlier in pass 1, but since i_file_acl
6492 * hadn't yet been cleared, ext2fs_read_inode()
6493 * assumed that the file was short symlink and would
6494 * not have byte swapped i_block[0]. Hence, we have
6495 * to byte-swap it here.
6497 if (LINUX_S_ISLNK(inode
.i_mode
) &&
6498 (fs
->flags
& EXT2_FLAG_SWAP_BYTES
) &&
6499 (inode
.i_blocks
== fs
->blocksize
>> 9))
6500 inode
.i_block
[0] = ext2fs_swab32(inode
.i_block
[0]);
6506 if (!LINUX_S_ISDIR(inode
.i_mode
) && !LINUX_S_ISREG(inode
.i_mode
) &&
6507 !LINUX_S_ISCHR(inode
.i_mode
) && !LINUX_S_ISBLK(inode
.i_mode
) &&
6508 !LINUX_S_ISLNK(inode
.i_mode
) && !LINUX_S_ISFIFO(inode
.i_mode
) &&
6509 !(LINUX_S_ISSOCK(inode
.i_mode
)))
6510 problem
= PR_2_BAD_MODE
;
6511 else if (LINUX_S_ISCHR(inode
.i_mode
)
6512 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
6513 problem
= PR_2_BAD_CHAR_DEV
;
6514 else if (LINUX_S_ISBLK(inode
.i_mode
)
6515 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
6516 problem
= PR_2_BAD_BLOCK_DEV
;
6517 else if (LINUX_S_ISFIFO(inode
.i_mode
)
6518 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
6519 problem
= PR_2_BAD_FIFO
;
6520 else if (LINUX_S_ISSOCK(inode
.i_mode
)
6521 && !e2fsck_pass1_check_device_inode(fs
, &inode
))
6522 problem
= PR_2_BAD_SOCKET
;
6523 else if (LINUX_S_ISLNK(inode
.i_mode
)
6524 && !e2fsck_pass1_check_symlink(fs
, &inode
, buf
)) {
6525 problem
= PR_2_INVALID_SYMLINK
;
6529 if (fix_problem(ctx
, problem
, &pctx
)) {
6530 deallocate_inode(ctx
, ino
, 0);
6531 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
6539 if (inode
.i_faddr
) {
6540 if (fix_problem(ctx
, PR_2_FADDR_ZERO
, &pctx
)) {
6547 switch (fs
->super
->s_creator_os
) {
6549 frag
= &inode
.osd2
.linux2
.l_i_frag
;
6550 fsize
= &inode
.osd2
.linux2
.l_i_fsize
;
6553 frag
= &inode
.osd2
.hurd2
.h_i_frag
;
6554 fsize
= &inode
.osd2
.hurd2
.h_i_fsize
;
6557 frag
= &inode
.osd2
.masix2
.m_i_frag
;
6558 fsize
= &inode
.osd2
.masix2
.m_i_fsize
;
6563 if (frag
&& *frag
) {
6565 if (fix_problem(ctx
, PR_2_FRAG_ZERO
, &pctx
)) {
6572 if (fsize
&& *fsize
) {
6574 if (fix_problem(ctx
, PR_2_FSIZE_ZERO
, &pctx
)) {
6582 if (inode
.i_file_acl
&&
6583 ((inode
.i_file_acl
< fs
->super
->s_first_data_block
) ||
6584 (inode
.i_file_acl
>= fs
->super
->s_blocks_count
))) {
6585 if (fix_problem(ctx
, PR_2_FILE_ACL_BAD
, &pctx
)) {
6586 inode
.i_file_acl
= 0;
6591 if (inode
.i_dir_acl
&&
6592 LINUX_S_ISDIR(inode
.i_mode
)) {
6593 if (fix_problem(ctx
, PR_2_DIR_ACL_ZERO
, &pctx
)) {
6594 inode
.i_dir_acl
= 0;
6601 e2fsck_write_inode(ctx
, ino
, &inode
, "process_bad_inode");
6603 ext2fs_unmark_inode_bitmap(ctx
->inode_bad_map
, ino
);
6609 * allocate_dir_block --- this function allocates a new directory
6610 * block for a particular inode; this is done if a directory has
6611 * a "hole" in it, or if a directory has a illegal block number
6612 * that was zeroed out and now needs to be replaced.
6614 static int allocate_dir_block(e2fsck_t ctx
, struct ext2_db_entry
*db
,
6615 struct problem_context
*pctx
)
6617 ext2_filsys fs
= ctx
->fs
;
6620 struct ext2_inode inode
;
6622 if (fix_problem(ctx
, PR_2_DIRECTORY_HOLE
, pctx
) == 0)
6626 * Read the inode and block bitmaps in; we'll be messing with
6629 e2fsck_read_bitmaps(ctx
);
6632 * First, find a free block
6634 pctx
->errcode
= ext2fs_new_block(fs
, 0, ctx
->block_found_map
, &blk
);
6635 if (pctx
->errcode
) {
6636 pctx
->str
= "ext2fs_new_block";
6637 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
6640 ext2fs_mark_block_bitmap(ctx
->block_found_map
, blk
);
6641 ext2fs_mark_block_bitmap(fs
->block_map
, blk
);
6642 ext2fs_mark_bb_dirty(fs
);
6645 * Now let's create the actual data block for the inode
6648 pctx
->errcode
= ext2fs_new_dir_block(fs
, 0, 0, &block
);
6650 pctx
->errcode
= ext2fs_new_dir_block(fs
, db
->ino
,
6651 EXT2_ROOT_INO
, &block
);
6653 if (pctx
->errcode
) {
6654 pctx
->str
= "ext2fs_new_dir_block";
6655 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
6659 pctx
->errcode
= ext2fs_write_dir_block(fs
, blk
, block
);
6660 ext2fs_free_mem(&block
);
6661 if (pctx
->errcode
) {
6662 pctx
->str
= "ext2fs_write_dir_block";
6663 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
6668 * Update the inode block count
6670 e2fsck_read_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
6671 inode
.i_blocks
+= fs
->blocksize
/ 512;
6672 if (inode
.i_size
< (db
->blockcnt
+1) * fs
->blocksize
)
6673 inode
.i_size
= (db
->blockcnt
+1) * fs
->blocksize
;
6674 e2fsck_write_inode(ctx
, db
->ino
, &inode
, "allocate_dir_block");
6677 * Finally, update the block pointers for the inode
6680 pctx
->errcode
= ext2fs_block_iterate2(fs
, db
->ino
, BLOCK_FLAG_HOLE
,
6681 0, update_dir_block
, db
);
6682 if (pctx
->errcode
) {
6683 pctx
->str
= "ext2fs_block_iterate";
6684 fix_problem(ctx
, PR_2_ALLOC_DIRBOCK
, pctx
);
6692 * This is a helper function for allocate_dir_block().
6694 static int update_dir_block(ext2_filsys fs
FSCK_ATTR((unused
)),
6696 e2_blkcnt_t blockcnt
,
6697 blk_t ref_block
FSCK_ATTR((unused
)),
6698 int ref_offset
FSCK_ATTR((unused
)),
6701 struct ext2_db_entry
*db
;
6703 db
= (struct ext2_db_entry
*) priv_data
;
6704 if (db
->blockcnt
== (int) blockcnt
) {
6705 *block_nr
= db
->blk
;
6706 return BLOCK_CHANGED
;
6712 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6714 * Pass #3 assures that all directories are connected to the
6715 * filesystem tree, using the following algorithm:
6717 * First, the root directory is checked to make sure it exists; if
6718 * not, e2fsck will offer to create a new one. It is then marked as
6721 * Then, pass3 interates over all directory inodes; for each directory
6722 * it attempts to trace up the filesystem tree, using dirinfo.parent
6723 * until it reaches a directory which has been marked "done". If it
6724 * cannot do so, then the directory must be disconnected, and e2fsck
6725 * will offer to reconnect it to /lost+found. While it is chasing
6726 * parent pointers up the filesystem tree, if pass3 sees a directory
6727 * twice, then it has detected a filesystem loop, and it will again
6728 * offer to reconnect the directory to /lost+found in to break the
6731 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6732 * reconnect inodes to /lost+found; this subroutine is also used by
6733 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6734 * is responsible for creating /lost+found if it does not exist.
6736 * Pass 3 frees the following data structures:
6737 * - The dirinfo directory information cache.
6740 static void check_root(e2fsck_t ctx
);
6741 static int check_directory(e2fsck_t ctx
, struct dir_info
*dir
,
6742 struct problem_context
*pctx
);
6743 static void fix_dotdot(e2fsck_t ctx
, struct dir_info
*dir
, ext2_ino_t parent
);
6745 static ext2fs_inode_bitmap inode_loop_detect
;
6746 static ext2fs_inode_bitmap inode_done_map
;
6748 static void e2fsck_pass3(e2fsck_t ctx
)
6750 ext2_filsys fs
= ctx
->fs
;
6752 struct problem_context pctx
;
6753 struct dir_info
*dir
;
6754 unsigned long maxdirs
, count
;
6756 clear_problem_context(&pctx
);
6760 if (!(ctx
->options
& E2F_OPT_PREEN
))
6761 fix_problem(ctx
, PR_3_PASS_HEADER
, &pctx
);
6764 * Allocate some bitmaps to do loop detection.
6766 pctx
.errcode
= ext2fs_allocate_inode_bitmap(fs
, _("inode done bitmap"),
6770 fix_problem(ctx
, PR_3_ALLOCATE_IBITMAP_ERROR
, &pctx
);
6771 ctx
->flags
|= E2F_FLAG_ABORT
;
6775 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
6778 ext2fs_mark_inode_bitmap(inode_done_map
, EXT2_ROOT_INO
);
6780 maxdirs
= e2fsck_get_num_dirinfo(ctx
);
6784 if ((ctx
->progress
)(ctx
, 3, 0, maxdirs
))
6787 for (i
=0; (dir
= e2fsck_dir_info_iter(ctx
, &i
)) != 0;) {
6788 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
6790 if (ctx
->progress
&& (ctx
->progress
)(ctx
, 3, count
++, maxdirs
))
6792 if (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
, dir
->ino
))
6793 if (check_directory(ctx
, dir
, &pctx
))
6798 * Force the creation of /lost+found if not present
6800 if ((ctx
->flags
& E2F_OPT_READONLY
) == 0)
6801 e2fsck_get_lost_and_found(ctx
, 1);
6804 * If there are any directories that need to be indexed or
6805 * optimized, do it here.
6807 e2fsck_rehash_directories(ctx
);
6810 e2fsck_free_dir_info(ctx
);
6811 ext2fs_free_inode_bitmap(inode_loop_detect
);
6812 inode_loop_detect
= 0;
6813 ext2fs_free_inode_bitmap(inode_done_map
);
6818 * This makes sure the root inode is present; if not, we ask if the
6819 * user wants us to create it. Not creating it is a fatal error.
6821 static void check_root(e2fsck_t ctx
)
6823 ext2_filsys fs
= ctx
->fs
;
6825 struct ext2_inode inode
;
6827 struct problem_context pctx
;
6829 clear_problem_context(&pctx
);
6831 if (ext2fs_test_inode_bitmap(ctx
->inode_used_map
, EXT2_ROOT_INO
)) {
6833 * If the root inode is not a directory, die here. The
6834 * user must have answered 'no' in pass1 when we
6835 * offered to clear it.
6837 if (!(ext2fs_test_inode_bitmap(ctx
->inode_dir_map
,
6839 fix_problem(ctx
, PR_3_ROOT_NOT_DIR_ABORT
, &pctx
);
6840 ctx
->flags
|= E2F_FLAG_ABORT
;
6845 if (!fix_problem(ctx
, PR_3_NO_ROOT_INODE
, &pctx
)) {
6846 fix_problem(ctx
, PR_3_NO_ROOT_INODE_ABORT
, &pctx
);
6847 ctx
->flags
|= E2F_FLAG_ABORT
;
6851 e2fsck_read_bitmaps(ctx
);
6854 * First, find a free block
6856 pctx
.errcode
= ext2fs_new_block(fs
, 0, ctx
->block_found_map
, &blk
);
6858 pctx
.str
= "ext2fs_new_block";
6859 fix_problem(ctx
, PR_3_CREATE_ROOT_ERROR
, &pctx
);
6860 ctx
->flags
|= E2F_FLAG_ABORT
;
6863 ext2fs_mark_block_bitmap(ctx
->block_found_map
, blk
);
6864 ext2fs_mark_block_bitmap(fs
->block_map
, blk
);
6865 ext2fs_mark_bb_dirty(fs
);
6868 * Now let's create the actual data block for the inode
6870 pctx
.errcode
= ext2fs_new_dir_block(fs
, EXT2_ROOT_INO
, EXT2_ROOT_INO
,
6873 pctx
.str
= "ext2fs_new_dir_block";
6874 fix_problem(ctx
, PR_3_CREATE_ROOT_ERROR
, &pctx
);
6875 ctx
->flags
|= E2F_FLAG_ABORT
;
6879 pctx
.errcode
= ext2fs_write_dir_block(fs
, blk
, block
);
6881 pctx
.str
= "ext2fs_write_dir_block";
6882 fix_problem(ctx
, PR_3_CREATE_ROOT_ERROR
, &pctx
);
6883 ctx
->flags
|= E2F_FLAG_ABORT
;
6886 ext2fs_free_mem(&block
);
6889 * Set up the inode structure
6891 memset(&inode
, 0, sizeof(inode
));
6892 inode
.i_mode
= 040755;
6893 inode
.i_size
= fs
->blocksize
;
6894 inode
.i_atime
= inode
.i_ctime
= inode
.i_mtime
= time(NULL
);
6895 inode
.i_links_count
= 2;
6896 inode
.i_blocks
= fs
->blocksize
/ 512;
6897 inode
.i_block
[0] = blk
;
6900 * Write out the inode.
6902 pctx
.errcode
= ext2fs_write_new_inode(fs
, EXT2_ROOT_INO
, &inode
);
6904 pctx
.str
= "ext2fs_write_inode";
6905 fix_problem(ctx
, PR_3_CREATE_ROOT_ERROR
, &pctx
);
6906 ctx
->flags
|= E2F_FLAG_ABORT
;
6911 * Miscellaneous bookkeeping...
6913 e2fsck_add_dir_info(ctx
, EXT2_ROOT_INO
, EXT2_ROOT_INO
);
6914 ext2fs_icount_store(ctx
->inode_count
, EXT2_ROOT_INO
, 2);
6915 ext2fs_icount_store(ctx
->inode_link_info
, EXT2_ROOT_INO
, 2);
6917 ext2fs_mark_inode_bitmap(ctx
->inode_used_map
, EXT2_ROOT_INO
);
6918 ext2fs_mark_inode_bitmap(ctx
->inode_dir_map
, EXT2_ROOT_INO
);
6919 ext2fs_mark_inode_bitmap(fs
->inode_map
, EXT2_ROOT_INO
);
6920 ext2fs_mark_ib_dirty(fs
);
6924 * This subroutine is responsible for making sure that a particular
6925 * directory is connected to the root; if it isn't we trace it up as
6926 * far as we can go, and then offer to connect the resulting parent to
6927 * the lost+found. We have to do loop detection; if we ever discover
6928 * a loop, we treat that as a disconnected directory and offer to
6929 * reparent it to lost+found.
6931 * However, loop detection is expensive, because for very large
6932 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6933 * is non-trivial. Loops in filesystems are also a rare error case,
6934 * and we shouldn't optimize for error cases. So we try two passes of
6935 * the algorithm. The first time, we ignore loop detection and merely
6936 * increment a counter; if the counter exceeds some extreme threshold,
6937 * then we try again with the loop detection bitmap enabled.
6939 static int check_directory(e2fsck_t ctx
, struct dir_info
*dir
,
6940 struct problem_context
*pctx
)
6942 ext2_filsys fs
= ctx
->fs
;
6943 struct dir_info
*p
= dir
;
6944 int loop_pass
= 0, parent_count
= 0;
6951 * Mark this inode as being "done"; by the time we
6952 * return from this function, the inode we either be
6953 * verified as being connected to the directory tree,
6954 * or we will have offered to reconnect this to
6957 * If it was marked done already, then we've reached a
6958 * parent we've already checked.
6960 if (ext2fs_mark_inode_bitmap(inode_done_map
, p
->ino
))
6964 * If this directory doesn't have a parent, or we've
6965 * seen the parent once already, then offer to
6966 * reparent it to lost+found
6970 (ext2fs_test_inode_bitmap(inode_loop_detect
,
6973 if (fix_problem(ctx
, PR_3_UNCONNECTED_DIR
, pctx
)) {
6974 if (e2fsck_reconnect_file(ctx
, pctx
->ino
))
6975 ext2fs_unmark_valid(fs
);
6977 p
= e2fsck_get_dir_info(ctx
, pctx
->ino
);
6978 p
->parent
= ctx
->lost_and_found
;
6979 fix_dotdot(ctx
, p
, ctx
->lost_and_found
);
6984 p
= e2fsck_get_dir_info(ctx
, p
->parent
);
6986 fix_problem(ctx
, PR_3_NO_DIRINFO
, pctx
);
6990 ext2fs_mark_inode_bitmap(inode_loop_detect
,
6992 } else if (parent_count
++ > 2048) {
6994 * If we've run into a path depth that's
6995 * greater than 2048, try again with the inode
6996 * loop bitmap turned on and start from the
7000 if (inode_loop_detect
)
7001 ext2fs_clear_inode_bitmap(inode_loop_detect
);
7003 pctx
->errcode
= ext2fs_allocate_inode_bitmap(fs
, _("inode loop detection bitmap"), &inode_loop_detect
);
7004 if (pctx
->errcode
) {
7007 PR_3_ALLOCATE_IBITMAP_ERROR
, pctx
);
7008 ctx
->flags
|= E2F_FLAG_ABORT
;
7017 * Make sure that .. and the parent directory are the same;
7018 * offer to fix it if not.
7020 if (dir
->parent
!= dir
->dotdot
) {
7021 pctx
->ino
= dir
->ino
;
7022 pctx
->ino2
= dir
->dotdot
;
7023 pctx
->dir
= dir
->parent
;
7024 if (fix_problem(ctx
, PR_3_BAD_DOT_DOT
, pctx
))
7025 fix_dotdot(ctx
, dir
, dir
->parent
);
7031 * This routine gets the lost_and_found inode, making it a directory
7034 ext2_ino_t
e2fsck_get_lost_and_found(e2fsck_t ctx
, int fix
)
7036 ext2_filsys fs
= ctx
->fs
;
7040 struct ext2_inode inode
;
7042 static const char name
[] = "lost+found";
7043 struct problem_context pctx
;
7044 struct dir_info
*dirinfo
;
7046 if (ctx
->lost_and_found
)
7047 return ctx
->lost_and_found
;
7049 clear_problem_context(&pctx
);
7051 retval
= ext2fs_lookup(fs
, EXT2_ROOT_INO
, name
,
7052 sizeof(name
)-1, 0, &ino
);
7056 if (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
, ino
)) {
7057 ctx
->lost_and_found
= ino
;
7061 /* Lost+found isn't a directory! */
7065 if (!fix_problem(ctx
, PR_3_LPF_NOTDIR
, &pctx
))
7068 /* OK, unlink the old /lost+found file. */
7069 pctx
.errcode
= ext2fs_unlink(fs
, EXT2_ROOT_INO
, name
, ino
, 0);
7071 pctx
.str
= "ext2fs_unlink";
7072 fix_problem(ctx
, PR_3_CREATE_LPF_ERROR
, &pctx
);
7075 dirinfo
= e2fsck_get_dir_info(ctx
, ino
);
7077 dirinfo
->parent
= 0;
7078 e2fsck_adjust_inode_count(ctx
, ino
, -1);
7079 } else if (retval
!= EXT2_ET_FILE_NOT_FOUND
) {
7080 pctx
.errcode
= retval
;
7081 fix_problem(ctx
, PR_3_ERR_FIND_LPF
, &pctx
);
7083 if (!fix_problem(ctx
, PR_3_NO_LF_DIR
, 0))
7087 * Read the inode and block bitmaps in; we'll be messing with
7090 e2fsck_read_bitmaps(ctx
);
7093 * First, find a free block
7095 retval
= ext2fs_new_block(fs
, 0, ctx
->block_found_map
, &blk
);
7097 pctx
.errcode
= retval
;
7098 fix_problem(ctx
, PR_3_ERR_LPF_NEW_BLOCK
, &pctx
);
7101 ext2fs_mark_block_bitmap(ctx
->block_found_map
, blk
);
7102 ext2fs_block_alloc_stats(fs
, blk
, +1);
7105 * Next find a free inode.
7107 retval
= ext2fs_new_inode(fs
, EXT2_ROOT_INO
, 040700,
7108 ctx
->inode_used_map
, &ino
);
7110 pctx
.errcode
= retval
;
7111 fix_problem(ctx
, PR_3_ERR_LPF_NEW_INODE
, &pctx
);
7114 ext2fs_mark_inode_bitmap(ctx
->inode_used_map
, ino
);
7115 ext2fs_mark_inode_bitmap(ctx
->inode_dir_map
, ino
);
7116 ext2fs_inode_alloc_stats2(fs
, ino
, +1, 1);
7119 * Now let's create the actual data block for the inode
7121 retval
= ext2fs_new_dir_block(fs
, ino
, EXT2_ROOT_INO
, &block
);
7123 pctx
.errcode
= retval
;
7124 fix_problem(ctx
, PR_3_ERR_LPF_NEW_DIR_BLOCK
, &pctx
);
7128 retval
= ext2fs_write_dir_block(fs
, blk
, block
);
7129 ext2fs_free_mem(&block
);
7131 pctx
.errcode
= retval
;
7132 fix_problem(ctx
, PR_3_ERR_LPF_WRITE_BLOCK
, &pctx
);
7137 * Set up the inode structure
7139 memset(&inode
, 0, sizeof(inode
));
7140 inode
.i_mode
= 040700;
7141 inode
.i_size
= fs
->blocksize
;
7142 inode
.i_atime
= inode
.i_ctime
= inode
.i_mtime
= time(NULL
);
7143 inode
.i_links_count
= 2;
7144 inode
.i_blocks
= fs
->blocksize
/ 512;
7145 inode
.i_block
[0] = blk
;
7148 * Next, write out the inode.
7150 pctx
.errcode
= ext2fs_write_new_inode(fs
, ino
, &inode
);
7152 pctx
.str
= "ext2fs_write_inode";
7153 fix_problem(ctx
, PR_3_CREATE_LPF_ERROR
, &pctx
);
7157 * Finally, create the directory link
7159 pctx
.errcode
= ext2fs_link(fs
, EXT2_ROOT_INO
, name
, ino
, EXT2_FT_DIR
);
7161 pctx
.str
= "ext2fs_link";
7162 fix_problem(ctx
, PR_3_CREATE_LPF_ERROR
, &pctx
);
7167 * Miscellaneous bookkeeping that needs to be kept straight.
7169 e2fsck_add_dir_info(ctx
, ino
, EXT2_ROOT_INO
);
7170 e2fsck_adjust_inode_count(ctx
, EXT2_ROOT_INO
, 1);
7171 ext2fs_icount_store(ctx
->inode_count
, ino
, 2);
7172 ext2fs_icount_store(ctx
->inode_link_info
, ino
, 2);
7173 ctx
->lost_and_found
= ino
;
7178 * This routine will connect a file to lost+found
7180 int e2fsck_reconnect_file(e2fsck_t ctx
, ext2_ino_t ino
)
7182 ext2_filsys fs
= ctx
->fs
;
7185 struct problem_context pctx
;
7186 struct ext2_inode inode
;
7189 clear_problem_context(&pctx
);
7192 if (!ctx
->bad_lost_and_found
&& !ctx
->lost_and_found
) {
7193 if (e2fsck_get_lost_and_found(ctx
, 1) == 0)
7194 ctx
->bad_lost_and_found
++;
7196 if (ctx
->bad_lost_and_found
) {
7197 fix_problem(ctx
, PR_3_NO_LPF
, &pctx
);
7201 sprintf(name
, "#%u", ino
);
7202 if (ext2fs_read_inode(fs
, ino
, &inode
) == 0)
7203 file_type
= ext2_file_type(inode
.i_mode
);
7204 retval
= ext2fs_link(fs
, ctx
->lost_and_found
, name
, ino
, file_type
);
7205 if (retval
== EXT2_ET_DIR_NO_SPACE
) {
7206 if (!fix_problem(ctx
, PR_3_EXPAND_LF_DIR
, &pctx
))
7208 retval
= e2fsck_expand_directory(ctx
, ctx
->lost_and_found
,
7211 pctx
.errcode
= retval
;
7212 fix_problem(ctx
, PR_3_CANT_EXPAND_LPF
, &pctx
);
7215 retval
= ext2fs_link(fs
, ctx
->lost_and_found
, name
,
7219 pctx
.errcode
= retval
;
7220 fix_problem(ctx
, PR_3_CANT_RECONNECT
, &pctx
);
7223 e2fsck_adjust_inode_count(ctx
, ino
, 1);
7229 * Utility routine to adjust the inode counts on an inode.
7231 errcode_t
e2fsck_adjust_inode_count(e2fsck_t ctx
, ext2_ino_t ino
, int adj
)
7233 ext2_filsys fs
= ctx
->fs
;
7235 struct ext2_inode inode
;
7240 retval
= ext2fs_read_inode(fs
, ino
, &inode
);
7245 ext2fs_icount_increment(ctx
->inode_count
, ino
, 0);
7246 if (inode
.i_links_count
== (__u16
) ~0)
7248 ext2fs_icount_increment(ctx
->inode_link_info
, ino
, 0);
7249 inode
.i_links_count
++;
7250 } else if (adj
== -1) {
7251 ext2fs_icount_decrement(ctx
->inode_count
, ino
, 0);
7252 if (inode
.i_links_count
== 0)
7254 ext2fs_icount_decrement(ctx
->inode_link_info
, ino
, 0);
7255 inode
.i_links_count
--;
7258 retval
= ext2fs_write_inode(fs
, ino
, &inode
);
7266 * Fix parent --- this routine fixes up the parent of a directory.
7268 struct fix_dotdot_struct
{
7275 static int fix_dotdot_proc(struct ext2_dir_entry
*dirent
,
7276 int offset
FSCK_ATTR((unused
)),
7277 int blocksize
FSCK_ATTR((unused
)),
7278 char *buf
FSCK_ATTR((unused
)),
7281 struct fix_dotdot_struct
*fp
= (struct fix_dotdot_struct
*) priv_data
;
7283 struct problem_context pctx
;
7285 if ((dirent
->name_len
& 0xFF) != 2)
7287 if (strncmp(dirent
->name
, "..", 2))
7290 clear_problem_context(&pctx
);
7292 retval
= e2fsck_adjust_inode_count(fp
->ctx
, dirent
->inode
, -1);
7294 pctx
.errcode
= retval
;
7295 fix_problem(fp
->ctx
, PR_3_ADJUST_INODE
, &pctx
);
7297 retval
= e2fsck_adjust_inode_count(fp
->ctx
, fp
->parent
, 1);
7299 pctx
.errcode
= retval
;
7300 fix_problem(fp
->ctx
, PR_3_ADJUST_INODE
, &pctx
);
7302 dirent
->inode
= fp
->parent
;
7305 return DIRENT_ABORT
| DIRENT_CHANGED
;
7308 static void fix_dotdot(e2fsck_t ctx
, struct dir_info
*dir
, ext2_ino_t parent
)
7310 ext2_filsys fs
= ctx
->fs
;
7312 struct fix_dotdot_struct fp
;
7313 struct problem_context pctx
;
7320 retval
= ext2fs_dir_iterate(fs
, dir
->ino
, DIRENT_FLAG_INCLUDE_EMPTY
,
7321 0, fix_dotdot_proc
, &fp
);
7322 if (retval
|| !fp
.done
) {
7323 clear_problem_context(&pctx
);
7324 pctx
.ino
= dir
->ino
;
7325 pctx
.errcode
= retval
;
7326 fix_problem(ctx
, retval
? PR_3_FIX_PARENT_ERR
:
7327 PR_3_FIX_PARENT_NOFIND
, &pctx
);
7328 ext2fs_unmark_valid(fs
);
7330 dir
->dotdot
= parent
;
7334 * These routines are responsible for expanding a /lost+found if it is
7338 struct expand_dir_struct
{
7340 int guaranteed_size
;
7347 static int expand_dir_proc(ext2_filsys fs
,
7349 e2_blkcnt_t blockcnt
,
7350 blk_t ref_block
FSCK_ATTR((unused
)),
7351 int ref_offset
FSCK_ATTR((unused
)),
7354 struct expand_dir_struct
*es
= (struct expand_dir_struct
*) priv_data
;
7356 static blk_t last_blk
= 0;
7363 if (es
->guaranteed_size
&& blockcnt
>= es
->guaranteed_size
)
7367 es
->last_block
= blockcnt
;
7369 last_blk
= *blocknr
;
7372 retval
= ext2fs_new_block(fs
, last_blk
, ctx
->block_found_map
,
7379 retval
= ext2fs_new_dir_block(fs
, 0, 0, &block
);
7385 retval
= ext2fs_write_dir_block(fs
, new_blk
, block
);
7387 retval
= ext2fs_get_mem(fs
->blocksize
, &block
);
7392 memset(block
, 0, fs
->blocksize
);
7393 retval
= io_channel_write_blk(fs
->io
, new_blk
, 1, block
);
7399 ext2fs_free_mem(&block
);
7401 ext2fs_mark_block_bitmap(ctx
->block_found_map
, new_blk
);
7402 ext2fs_block_alloc_stats(fs
, new_blk
, +1);
7406 return (BLOCK_CHANGED
| BLOCK_ABORT
);
7408 return BLOCK_CHANGED
;
7411 errcode_t
e2fsck_expand_directory(e2fsck_t ctx
, ext2_ino_t dir
,
7412 int num
, int guaranteed_size
)
7414 ext2_filsys fs
= ctx
->fs
;
7416 struct expand_dir_struct es
;
7417 struct ext2_inode inode
;
7419 if (!(fs
->flags
& EXT2_FLAG_RW
))
7420 return EXT2_ET_RO_FILSYS
;
7423 * Read the inode and block bitmaps in; we'll be messing with
7426 e2fsck_read_bitmaps(ctx
);
7428 retval
= ext2fs_check_directory(fs
, dir
);
7433 es
.guaranteed_size
= guaranteed_size
;
7439 retval
= ext2fs_block_iterate2(fs
, dir
, BLOCK_FLAG_APPEND
,
7440 0, expand_dir_proc
, &es
);
7446 * Update the size and block count fields in the inode.
7448 retval
= ext2fs_read_inode(fs
, dir
, &inode
);
7452 inode
.i_size
= (es
.last_block
+ 1) * fs
->blocksize
;
7453 inode
.i_blocks
+= (fs
->blocksize
/ 512) * es
.newblocks
;
7455 e2fsck_write_inode(ctx
, dir
, &inode
, "expand_directory");
7461 * pass4.c -- pass #4 of e2fsck: Check reference counts
7463 * Pass 4 frees the following data structures:
7464 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7468 * This routine is called when an inode is not connected to the
7471 * This subroutine returns 1 then the caller shouldn't bother with the
7472 * rest of the pass 4 tests.
7474 static int disconnect_inode(e2fsck_t ctx
, ext2_ino_t i
)
7476 ext2_filsys fs
= ctx
->fs
;
7477 struct ext2_inode inode
;
7478 struct problem_context pctx
;
7480 e2fsck_read_inode(ctx
, i
, &inode
, "pass4: disconnect_inode");
7481 clear_problem_context(&pctx
);
7483 pctx
.inode
= &inode
;
7486 * Offer to delete any zero-length files that does not have
7487 * blocks. If there is an EA block, it might have useful
7488 * information, so we won't prompt to delete it, but let it be
7489 * reconnected to lost+found.
7491 if (!inode
.i_blocks
&& (LINUX_S_ISREG(inode
.i_mode
) ||
7492 LINUX_S_ISDIR(inode
.i_mode
))) {
7493 if (fix_problem(ctx
, PR_4_ZERO_LEN_INODE
, &pctx
)) {
7494 ext2fs_icount_store(ctx
->inode_link_info
, i
, 0);
7495 inode
.i_links_count
= 0;
7496 inode
.i_dtime
= time(NULL
);
7497 e2fsck_write_inode(ctx
, i
, &inode
,
7498 "disconnect_inode");
7500 * Fix up the bitmaps...
7502 e2fsck_read_bitmaps(ctx
);
7503 ext2fs_unmark_inode_bitmap(ctx
->inode_used_map
, i
);
7504 ext2fs_unmark_inode_bitmap(ctx
->inode_dir_map
, i
);
7505 ext2fs_inode_alloc_stats2(fs
, i
, -1,
7506 LINUX_S_ISDIR(inode
.i_mode
));
7512 * Prompt to reconnect.
7514 if (fix_problem(ctx
, PR_4_UNATTACHED_INODE
, &pctx
)) {
7515 if (e2fsck_reconnect_file(ctx
, i
))
7516 ext2fs_unmark_valid(fs
);
7519 * If we don't attach the inode, then skip the
7520 * i_links_test since there's no point in trying to
7521 * force i_links_count to zero.
7523 ext2fs_unmark_valid(fs
);
7530 static void e2fsck_pass4(e2fsck_t ctx
)
7532 ext2_filsys fs
= ctx
->fs
;
7534 struct ext2_inode inode
;
7535 struct problem_context pctx
;
7536 __u16 link_count
, link_counted
;
7538 int group
, maxgroup
;
7542 clear_problem_context(&pctx
);
7544 if (!(ctx
->options
& E2F_OPT_PREEN
))
7545 fix_problem(ctx
, PR_4_PASS_HEADER
, &pctx
);
7548 maxgroup
= fs
->group_desc_count
;
7550 if ((ctx
->progress
)(ctx
, 4, 0, maxgroup
))
7553 for (i
=1; i
<= fs
->super
->s_inodes_count
; i
++) {
7554 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
7556 if ((i
% fs
->super
->s_inodes_per_group
) == 0) {
7559 if ((ctx
->progress
)(ctx
, 4, group
, maxgroup
))
7562 if (i
== EXT2_BAD_INO
||
7563 (i
> EXT2_ROOT_INO
&& i
< EXT2_FIRST_INODE(fs
->super
)))
7565 if (!(ext2fs_test_inode_bitmap(ctx
->inode_used_map
, i
)) ||
7566 (ctx
->inode_imagic_map
&&
7567 ext2fs_test_inode_bitmap(ctx
->inode_imagic_map
, i
)))
7569 ext2fs_icount_fetch(ctx
->inode_link_info
, i
, &link_count
);
7570 ext2fs_icount_fetch(ctx
->inode_count
, i
, &link_counted
);
7571 if (link_counted
== 0) {
7573 buf
= e2fsck_allocate_memory(ctx
,
7574 fs
->blocksize
, "bad_inode buffer");
7575 if (e2fsck_process_bad_inode(ctx
, 0, i
, buf
))
7577 if (disconnect_inode(ctx
, i
))
7579 ext2fs_icount_fetch(ctx
->inode_link_info
, i
,
7581 ext2fs_icount_fetch(ctx
->inode_count
, i
,
7584 if (link_counted
!= link_count
) {
7585 e2fsck_read_inode(ctx
, i
, &inode
, "pass4");
7587 pctx
.inode
= &inode
;
7588 if (link_count
!= inode
.i_links_count
) {
7589 pctx
.num
= link_count
;
7591 PR_4_INCONSISTENT_COUNT
, &pctx
);
7593 pctx
.num
= link_counted
;
7594 if (fix_problem(ctx
, PR_4_BAD_REF_COUNT
, &pctx
)) {
7595 inode
.i_links_count
= link_counted
;
7596 e2fsck_write_inode(ctx
, i
, &inode
, "pass4");
7600 ext2fs_free_icount(ctx
->inode_link_info
); ctx
->inode_link_info
= 0;
7601 ext2fs_free_icount(ctx
->inode_count
); ctx
->inode_count
= 0;
7602 ext2fs_free_inode_bitmap(ctx
->inode_imagic_map
);
7603 ctx
->inode_imagic_map
= 0;
7604 ext2fs_free_mem(&buf
);
7608 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7611 #define NO_BLK ((blk_t) -1)
7613 static void print_bitmap_problem(e2fsck_t ctx
, int problem
,
7614 struct problem_context
*pctx
)
7617 case PR_5_BLOCK_UNUSED
:
7618 if (pctx
->blk
== pctx
->blk2
)
7621 problem
= PR_5_BLOCK_RANGE_UNUSED
;
7623 case PR_5_BLOCK_USED
:
7624 if (pctx
->blk
== pctx
->blk2
)
7627 problem
= PR_5_BLOCK_RANGE_USED
;
7629 case PR_5_INODE_UNUSED
:
7630 if (pctx
->ino
== pctx
->ino2
)
7633 problem
= PR_5_INODE_RANGE_UNUSED
;
7635 case PR_5_INODE_USED
:
7636 if (pctx
->ino
== pctx
->ino2
)
7639 problem
= PR_5_INODE_RANGE_USED
;
7642 fix_problem(ctx
, problem
, pctx
);
7643 pctx
->blk
= pctx
->blk2
= NO_BLK
;
7644 pctx
->ino
= pctx
->ino2
= 0;
7647 static void check_block_bitmaps(e2fsck_t ctx
)
7649 ext2_filsys fs
= ctx
->fs
;
7653 unsigned int blocks
= 0;
7654 unsigned int free_blocks
= 0;
7657 struct problem_context pctx
;
7658 int problem
, save_problem
, fixit
, had_problem
;
7661 clear_problem_context(&pctx
);
7662 free_array
= (int *) e2fsck_allocate_memory(ctx
,
7663 fs
->group_desc_count
* sizeof(int), "free block count array");
7665 if ((fs
->super
->s_first_data_block
<
7666 ext2fs_get_block_bitmap_start(ctx
->block_found_map
)) ||
7667 (fs
->super
->s_blocks_count
-1 >
7668 ext2fs_get_block_bitmap_end(ctx
->block_found_map
))) {
7670 pctx
.blk
= fs
->super
->s_first_data_block
;
7671 pctx
.blk2
= fs
->super
->s_blocks_count
-1;
7672 pctx
.ino
= ext2fs_get_block_bitmap_start(ctx
->block_found_map
);
7673 pctx
.ino2
= ext2fs_get_block_bitmap_end(ctx
->block_found_map
);
7674 fix_problem(ctx
, PR_5_BMAP_ENDPOINTS
, &pctx
);
7676 ctx
->flags
|= E2F_FLAG_ABORT
; /* fatal */
7680 if ((fs
->super
->s_first_data_block
<
7681 ext2fs_get_block_bitmap_start(fs
->block_map
)) ||
7682 (fs
->super
->s_blocks_count
-1 >
7683 ext2fs_get_block_bitmap_end(fs
->block_map
))) {
7685 pctx
.blk
= fs
->super
->s_first_data_block
;
7686 pctx
.blk2
= fs
->super
->s_blocks_count
-1;
7687 pctx
.ino
= ext2fs_get_block_bitmap_start(fs
->block_map
);
7688 pctx
.ino2
= ext2fs_get_block_bitmap_end(fs
->block_map
);
7689 fix_problem(ctx
, PR_5_BMAP_ENDPOINTS
, &pctx
);
7691 ctx
->flags
|= E2F_FLAG_ABORT
; /* fatal */
7698 pctx
.blk
= pctx
.blk2
= NO_BLK
;
7699 for (i
= fs
->super
->s_first_data_block
;
7700 i
< fs
->super
->s_blocks_count
;
7702 actual
= ext2fs_fast_test_block_bitmap(ctx
->block_found_map
, i
);
7703 bitmap
= ext2fs_fast_test_block_bitmap(fs
->block_map
, i
);
7705 if (actual
== bitmap
)
7708 if (!actual
&& bitmap
) {
7710 * Block not used, but marked in use in the bitmap.
7712 problem
= PR_5_BLOCK_UNUSED
;
7715 * Block used, but not marked in use in the bitmap.
7717 problem
= PR_5_BLOCK_USED
;
7719 if (pctx
.blk
== NO_BLK
) {
7720 pctx
.blk
= pctx
.blk2
= i
;
7721 save_problem
= problem
;
7723 if ((problem
== save_problem
) &&
7727 print_bitmap_problem(ctx
, save_problem
, &pctx
);
7728 pctx
.blk
= pctx
.blk2
= i
;
7729 save_problem
= problem
;
7732 ctx
->flags
|= E2F_FLAG_PROG_SUPPRESS
;
7741 if ((blocks
== fs
->super
->s_blocks_per_group
) ||
7742 (i
== fs
->super
->s_blocks_count
-1)) {
7743 free_array
[group
] = group_free
;
7748 if ((ctx
->progress
)(ctx
, 5, group
,
7749 fs
->group_desc_count
*2))
7753 if (pctx
.blk
!= NO_BLK
)
7754 print_bitmap_problem(ctx
, save_problem
, &pctx
);
7756 fixit
= end_problem_latch(ctx
, PR_LATCH_BBITMAP
);
7759 ctx
->flags
&= ~E2F_FLAG_PROG_SUPPRESS
;
7762 ext2fs_free_block_bitmap(fs
->block_map
);
7763 retval
= ext2fs_copy_bitmap(ctx
->block_found_map
,
7766 clear_problem_context(&pctx
);
7767 fix_problem(ctx
, PR_5_COPY_BBITMAP_ERROR
, &pctx
);
7768 ctx
->flags
|= E2F_FLAG_ABORT
;
7771 ext2fs_set_bitmap_padding(fs
->block_map
);
7772 ext2fs_mark_bb_dirty(fs
);
7774 /* Redo the counts */
7775 blocks
= 0; free_blocks
= 0; group_free
= 0; group
= 0;
7776 memset(free_array
, 0, fs
->group_desc_count
* sizeof(int));
7778 } else if (fixit
== 0)
7779 ext2fs_unmark_valid(fs
);
7781 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
7782 if (free_array
[i
] != fs
->group_desc
[i
].bg_free_blocks_count
) {
7784 pctx
.blk
= fs
->group_desc
[i
].bg_free_blocks_count
;
7785 pctx
.blk2
= free_array
[i
];
7787 if (fix_problem(ctx
, PR_5_FREE_BLOCK_COUNT_GROUP
,
7789 fs
->group_desc
[i
].bg_free_blocks_count
=
7791 ext2fs_mark_super_dirty(fs
);
7793 ext2fs_unmark_valid(fs
);
7796 if (free_blocks
!= fs
->super
->s_free_blocks_count
) {
7798 pctx
.blk
= fs
->super
->s_free_blocks_count
;
7799 pctx
.blk2
= free_blocks
;
7801 if (fix_problem(ctx
, PR_5_FREE_BLOCK_COUNT
, &pctx
)) {
7802 fs
->super
->s_free_blocks_count
= free_blocks
;
7803 ext2fs_mark_super_dirty(fs
);
7805 ext2fs_unmark_valid(fs
);
7807 ext2fs_free_mem(&free_array
);
7810 static void check_inode_bitmaps(e2fsck_t ctx
)
7812 ext2_filsys fs
= ctx
->fs
;
7814 unsigned int free_inodes
= 0;
7818 unsigned int inodes
= 0;
7823 struct problem_context pctx
;
7824 int problem
, save_problem
, fixit
, had_problem
;
7826 clear_problem_context(&pctx
);
7827 free_array
= (int *) e2fsck_allocate_memory(ctx
,
7828 fs
->group_desc_count
* sizeof(int), "free inode count array");
7830 dir_array
= (int *) e2fsck_allocate_memory(ctx
,
7831 fs
->group_desc_count
* sizeof(int), "directory count array");
7833 if ((1 < ext2fs_get_inode_bitmap_start(ctx
->inode_used_map
)) ||
7834 (fs
->super
->s_inodes_count
>
7835 ext2fs_get_inode_bitmap_end(ctx
->inode_used_map
))) {
7838 pctx
.blk2
= fs
->super
->s_inodes_count
;
7839 pctx
.ino
= ext2fs_get_inode_bitmap_start(ctx
->inode_used_map
);
7840 pctx
.ino2
= ext2fs_get_inode_bitmap_end(ctx
->inode_used_map
);
7841 fix_problem(ctx
, PR_5_BMAP_ENDPOINTS
, &pctx
);
7843 ctx
->flags
|= E2F_FLAG_ABORT
; /* fatal */
7846 if ((1 < ext2fs_get_inode_bitmap_start(fs
->inode_map
)) ||
7847 (fs
->super
->s_inodes_count
>
7848 ext2fs_get_inode_bitmap_end(fs
->inode_map
))) {
7851 pctx
.blk2
= fs
->super
->s_inodes_count
;
7852 pctx
.ino
= ext2fs_get_inode_bitmap_start(fs
->inode_map
);
7853 pctx
.ino2
= ext2fs_get_inode_bitmap_end(fs
->inode_map
);
7854 fix_problem(ctx
, PR_5_BMAP_ENDPOINTS
, &pctx
);
7856 ctx
->flags
|= E2F_FLAG_ABORT
; /* fatal */
7863 pctx
.ino
= pctx
.ino2
= 0;
7864 for (i
= 1; i
<= fs
->super
->s_inodes_count
; i
++) {
7865 actual
= ext2fs_fast_test_inode_bitmap(ctx
->inode_used_map
, i
);
7866 bitmap
= ext2fs_fast_test_inode_bitmap(fs
->inode_map
, i
);
7868 if (actual
== bitmap
)
7871 if (!actual
&& bitmap
) {
7873 * Inode wasn't used, but marked in bitmap
7875 problem
= PR_5_INODE_UNUSED
;
7876 } else /* if (actual && !bitmap) */ {
7878 * Inode used, but not in bitmap
7880 problem
= PR_5_INODE_USED
;
7882 if (pctx
.ino
== 0) {
7883 pctx
.ino
= pctx
.ino2
= i
;
7884 save_problem
= problem
;
7886 if ((problem
== save_problem
) &&
7890 print_bitmap_problem(ctx
, save_problem
, &pctx
);
7891 pctx
.ino
= pctx
.ino2
= i
;
7892 save_problem
= problem
;
7895 ctx
->flags
|= E2F_FLAG_PROG_SUPPRESS
;
7903 if (ext2fs_test_inode_bitmap(ctx
->inode_dir_map
, i
))
7907 if ((inodes
== fs
->super
->s_inodes_per_group
) ||
7908 (i
== fs
->super
->s_inodes_count
)) {
7909 free_array
[group
] = group_free
;
7910 dir_array
[group
] = dirs_count
;
7916 if ((ctx
->progress
)(ctx
, 5,
7917 group
+ fs
->group_desc_count
,
7918 fs
->group_desc_count
*2))
7923 print_bitmap_problem(ctx
, save_problem
, &pctx
);
7926 fixit
= end_problem_latch(ctx
, PR_LATCH_IBITMAP
);
7929 ctx
->flags
&= ~E2F_FLAG_PROG_SUPPRESS
;
7932 ext2fs_free_inode_bitmap(fs
->inode_map
);
7933 retval
= ext2fs_copy_bitmap(ctx
->inode_used_map
,
7936 clear_problem_context(&pctx
);
7937 fix_problem(ctx
, PR_5_COPY_IBITMAP_ERROR
, &pctx
);
7938 ctx
->flags
|= E2F_FLAG_ABORT
;
7941 ext2fs_set_bitmap_padding(fs
->inode_map
);
7942 ext2fs_mark_ib_dirty(fs
);
7945 inodes
= 0; free_inodes
= 0; group_free
= 0;
7946 dirs_count
= 0; group
= 0;
7947 memset(free_array
, 0, fs
->group_desc_count
* sizeof(int));
7948 memset(dir_array
, 0, fs
->group_desc_count
* sizeof(int));
7950 } else if (fixit
== 0)
7951 ext2fs_unmark_valid(fs
);
7953 for (i
= 0; i
< fs
->group_desc_count
; i
++) {
7954 if (free_array
[i
] != fs
->group_desc
[i
].bg_free_inodes_count
) {
7956 pctx
.ino
= fs
->group_desc
[i
].bg_free_inodes_count
;
7957 pctx
.ino2
= free_array
[i
];
7958 if (fix_problem(ctx
, PR_5_FREE_INODE_COUNT_GROUP
,
7960 fs
->group_desc
[i
].bg_free_inodes_count
=
7962 ext2fs_mark_super_dirty(fs
);
7964 ext2fs_unmark_valid(fs
);
7966 if (dir_array
[i
] != fs
->group_desc
[i
].bg_used_dirs_count
) {
7968 pctx
.ino
= fs
->group_desc
[i
].bg_used_dirs_count
;
7969 pctx
.ino2
= dir_array
[i
];
7971 if (fix_problem(ctx
, PR_5_FREE_DIR_COUNT_GROUP
,
7973 fs
->group_desc
[i
].bg_used_dirs_count
=
7975 ext2fs_mark_super_dirty(fs
);
7977 ext2fs_unmark_valid(fs
);
7980 if (free_inodes
!= fs
->super
->s_free_inodes_count
) {
7982 pctx
.ino
= fs
->super
->s_free_inodes_count
;
7983 pctx
.ino2
= free_inodes
;
7985 if (fix_problem(ctx
, PR_5_FREE_INODE_COUNT
, &pctx
)) {
7986 fs
->super
->s_free_inodes_count
= free_inodes
;
7987 ext2fs_mark_super_dirty(fs
);
7989 ext2fs_unmark_valid(fs
);
7991 ext2fs_free_mem(&free_array
);
7992 ext2fs_free_mem(&dir_array
);
7995 static void check_inode_end(e2fsck_t ctx
)
7997 ext2_filsys fs
= ctx
->fs
;
7998 ext2_ino_t end
, save_inodes_count
, i
;
7999 struct problem_context pctx
;
8001 clear_problem_context(&pctx
);
8003 end
= EXT2_INODES_PER_GROUP(fs
->super
) * fs
->group_desc_count
;
8004 pctx
.errcode
= ext2fs_fudge_inode_bitmap_end(fs
->inode_map
, end
,
8005 &save_inodes_count
);
8008 fix_problem(ctx
, PR_5_FUDGE_BITMAP_ERROR
, &pctx
);
8009 ctx
->flags
|= E2F_FLAG_ABORT
; /* fatal */
8012 if (save_inodes_count
== end
)
8015 for (i
= save_inodes_count
+ 1; i
<= end
; i
++) {
8016 if (!ext2fs_test_inode_bitmap(fs
->inode_map
, i
)) {
8017 if (fix_problem(ctx
, PR_5_INODE_BMAP_PADDING
, &pctx
)) {
8018 for (i
= save_inodes_count
+ 1; i
<= end
; i
++)
8019 ext2fs_mark_inode_bitmap(fs
->inode_map
,
8021 ext2fs_mark_ib_dirty(fs
);
8023 ext2fs_unmark_valid(fs
);
8028 pctx
.errcode
= ext2fs_fudge_inode_bitmap_end(fs
->inode_map
,
8029 save_inodes_count
, 0);
8032 fix_problem(ctx
, PR_5_FUDGE_BITMAP_ERROR
, &pctx
);
8033 ctx
->flags
|= E2F_FLAG_ABORT
; /* fatal */
8038 static void check_block_end(e2fsck_t ctx
)
8040 ext2_filsys fs
= ctx
->fs
;
8041 blk_t end
, save_blocks_count
, i
;
8042 struct problem_context pctx
;
8044 clear_problem_context(&pctx
);
8046 end
= fs
->block_map
->start
+
8047 (EXT2_BLOCKS_PER_GROUP(fs
->super
) * fs
->group_desc_count
) - 1;
8048 pctx
.errcode
= ext2fs_fudge_block_bitmap_end(fs
->block_map
, end
,
8049 &save_blocks_count
);
8052 fix_problem(ctx
, PR_5_FUDGE_BITMAP_ERROR
, &pctx
);
8053 ctx
->flags
|= E2F_FLAG_ABORT
; /* fatal */
8056 if (save_blocks_count
== end
)
8059 for (i
= save_blocks_count
+ 1; i
<= end
; i
++) {
8060 if (!ext2fs_test_block_bitmap(fs
->block_map
, i
)) {
8061 if (fix_problem(ctx
, PR_5_BLOCK_BMAP_PADDING
, &pctx
)) {
8062 for (i
= save_blocks_count
+ 1; i
<= end
; i
++)
8063 ext2fs_mark_block_bitmap(fs
->block_map
,
8065 ext2fs_mark_bb_dirty(fs
);
8067 ext2fs_unmark_valid(fs
);
8072 pctx
.errcode
= ext2fs_fudge_block_bitmap_end(fs
->block_map
,
8073 save_blocks_count
, 0);
8076 fix_problem(ctx
, PR_5_FUDGE_BITMAP_ERROR
, &pctx
);
8077 ctx
->flags
|= E2F_FLAG_ABORT
; /* fatal */
8082 static void e2fsck_pass5(e2fsck_t ctx
)
8084 struct problem_context pctx
;
8088 clear_problem_context(&pctx
);
8090 if (!(ctx
->options
& E2F_OPT_PREEN
))
8091 fix_problem(ctx
, PR_5_PASS_HEADER
, &pctx
);
8094 if ((ctx
->progress
)(ctx
, 5, 0, ctx
->fs
->group_desc_count
*2))
8097 e2fsck_read_bitmaps(ctx
);
8099 check_block_bitmaps(ctx
);
8100 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
8102 check_inode_bitmaps(ctx
);
8103 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
8105 check_inode_end(ctx
);
8106 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
8108 check_block_end(ctx
);
8109 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
8112 ext2fs_free_inode_bitmap(ctx
->inode_used_map
);
8113 ctx
->inode_used_map
= 0;
8114 ext2fs_free_inode_bitmap(ctx
->inode_dir_map
);
8115 ctx
->inode_dir_map
= 0;
8116 ext2fs_free_block_bitmap(ctx
->block_found_map
);
8117 ctx
->block_found_map
= 0;
8121 * problem.c --- report filesystem problems to the user
8124 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8125 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8126 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8127 #define PR_MSG_ONLY 0x000008 /* Print message only */
8129 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8131 #define PR_FATAL 0x001000 /* Fatal error */
8132 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8134 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8135 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8136 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8137 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8138 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8141 #define PROMPT_NONE 0
8142 #define PROMPT_FIX 1
8143 #define PROMPT_CLEAR 2
8144 #define PROMPT_RELOCATE 3
8145 #define PROMPT_ALLOCATE 4
8146 #define PROMPT_EXPAND 5
8147 #define PROMPT_CONNECT 6
8148 #define PROMPT_CREATE 7
8149 #define PROMPT_SALVAGE 8
8150 #define PROMPT_TRUNCATE 9
8151 #define PROMPT_CLEAR_INODE 10
8152 #define PROMPT_ABORT 11
8153 #define PROMPT_SPLIT 12
8154 #define PROMPT_CONTINUE 13
8155 #define PROMPT_CLONE 14
8156 #define PROMPT_DELETE 15
8157 #define PROMPT_SUPPRESS 16
8158 #define PROMPT_UNLINK 17
8159 #define PROMPT_CLEAR_HTREE 18
8160 #define PROMPT_RECREATE 19
8161 #define PROMPT_NULL 20
8163 struct e2fsck_problem
{
8165 const char * e2p_description
;
8168 problem_t second_code
;
8171 struct latch_descr
{
8174 problem_t end_message
;
8179 * These are the prompts which are used to ask the user if they want
8182 static const char *const prompt
[] = {
8183 N_("(no prompt)"), /* 0 */
8185 N_("Clear"), /* 2 */
8186 N_("Relocate"), /* 3 */
8187 N_("Allocate"), /* 4 */
8188 N_("Expand"), /* 5 */
8189 N_("Connect to /lost+found"), /* 6 */
8190 N_("Create"), /* 7 */
8191 N_("Salvage"), /* 8 */
8192 N_("Truncate"), /* 9 */
8193 N_("Clear inode"), /* 10 */
8194 N_("Abort"), /* 11 */
8195 N_("Split"), /* 12 */
8196 N_("Continue"), /* 13 */
8197 N_("Clone multiply-claimed blocks"), /* 14 */
8198 N_("Delete file"), /* 15 */
8199 N_("Suppress messages"),/* 16 */
8200 N_("Unlink"), /* 17 */
8201 N_("Clear HTree index"),/* 18 */
8202 N_("Recreate"), /* 19 */
8207 * These messages are printed when we are preen mode and we will be
8208 * automatically fixing the problem.
8210 static const char *const preen_msg
[] = {
8211 N_("(NONE)"), /* 0 */
8212 N_("FIXED"), /* 1 */
8213 N_("CLEARED"), /* 2 */
8214 N_("RELOCATED"), /* 3 */
8215 N_("ALLOCATED"), /* 4 */
8216 N_("EXPANDED"), /* 5 */
8217 N_("RECONNECTED"), /* 6 */
8218 N_("CREATED"), /* 7 */
8219 N_("SALVAGED"), /* 8 */
8220 N_("TRUNCATED"), /* 9 */
8221 N_("INODE CLEARED"), /* 10 */
8222 N_("ABORTED"), /* 11 */
8223 N_("SPLIT"), /* 12 */
8224 N_("CONTINUING"), /* 13 */
8225 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8226 N_("FILE DELETED"), /* 15 */
8227 N_("SUPPRESSED"), /* 16 */
8228 N_("UNLINKED"), /* 17 */
8229 N_("HTREE INDEX CLEARED"),/* 18 */
8230 N_("WILL RECREATE"), /* 19 */
8234 static const struct e2fsck_problem problem_table
[] = {
8236 /* Pre-Pass 1 errors */
8238 /* Block bitmap not in group */
8239 { PR_0_BB_NOT_GROUP
, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8240 PROMPT_RELOCATE
, PR_LATCH_RELOC
},
8242 /* Inode bitmap not in group */
8243 { PR_0_IB_NOT_GROUP
, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8244 PROMPT_RELOCATE
, PR_LATCH_RELOC
},
8246 /* Inode table not in group */
8247 { PR_0_ITABLE_NOT_GROUP
,
8248 N_("@i table for @g %g is not in @g. (@b %b)\n"
8249 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8250 PROMPT_RELOCATE
, PR_LATCH_RELOC
},
8252 /* Superblock corrupt */
8254 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8255 "@f. If the @v is valid and it really contains an ext2\n"
8256 "@f (and not swap or ufs or something else), then the @S\n"
8257 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8258 " e2fsck -b %S <@v>\n\n"),
8259 PROMPT_NONE
, PR_FATAL
},
8261 /* Filesystem size is wrong */
8262 { PR_0_FS_SIZE_WRONG
,
8263 N_("The @f size (according to the @S) is %b @bs\n"
8264 "The physical size of the @v is %c @bs\n"
8265 "Either the @S or the partition table is likely to be corrupt!\n"),
8268 /* Fragments not supported */
8269 { PR_0_NO_FRAGMENTS
,
8270 N_("@S @b_size = %b, fragsize = %c.\n"
8271 "This version of e2fsck does not support fragment sizes different\n"
8272 "from the @b size.\n"),
8273 PROMPT_NONE
, PR_FATAL
},
8275 /* Bad blocks_per_group */
8276 { PR_0_BLOCKS_PER_GROUP
,
8277 N_("@S @bs_per_group = %b, should have been %c\n"),
8278 PROMPT_NONE
, PR_AFTER_CODE
, PR_0_SB_CORRUPT
},
8280 /* Bad first_data_block */
8281 { PR_0_FIRST_DATA_BLOCK
,
8282 N_("@S first_data_@b = %b, should have been %c\n"),
8283 PROMPT_NONE
, PR_AFTER_CODE
, PR_0_SB_CORRUPT
},
8285 /* Adding UUID to filesystem */
8287 N_("@f did not have a UUID; generating one.\n\n"),
8291 { PR_0_RELOCATE_HINT
,
8292 N_("Note: if several inode or block bitmap blocks or part\n"
8293 "of the inode table require relocation, you may wish to try\n"
8294 "running e2fsck with the '-b %S' option first. The problem\n"
8295 "may lie only with the primary block group descriptors, and\n"
8296 "the backup block group descriptors may be OK.\n\n"),
8297 PROMPT_NONE
, PR_PREEN_OK
| PR_NOCOLLATE
},
8299 /* Miscellaneous superblock corruption */
8300 { PR_0_MISC_CORRUPT_SUPER
,
8301 N_("Corruption found in @S. (%s = %N).\n"),
8302 PROMPT_NONE
, PR_AFTER_CODE
, PR_0_SB_CORRUPT
},
8304 /* Error determing physical device size of filesystem */
8305 { PR_0_GETSIZE_ERROR
,
8306 N_("Error determining size of the physical @v: %m\n"),
8307 PROMPT_NONE
, PR_FATAL
},
8309 /* Inode count in superblock is incorrect */
8310 { PR_0_INODE_COUNT_WRONG
,
8311 N_("@i count in @S is %i, @s %j.\n"),
8314 { PR_0_HURD_CLEAR_FILETYPE
,
8315 N_("The Hurd does not support the filetype feature.\n"),
8318 /* Journal inode is invalid */
8319 { PR_0_JOURNAL_BAD_INODE
,
8320 N_("@S has an @n ext3 @j (@i %i).\n"),
8321 PROMPT_CLEAR
, PR_PREEN_OK
},
8323 /* The external journal has (unsupported) multiple filesystems */
8324 { PR_0_JOURNAL_UNSUPP_MULTIFS
,
8325 N_("External @j has multiple @f users (unsupported).\n"),
8326 PROMPT_NONE
, PR_FATAL
},
8328 /* Can't find external journal */
8329 { PR_0_CANT_FIND_JOURNAL
,
8330 N_("Can't find external @j\n"),
8331 PROMPT_NONE
, PR_FATAL
},
8333 /* External journal has bad superblock */
8334 { PR_0_EXT_JOURNAL_BAD_SUPER
,
8335 N_("External @j has bad @S\n"),
8336 PROMPT_NONE
, PR_FATAL
},
8338 /* Superblock has a bad journal UUID */
8339 { PR_0_JOURNAL_BAD_UUID
,
8340 N_("External @j does not support this @f\n"),
8341 PROMPT_NONE
, PR_FATAL
},
8343 /* Journal has an unknown superblock type */
8344 { PR_0_JOURNAL_UNSUPP_SUPER
,
8345 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8346 "It is likely that your copy of e2fsck is old and/or doesn't "
8347 "support this @j format.\n"
8348 "It is also possible the @j @S is corrupt.\n"),
8349 PROMPT_ABORT
, PR_NO_OK
| PR_AFTER_CODE
, PR_0_JOURNAL_BAD_SUPER
},
8351 /* Journal superblock is corrupt */
8352 { PR_0_JOURNAL_BAD_SUPER
,
8353 N_("Ext3 @j @S is corrupt.\n"),
8354 PROMPT_FIX
, PR_PREEN_OK
},
8356 /* Superblock flag should be cleared */
8357 { PR_0_JOURNAL_HAS_JOURNAL
,
8358 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8359 PROMPT_CLEAR
, PR_PREEN_OK
},
8361 /* Superblock flag is incorrect */
8362 { PR_0_JOURNAL_RECOVER_SET
,
8363 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8364 PROMPT_CLEAR
, PR_PREEN_OK
},
8366 /* Journal has data, but recovery flag is clear */
8367 { PR_0_JOURNAL_RECOVERY_CLEAR
,
8368 N_("ext3 recovery flag is clear, but @j has data.\n"),
8371 /* Ask if we should clear the journal */
8372 { PR_0_JOURNAL_RESET_JOURNAL
,
8374 PROMPT_NULL
, PR_PREEN_NOMSG
},
8376 /* Ask if we should run the journal anyway */
8378 N_("Run @j anyway"),
8381 /* Run the journal by default */
8382 { PR_0_JOURNAL_RUN_DEFAULT
,
8383 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8386 /* Clearing orphan inode */
8387 { PR_0_ORPHAN_CLEAR_INODE
,
8388 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8391 /* Illegal block found in orphaned inode */
8392 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM
,
8393 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8396 /* Already cleared block found in orphaned inode */
8397 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK
,
8398 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8401 /* Illegal orphan inode in superblock */
8402 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE
,
8403 N_("@I @o @i %i in @S.\n"),
8406 /* Illegal inode in orphaned inode list */
8407 { PR_0_ORPHAN_ILLEGAL_INODE
,
8408 N_("@I @i %i in @o @i list.\n"),
8411 /* Filesystem revision is 0, but feature flags are set */
8412 { PR_0_FS_REV_LEVEL
,
8413 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8414 PROMPT_FIX
, PR_PREEN_OK
| PR_NO_OK
},
8416 /* Journal superblock has an unknown read-only feature flag set */
8417 { PR_0_JOURNAL_UNSUPP_ROCOMPAT
,
8418 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8421 /* Journal superblock has an unknown incompatible feature flag set */
8422 { PR_0_JOURNAL_UNSUPP_INCOMPAT
,
8423 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8426 /* Journal has unsupported version number */
8427 { PR_0_JOURNAL_UNSUPP_VERSION
,
8428 N_("@j version not supported by this e2fsck.\n"),
8431 /* Moving journal to hidden file */
8432 { PR_0_MOVE_JOURNAL
,
8433 N_("Moving @j from /%s to hidden @i.\n\n"),
8436 /* Error moving journal to hidden file */
8437 { PR_0_ERR_MOVE_JOURNAL
,
8438 N_("Error moving @j: %m\n\n"),
8441 /* Clearing V2 journal superblock */
8442 { PR_0_CLEAR_V2_JOURNAL
,
8443 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8444 "Clearing fields beyond the V1 @j @S...\n\n"),
8447 /* Backup journal inode blocks */
8449 N_("Backing up @j @i @b information.\n\n"),
8452 /* Reserved blocks w/o resize_inode */
8453 { PR_0_NONZERO_RESERVED_GDT_BLOCKS
,
8454 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8455 "is %N; @s zero. "),
8458 /* Resize_inode not enabled, but resize inode is non-zero */
8459 { PR_0_CLEAR_RESIZE_INODE
,
8460 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8463 /* Resize inode invalid */
8464 { PR_0_RESIZE_INODE_INVALID
,
8465 N_("Resize @i not valid. "),
8466 PROMPT_RECREATE
, 0 },
8470 /* Pass 1: Checking inodes, blocks, and sizes */
8472 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8475 /* Root directory is not an inode */
8476 { PR_1_ROOT_NO_DIR
, N_("@r is not a @d. "),
8479 /* Root directory has dtime set */
8481 N_("@r has dtime set (probably due to old mke2fs). "),
8482 PROMPT_FIX
, PR_PREEN_OK
},
8484 /* Reserved inode has bad mode */
8485 { PR_1_RESERVED_BAD_MODE
,
8486 N_("Reserved @i %i (%Q) has @n mode. "),
8487 PROMPT_CLEAR
, PR_PREEN_OK
},
8489 /* Deleted inode has zero dtime */
8491 N_("@D @i %i has zero dtime. "),
8492 PROMPT_FIX
, PR_PREEN_OK
},
8494 /* Inode in use, but dtime set */
8496 N_("@i %i is in use, but has dtime set. "),
8497 PROMPT_FIX
, PR_PREEN_OK
},
8499 /* Zero-length directory */
8500 { PR_1_ZERO_LENGTH_DIR
,
8501 N_("@i %i is a @z @d. "),
8502 PROMPT_CLEAR
, PR_PREEN_OK
},
8504 /* Block bitmap conflicts with some other fs block */
8506 N_("@g %g's @b @B at %b @C.\n"),
8507 PROMPT_RELOCATE
, 0 },
8509 /* Inode bitmap conflicts with some other fs block */
8511 N_("@g %g's @i @B at %b @C.\n"),
8512 PROMPT_RELOCATE
, 0 },
8514 /* Inode table conflicts with some other fs block */
8515 { PR_1_ITABLE_CONFLICT
,
8516 N_("@g %g's @i table at %b @C.\n"),
8517 PROMPT_RELOCATE
, 0 },
8519 /* Block bitmap is on a bad block */
8520 { PR_1_BB_BAD_BLOCK
,
8521 N_("@g %g's @b @B (%b) is bad. "),
8522 PROMPT_RELOCATE
, 0 },
8524 /* Inode bitmap is on a bad block */
8525 { PR_1_IB_BAD_BLOCK
,
8526 N_("@g %g's @i @B (%b) is bad. "),
8527 PROMPT_RELOCATE
, 0 },
8529 /* Inode has incorrect i_size */
8531 N_("@i %i, i_size is %Is, @s %N. "),
8532 PROMPT_FIX
, PR_PREEN_OK
},
8534 /* Inode has incorrect i_blocks */
8535 { PR_1_BAD_I_BLOCKS
,
8536 N_("@i %i, i_@bs is %Ib, @s %N. "),
8537 PROMPT_FIX
, PR_PREEN_OK
},
8539 /* Illegal blocknumber in inode */
8540 { PR_1_ILLEGAL_BLOCK_NUM
,
8541 N_("@I @b #%B (%b) in @i %i. "),
8542 PROMPT_CLEAR
, PR_LATCH_BLOCK
},
8544 /* Block number overlaps fs metadata */
8545 { PR_1_BLOCK_OVERLAPS_METADATA
,
8546 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8547 PROMPT_CLEAR
, PR_LATCH_BLOCK
},
8549 /* Inode has illegal blocks (latch question) */
8550 { PR_1_INODE_BLOCK_LATCH
,
8551 N_("@i %i has illegal @b(s). "),
8554 /* Too many bad blocks in inode */
8555 { PR_1_TOO_MANY_BAD_BLOCKS
,
8556 N_("Too many illegal @bs in @i %i.\n"),
8557 PROMPT_CLEAR_INODE
, PR_NO_OK
},
8559 /* Illegal block number in bad block inode */
8560 { PR_1_BB_ILLEGAL_BLOCK_NUM
,
8561 N_("@I @b #%B (%b) in bad @b @i. "),
8562 PROMPT_CLEAR
, PR_LATCH_BBLOCK
},
8564 /* Bad block inode has illegal blocks (latch question) */
8565 { PR_1_INODE_BBLOCK_LATCH
,
8566 N_("Bad @b @i has illegal @b(s). "),
8569 /* Duplicate or bad blocks in use! */
8570 { PR_1_DUP_BLOCKS_PREENSTOP
,
8571 N_("Duplicate or bad @b in use!\n"),
8574 /* Bad block used as bad block indirect block */
8575 { PR_1_BBINODE_BAD_METABLOCK
,
8576 N_("Bad @b %b used as bad @b @i indirect @b. "),
8577 PROMPT_CLEAR
, PR_LATCH_BBLOCK
},
8579 /* Inconsistency can't be fixed prompt */
8580 { PR_1_BBINODE_BAD_METABLOCK_PROMPT
,
8581 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8582 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8584 PROMPT_CONTINUE
, PR_PREEN_NOMSG
},
8586 /* Bad primary block */
8587 { PR_1_BAD_PRIMARY_BLOCK
,
8588 N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
8589 PROMPT_NONE
, PR_AFTER_CODE
, PR_1_BAD_PRIMARY_BLOCK_PROMPT
},
8591 /* Bad primary block prompt */
8592 { PR_1_BAD_PRIMARY_BLOCK_PROMPT
,
8593 N_("You can remove this @b from the bad @b list and hope\n"
8594 "that the @b is really OK. But there are no guarantees.\n\n"),
8595 PROMPT_CLEAR
, PR_PREEN_NOMSG
},
8597 /* Bad primary superblock */
8598 { PR_1_BAD_PRIMARY_SUPERBLOCK
,
8599 N_("The primary @S (%b) is on the bad @b list.\n"),
8600 PROMPT_NONE
, PR_AFTER_CODE
, PR_1_BAD_PRIMARY_BLOCK
},
8602 /* Bad primary block group descriptors */
8603 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR
,
8604 N_("Block %b in the primary @g descriptors "
8605 "is on the bad @b list\n"),
8606 PROMPT_NONE
, PR_AFTER_CODE
, PR_1_BAD_PRIMARY_BLOCK
},
8608 /* Bad superblock in group */
8609 { PR_1_BAD_SUPERBLOCK
,
8610 N_("Warning: Group %g's @S (%b) is bad.\n"),
8611 PROMPT_NONE
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
8613 /* Bad block group descriptors in group */
8614 { PR_1_BAD_GROUP_DESCRIPTORS
,
8615 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8617 PROMPT_NONE
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
8619 /* Block claimed for no reason */
8620 { PR_1_PROGERR_CLAIMED_BLOCK
,
8621 N_("Programming error? @b #%b claimed for no reason in "
8622 "process_bad_@b.\n"),
8623 PROMPT_NONE
, PR_PREEN_OK
},
8625 /* Error allocating blocks for relocating metadata */
8626 { PR_1_RELOC_BLOCK_ALLOCATE
,
8627 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8628 PROMPT_NONE
, PR_PREEN_OK
},
8630 /* Error allocating block buffer during relocation process */
8631 { PR_1_RELOC_MEMORY_ALLOCATE
,
8632 N_("@A @b buffer for relocating %s\n"),
8633 PROMPT_NONE
, PR_PREEN_OK
},
8635 /* Relocating metadata group information from X to Y */
8636 { PR_1_RELOC_FROM_TO
,
8637 N_("Relocating @g %g's %s from %b to %c...\n"),
8638 PROMPT_NONE
, PR_PREEN_OK
},
8640 /* Relocating metatdata group information to X */
8642 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8643 PROMPT_NONE
, PR_PREEN_OK
},
8645 /* Block read error during relocation process */
8646 { PR_1_RELOC_READ_ERR
,
8647 N_("Warning: could not read @b %b of %s: %m\n"),
8648 PROMPT_NONE
, PR_PREEN_OK
},
8650 /* Block write error during relocation process */
8651 { PR_1_RELOC_WRITE_ERR
,
8652 N_("Warning: could not write @b %b for %s: %m\n"),
8653 PROMPT_NONE
, PR_PREEN_OK
},
8655 /* Error allocating inode bitmap */
8656 { PR_1_ALLOCATE_IBITMAP_ERROR
,
8657 N_("@A @i @B (%N): %m\n"),
8658 PROMPT_NONE
, PR_FATAL
},
8660 /* Error allocating block bitmap */
8661 { PR_1_ALLOCATE_BBITMAP_ERROR
,
8662 N_("@A @b @B (%N): %m\n"),
8663 PROMPT_NONE
, PR_FATAL
},
8665 /* Error allocating icount structure */
8666 { PR_1_ALLOCATE_ICOUNT
,
8667 N_("@A icount link information: %m\n"),
8668 PROMPT_NONE
, PR_FATAL
},
8670 /* Error allocating dbcount */
8671 { PR_1_ALLOCATE_DBCOUNT
,
8672 N_("@A @d @b array: %m\n"),
8673 PROMPT_NONE
, PR_FATAL
},
8675 /* Error while scanning inodes */
8677 N_("Error while scanning @is (%i): %m\n"),
8678 PROMPT_NONE
, PR_FATAL
},
8680 /* Error while iterating over blocks */
8681 { PR_1_BLOCK_ITERATE
,
8682 N_("Error while iterating over @bs in @i %i: %m\n"),
8683 PROMPT_NONE
, PR_FATAL
},
8685 /* Error while storing inode count information */
8686 { PR_1_ICOUNT_STORE
,
8687 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8688 PROMPT_NONE
, PR_FATAL
},
8690 /* Error while storing directory block information */
8692 N_("Error storing @d @b information "
8693 "(@i=%i, @b=%b, num=%N): %m\n"),
8694 PROMPT_NONE
, PR_FATAL
},
8696 /* Error while reading inode (for clearing) */
8698 N_("Error reading @i %i: %m\n"),
8699 PROMPT_NONE
, PR_FATAL
},
8701 /* Suppress messages prompt */
8702 { PR_1_SUPPRESS_MESSAGES
, "", PROMPT_SUPPRESS
, PR_NO_OK
},
8704 /* Imagic flag set on an inode when filesystem doesn't support it */
8706 N_("@i %i has imagic flag set. "),
8709 /* Immutable flag set on a device or socket inode */
8710 { PR_1_SET_IMMUTABLE
,
8711 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8712 "or append-only flag set. "),
8713 PROMPT_CLEAR
, PR_PREEN_OK
| PR_PREEN_NO
| PR_NO_OK
},
8715 /* Compression flag set on an inode when filesystem doesn't support it */
8717 N_("@i %i has @cion flag set on @f without @cion support. "),
8720 /* Non-zero size for device, fifo or socket inode */
8721 { PR_1_SET_NONZSIZE
,
8722 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8723 PROMPT_FIX
, PR_PREEN_OK
},
8725 /* Filesystem revision is 0, but feature flags are set */
8726 { PR_1_FS_REV_LEVEL
,
8727 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8728 PROMPT_FIX
, PR_PREEN_OK
| PR_NO_OK
},
8730 /* Journal inode is not in use, but contains data */
8731 { PR_1_JOURNAL_INODE_NOT_CLEAR
,
8732 N_("@j @i is not in use, but contains data. "),
8733 PROMPT_CLEAR
, PR_PREEN_OK
},
8735 /* Journal has bad mode */
8736 { PR_1_JOURNAL_BAD_MODE
,
8737 N_("@j is not regular file. "),
8738 PROMPT_FIX
, PR_PREEN_OK
},
8740 /* Deal with inodes that were part of orphan linked list */
8742 N_("@i %i was part of the @o @i list. "),
8743 PROMPT_FIX
, PR_LATCH_LOW_DTIME
, 0 },
8745 /* Deal with inodes that were part of corrupted orphan linked
8746 list (latch question) */
8747 { PR_1_ORPHAN_LIST_REFUGEES
,
8748 N_("@is that were part of a corrupted orphan linked list found. "),
8751 /* Error allocating refcount structure */
8752 { PR_1_ALLOCATE_REFCOUNT
,
8753 N_("@A refcount structure (%N): %m\n"),
8754 PROMPT_NONE
, PR_FATAL
},
8756 /* Error reading extended attribute block */
8757 { PR_1_READ_EA_BLOCK
,
8758 N_("Error reading @a @b %b for @i %i. "),
8761 /* Invalid extended attribute block */
8762 { PR_1_BAD_EA_BLOCK
,
8763 N_("@i %i has a bad @a @b %b. "),
8766 /* Error reading Extended Attribute block while fixing refcount */
8767 { PR_1_EXTATTR_READ_ABORT
,
8768 N_("Error reading @a @b %b (%m). "),
8771 /* Extended attribute reference count incorrect */
8772 { PR_1_EXTATTR_REFCOUNT
,
8773 N_("@a @b %b has reference count %B, @s %N. "),
8776 /* Error writing Extended Attribute block while fixing refcount */
8777 { PR_1_EXTATTR_WRITE
,
8778 N_("Error writing @a @b %b (%m). "),
8781 /* Multiple EA blocks not supported */
8782 { PR_1_EA_MULTI_BLOCK
,
8783 N_("@a @b %b has h_@bs > 1. "),
8786 /* Error allocating EA region allocation structure */
8787 { PR_1_EA_ALLOC_REGION
,
8788 N_("@A @a @b %b. "),
8791 /* Error EA allocation collision */
8792 { PR_1_EA_ALLOC_COLLISION
,
8793 N_("@a @b %b is corrupt (allocation collision). "),
8796 /* Bad extended attribute name */
8798 N_("@a @b %b is corrupt (@n name). "),
8801 /* Bad extended attribute value */
8802 { PR_1_EA_BAD_VALUE
,
8803 N_("@a @b %b is corrupt (@n value). "),
8806 /* Inode too big (latch question) */
8807 { PR_1_INODE_TOOBIG
,
8808 N_("@i %i is too big. "), PROMPT_TRUNCATE
, 0 },
8810 /* Directory too big */
8812 N_("@b #%B (%b) causes @d to be too big. "),
8813 PROMPT_CLEAR
, PR_LATCH_TOOBIG
},
8815 /* Regular file too big */
8817 N_("@b #%B (%b) causes file to be too big. "),
8818 PROMPT_CLEAR
, PR_LATCH_TOOBIG
},
8820 /* Symlink too big */
8821 { PR_1_TOOBIG_SYMLINK
,
8822 N_("@b #%B (%b) causes symlink to be too big. "),
8823 PROMPT_CLEAR
, PR_LATCH_TOOBIG
},
8825 /* INDEX_FL flag set on a non-HTREE filesystem */
8827 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8828 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
8830 /* INDEX_FL flag set on a non-directory */
8832 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8833 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
8835 /* Invalid root node in HTREE directory */
8836 { PR_1_HTREE_BADROOT
,
8837 N_("@h %i has an @n root node.\n"),
8838 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
8840 /* Unsupported hash version in HTREE directory */
8842 N_("@h %i has an unsupported hash version (%N)\n"),
8843 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
8845 /* Incompatible flag in HTREE root node */
8846 { PR_1_HTREE_INCOMPAT
,
8847 N_("@h %i uses an incompatible htree root node flag.\n"),
8848 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
8850 /* HTREE too deep */
8852 N_("@h %i has a tree depth (%N) which is too big\n"),
8853 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
8855 /* Bad block has indirect block that conflicts with filesystem block */
8857 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8859 PROMPT_CLEAR
, PR_LATCH_BBLOCK
},
8861 /* Resize inode failed */
8862 { PR_1_RESIZE_INODE_CREATE
,
8863 N_("Resize @i (re)creation failed: %m."),
8866 /* invalid inode->i_extra_isize */
8868 N_("@i %i has a extra size (%IS) which is @n\n"),
8869 PROMPT_FIX
, PR_PREEN_OK
},
8871 /* invalid ea entry->e_name_len */
8872 { PR_1_ATTR_NAME_LEN
,
8873 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8874 PROMPT_CLEAR
, PR_PREEN_OK
},
8876 /* invalid ea entry->e_value_size */
8877 { PR_1_ATTR_VALUE_SIZE
,
8878 N_("@a in @i %i has a value size (%N) which is @n\n"),
8879 PROMPT_CLEAR
, PR_PREEN_OK
},
8881 /* invalid ea entry->e_value_offs */
8882 { PR_1_ATTR_VALUE_OFFSET
,
8883 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8884 PROMPT_CLEAR
, PR_PREEN_OK
},
8886 /* invalid ea entry->e_value_block */
8887 { PR_1_ATTR_VALUE_BLOCK
,
8888 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8889 PROMPT_CLEAR
, PR_PREEN_OK
},
8891 /* invalid ea entry->e_hash */
8893 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8894 PROMPT_CLEAR
, PR_PREEN_OK
},
8896 /* Pass 1b errors */
8898 /* Pass 1B: Rescan for duplicate/bad blocks */
8899 { PR_1B_PASS_HEADER
,
8900 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8901 "Pass 1B: Rescanning for @m @bs\n"),
8904 /* Duplicate/bad block(s) header */
8905 { PR_1B_DUP_BLOCK_HEADER
,
8906 N_("@m @b(s) in @i %i:"),
8909 /* Duplicate/bad block(s) in inode */
8912 PROMPT_NONE
, PR_LATCH_DBLOCK
| PR_PREEN_NOHDR
},
8914 /* Duplicate/bad block(s) end */
8915 { PR_1B_DUP_BLOCK_END
,
8917 PROMPT_NONE
, PR_PREEN_NOHDR
},
8919 /* Error while scanning inodes */
8920 { PR_1B_ISCAN_ERROR
,
8921 N_("Error while scanning inodes (%i): %m\n"),
8922 PROMPT_NONE
, PR_FATAL
},
8924 /* Error allocating inode bitmap */
8925 { PR_1B_ALLOCATE_IBITMAP_ERROR
,
8926 N_("@A @i @B (@i_dup_map): %m\n"),
8927 PROMPT_NONE
, PR_FATAL
},
8929 /* Error while iterating over blocks */
8930 { PR_1B_BLOCK_ITERATE
,
8931 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8934 /* Error adjusting EA refcount */
8935 { PR_1B_ADJ_EA_REFCOUNT
,
8936 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8940 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8941 { PR_1C_PASS_HEADER
,
8942 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8946 /* Pass 1D: Reconciling multiply-claimed blocks */
8947 { PR_1D_PASS_HEADER
,
8948 N_("Pass 1D: Reconciling @m @bs\n"),
8951 /* File has duplicate blocks */
8953 N_("File %Q (@i #%i, mod time %IM)\n"
8954 " has %B @m @b(s), shared with %N file(s):\n"),
8957 /* List of files sharing duplicate blocks */
8958 { PR_1D_DUP_FILE_LIST
,
8959 N_("\t%Q (@i #%i, mod time %IM)\n"),
8962 /* File sharing blocks with filesystem metadata */
8963 { PR_1D_SHARE_METADATA
,
8964 N_("\t<@f metadata>\n"),
8967 /* Report of how many duplicate/bad inodes */
8968 { PR_1D_NUM_DUP_INODES
,
8969 N_("(There are %N @is containing @m @bs.)\n\n"),
8972 /* Duplicated blocks already reassigned or cloned. */
8973 { PR_1D_DUP_BLOCKS_DEALT
,
8974 N_("@m @bs already reassigned or cloned.\n\n"),
8977 /* Clone duplicate/bad blocks? */
8978 { PR_1D_CLONE_QUESTION
,
8979 "", PROMPT_CLONE
, PR_NO_OK
},
8982 { PR_1D_DELETE_QUESTION
,
8983 "", PROMPT_DELETE
, 0 },
8985 /* Couldn't clone file (error) */
8986 { PR_1D_CLONE_ERROR
,
8987 N_("Couldn't clone file: %m\n"), PROMPT_NONE
, 0 },
8991 /* Pass 2: Checking directory structure */
8993 N_("Pass 2: Checking @d structure\n"),
8996 /* Bad inode number for '.' */
8997 { PR_2_BAD_INODE_DOT
,
8998 N_("@n @i number for '.' in @d @i %i.\n"),
9001 /* Directory entry has bad inode number */
9003 N_("@E has @n @i #: %Di.\n"),
9006 /* Directory entry has deleted or unused inode */
9007 { PR_2_UNUSED_INODE
,
9008 N_("@E has @D/unused @i %Di. "),
9009 PROMPT_CLEAR
, PR_PREEN_OK
},
9011 /* Directry entry is link to '.' */
9013 N_("@E @L to '.' "),
9016 /* Directory entry points to inode now located in a bad block */
9018 N_("@E points to @i (%Di) located in a bad @b.\n"),
9021 /* Directory entry contains a link to a directory */
9023 N_("@E @L to @d %P (%Di).\n"),
9026 /* Directory entry contains a link to the root directry */
9028 N_("@E @L to the @r.\n"),
9031 /* Directory entry has illegal characters in its name */
9033 N_("@E has illegal characters in its name.\n"),
9036 /* Missing '.' in directory inode */
9038 N_("Missing '.' in @d @i %i.\n"),
9041 /* Missing '..' in directory inode */
9042 { PR_2_MISSING_DOT_DOT
,
9043 N_("Missing '..' in @d @i %i.\n"),
9046 /* First entry in directory inode doesn't contain '.' */
9048 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9051 /* Second entry in directory inode doesn't contain '..' */
9052 { PR_2_2ND_NOT_DOT_DOT
,
9053 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9056 /* i_faddr should be zero */
9058 N_("i_faddr @F %IF, @s zero.\n"),
9061 /* i_file_acl should be zero */
9062 { PR_2_FILE_ACL_ZERO
,
9063 N_("i_file_acl @F %If, @s zero.\n"),
9066 /* i_dir_acl should be zero */
9067 { PR_2_DIR_ACL_ZERO
,
9068 N_("i_dir_acl @F %Id, @s zero.\n"),
9071 /* i_frag should be zero */
9073 N_("i_frag @F %N, @s zero.\n"),
9076 /* i_fsize should be zero */
9078 N_("i_fsize @F %N, @s zero.\n"),
9081 /* inode has bad mode */
9083 N_("@i %i (%Q) has @n mode (%Im).\n"),
9086 /* directory corrupted */
9087 { PR_2_DIR_CORRUPTED
,
9088 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9089 PROMPT_SALVAGE
, 0 },
9091 /* filename too long */
9092 { PR_2_FILENAME_LONG
,
9093 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9094 PROMPT_TRUNCATE
, 0 },
9096 /* Directory inode has a missing block (hole) */
9097 { PR_2_DIRECTORY_HOLE
,
9098 N_("@d @i %i has an unallocated @b #%B. "),
9099 PROMPT_ALLOCATE
, 0 },
9101 /* '.' is not NULL terminated */
9102 { PR_2_DOT_NULL_TERM
,
9103 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9106 /* '..' is not NULL terminated */
9107 { PR_2_DOT_DOT_NULL_TERM
,
9108 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9111 /* Illegal character device inode */
9112 { PR_2_BAD_CHAR_DEV
,
9113 N_("@i %i (%Q) is an @I character @v.\n"),
9116 /* Illegal block device inode */
9117 { PR_2_BAD_BLOCK_DEV
,
9118 N_("@i %i (%Q) is an @I @b @v.\n"),
9121 /* Duplicate '.' entry */
9123 N_("@E is duplicate '.' @e.\n"),
9126 /* Duplicate '..' entry */
9128 N_("@E is duplicate '..' @e.\n"),
9131 /* Internal error: couldn't find dir_info */
9133 N_("Internal error: cannot find dir_info for %i.\n"),
9134 PROMPT_NONE
, PR_FATAL
},
9136 /* Final rec_len is wrong */
9137 { PR_2_FINAL_RECLEN
,
9138 N_("@E has rec_len of %Dr, @s %N.\n"),
9141 /* Error allocating icount structure */
9142 { PR_2_ALLOCATE_ICOUNT
,
9143 N_("@A icount structure: %m\n"),
9144 PROMPT_NONE
, PR_FATAL
},
9146 /* Error iterating over directory blocks */
9147 { PR_2_DBLIST_ITERATE
,
9148 N_("Error iterating over @d @bs: %m\n"),
9149 PROMPT_NONE
, PR_FATAL
},
9151 /* Error reading directory block */
9152 { PR_2_READ_DIRBLOCK
,
9153 N_("Error reading @d @b %b (@i %i): %m\n"),
9154 PROMPT_CONTINUE
, 0 },
9156 /* Error writing directory block */
9157 { PR_2_WRITE_DIRBLOCK
,
9158 N_("Error writing @d @b %b (@i %i): %m\n"),
9159 PROMPT_CONTINUE
, 0 },
9161 /* Error allocating new directory block */
9162 { PR_2_ALLOC_DIRBOCK
,
9163 N_("@A new @d @b for @i %i (%s): %m\n"),
9166 /* Error deallocating inode */
9167 { PR_2_DEALLOC_INODE
,
9168 N_("Error deallocating @i %i: %m\n"),
9169 PROMPT_NONE
, PR_FATAL
},
9171 /* Directory entry for '.' is big. Split? */
9173 N_("@d @e for '.' is big. "),
9174 PROMPT_SPLIT
, PR_NO_OK
},
9176 /* Illegal FIFO inode */
9178 N_("@i %i (%Q) is an @I FIFO.\n"),
9181 /* Illegal socket inode */
9183 N_("@i %i (%Q) is an @I socket.\n"),
9186 /* Directory filetype not set */
9187 { PR_2_SET_FILETYPE
,
9188 N_("Setting filetype for @E to %N.\n"),
9189 PROMPT_NONE
, PR_PREEN_OK
| PR_NO_OK
| PR_NO_NOMSG
},
9191 /* Directory filetype incorrect */
9192 { PR_2_BAD_FILETYPE
,
9193 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9196 /* Directory filetype set on filesystem */
9197 { PR_2_CLEAR_FILETYPE
,
9198 N_("@E has filetype set.\n"),
9199 PROMPT_CLEAR
, PR_PREEN_OK
},
9201 /* Directory filename is null */
9203 N_("@E has a @z name.\n"),
9206 /* Invalid symlink */
9207 { PR_2_INVALID_SYMLINK
,
9208 N_("Symlink %Q (@i #%i) is @n.\n"),
9211 /* i_file_acl (extended attribute block) is bad */
9212 { PR_2_FILE_ACL_BAD
,
9213 N_("@a @b @F @n (%If).\n"),
9216 /* Filesystem contains large files, but has no such flag in sb */
9217 { PR_2_FEATURE_LARGE_FILES
,
9218 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9221 /* Node in HTREE directory not referenced */
9222 { PR_2_HTREE_NOTREF
,
9223 N_("@p @h %d: node (%B) not referenced\n"),
9226 /* Node in HTREE directory referenced twice */
9227 { PR_2_HTREE_DUPREF
,
9228 N_("@p @h %d: node (%B) referenced twice\n"),
9231 /* Node in HTREE directory has bad min hash */
9232 { PR_2_HTREE_MIN_HASH
,
9233 N_("@p @h %d: node (%B) has bad min hash\n"),
9236 /* Node in HTREE directory has bad max hash */
9237 { PR_2_HTREE_MAX_HASH
,
9238 N_("@p @h %d: node (%B) has bad max hash\n"),
9241 /* Clear invalid HTREE directory */
9243 N_("@n @h %d (%q). "), PROMPT_CLEAR
, 0 },
9245 /* Bad block in htree interior node */
9246 { PR_2_HTREE_BADBLK
,
9247 N_("@p @h %d (%q): bad @b number %b.\n"),
9248 PROMPT_CLEAR_HTREE
, 0 },
9250 /* Error adjusting EA refcount */
9251 { PR_2_ADJ_EA_REFCOUNT
,
9252 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9253 PROMPT_NONE
, PR_FATAL
},
9255 /* Invalid HTREE root node */
9256 { PR_2_HTREE_BAD_ROOT
,
9257 N_("@p @h %d: root node is @n\n"),
9258 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
9260 /* Invalid HTREE limit */
9261 { PR_2_HTREE_BAD_LIMIT
,
9262 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9263 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
9265 /* Invalid HTREE count */
9266 { PR_2_HTREE_BAD_COUNT
,
9267 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9268 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
9270 /* HTREE interior node has out-of-order hashes in table */
9271 { PR_2_HTREE_HASH_ORDER
,
9272 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9273 PROMPT_CLEAR_HTREE
, PR_PREEN_OK
},
9275 /* Node in HTREE directory has invalid depth */
9276 { PR_2_HTREE_BAD_DEPTH
,
9277 N_("@p @h %d: node (%B) has @n depth\n"),
9280 /* Duplicate directory entry found */
9281 { PR_2_DUPLICATE_DIRENT
,
9282 N_("Duplicate @E found. "),
9285 /* Non-unique filename found */
9286 { PR_2_NON_UNIQUE_FILE
, /* xgettext: no-c-format */
9287 N_("@E has a non-unique filename.\nRename to %s"),
9290 /* Duplicate directory entry found */
9291 { PR_2_REPORT_DUP_DIRENT
,
9292 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9297 /* Pass 3: Checking directory connectivity */
9299 N_("Pass 3: Checking @d connectivity\n"),
9302 /* Root inode not allocated */
9303 { PR_3_NO_ROOT_INODE
,
9304 N_("@r not allocated. "),
9305 PROMPT_ALLOCATE
, 0 },
9307 /* No room in lost+found */
9308 { PR_3_EXPAND_LF_DIR
,
9309 N_("No room in @l @d. "),
9312 /* Unconnected directory inode */
9313 { PR_3_UNCONNECTED_DIR
,
9314 N_("Unconnected @d @i %i (%p)\n"),
9315 PROMPT_CONNECT
, 0 },
9317 /* /lost+found not found */
9319 N_("/@l not found. "),
9320 PROMPT_CREATE
, PR_PREEN_OK
},
9322 /* .. entry is incorrect */
9324 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9327 /* Bad or non-existent /lost+found. Cannot reconnect */
9329 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9332 /* Could not expand /lost+found */
9333 { PR_3_CANT_EXPAND_LPF
,
9334 N_("Could not expand /@l: %m\n"),
9337 /* Could not reconnect inode */
9338 { PR_3_CANT_RECONNECT
,
9339 N_("Could not reconnect %i: %m\n"),
9342 /* Error while trying to find /lost+found */
9343 { PR_3_ERR_FIND_LPF
,
9344 N_("Error while trying to find /@l: %m\n"),
9347 /* Error in ext2fs_new_block while creating /lost+found */
9348 { PR_3_ERR_LPF_NEW_BLOCK
,
9349 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9352 /* Error in ext2fs_new_inode while creating /lost+found */
9353 { PR_3_ERR_LPF_NEW_INODE
,
9354 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9357 /* Error in ext2fs_new_dir_block while creating /lost+found */
9358 { PR_3_ERR_LPF_NEW_DIR_BLOCK
,
9359 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9362 /* Error while writing directory block for /lost+found */
9363 { PR_3_ERR_LPF_WRITE_BLOCK
,
9364 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9367 /* Error while adjusting inode count */
9368 { PR_3_ADJUST_INODE
,
9369 N_("Error while adjusting @i count on @i %i\n"),
9372 /* Couldn't fix parent directory -- error */
9373 { PR_3_FIX_PARENT_ERR
,
9374 N_("Couldn't fix parent of @i %i: %m\n\n"),
9377 /* Couldn't fix parent directory -- couldn't find it */
9378 { PR_3_FIX_PARENT_NOFIND
,
9379 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9382 /* Error allocating inode bitmap */
9383 { PR_3_ALLOCATE_IBITMAP_ERROR
,
9384 N_("@A @i @B (%N): %m\n"),
9385 PROMPT_NONE
, PR_FATAL
},
9387 /* Error creating root directory */
9388 { PR_3_CREATE_ROOT_ERROR
,
9389 N_("Error creating root @d (%s): %m\n"),
9390 PROMPT_NONE
, PR_FATAL
},
9392 /* Error creating lost and found directory */
9393 { PR_3_CREATE_LPF_ERROR
,
9394 N_("Error creating /@l @d (%s): %m\n"),
9395 PROMPT_NONE
, PR_FATAL
},
9397 /* Root inode is not directory; aborting */
9398 { PR_3_ROOT_NOT_DIR_ABORT
,
9399 N_("@r is not a @d; aborting.\n"),
9400 PROMPT_NONE
, PR_FATAL
},
9402 /* Cannot proceed without a root inode. */
9403 { PR_3_NO_ROOT_INODE_ABORT
,
9404 N_("can't proceed without a @r.\n"),
9405 PROMPT_NONE
, PR_FATAL
},
9407 /* Internal error: couldn't find dir_info */
9409 N_("Internal error: cannot find dir_info for %i.\n"),
9410 PROMPT_NONE
, PR_FATAL
},
9412 /* Lost+found not a directory */
9414 N_("/@l is not a @d (ino=%i)\n"),
9417 /* Pass 3A Directory Optimization */
9419 /* Pass 3A: Optimizing directories */
9420 { PR_3A_PASS_HEADER
,
9421 N_("Pass 3A: Optimizing directories\n"),
9422 PROMPT_NONE
, PR_PREEN_NOMSG
},
9424 /* Error iterating over directories */
9425 { PR_3A_OPTIMIZE_ITER
,
9426 N_("Failed to create dirs_to_hash iterator: %m"),
9429 /* Error rehash directory */
9430 { PR_3A_OPTIMIZE_DIR_ERR
,
9431 N_("Failed to optimize directory %q (%d): %m"),
9434 /* Rehashing dir header */
9435 { PR_3A_OPTIMIZE_DIR_HEADER
,
9436 N_("Optimizing directories: "),
9437 PROMPT_NONE
, PR_MSG_ONLY
},
9439 /* Rehashing directory %d */
9440 { PR_3A_OPTIMIZE_DIR
,
9442 PROMPT_NONE
, PR_LATCH_OPTIMIZE_DIR
| PR_PREEN_NOHDR
},
9444 /* Rehashing dir end */
9445 { PR_3A_OPTIMIZE_DIR_END
,
9447 PROMPT_NONE
, PR_PREEN_NOHDR
},
9451 /* Pass 4: Checking reference counts */
9453 N_("Pass 4: Checking reference counts\n"),
9456 /* Unattached zero-length inode */
9457 { PR_4_ZERO_LEN_INODE
,
9458 N_("@u @z @i %i. "),
9459 PROMPT_CLEAR
, PR_PREEN_OK
|PR_NO_OK
},
9461 /* Unattached inode */
9462 { PR_4_UNATTACHED_INODE
,
9464 PROMPT_CONNECT
, 0 },
9466 /* Inode ref count wrong */
9467 { PR_4_BAD_REF_COUNT
,
9468 N_("@i %i ref count is %Il, @s %N. "),
9469 PROMPT_FIX
, PR_PREEN_OK
},
9471 { PR_4_INCONSISTENT_COUNT
,
9472 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9473 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9474 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9475 "They @s the same!\n"),
9480 /* Pass 5: Checking group summary information */
9482 N_("Pass 5: Checking @g summary information\n"),
9485 /* Padding at end of inode bitmap is not set. */
9486 { PR_5_INODE_BMAP_PADDING
,
9487 N_("Padding at end of @i @B is not set. "),
9488 PROMPT_FIX
, PR_PREEN_OK
},
9490 /* Padding at end of block bitmap is not set. */
9491 { PR_5_BLOCK_BMAP_PADDING
,
9492 N_("Padding at end of @b @B is not set. "),
9493 PROMPT_FIX
, PR_PREEN_OK
},
9495 /* Block bitmap differences header */
9496 { PR_5_BLOCK_BITMAP_HEADER
,
9497 N_("@b @B differences: "),
9498 PROMPT_NONE
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9500 /* Block not used, but marked in bitmap */
9501 { PR_5_BLOCK_UNUSED
,
9503 PROMPT_NONE
, PR_LATCH_BBITMAP
| PR_PREEN_OK
| PR_PREEN_NOMSG
},
9505 /* Block used, but not marked used in bitmap */
9508 PROMPT_NONE
, PR_LATCH_BBITMAP
| PR_PREEN_OK
| PR_PREEN_NOMSG
},
9510 /* Block bitmap differences end */
9511 { PR_5_BLOCK_BITMAP_END
,
9513 PROMPT_FIX
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9515 /* Inode bitmap differences header */
9516 { PR_5_INODE_BITMAP_HEADER
,
9517 N_("@i @B differences: "),
9518 PROMPT_NONE
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9520 /* Inode not used, but marked in bitmap */
9521 { PR_5_INODE_UNUSED
,
9523 PROMPT_NONE
, PR_LATCH_IBITMAP
| PR_PREEN_OK
| PR_PREEN_NOMSG
},
9525 /* Inode used, but not marked used in bitmap */
9528 PROMPT_NONE
, PR_LATCH_IBITMAP
| PR_PREEN_OK
| PR_PREEN_NOMSG
},
9530 /* Inode bitmap differences end */
9531 { PR_5_INODE_BITMAP_END
,
9533 PROMPT_FIX
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9535 /* Free inodes count for group wrong */
9536 { PR_5_FREE_INODE_COUNT_GROUP
,
9537 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9538 PROMPT_FIX
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9540 /* Directories count for group wrong */
9541 { PR_5_FREE_DIR_COUNT_GROUP
,
9542 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9543 PROMPT_FIX
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9545 /* Free inodes count wrong */
9546 { PR_5_FREE_INODE_COUNT
,
9547 N_("Free @is count wrong (%i, counted=%j).\n"),
9548 PROMPT_FIX
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9550 /* Free blocks count for group wrong */
9551 { PR_5_FREE_BLOCK_COUNT_GROUP
,
9552 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9553 PROMPT_FIX
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9555 /* Free blocks count wrong */
9556 { PR_5_FREE_BLOCK_COUNT
,
9557 N_("Free @bs count wrong (%b, counted=%c).\n"),
9558 PROMPT_FIX
, PR_PREEN_OK
| PR_PREEN_NOMSG
},
9560 /* Programming error: bitmap endpoints don't match */
9561 { PR_5_BMAP_ENDPOINTS
,
9562 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9563 "match calculated @B endpoints (%i, %j)\n"),
9564 PROMPT_NONE
, PR_FATAL
},
9566 /* Internal error: fudging end of bitmap */
9567 { PR_5_FUDGE_BITMAP_ERROR
,
9568 N_("Internal error: fudging end of bitmap (%N)\n"),
9569 PROMPT_NONE
, PR_FATAL
},
9571 /* Error copying in replacement inode bitmap */
9572 { PR_5_COPY_IBITMAP_ERROR
,
9573 N_("Error copying in replacement @i @B: %m\n"),
9574 PROMPT_NONE
, PR_FATAL
},
9576 /* Error copying in replacement block bitmap */
9577 { PR_5_COPY_BBITMAP_ERROR
,
9578 N_("Error copying in replacement @b @B: %m\n"),
9579 PROMPT_NONE
, PR_FATAL
},
9581 /* Block range not used, but marked in bitmap */
9582 { PR_5_BLOCK_RANGE_UNUSED
,
9584 PROMPT_NONE
, PR_LATCH_BBITMAP
| PR_PREEN_OK
| PR_PREEN_NOMSG
},
9586 /* Block range used, but not marked used in bitmap */
9587 { PR_5_BLOCK_RANGE_USED
,
9589 PROMPT_NONE
, PR_LATCH_BBITMAP
| PR_PREEN_OK
| PR_PREEN_NOMSG
},
9591 /* Inode range not used, but marked in bitmap */
9592 { PR_5_INODE_RANGE_UNUSED
,
9594 PROMPT_NONE
, PR_LATCH_IBITMAP
| PR_PREEN_OK
| PR_PREEN_NOMSG
},
9596 /* Inode range used, but not marked used in bitmap */
9597 { PR_5_INODE_RANGE_USED
,
9599 PROMPT_NONE
, PR_LATCH_IBITMAP
| PR_PREEN_OK
| PR_PREEN_NOMSG
},
9605 * This is the latch flags register. It allows several problems to be
9606 * "latched" together. This means that the user has to answer but one
9607 * question for the set of problems, and all of the associated
9608 * problems will be either fixed or not fixed.
9610 static struct latch_descr pr_latch_info
[] = {
9611 { PR_LATCH_BLOCK
, PR_1_INODE_BLOCK_LATCH
, 0 },
9612 { PR_LATCH_BBLOCK
, PR_1_INODE_BBLOCK_LATCH
, 0 },
9613 { PR_LATCH_IBITMAP
, PR_5_INODE_BITMAP_HEADER
, PR_5_INODE_BITMAP_END
},
9614 { PR_LATCH_BBITMAP
, PR_5_BLOCK_BITMAP_HEADER
, PR_5_BLOCK_BITMAP_END
},
9615 { PR_LATCH_RELOC
, PR_0_RELOCATE_HINT
, 0 },
9616 { PR_LATCH_DBLOCK
, PR_1B_DUP_BLOCK_HEADER
, PR_1B_DUP_BLOCK_END
},
9617 { PR_LATCH_LOW_DTIME
, PR_1_ORPHAN_LIST_REFUGEES
, 0 },
9618 { PR_LATCH_TOOBIG
, PR_1_INODE_TOOBIG
, 0 },
9619 { PR_LATCH_OPTIMIZE_DIR
, PR_3A_OPTIMIZE_DIR_HEADER
, PR_3A_OPTIMIZE_DIR_END
},
9623 static const struct e2fsck_problem
*find_problem(problem_t code
)
9627 for (i
=0; problem_table
[i
].e2p_code
; i
++) {
9628 if (problem_table
[i
].e2p_code
== code
)
9629 return &problem_table
[i
];
9634 static struct latch_descr
*find_latch(int code
)
9638 for (i
=0; pr_latch_info
[i
].latch_code
>= 0; i
++) {
9639 if (pr_latch_info
[i
].latch_code
== code
)
9640 return &pr_latch_info
[i
];
9645 int end_problem_latch(e2fsck_t ctx
, int mask
)
9647 struct latch_descr
*ldesc
;
9648 struct problem_context pctx
;
9651 ldesc
= find_latch(mask
);
9652 if (ldesc
->end_message
&& (ldesc
->flags
& PRL_LATCHED
)) {
9653 clear_problem_context(&pctx
);
9654 answer
= fix_problem(ctx
, ldesc
->end_message
, &pctx
);
9656 ldesc
->flags
&= ~(PRL_VARIABLE
);
9660 int set_latch_flags(int mask
, int setflags
, int clearflags
)
9662 struct latch_descr
*ldesc
;
9664 ldesc
= find_latch(mask
);
9667 ldesc
->flags
|= setflags
;
9668 ldesc
->flags
&= ~clearflags
;
9672 void clear_problem_context(struct problem_context
*ctx
)
9674 memset(ctx
, 0, sizeof(struct problem_context
));
9679 int fix_problem(e2fsck_t ctx
, problem_t code
, struct problem_context
*pctx
)
9681 ext2_filsys fs
= ctx
->fs
;
9682 const struct e2fsck_problem
*ptr
;
9683 struct latch_descr
*ldesc
= NULL
;
9684 const char *message
;
9685 int def_yn
, answer
, ans
;
9686 int print_answer
= 0;
9689 ptr
= find_problem(code
);
9691 printf(_("Unhandled error code (0x%x)!\n"), code
);
9695 if ((ptr
->flags
& PR_NO_DEFAULT
) ||
9696 ((ptr
->flags
& PR_PREEN_NO
) && (ctx
->options
& E2F_OPT_PREEN
)) ||
9697 (ctx
->options
& E2F_OPT_NO
))
9701 * Do special latch processing. This is where we ask the
9702 * latch question, if it exists
9704 if (ptr
->flags
& PR_LATCH_MASK
) {
9705 ldesc
= find_latch(ptr
->flags
& PR_LATCH_MASK
);
9706 if (ldesc
->question
&& !(ldesc
->flags
& PRL_LATCHED
)) {
9707 ans
= fix_problem(ctx
, ldesc
->question
, pctx
);
9709 ldesc
->flags
|= PRL_YES
;
9711 ldesc
->flags
|= PRL_NO
;
9712 ldesc
->flags
|= PRL_LATCHED
;
9714 if (ldesc
->flags
& PRL_SUPPRESS
)
9717 if ((ptr
->flags
& PR_PREEN_NOMSG
) &&
9718 (ctx
->options
& E2F_OPT_PREEN
))
9720 if ((ptr
->flags
& PR_NO_NOMSG
) &&
9721 (ctx
->options
& E2F_OPT_NO
))
9724 message
= ptr
->e2p_description
;
9725 if ((ctx
->options
& E2F_OPT_PREEN
) &&
9726 !(ptr
->flags
& PR_PREEN_NOHDR
)) {
9727 printf("%s: ", ctx
->device_name
?
9728 ctx
->device_name
: ctx
->filesystem_name
);
9731 print_e2fsck_message(ctx
, _(message
), pctx
, 1);
9733 if (!(ptr
->flags
& PR_PREEN_OK
) && (ptr
->prompt
!= PROMPT_NONE
))
9736 if (ptr
->flags
& PR_FATAL
)
9737 bb_error_msg_and_die(0);
9739 if (ptr
->prompt
== PROMPT_NONE
) {
9740 if (ptr
->flags
& PR_NOCOLLATE
)
9745 if (ctx
->options
& E2F_OPT_PREEN
) {
9747 if (!(ptr
->flags
& PR_PREEN_NOMSG
))
9749 } else if ((ptr
->flags
& PR_LATCH_MASK
) &&
9750 (ldesc
->flags
& (PRL_YES
| PRL_NO
))) {
9753 if (ldesc
->flags
& PRL_YES
)
9758 answer
= ask(ctx
, _(prompt
[(int) ptr
->prompt
]), def_yn
);
9759 if (!answer
&& !(ptr
->flags
& PR_NO_OK
))
9760 ext2fs_unmark_valid(fs
);
9763 printf("%s.\n", answer
?
9764 _(preen_msg
[(int) ptr
->prompt
]) : _("IGNORED"));
9767 if ((ptr
->prompt
== PROMPT_ABORT
) && answer
)
9768 bb_error_msg_and_die(0);
9770 if (ptr
->flags
& PR_AFTER_CODE
)
9771 answer
= fix_problem(ctx
, ptr
->second_code
, pctx
);
9777 * linux/fs/recovery.c
9779 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9783 * Maintain information about the progress of the recovery job, so that
9784 * the different passes can carry information between them.
9786 struct recovery_info
9788 tid_t start_transaction
;
9789 tid_t end_transaction
;
9796 enum passtype
{PASS_SCAN
, PASS_REVOKE
, PASS_REPLAY
};
9797 static int do_one_pass(journal_t
*journal
,
9798 struct recovery_info
*info
, enum passtype pass
);
9799 static int scan_revoke_records(journal_t
*, struct buffer_head
*,
9800 tid_t
, struct recovery_info
*);
9803 * Read a block from the journal
9806 static int jread(struct buffer_head
**bhp
, journal_t
*journal
,
9807 unsigned int offset
)
9810 unsigned long blocknr
;
9811 struct buffer_head
*bh
;
9815 err
= journal_bmap(journal
, offset
, &blocknr
);
9818 printf("JBD: bad block at offset %u\n", offset
);
9822 bh
= getblk(journal
->j_dev
, blocknr
, journal
->j_blocksize
);
9826 if (!buffer_uptodate(bh
)) {
9827 /* If this is a brand new buffer, start readahead.
9828 Otherwise, we assume we are already reading it. */
9829 if (!buffer_req(bh
))
9830 do_readahead(journal
, offset
);
9834 if (!buffer_uptodate(bh
)) {
9835 printf("JBD: Failed to read block at offset %u\n", offset
);
9846 * Count the number of in-use tags in a journal descriptor block.
9849 static int count_tags(struct buffer_head
*bh
, int size
)
9852 journal_block_tag_t
* tag
;
9855 tagp
= &bh
->b_data
[sizeof(journal_header_t
)];
9857 while ((tagp
- bh
->b_data
+ sizeof(journal_block_tag_t
)) <= size
) {
9858 tag
= (journal_block_tag_t
*) tagp
;
9861 tagp
+= sizeof(journal_block_tag_t
);
9862 if (!(tag
->t_flags
& htonl(JFS_FLAG_SAME_UUID
)))
9865 if (tag
->t_flags
& htonl(JFS_FLAG_LAST_TAG
))
9873 /* Make sure we wrap around the log correctly! */
9874 #define wrap(journal, var) \
9876 if (var >= (journal)->j_last) \
9877 var -= ((journal)->j_last - (journal)->j_first); \
9881 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9882 * @journal: the journal to recover
9884 * The primary function for recovering the log contents when mounting a
9887 * Recovery is done in three passes. In the first pass, we look for the
9888 * end of the log. In the second, we assemble the list of revoke
9889 * blocks. In the third and final pass, we replay any un-revoked blocks
9892 int journal_recover(journal_t
*journal
)
9895 journal_superblock_t
* sb
;
9897 struct recovery_info info
;
9899 memset(&info
, 0, sizeof(info
));
9900 sb
= journal
->j_superblock
;
9903 * The journal superblock's s_start field (the current log head)
9904 * is always zero if, and only if, the journal was cleanly
9909 journal
->j_transaction_sequence
= ntohl(sb
->s_sequence
) + 1;
9913 err
= do_one_pass(journal
, &info
, PASS_SCAN
);
9915 err
= do_one_pass(journal
, &info
, PASS_REVOKE
);
9917 err
= do_one_pass(journal
, &info
, PASS_REPLAY
);
9919 /* Restart the log at the next transaction ID, thus invalidating
9920 * any existing commit records in the log. */
9921 journal
->j_transaction_sequence
= ++info
.end_transaction
;
9923 journal_clear_revoke(journal
);
9924 sync_blockdev(journal
->j_fs_dev
);
9928 static int do_one_pass(journal_t
*journal
,
9929 struct recovery_info
*info
, enum passtype pass
)
9931 unsigned int first_commit_ID
, next_commit_ID
;
9932 unsigned long next_log_block
;
9933 int err
, success
= 0;
9934 journal_superblock_t
* sb
;
9935 journal_header_t
* tmp
;
9936 struct buffer_head
* bh
;
9937 unsigned int sequence
;
9940 /* Precompute the maximum metadata descriptors in a descriptor block */
9941 int MAX_BLOCKS_PER_DESC
;
9942 MAX_BLOCKS_PER_DESC
= ((journal
->j_blocksize
-sizeof(journal_header_t
))
9943 / sizeof(journal_block_tag_t
));
9946 * First thing is to establish what we expect to find in the log
9947 * (in terms of transaction IDs), and where (in terms of log
9948 * block offsets): query the superblock.
9951 sb
= journal
->j_superblock
;
9952 next_commit_ID
= ntohl(sb
->s_sequence
);
9953 next_log_block
= ntohl(sb
->s_start
);
9955 first_commit_ID
= next_commit_ID
;
9956 if (pass
== PASS_SCAN
)
9957 info
->start_transaction
= first_commit_ID
;
9960 * Now we walk through the log, transaction by transaction,
9961 * making sure that each transaction has a commit block in the
9962 * expected place. Each complete transaction gets replayed back
9963 * into the main filesystem.
9969 journal_block_tag_t
* tag
;
9970 struct buffer_head
* obh
;
9971 struct buffer_head
* nbh
;
9973 /* If we already know where to stop the log traversal,
9974 * check right now that we haven't gone past the end of
9977 if (pass
!= PASS_SCAN
)
9978 if (tid_geq(next_commit_ID
, info
->end_transaction
))
9981 /* Skip over each chunk of the transaction looking
9982 * either the next descriptor block or the final commit
9985 err
= jread(&bh
, journal
, next_log_block
);
9990 wrap(journal
, next_log_block
);
9992 /* What kind of buffer is it?
9994 * If it is a descriptor block, check that it has the
9995 * expected sequence number. Otherwise, we're all done
9998 tmp
= (journal_header_t
*)bh
->b_data
;
10000 if (tmp
->h_magic
!= htonl(JFS_MAGIC_NUMBER
)) {
10005 blocktype
= ntohl(tmp
->h_blocktype
);
10006 sequence
= ntohl(tmp
->h_sequence
);
10008 if (sequence
!= next_commit_ID
) {
10013 /* OK, we have a valid descriptor block which matches
10014 * all of the sequence number checks. What are we going
10015 * to do with it? That depends on the pass... */
10017 switch (blocktype
) {
10018 case JFS_DESCRIPTOR_BLOCK
:
10019 /* If it is a valid descriptor block, replay it
10020 * in pass REPLAY; otherwise, just skip over the
10021 * blocks it describes. */
10022 if (pass
!= PASS_REPLAY
) {
10024 count_tags(bh
, journal
->j_blocksize
);
10025 wrap(journal
, next_log_block
);
10030 /* A descriptor block: we can now write all of
10031 * the data blocks. Yay, useful work is finally
10032 * getting done here! */
10034 tagp
= &bh
->b_data
[sizeof(journal_header_t
)];
10035 while ((tagp
- bh
->b_data
+sizeof(journal_block_tag_t
))
10036 <= journal
->j_blocksize
) {
10037 unsigned long io_block
;
10039 tag
= (journal_block_tag_t
*) tagp
;
10040 flags
= ntohl(tag
->t_flags
);
10042 io_block
= next_log_block
++;
10043 wrap(journal
, next_log_block
);
10044 err
= jread(&obh
, journal
, io_block
);
10046 /* Recover what we can, but
10047 * report failure at the end. */
10049 printf("JBD: IO error %d recovering "
10050 "block %ld in log\n",
10053 unsigned long blocknr
;
10055 blocknr
= ntohl(tag
->t_blocknr
);
10057 /* If the block has been
10058 * revoked, then we're all done
10060 if (journal_test_revoke
10064 ++info
->nr_revoke_hits
;
10068 /* Find a buffer for the new
10069 * data being restored */
10070 nbh
= getblk(journal
->j_fs_dev
,
10072 journal
->j_blocksize
);
10074 printf("JBD: Out of memory "
10075 "during recovery.\n");
10083 memcpy(nbh
->b_data
, obh
->b_data
,
10084 journal
->j_blocksize
);
10085 if (flags
& JFS_FLAG_ESCAPE
) {
10086 *((unsigned int *)bh
->b_data
) =
10087 htonl(JFS_MAGIC_NUMBER
);
10090 mark_buffer_uptodate(nbh
, 1);
10091 mark_buffer_dirty(nbh
);
10092 ++info
->nr_replays
;
10093 /* ll_rw_block(WRITE, 1, &nbh); */
10094 unlock_buffer(nbh
);
10100 tagp
+= sizeof(journal_block_tag_t
);
10101 if (!(flags
& JFS_FLAG_SAME_UUID
))
10104 if (flags
& JFS_FLAG_LAST_TAG
)
10111 case JFS_COMMIT_BLOCK
:
10112 /* Found an expected commit block: not much to
10113 * do other than move on to the next sequence
10119 case JFS_REVOKE_BLOCK
:
10120 /* If we aren't in the REVOKE pass, then we can
10121 * just skip over this block. */
10122 if (pass
!= PASS_REVOKE
) {
10127 err
= scan_revoke_records(journal
, bh
,
10128 next_commit_ID
, info
);
10141 * We broke out of the log scan loop: either we came to the
10142 * known end of the log or we found an unexpected block in the
10143 * log. If the latter happened, then we know that the "current"
10144 * transaction marks the end of the valid log.
10147 if (pass
== PASS_SCAN
)
10148 info
->end_transaction
= next_commit_ID
;
10150 /* It's really bad news if different passes end up at
10151 * different places (but possible due to IO errors). */
10152 if (info
->end_transaction
!= next_commit_ID
) {
10153 printf("JBD: recovery pass %d ended at "
10154 "transaction %u, expected %u\n",
10155 pass
, next_commit_ID
, info
->end_transaction
);
10168 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10170 static int scan_revoke_records(journal_t
*journal
, struct buffer_head
*bh
,
10171 tid_t sequence
, struct recovery_info
*info
)
10173 journal_revoke_header_t
*header
;
10176 header
= (journal_revoke_header_t
*) bh
->b_data
;
10177 offset
= sizeof(journal_revoke_header_t
);
10178 max
= ntohl(header
->r_count
);
10180 while (offset
< max
) {
10181 unsigned long blocknr
;
10184 blocknr
= ntohl(* ((unsigned int *) (bh
->b_data
+offset
)));
10186 err
= journal_set_revoke(journal
, blocknr
, sequence
);
10189 ++info
->nr_revokes
;
10196 * rehash.c --- rebuild hash tree directories
10198 * This algorithm is designed for simplicity of implementation and to
10199 * pack the directory as much as possible. It however requires twice
10200 * as much memory as the size of the directory. The maximum size
10201 * directory supported using a 4k blocksize is roughly a gigabyte, and
10202 * so there may very well be problems with machines that don't have
10203 * virtual memory, and obscenely large directories.
10205 * An alternate algorithm which is much more disk intensive could be
10206 * written, and probably will need to be written in the future. The
10207 * design goals of such an algorithm are: (a) use (roughly) constant
10208 * amounts of memory, no matter how large the directory, (b) the
10209 * directory must be safe at all times, even if e2fsck is interrupted
10210 * in the middle, (c) we must use minimal amounts of extra disk
10211 * blocks. This pretty much requires an incremental approach, where
10212 * we are reading from one part of the directory, and inserting into
10213 * the front half. So the algorithm will have to keep track of a
10214 * moving block boundary between the new tree and the old tree, and
10215 * files will need to be moved from the old directory and inserted
10216 * into the new tree. If the new directory requires space which isn't
10217 * yet available, blocks from the beginning part of the old directory
10218 * may need to be moved to the end of the directory to make room for
10221 * --------------------------------------------------------
10222 * | new tree | | old tree |
10223 * --------------------------------------------------------
10225 * tail new head old
10227 * This is going to be a pain in the tuckus to implement, and will
10228 * require a lot more disk accesses. So I'm going to skip it for now;
10229 * it's only really going to be an issue for really, really big
10230 * filesystems (when we reach the level of tens of millions of files
10231 * in a single directory). It will probably be easier to simply
10232 * require that e2fsck use VM first.
10235 struct fill_dir_struct
{
10237 struct ext2_inode
*inode
;
10240 struct hash_entry
*harray
;
10241 int max_array
, num_array
;
10247 struct hash_entry
{
10248 ext2_dirhash_t hash
;
10249 ext2_dirhash_t minor_hash
;
10250 struct ext2_dir_entry
*dir
;
10257 ext2_dirhash_t
*hashes
;
10260 static int fill_dir_block(ext2_filsys fs
,
10262 e2_blkcnt_t blockcnt
,
10263 blk_t ref_block
FSCK_ATTR((unused
)),
10264 int ref_offset
FSCK_ATTR((unused
)),
10267 struct fill_dir_struct
*fd
= (struct fill_dir_struct
*) priv_data
;
10268 struct hash_entry
*new_array
, *ent
;
10269 struct ext2_dir_entry
*dirent
;
10271 unsigned int offset
, dir_offset
;
10276 offset
= blockcnt
* fs
->blocksize
;
10277 if (offset
+ fs
->blocksize
> fd
->inode
->i_size
) {
10278 fd
->err
= EXT2_ET_DIR_CORRUPTED
;
10279 return BLOCK_ABORT
;
10281 dir
= (fd
->buf
+offset
);
10282 if (HOLE_BLKADDR(*block_nr
)) {
10283 memset(dir
, 0, fs
->blocksize
);
10284 dirent
= (struct ext2_dir_entry
*) dir
;
10285 dirent
->rec_len
= fs
->blocksize
;
10287 fd
->err
= ext2fs_read_dir_block(fs
, *block_nr
, dir
);
10289 return BLOCK_ABORT
;
10291 /* While the directory block is "hot", index it. */
10293 while (dir_offset
< fs
->blocksize
) {
10294 dirent
= (struct ext2_dir_entry
*) (dir
+ dir_offset
);
10295 if (((dir_offset
+ dirent
->rec_len
) > fs
->blocksize
) ||
10296 (dirent
->rec_len
< 8) ||
10297 ((dirent
->rec_len
% 4) != 0) ||
10298 (((dirent
->name_len
& 0xFF)+8) > dirent
->rec_len
)) {
10299 fd
->err
= EXT2_ET_DIR_CORRUPTED
;
10300 return BLOCK_ABORT
;
10302 dir_offset
+= dirent
->rec_len
;
10303 if (dirent
->inode
== 0)
10305 if (!fd
->compress
&& ((dirent
->name_len
&0xFF) == 1) &&
10306 (dirent
->name
[0] == '.'))
10308 if (!fd
->compress
&& ((dirent
->name_len
&0xFF) == 2) &&
10309 (dirent
->name
[0] == '.') && (dirent
->name
[1] == '.')) {
10310 fd
->parent
= dirent
->inode
;
10313 if (fd
->num_array
>= fd
->max_array
) {
10314 new_array
= xrealloc(fd
->harray
,
10315 sizeof(struct hash_entry
) * (fd
->max_array
+500));
10316 fd
->harray
= new_array
;
10317 fd
->max_array
+= 500;
10319 ent
= fd
->harray
+ fd
->num_array
++;
10321 fd
->dir_size
+= EXT2_DIR_REC_LEN(dirent
->name_len
& 0xFF);
10323 ent
->hash
= ent
->minor_hash
= 0;
10325 fd
->err
= ext2fs_dirhash(fs
->super
->s_def_hash_version
,
10327 dirent
->name_len
& 0xFF,
10328 fs
->super
->s_hash_seed
,
10329 &ent
->hash
, &ent
->minor_hash
);
10331 return BLOCK_ABORT
;
10338 /* Used for sorting the hash entry */
10339 static int name_cmp(const void *a
, const void *b
)
10341 const struct hash_entry
*he_a
= (const struct hash_entry
*) a
;
10342 const struct hash_entry
*he_b
= (const struct hash_entry
*) b
;
10346 min_len
= he_a
->dir
->name_len
;
10347 if (min_len
> he_b
->dir
->name_len
)
10348 min_len
= he_b
->dir
->name_len
;
10350 ret
= strncmp(he_a
->dir
->name
, he_b
->dir
->name
, min_len
);
10352 if (he_a
->dir
->name_len
> he_b
->dir
->name_len
)
10354 else if (he_a
->dir
->name_len
< he_b
->dir
->name_len
)
10357 ret
= he_b
->dir
->inode
- he_a
->dir
->inode
;
10362 /* Used for sorting the hash entry */
10363 static int hash_cmp(const void *a
, const void *b
)
10365 const struct hash_entry
*he_a
= (const struct hash_entry
*) a
;
10366 const struct hash_entry
*he_b
= (const struct hash_entry
*) b
;
10369 if (he_a
->hash
> he_b
->hash
)
10371 else if (he_a
->hash
< he_b
->hash
)
10374 if (he_a
->minor_hash
> he_b
->minor_hash
)
10376 else if (he_a
->minor_hash
< he_b
->minor_hash
)
10379 ret
= name_cmp(a
, b
);
10384 static errcode_t
alloc_size_dir(ext2_filsys fs
, struct out_dir
*outdir
,
10390 new_mem
= xrealloc(outdir
->buf
, blocks
* fs
->blocksize
);
10391 outdir
->buf
= new_mem
;
10392 new_mem
= xrealloc(outdir
->hashes
,
10393 blocks
* sizeof(ext2_dirhash_t
));
10394 outdir
->hashes
= new_mem
;
10396 outdir
->buf
= xmalloc(blocks
* fs
->blocksize
);
10397 outdir
->hashes
= xmalloc(blocks
* sizeof(ext2_dirhash_t
));
10400 outdir
->max
= blocks
;
10404 static void free_out_dir(struct out_dir
*outdir
)
10407 free(outdir
->hashes
);
10412 static errcode_t
get_next_block(ext2_filsys fs
, struct out_dir
*outdir
,
10417 if (outdir
->num
>= outdir
->max
) {
10418 retval
= alloc_size_dir(fs
, outdir
, outdir
->max
+ 50);
10422 *ret
= outdir
->buf
+ (outdir
->num
++ * fs
->blocksize
);
10423 memset(*ret
, 0, fs
->blocksize
);
10428 * This function is used to make a unique filename. We do this by
10429 * appending ~0, and then incrementing the number. However, we cannot
10430 * expand the length of the filename beyond the padding available in
10431 * the directory entry.
10433 static void mutate_name(char *str
, __u16
*len
)
10436 __u16 l
= *len
& 0xFF, h
= *len
& 0xff00;
10439 * First check to see if it looks the name has been mutated
10442 for (i
= l
-1; i
> 0; i
--) {
10443 if (!isdigit(str
[i
]))
10446 if ((i
== l
-1) || (str
[i
] != '~')) {
10447 if (((l
-1) & 3) < 2)
10456 for (i
= l
-1; i
>= 0; i
--) {
10457 if (isdigit(str
[i
])) {
10469 else if (str
[0] == 'Z') {
10474 } else if (i
> 0) {
10487 static int duplicate_search_and_fix(e2fsck_t ctx
, ext2_filsys fs
,
10489 struct fill_dir_struct
*fd
)
10491 struct problem_context pctx
;
10492 struct hash_entry
*ent
, *prev
;
10495 char new_name
[256];
10498 clear_problem_context(&pctx
);
10501 for (i
=1; i
< fd
->num_array
; i
++) {
10502 ent
= fd
->harray
+ i
;
10504 if (!ent
->dir
->inode
||
10505 ((ent
->dir
->name_len
& 0xFF) !=
10506 (prev
->dir
->name_len
& 0xFF)) ||
10507 (strncmp(ent
->dir
->name
, prev
->dir
->name
,
10508 ent
->dir
->name_len
& 0xFF)))
10510 pctx
.dirent
= ent
->dir
;
10511 if ((ent
->dir
->inode
== prev
->dir
->inode
) &&
10512 fix_problem(ctx
, PR_2_DUPLICATE_DIRENT
, &pctx
)) {
10513 e2fsck_adjust_inode_count(ctx
, ent
->dir
->inode
, -1);
10514 ent
->dir
->inode
= 0;
10518 memcpy(new_name
, ent
->dir
->name
, ent
->dir
->name_len
& 0xFF);
10519 new_len
= ent
->dir
->name_len
;
10520 mutate_name(new_name
, &new_len
);
10521 for (j
=0; j
< fd
->num_array
; j
++) {
10523 ((ent
->dir
->name_len
& 0xFF) !=
10524 (fd
->harray
[j
].dir
->name_len
& 0xFF)) ||
10525 (strncmp(new_name
, fd
->harray
[j
].dir
->name
,
10528 mutate_name(new_name
, &new_len
);
10532 new_name
[new_len
& 0xFF] = 0;
10533 pctx
.str
= new_name
;
10534 if (fix_problem(ctx
, PR_2_NON_UNIQUE_FILE
, &pctx
)) {
10535 memcpy(ent
->dir
->name
, new_name
, new_len
& 0xFF);
10536 ent
->dir
->name_len
= new_len
;
10537 ext2fs_dirhash(fs
->super
->s_def_hash_version
,
10539 ent
->dir
->name_len
& 0xFF,
10540 fs
->super
->s_hash_seed
,
10541 &ent
->hash
, &ent
->minor_hash
);
10549 static errcode_t
copy_dir_entries(ext2_filsys fs
,
10550 struct fill_dir_struct
*fd
,
10551 struct out_dir
*outdir
)
10555 struct hash_entry
*ent
;
10556 struct ext2_dir_entry
*dirent
;
10557 int i
, rec_len
, left
;
10558 ext2_dirhash_t prev_hash
;
10562 retval
= alloc_size_dir(fs
, outdir
,
10563 (fd
->dir_size
/ fs
->blocksize
) + 2);
10566 outdir
->num
= fd
->compress
? 0 : 1;
10568 outdir
->hashes
[0] = 0;
10570 if ((retval
= get_next_block(fs
, outdir
, &block_start
)))
10572 dirent
= (struct ext2_dir_entry
*) block_start
;
10573 left
= fs
->blocksize
;
10574 for (i
=0; i
< fd
->num_array
; i
++) {
10575 ent
= fd
->harray
+ i
;
10576 if (ent
->dir
->inode
== 0)
10578 rec_len
= EXT2_DIR_REC_LEN(ent
->dir
->name_len
& 0xFF);
10579 if (rec_len
> left
) {
10581 dirent
->rec_len
+= left
;
10582 if ((retval
= get_next_block(fs
, outdir
,
10587 left
= fs
->blocksize
- offset
;
10588 dirent
= (struct ext2_dir_entry
*) (block_start
+ offset
);
10590 if (ent
->hash
== prev_hash
)
10591 outdir
->hashes
[outdir
->num
-1] = ent
->hash
| 1;
10593 outdir
->hashes
[outdir
->num
-1] = ent
->hash
;
10595 dirent
->inode
= ent
->dir
->inode
;
10596 dirent
->name_len
= ent
->dir
->name_len
;
10597 dirent
->rec_len
= rec_len
;
10598 memcpy(dirent
->name
, ent
->dir
->name
, dirent
->name_len
& 0xFF);
10602 dirent
->rec_len
+= left
;
10606 prev_hash
= ent
->hash
;
10609 dirent
->rec_len
+= left
;
10615 static struct ext2_dx_root_info
*set_root_node(ext2_filsys fs
, char *buf
,
10616 ext2_ino_t ino
, ext2_ino_t parent
)
10618 struct ext2_dir_entry
*dir
;
10619 struct ext2_dx_root_info
*root
;
10620 struct ext2_dx_countlimit
*limits
;
10623 if (fs
->super
->s_feature_incompat
& EXT2_FEATURE_INCOMPAT_FILETYPE
)
10624 filetype
= EXT2_FT_DIR
<< 8;
10626 memset(buf
, 0, fs
->blocksize
);
10627 dir
= (struct ext2_dir_entry
*) buf
;
10629 dir
->name
[0] = '.';
10630 dir
->name_len
= 1 | filetype
;
10632 dir
= (struct ext2_dir_entry
*) (buf
+ 12);
10633 dir
->inode
= parent
;
10634 dir
->name
[0] = '.';
10635 dir
->name
[1] = '.';
10636 dir
->name_len
= 2 | filetype
;
10637 dir
->rec_len
= fs
->blocksize
- 12;
10639 root
= (struct ext2_dx_root_info
*) (buf
+24);
10640 root
->reserved_zero
= 0;
10641 root
->hash_version
= fs
->super
->s_def_hash_version
;
10642 root
->info_length
= 8;
10643 root
->indirect_levels
= 0;
10644 root
->unused_flags
= 0;
10646 limits
= (struct ext2_dx_countlimit
*) (buf
+32);
10647 limits
->limit
= (fs
->blocksize
- 32) / sizeof(struct ext2_dx_entry
);
10654 static struct ext2_dx_entry
*set_int_node(ext2_filsys fs
, char *buf
)
10656 struct ext2_dir_entry
*dir
;
10657 struct ext2_dx_countlimit
*limits
;
10659 memset(buf
, 0, fs
->blocksize
);
10660 dir
= (struct ext2_dir_entry
*) buf
;
10662 dir
->rec_len
= fs
->blocksize
;
10664 limits
= (struct ext2_dx_countlimit
*) (buf
+8);
10665 limits
->limit
= (fs
->blocksize
- 8) / sizeof(struct ext2_dx_entry
);
10668 return (struct ext2_dx_entry
*) limits
;
10672 * This function takes the leaf nodes which have been written in
10673 * outdir, and populates the root node and any necessary interior nodes.
10675 static errcode_t
calculate_tree(ext2_filsys fs
,
10676 struct out_dir
*outdir
,
10680 struct ext2_dx_root_info
*root_info
;
10681 struct ext2_dx_entry
*root
, *dx_ent
= NULL
;
10682 struct ext2_dx_countlimit
*root_limit
, *limit
;
10684 char * block_start
;
10685 int i
, c1
, c2
, nblks
;
10686 int limit_offset
, root_offset
;
10688 root_info
= set_root_node(fs
, outdir
->buf
, ino
, parent
);
10689 root_offset
= limit_offset
= ((char *) root_info
- outdir
->buf
) +
10690 root_info
->info_length
;
10691 root_limit
= (struct ext2_dx_countlimit
*) (outdir
->buf
+ limit_offset
);
10692 c1
= root_limit
->limit
;
10693 nblks
= outdir
->num
;
10695 /* Write out the pointer blocks */
10696 if (nblks
-1 <= c1
) {
10697 /* Just write out the root block, and we're done */
10698 root
= (struct ext2_dx_entry
*) (outdir
->buf
+ root_offset
);
10699 for (i
=1; i
< nblks
; i
++) {
10700 root
->block
= ext2fs_cpu_to_le32(i
);
10703 ext2fs_cpu_to_le32(outdir
->hashes
[i
]);
10710 root_info
->indirect_levels
= 1;
10711 for (i
=1; i
< nblks
; i
++) {
10716 limit
->limit
= limit
->count
=
10717 ext2fs_cpu_to_le16(limit
->limit
);
10718 root
= (struct ext2_dx_entry
*)
10719 (outdir
->buf
+ root_offset
);
10720 root
->block
= ext2fs_cpu_to_le32(outdir
->num
);
10723 ext2fs_cpu_to_le32(outdir
->hashes
[i
]);
10724 if ((retval
= get_next_block(fs
, outdir
,
10727 dx_ent
= set_int_node(fs
, block_start
);
10728 limit
= (struct ext2_dx_countlimit
*) dx_ent
;
10730 root_offset
+= sizeof(struct ext2_dx_entry
);
10733 dx_ent
->block
= ext2fs_cpu_to_le32(i
);
10734 if (c2
!= limit
->limit
)
10736 ext2fs_cpu_to_le32(outdir
->hashes
[i
]);
10740 limit
->count
= ext2fs_cpu_to_le16(limit
->limit
- c2
);
10741 limit
->limit
= ext2fs_cpu_to_le16(limit
->limit
);
10743 root_limit
= (struct ext2_dx_countlimit
*) (outdir
->buf
+ limit_offset
);
10744 root_limit
->count
= ext2fs_cpu_to_le16(root_limit
->limit
- c1
);
10745 root_limit
->limit
= ext2fs_cpu_to_le16(root_limit
->limit
);
10750 struct write_dir_struct
{
10751 struct out_dir
*outdir
;
10758 * Helper function which writes out a directory block.
10760 static int write_dir_block(ext2_filsys fs
,
10762 e2_blkcnt_t blockcnt
,
10763 blk_t ref_block
FSCK_ATTR((unused
)),
10764 int ref_offset
FSCK_ATTR((unused
)),
10767 struct write_dir_struct
*wd
= (struct write_dir_struct
*) priv_data
;
10771 if (*block_nr
== 0)
10773 if (blockcnt
>= wd
->outdir
->num
) {
10774 e2fsck_read_bitmaps(wd
->ctx
);
10776 ext2fs_unmark_block_bitmap(wd
->ctx
->block_found_map
, blk
);
10777 ext2fs_block_alloc_stats(fs
, blk
, -1);
10780 return BLOCK_CHANGED
;
10785 dir
= wd
->outdir
->buf
+ (blockcnt
* fs
->blocksize
);
10786 wd
->err
= ext2fs_write_dir_block(fs
, *block_nr
, dir
);
10788 return BLOCK_ABORT
;
10792 static errcode_t
write_directory(e2fsck_t ctx
, ext2_filsys fs
,
10793 struct out_dir
*outdir
,
10794 ext2_ino_t ino
, int compress
)
10796 struct write_dir_struct wd
;
10798 struct ext2_inode inode
;
10800 retval
= e2fsck_expand_directory(ctx
, ino
, -1, outdir
->num
);
10804 wd
.outdir
= outdir
;
10809 retval
= ext2fs_block_iterate2(fs
, ino
, 0, 0,
10810 write_dir_block
, &wd
);
10816 e2fsck_read_inode(ctx
, ino
, &inode
, "rehash_dir");
10818 inode
.i_flags
&= ~EXT2_INDEX_FL
;
10820 inode
.i_flags
|= EXT2_INDEX_FL
;
10821 inode
.i_size
= outdir
->num
* fs
->blocksize
;
10822 inode
.i_blocks
-= (fs
->blocksize
/ 512) * wd
.cleared
;
10823 e2fsck_write_inode(ctx
, ino
, &inode
, "rehash_dir");
10828 static errcode_t
e2fsck_rehash_dir(e2fsck_t ctx
, ext2_ino_t ino
)
10830 ext2_filsys fs
= ctx
->fs
;
10832 struct ext2_inode inode
;
10833 char *dir_buf
= NULL
;
10834 struct fill_dir_struct fd
;
10835 struct out_dir outdir
;
10837 outdir
.max
= outdir
.num
= 0;
10840 e2fsck_read_inode(ctx
, ino
, &inode
, "rehash_dir");
10844 dir_buf
= xmalloc(inode
.i_size
);
10846 fd
.max_array
= inode
.i_size
/ 32;
10848 fd
.harray
= xmalloc(fd
.max_array
* sizeof(struct hash_entry
));
10856 if (!(fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
) ||
10857 (inode
.i_size
/ fs
->blocksize
) < 2)
10861 /* Read in the entire directory into memory */
10862 retval
= ext2fs_block_iterate2(fs
, ino
, 0, 0,
10863 fill_dir_block
, &fd
);
10869 /* Sort the list */
10872 qsort(fd
.harray
+2, fd
.num_array
-2,
10873 sizeof(struct hash_entry
), name_cmp
);
10875 qsort(fd
.harray
, fd
.num_array
,
10876 sizeof(struct hash_entry
), hash_cmp
);
10879 * Look for duplicates
10881 if (duplicate_search_and_fix(ctx
, fs
, ino
, &fd
))
10884 if (ctx
->options
& E2F_OPT_NO
) {
10890 * Copy the directory entries. In a htree directory these
10891 * will become the leaf nodes.
10893 retval
= copy_dir_entries(fs
, &fd
, &outdir
);
10897 free(dir_buf
); dir_buf
= 0;
10899 if (!fd
.compress
) {
10900 /* Calculate the interior nodes */
10901 retval
= calculate_tree(fs
, &outdir
, ino
, fd
.parent
);
10906 retval
= write_directory(ctx
, fs
, &outdir
, ino
, fd
.compress
);
10912 free_out_dir(&outdir
);
10916 void e2fsck_rehash_directories(e2fsck_t ctx
)
10918 struct problem_context pctx
;
10919 struct dir_info
*dir
;
10920 ext2_u32_iterate iter
;
10923 int i
, cur
, max
, all_dirs
, dir_index
, first
= 1;
10925 all_dirs
= ctx
->options
& E2F_OPT_COMPRESS_DIRS
;
10927 if (!ctx
->dirs_to_hash
&& !all_dirs
)
10930 e2fsck_get_lost_and_found(ctx
, 0);
10932 clear_problem_context(&pctx
);
10934 dir_index
= ctx
->fs
->super
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
;
10938 max
= e2fsck_get_num_dirinfo(ctx
);
10940 retval
= ext2fs_u32_list_iterate_begin(ctx
->dirs_to_hash
,
10943 pctx
.errcode
= retval
;
10944 fix_problem(ctx
, PR_3A_OPTIMIZE_ITER
, &pctx
);
10947 max
= ext2fs_u32_list_count(ctx
->dirs_to_hash
);
10951 if ((dir
= e2fsck_dir_info_iter(ctx
, &i
)) == 0)
10955 if (!ext2fs_u32_list_iterate(iter
, &ino
))
10958 if (ino
== ctx
->lost_and_found
)
10962 fix_problem(ctx
, PR_3A_PASS_HEADER
, &pctx
);
10965 pctx
.errcode
= e2fsck_rehash_dir(ctx
, ino
);
10966 if (pctx
.errcode
) {
10967 end_problem_latch(ctx
, PR_LATCH_OPTIMIZE_DIR
);
10968 fix_problem(ctx
, PR_3A_OPTIMIZE_DIR_ERR
, &pctx
);
10970 if (ctx
->progress
&& !ctx
->progress_fd
)
10971 e2fsck_simple_progress(ctx
, "Rebuilding directory",
10972 100.0 * (float) (++cur
) / (float) max
, ino
);
10974 end_problem_latch(ctx
, PR_LATCH_OPTIMIZE_DIR
);
10976 ext2fs_u32_list_iterate_end(iter
);
10978 ext2fs_u32_list_free(ctx
->dirs_to_hash
);
10979 ctx
->dirs_to_hash
= 0;
10983 * linux/fs/revoke.c
10985 * Journal revoke routines for the generic filesystem journaling code;
10986 * part of the ext2fs journaling system.
10988 * Revoke is the mechanism used to prevent old log records for deleted
10989 * metadata from being replayed on top of newer data using the same
10990 * blocks. The revoke mechanism is used in two separate places:
10992 * + Commit: during commit we write the entire list of the current
10993 * transaction's revoked blocks to the journal
10995 * + Recovery: during recovery we record the transaction ID of all
10996 * revoked blocks. If there are multiple revoke records in the log
10997 * for a single block, only the last one counts, and if there is a log
10998 * entry for a block beyond the last revoke, then that log entry still
11001 * We can get interactions between revokes and new log data within a
11002 * single transaction:
11004 * Block is revoked and then journaled:
11005 * The desired end result is the journaling of the new block, so we
11006 * cancel the revoke before the transaction commits.
11008 * Block is journaled and then revoked:
11009 * The revoke must take precedence over the write of the block, so we
11010 * need either to cancel the journal entry or to write the revoke
11011 * later in the log than the log block. In this case, we choose the
11012 * latter: journaling a block cancels any revoke record for that block
11013 * in the current transaction, so any revoke for that block in the
11014 * transaction must have happened after the block was journaled and so
11015 * the revoke must take precedence.
11017 * Block is revoked and then written as data:
11018 * The data write is allowed to succeed, but the revoke is _not_
11019 * cancelled. We still need to prevent old log records from
11020 * overwriting the new data. We don't even need to clear the revoke
11023 * Revoke information on buffers is a tri-state value:
11025 * RevokeValid clear: no cached revoke status, need to look it up
11026 * RevokeValid set, Revoked clear:
11027 * buffer has not been revoked, and cancel_revoke
11029 * RevokeValid set, Revoked set:
11030 * buffer has been revoked.
11033 static kmem_cache_t
*revoke_record_cache
;
11034 static kmem_cache_t
*revoke_table_cache
;
11036 /* Each revoke record represents one single revoked block. During
11037 journal replay, this involves recording the transaction ID of the
11038 last transaction to revoke this block. */
11040 struct jbd_revoke_record_s
11042 struct list_head hash
;
11043 tid_t sequence
; /* Used for recovery only */
11044 unsigned long blocknr
;
11048 /* The revoke table is just a simple hash table of revoke records. */
11049 struct jbd_revoke_table_s
11051 /* It is conceivable that we might want a larger hash table
11052 * for recovery. Must be a power of two. */
11055 struct list_head
*hash_table
;
11059 /* Utility functions to maintain the revoke table */
11061 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11062 static int hash(journal_t
*journal
, unsigned long block
)
11064 struct jbd_revoke_table_s
*table
= journal
->j_revoke
;
11065 int hash_shift
= table
->hash_shift
;
11067 return ((block
<< (hash_shift
- 6)) ^
11069 (block
<< (hash_shift
- 12))) & (table
->hash_size
- 1);
11072 static int insert_revoke_hash(journal_t
*journal
, unsigned long blocknr
,
11075 struct list_head
*hash_list
;
11076 struct jbd_revoke_record_s
*record
;
11078 record
= kmem_cache_alloc(revoke_record_cache
, GFP_NOFS
);
11082 record
->sequence
= seq
;
11083 record
->blocknr
= blocknr
;
11084 hash_list
= &journal
->j_revoke
->hash_table
[hash(journal
, blocknr
)];
11085 list_add(&record
->hash
, hash_list
);
11092 /* Find a revoke record in the journal's hash table. */
11094 static struct jbd_revoke_record_s
*find_revoke_record(journal_t
*journal
,
11095 unsigned long blocknr
)
11097 struct list_head
*hash_list
;
11098 struct jbd_revoke_record_s
*record
;
11100 hash_list
= &journal
->j_revoke
->hash_table
[hash(journal
, blocknr
)];
11102 record
= (struct jbd_revoke_record_s
*) hash_list
->next
;
11103 while (&(record
->hash
) != hash_list
) {
11104 if (record
->blocknr
== blocknr
)
11106 record
= (struct jbd_revoke_record_s
*) record
->hash
.next
;
11111 int journal_init_revoke_caches(void)
11113 revoke_record_cache
= do_cache_create(sizeof(struct jbd_revoke_record_s
));
11114 if (revoke_record_cache
== 0)
11117 revoke_table_cache
= do_cache_create(sizeof(struct jbd_revoke_table_s
));
11118 if (revoke_table_cache
== 0) {
11119 do_cache_destroy(revoke_record_cache
);
11120 revoke_record_cache
= NULL
;
11126 void journal_destroy_revoke_caches(void)
11128 do_cache_destroy(revoke_record_cache
);
11129 revoke_record_cache
= 0;
11130 do_cache_destroy(revoke_table_cache
);
11131 revoke_table_cache
= 0;
11134 /* Initialise the revoke table for a given journal to a given size. */
11136 int journal_init_revoke(journal_t
*journal
, int hash_size
)
11140 journal
->j_revoke
= kmem_cache_alloc(revoke_table_cache
, GFP_KERNEL
);
11141 if (!journal
->j_revoke
)
11144 /* Check that the hash_size is a power of two */
11145 journal
->j_revoke
->hash_size
= hash_size
;
11149 while ((tmp
>>= 1UL) != 0UL)
11151 journal
->j_revoke
->hash_shift
= shift
;
11153 journal
->j_revoke
->hash_table
= xmalloc(hash_size
* sizeof(struct list_head
));
11155 for (tmp
= 0; tmp
< hash_size
; tmp
++)
11156 INIT_LIST_HEAD(&journal
->j_revoke
->hash_table
[tmp
]);
11161 /* Destoy a journal's revoke table. The table must already be empty! */
11163 void journal_destroy_revoke(journal_t
*journal
)
11165 struct jbd_revoke_table_s
*table
;
11166 struct list_head
*hash_list
;
11169 table
= journal
->j_revoke
;
11173 for (i
=0; i
<table
->hash_size
; i
++) {
11174 hash_list
= &table
->hash_table
[i
];
11177 free(table
->hash_table
);
11179 journal
->j_revoke
= NULL
;
11183 * Revoke support for recovery.
11185 * Recovery needs to be able to:
11187 * record all revoke records, including the tid of the latest instance
11188 * of each revoke in the journal
11190 * check whether a given block in a given transaction should be replayed
11191 * (ie. has not been revoked by a revoke record in that or a subsequent
11194 * empty the revoke table after recovery.
11198 * First, setting revoke records. We create a new revoke record for
11199 * every block ever revoked in the log as we scan it for recovery, and
11200 * we update the existing records if we find multiple revokes for a
11204 int journal_set_revoke(journal_t
*journal
, unsigned long blocknr
,
11207 struct jbd_revoke_record_s
*record
;
11209 record
= find_revoke_record(journal
, blocknr
);
11211 /* If we have multiple occurences, only record the
11212 * latest sequence number in the hashed record */
11213 if (tid_gt(sequence
, record
->sequence
))
11214 record
->sequence
= sequence
;
11217 return insert_revoke_hash(journal
, blocknr
, sequence
);
11221 * Test revoke records. For a given block referenced in the log, has
11222 * that block been revoked? A revoke record with a given transaction
11223 * sequence number revokes all blocks in that transaction and earlier
11224 * ones, but later transactions still need replayed.
11227 int journal_test_revoke(journal_t
*journal
, unsigned long blocknr
,
11230 struct jbd_revoke_record_s
*record
;
11232 record
= find_revoke_record(journal
, blocknr
);
11235 if (tid_gt(sequence
, record
->sequence
))
11241 * Finally, once recovery is over, we need to clear the revoke table so
11242 * that it can be reused by the running filesystem.
11245 void journal_clear_revoke(journal_t
*journal
)
11248 struct list_head
*hash_list
;
11249 struct jbd_revoke_record_s
*record
;
11250 struct jbd_revoke_table_s
*revoke_var
;
11252 revoke_var
= journal
->j_revoke
;
11254 for (i
= 0; i
< revoke_var
->hash_size
; i
++) {
11255 hash_list
= &revoke_var
->hash_table
[i
];
11256 while (!list_empty(hash_list
)) {
11257 record
= (struct jbd_revoke_record_s
*) hash_list
->next
;
11258 list_del(&record
->hash
);
11265 * e2fsck.c - superblock checks
11268 #define MIN_CHECK 1
11269 #define MAX_CHECK 2
11271 static void check_super_value(e2fsck_t ctx
, const char *descr
,
11272 unsigned long value
, int flags
,
11273 unsigned long min_val
, unsigned long max_val
)
11275 struct problem_context pctx
;
11277 if (((flags
& MIN_CHECK
) && (value
< min_val
)) ||
11278 ((flags
& MAX_CHECK
) && (value
> max_val
))) {
11279 clear_problem_context(&pctx
);
11282 fix_problem(ctx
, PR_0_MISC_CORRUPT_SUPER
, &pctx
);
11283 ctx
->flags
|= E2F_FLAG_ABORT
; /* never get here! */
11288 * This routine may get stubbed out in special compilations of the
11291 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11292 static errcode_t
e2fsck_get_device_size(e2fsck_t ctx
)
11294 return (ext2fs_get_device_size(ctx
->filesystem_name
,
11295 EXT2_BLOCK_SIZE(ctx
->fs
->super
),
11296 &ctx
->num_blocks
));
11301 * helper function to release an inode
11303 struct process_block_struct
{
11306 struct problem_context
*pctx
;
11308 int truncate_offset
;
11309 e2_blkcnt_t truncate_block
;
11310 int truncated_blocks
;
11315 static int release_inode_block(ext2_filsys fs
, blk_t
*block_nr
,
11316 e2_blkcnt_t blockcnt
,
11317 blk_t ref_blk
FSCK_ATTR((unused
)),
11318 int ref_offset
FSCK_ATTR((unused
)),
11321 struct process_block_struct
*pb
;
11323 struct problem_context
*pctx
;
11324 blk_t blk
= *block_nr
;
11327 pb
= (struct process_block_struct
*) priv_data
;
11332 pctx
->blkcount
= blockcnt
;
11334 if (HOLE_BLKADDR(blk
))
11337 if ((blk
< fs
->super
->s_first_data_block
) ||
11338 (blk
>= fs
->super
->s_blocks_count
)) {
11339 fix_problem(ctx
, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM
, pctx
);
11342 return BLOCK_ABORT
;
11345 if (!ext2fs_test_block_bitmap(fs
->block_map
, blk
)) {
11346 fix_problem(ctx
, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK
, pctx
);
11351 * If we are deleting an orphan, then we leave the fields alone.
11352 * If we are truncating an orphan, then update the inode fields
11353 * and clean up any partial block data.
11355 if (pb
->truncating
) {
11357 * We only remove indirect blocks if they are
11358 * completely empty.
11360 if (blockcnt
< 0) {
11364 pb
->errcode
= io_channel_read_blk(fs
->io
, blk
, 1,
11369 limit
= fs
->blocksize
>> 2;
11370 for (i
= 0, bp
= (blk_t
*) pb
->buf
;
11371 i
< limit
; i
++, bp
++)
11376 * We don't remove direct blocks until we've reached
11377 * the truncation block.
11379 if (blockcnt
>= 0 && blockcnt
< pb
->truncate_block
)
11382 * If part of the last block needs truncating, we do
11385 if ((blockcnt
== pb
->truncate_block
) && pb
->truncate_offset
) {
11386 pb
->errcode
= io_channel_read_blk(fs
->io
, blk
, 1,
11390 memset(pb
->buf
+ pb
->truncate_offset
, 0,
11391 fs
->blocksize
- pb
->truncate_offset
);
11392 pb
->errcode
= io_channel_write_blk(fs
->io
, blk
, 1,
11397 pb
->truncated_blocks
++;
11399 retval
|= BLOCK_CHANGED
;
11402 ext2fs_block_alloc_stats(fs
, blk
, -1);
11407 * This function releases an inode. Returns 1 if an inconsistency was
11408 * found. If the inode has a link count, then it is being truncated and
11411 static int release_inode_blocks(e2fsck_t ctx
, ext2_ino_t ino
,
11412 struct ext2_inode
*inode
, char *block_buf
,
11413 struct problem_context
*pctx
)
11415 struct process_block_struct pb
;
11416 ext2_filsys fs
= ctx
->fs
;
11420 if (!ext2fs_inode_has_valid_blocks(inode
))
11423 pb
.buf
= block_buf
+ 3 * ctx
->fs
->blocksize
;
11428 if (inode
->i_links_count
) {
11430 pb
.truncate_block
= (e2_blkcnt_t
)
11431 ((((long long)inode
->i_size_high
<< 32) +
11432 inode
->i_size
+ fs
->blocksize
- 1) /
11434 pb
.truncate_offset
= inode
->i_size
% fs
->blocksize
;
11437 pb
.truncate_block
= 0;
11438 pb
.truncate_offset
= 0;
11440 pb
.truncated_blocks
= 0;
11441 retval
= ext2fs_block_iterate2(fs
, ino
, BLOCK_FLAG_DEPTH_TRAVERSE
,
11442 block_buf
, release_inode_block
, &pb
);
11444 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11451 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11452 e2fsck_read_inode(ctx
, ino
, inode
, "release_inode_blocks");
11454 if (pb
.truncated_blocks
)
11455 inode
->i_blocks
-= pb
.truncated_blocks
*
11456 (fs
->blocksize
/ 512);
11458 if (inode
->i_file_acl
) {
11459 retval
= ext2fs_adjust_ea_refcount(fs
, inode
->i_file_acl
,
11460 block_buf
, -1, &count
);
11461 if (retval
== EXT2_ET_BAD_EA_BLOCK_NUM
) {
11466 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11471 ext2fs_block_alloc_stats(fs
, inode
->i_file_acl
, -1);
11472 inode
->i_file_acl
= 0;
11478 * This function releases all of the orphan inodes. It returns 1 if
11479 * it hit some error, and 0 on success.
11481 static int release_orphan_inodes(e2fsck_t ctx
)
11483 ext2_filsys fs
= ctx
->fs
;
11484 ext2_ino_t ino
, next_ino
;
11485 struct ext2_inode inode
;
11486 struct problem_context pctx
;
11489 if ((ino
= fs
->super
->s_last_orphan
) == 0)
11493 * Win or lose, we won't be using the head of the orphan inode
11496 fs
->super
->s_last_orphan
= 0;
11497 ext2fs_mark_super_dirty(fs
);
11500 * If the filesystem contains errors, don't run the orphan
11501 * list, since the orphan list can't be trusted; and we're
11502 * going to be running a full e2fsck run anyway...
11504 if (fs
->super
->s_state
& EXT2_ERROR_FS
)
11507 if ((ino
< EXT2_FIRST_INODE(fs
->super
)) ||
11508 (ino
> fs
->super
->s_inodes_count
)) {
11509 clear_problem_context(&pctx
);
11511 fix_problem(ctx
, PR_0_ORPHAN_ILLEGAL_HEAD_INODE
, &pctx
);
11515 block_buf
= (char *) e2fsck_allocate_memory(ctx
, fs
->blocksize
* 4,
11516 "block iterate buffer");
11517 e2fsck_read_bitmaps(ctx
);
11520 e2fsck_read_inode(ctx
, ino
, &inode
, "release_orphan_inodes");
11521 clear_problem_context(&pctx
);
11523 pctx
.inode
= &inode
;
11524 pctx
.str
= inode
.i_links_count
? _("Truncating") :
11527 fix_problem(ctx
, PR_0_ORPHAN_CLEAR_INODE
, &pctx
);
11529 next_ino
= inode
.i_dtime
;
11531 ((next_ino
< EXT2_FIRST_INODE(fs
->super
)) ||
11532 (next_ino
> fs
->super
->s_inodes_count
))) {
11533 pctx
.ino
= next_ino
;
11534 fix_problem(ctx
, PR_0_ORPHAN_ILLEGAL_INODE
, &pctx
);
11538 if (release_inode_blocks(ctx
, ino
, &inode
, block_buf
, &pctx
))
11541 if (!inode
.i_links_count
) {
11542 ext2fs_inode_alloc_stats2(fs
, ino
, -1,
11543 LINUX_S_ISDIR(inode
.i_mode
));
11544 inode
.i_dtime
= time(NULL
);
11548 e2fsck_write_inode(ctx
, ino
, &inode
, "delete_file");
11551 ext2fs_free_mem(&block_buf
);
11554 ext2fs_free_mem(&block_buf
);
11559 * Check the resize inode to make sure it is sane. We check both for
11560 * the case where on-line resizing is not enabled (in which case the
11561 * resize inode should be cleared) as well as the case where on-line
11562 * resizing is enabled.
11564 static void check_resize_inode(e2fsck_t ctx
)
11566 ext2_filsys fs
= ctx
->fs
;
11567 struct ext2_inode inode
;
11568 struct problem_context pctx
;
11569 int i
, j
, gdt_off
, ind_off
;
11570 blk_t blk
, pblk
, expect
;
11571 __u32
*dind_buf
= NULL
, *ind_buf
;
11574 clear_problem_context(&pctx
);
11577 * If the resize inode feature isn't set, then
11578 * s_reserved_gdt_blocks must be zero.
11580 if (!(fs
->super
->s_feature_compat
&
11581 EXT2_FEATURE_COMPAT_RESIZE_INO
)) {
11582 if (fs
->super
->s_reserved_gdt_blocks
) {
11583 pctx
.num
= fs
->super
->s_reserved_gdt_blocks
;
11584 if (fix_problem(ctx
, PR_0_NONZERO_RESERVED_GDT_BLOCKS
,
11586 fs
->super
->s_reserved_gdt_blocks
= 0;
11587 ext2fs_mark_super_dirty(fs
);
11592 /* Read the resize inode */
11593 pctx
.ino
= EXT2_RESIZE_INO
;
11594 retval
= ext2fs_read_inode(fs
, EXT2_RESIZE_INO
, &inode
);
11596 if (fs
->super
->s_feature_compat
&
11597 EXT2_FEATURE_COMPAT_RESIZE_INO
)
11598 ctx
->flags
|= E2F_FLAG_RESIZE_INODE
;
11603 * If the resize inode feature isn't set, check to make sure
11604 * the resize inode is cleared; then we're done.
11606 if (!(fs
->super
->s_feature_compat
&
11607 EXT2_FEATURE_COMPAT_RESIZE_INO
)) {
11608 for (i
=0; i
< EXT2_N_BLOCKS
; i
++) {
11609 if (inode
.i_block
[i
])
11612 if ((i
< EXT2_N_BLOCKS
) &&
11613 fix_problem(ctx
, PR_0_CLEAR_RESIZE_INODE
, &pctx
)) {
11614 memset(&inode
, 0, sizeof(inode
));
11615 e2fsck_write_inode(ctx
, EXT2_RESIZE_INO
, &inode
,
11622 * The resize inode feature is enabled; check to make sure the
11623 * only block in use is the double indirect block
11625 blk
= inode
.i_block
[EXT2_DIND_BLOCK
];
11626 for (i
=0; i
< EXT2_N_BLOCKS
; i
++) {
11627 if (i
!= EXT2_DIND_BLOCK
&& inode
.i_block
[i
])
11630 if ((i
< EXT2_N_BLOCKS
) || !blk
|| !inode
.i_links_count
||
11631 !(inode
.i_mode
& LINUX_S_IFREG
) ||
11632 (blk
< fs
->super
->s_first_data_block
||
11633 blk
>= fs
->super
->s_blocks_count
)) {
11634 resize_inode_invalid
:
11635 if (fix_problem(ctx
, PR_0_RESIZE_INODE_INVALID
, &pctx
)) {
11636 memset(&inode
, 0, sizeof(inode
));
11637 e2fsck_write_inode(ctx
, EXT2_RESIZE_INO
, &inode
,
11639 ctx
->flags
|= E2F_FLAG_RESIZE_INODE
;
11641 if (!(ctx
->options
& E2F_OPT_READONLY
)) {
11642 fs
->super
->s_state
&= ~EXT2_VALID_FS
;
11643 ext2fs_mark_super_dirty(fs
);
11647 dind_buf
= (__u32
*) e2fsck_allocate_memory(ctx
, fs
->blocksize
* 2,
11648 "resize dind buffer");
11649 ind_buf
= (__u32
*) ((char *) dind_buf
+ fs
->blocksize
);
11651 retval
= ext2fs_read_ind_block(fs
, blk
, dind_buf
);
11653 goto resize_inode_invalid
;
11655 gdt_off
= fs
->desc_blocks
;
11656 pblk
= fs
->super
->s_first_data_block
+ 1 + fs
->desc_blocks
;
11657 for (i
= 0; i
< fs
->super
->s_reserved_gdt_blocks
/ 4;
11658 i
++, gdt_off
++, pblk
++) {
11659 gdt_off
%= fs
->blocksize
/4;
11660 if (dind_buf
[gdt_off
] != pblk
)
11661 goto resize_inode_invalid
;
11662 retval
= ext2fs_read_ind_block(fs
, pblk
, ind_buf
);
11664 goto resize_inode_invalid
;
11666 for (j
= 1; j
< fs
->group_desc_count
; j
++) {
11667 if (!ext2fs_bg_has_super(fs
, j
))
11669 expect
= pblk
+ (j
* fs
->super
->s_blocks_per_group
);
11670 if (ind_buf
[ind_off
] != expect
)
11671 goto resize_inode_invalid
;
11677 ext2fs_free_mem(&dind_buf
);
11680 static void check_super_block(e2fsck_t ctx
)
11682 ext2_filsys fs
= ctx
->fs
;
11683 blk_t first_block
, last_block
;
11684 struct ext2_super_block
*sb
= fs
->super
;
11685 struct ext2_group_desc
*gd
;
11686 blk_t blocks_per_group
= fs
->super
->s_blocks_per_group
;
11688 int inodes_per_block
;
11693 struct problem_context pctx
;
11694 __u32 free_blocks
= 0, free_inodes
= 0;
11696 inodes_per_block
= EXT2_INODES_PER_BLOCK(fs
->super
);
11697 ipg_max
= inodes_per_block
* (blocks_per_group
- 4);
11698 if (ipg_max
> EXT2_MAX_INODES_PER_GROUP(sb
))
11699 ipg_max
= EXT2_MAX_INODES_PER_GROUP(sb
);
11700 bpg_max
= 8 * EXT2_BLOCK_SIZE(sb
);
11701 if (bpg_max
> EXT2_MAX_BLOCKS_PER_GROUP(sb
))
11702 bpg_max
= EXT2_MAX_BLOCKS_PER_GROUP(sb
);
11704 ctx
->invalid_inode_bitmap_flag
= (int *) e2fsck_allocate_memory(ctx
,
11705 sizeof(int) * fs
->group_desc_count
, "invalid_inode_bitmap");
11706 ctx
->invalid_block_bitmap_flag
= (int *) e2fsck_allocate_memory(ctx
,
11707 sizeof(int) * fs
->group_desc_count
, "invalid_block_bitmap");
11708 ctx
->invalid_inode_table_flag
= (int *) e2fsck_allocate_memory(ctx
,
11709 sizeof(int) * fs
->group_desc_count
, "invalid_inode_table");
11711 clear_problem_context(&pctx
);
11714 * Verify the super block constants...
11716 check_super_value(ctx
, "inodes_count", sb
->s_inodes_count
,
11718 check_super_value(ctx
, "blocks_count", sb
->s_blocks_count
,
11720 check_super_value(ctx
, "first_data_block", sb
->s_first_data_block
,
11721 MAX_CHECK
, 0, sb
->s_blocks_count
);
11722 check_super_value(ctx
, "log_block_size", sb
->s_log_block_size
,
11723 MIN_CHECK
| MAX_CHECK
, 0,
11724 EXT2_MAX_BLOCK_LOG_SIZE
- EXT2_MIN_BLOCK_LOG_SIZE
);
11725 check_super_value(ctx
, "log_frag_size", sb
->s_log_frag_size
,
11726 MIN_CHECK
| MAX_CHECK
, 0, sb
->s_log_block_size
);
11727 check_super_value(ctx
, "frags_per_group", sb
->s_frags_per_group
,
11728 MIN_CHECK
| MAX_CHECK
, sb
->s_blocks_per_group
,
11730 check_super_value(ctx
, "blocks_per_group", sb
->s_blocks_per_group
,
11731 MIN_CHECK
| MAX_CHECK
, 8, bpg_max
);
11732 check_super_value(ctx
, "inodes_per_group", sb
->s_inodes_per_group
,
11733 MIN_CHECK
| MAX_CHECK
, inodes_per_block
, ipg_max
);
11734 check_super_value(ctx
, "r_blocks_count", sb
->s_r_blocks_count
,
11735 MAX_CHECK
, 0, sb
->s_blocks_count
/ 2);
11736 check_super_value(ctx
, "reserved_gdt_blocks",
11737 sb
->s_reserved_gdt_blocks
, MAX_CHECK
, 0,
11739 inode_size
= EXT2_INODE_SIZE(sb
);
11740 check_super_value(ctx
, "inode_size",
11741 inode_size
, MIN_CHECK
| MAX_CHECK
,
11742 EXT2_GOOD_OLD_INODE_SIZE
, fs
->blocksize
);
11743 if (inode_size
& (inode_size
- 1)) {
11744 pctx
.num
= inode_size
;
11745 pctx
.str
= "inode_size";
11746 fix_problem(ctx
, PR_0_MISC_CORRUPT_SUPER
, &pctx
);
11747 ctx
->flags
|= E2F_FLAG_ABORT
; /* never get here! */
11751 if (!ctx
->num_blocks
) {
11752 pctx
.errcode
= e2fsck_get_device_size(ctx
);
11753 if (pctx
.errcode
&& pctx
.errcode
!= EXT2_ET_UNIMPLEMENTED
) {
11754 fix_problem(ctx
, PR_0_GETSIZE_ERROR
, &pctx
);
11755 ctx
->flags
|= E2F_FLAG_ABORT
;
11758 if ((pctx
.errcode
!= EXT2_ET_UNIMPLEMENTED
) &&
11759 (ctx
->num_blocks
< sb
->s_blocks_count
)) {
11760 pctx
.blk
= sb
->s_blocks_count
;
11761 pctx
.blk2
= ctx
->num_blocks
;
11762 if (fix_problem(ctx
, PR_0_FS_SIZE_WRONG
, &pctx
)) {
11763 ctx
->flags
|= E2F_FLAG_ABORT
;
11769 if (sb
->s_log_block_size
!= (__u32
) sb
->s_log_frag_size
) {
11770 pctx
.blk
= EXT2_BLOCK_SIZE(sb
);
11771 pctx
.blk2
= EXT2_FRAG_SIZE(sb
);
11772 fix_problem(ctx
, PR_0_NO_FRAGMENTS
, &pctx
);
11773 ctx
->flags
|= E2F_FLAG_ABORT
;
11777 should_be
= sb
->s_frags_per_group
>>
11778 (sb
->s_log_block_size
- sb
->s_log_frag_size
);
11779 if (sb
->s_blocks_per_group
!= should_be
) {
11780 pctx
.blk
= sb
->s_blocks_per_group
;
11781 pctx
.blk2
= should_be
;
11782 fix_problem(ctx
, PR_0_BLOCKS_PER_GROUP
, &pctx
);
11783 ctx
->flags
|= E2F_FLAG_ABORT
;
11787 should_be
= (sb
->s_log_block_size
== 0) ? 1 : 0;
11788 if (sb
->s_first_data_block
!= should_be
) {
11789 pctx
.blk
= sb
->s_first_data_block
;
11790 pctx
.blk2
= should_be
;
11791 fix_problem(ctx
, PR_0_FIRST_DATA_BLOCK
, &pctx
);
11792 ctx
->flags
|= E2F_FLAG_ABORT
;
11796 should_be
= sb
->s_inodes_per_group
* fs
->group_desc_count
;
11797 if (sb
->s_inodes_count
!= should_be
) {
11798 pctx
.ino
= sb
->s_inodes_count
;
11799 pctx
.ino2
= should_be
;
11800 if (fix_problem(ctx
, PR_0_INODE_COUNT_WRONG
, &pctx
)) {
11801 sb
->s_inodes_count
= should_be
;
11802 ext2fs_mark_super_dirty(fs
);
11807 * Verify the group descriptors....
11809 first_block
= sb
->s_first_data_block
;
11810 last_block
= first_block
+ blocks_per_group
;
11812 for (i
= 0, gd
=fs
->group_desc
; i
< fs
->group_desc_count
; i
++, gd
++) {
11815 if (i
== fs
->group_desc_count
- 1)
11816 last_block
= sb
->s_blocks_count
;
11817 if ((gd
->bg_block_bitmap
< first_block
) ||
11818 (gd
->bg_block_bitmap
>= last_block
)) {
11819 pctx
.blk
= gd
->bg_block_bitmap
;
11820 if (fix_problem(ctx
, PR_0_BB_NOT_GROUP
, &pctx
))
11821 gd
->bg_block_bitmap
= 0;
11823 if (gd
->bg_block_bitmap
== 0) {
11824 ctx
->invalid_block_bitmap_flag
[i
]++;
11825 ctx
->invalid_bitmaps
++;
11827 if ((gd
->bg_inode_bitmap
< first_block
) ||
11828 (gd
->bg_inode_bitmap
>= last_block
)) {
11829 pctx
.blk
= gd
->bg_inode_bitmap
;
11830 if (fix_problem(ctx
, PR_0_IB_NOT_GROUP
, &pctx
))
11831 gd
->bg_inode_bitmap
= 0;
11833 if (gd
->bg_inode_bitmap
== 0) {
11834 ctx
->invalid_inode_bitmap_flag
[i
]++;
11835 ctx
->invalid_bitmaps
++;
11837 if ((gd
->bg_inode_table
< first_block
) ||
11838 ((gd
->bg_inode_table
+
11839 fs
->inode_blocks_per_group
- 1) >= last_block
)) {
11840 pctx
.blk
= gd
->bg_inode_table
;
11841 if (fix_problem(ctx
, PR_0_ITABLE_NOT_GROUP
, &pctx
))
11842 gd
->bg_inode_table
= 0;
11844 if (gd
->bg_inode_table
== 0) {
11845 ctx
->invalid_inode_table_flag
[i
]++;
11846 ctx
->invalid_bitmaps
++;
11848 free_blocks
+= gd
->bg_free_blocks_count
;
11849 free_inodes
+= gd
->bg_free_inodes_count
;
11850 first_block
+= sb
->s_blocks_per_group
;
11851 last_block
+= sb
->s_blocks_per_group
;
11853 if ((gd
->bg_free_blocks_count
> sb
->s_blocks_per_group
) ||
11854 (gd
->bg_free_inodes_count
> sb
->s_inodes_per_group
) ||
11855 (gd
->bg_used_dirs_count
> sb
->s_inodes_per_group
))
11856 ext2fs_unmark_valid(fs
);
11860 * Update the global counts from the block group counts. This
11861 * is needed for an experimental patch which eliminates
11862 * locking the entire filesystem when allocating blocks or
11863 * inodes; if the filesystem is not unmounted cleanly, the
11864 * global counts may not be accurate.
11866 if ((free_blocks
!= sb
->s_free_blocks_count
) ||
11867 (free_inodes
!= sb
->s_free_inodes_count
)) {
11868 if (ctx
->options
& E2F_OPT_READONLY
)
11869 ext2fs_unmark_valid(fs
);
11871 sb
->s_free_blocks_count
= free_blocks
;
11872 sb
->s_free_inodes_count
= free_inodes
;
11873 ext2fs_mark_super_dirty(fs
);
11877 if ((sb
->s_free_blocks_count
> sb
->s_blocks_count
) ||
11878 (sb
->s_free_inodes_count
> sb
->s_inodes_count
))
11879 ext2fs_unmark_valid(fs
);
11883 * If we have invalid bitmaps, set the error state of the
11886 if (ctx
->invalid_bitmaps
&& !(ctx
->options
& E2F_OPT_READONLY
)) {
11887 sb
->s_state
&= ~EXT2_VALID_FS
;
11888 ext2fs_mark_super_dirty(fs
);
11891 clear_problem_context(&pctx
);
11894 * If the UUID field isn't assigned, assign it.
11896 if (!(ctx
->options
& E2F_OPT_READONLY
) && uuid_is_null(sb
->s_uuid
)) {
11897 if (fix_problem(ctx
, PR_0_ADD_UUID
, &pctx
)) {
11898 generate_uuid(sb
->s_uuid
);
11899 ext2fs_mark_super_dirty(fs
);
11900 fs
->flags
&= ~EXT2_FLAG_MASTER_SB_ONLY
;
11904 /* FIXME - HURD support?
11905 * For the Hurd, check to see if the filetype option is set,
11906 * since it doesn't support it.
11908 if (!(ctx
->options
& E2F_OPT_READONLY
) &&
11909 fs
->super
->s_creator_os
== EXT2_OS_HURD
&&
11910 (fs
->super
->s_feature_incompat
&
11911 EXT2_FEATURE_INCOMPAT_FILETYPE
)) {
11912 if (fix_problem(ctx
, PR_0_HURD_CLEAR_FILETYPE
, &pctx
)) {
11913 fs
->super
->s_feature_incompat
&=
11914 ~EXT2_FEATURE_INCOMPAT_FILETYPE
;
11915 ext2fs_mark_super_dirty(fs
);
11920 * If we have any of the compatibility flags set, we need to have a
11921 * revision 1 filesystem. Most kernels will not check the flags on
11922 * a rev 0 filesystem and we may have corruption issues because of
11923 * the incompatible changes to the filesystem.
11925 if (!(ctx
->options
& E2F_OPT_READONLY
) &&
11926 fs
->super
->s_rev_level
== EXT2_GOOD_OLD_REV
&&
11927 (fs
->super
->s_feature_compat
||
11928 fs
->super
->s_feature_ro_compat
||
11929 fs
->super
->s_feature_incompat
) &&
11930 fix_problem(ctx
, PR_0_FS_REV_LEVEL
, &pctx
)) {
11931 ext2fs_update_dynamic_rev(fs
);
11932 ext2fs_mark_super_dirty(fs
);
11935 check_resize_inode(ctx
);
11938 * Clean up any orphan inodes, if present.
11940 if (!(ctx
->options
& E2F_OPT_READONLY
) && release_orphan_inodes(ctx
)) {
11941 fs
->super
->s_state
&= ~EXT2_VALID_FS
;
11942 ext2fs_mark_super_dirty(fs
);
11946 * Move the ext3 journal file, if necessary.
11948 e2fsck_move_ext3_journal(ctx
);
11952 * swapfs.c --- byte-swap an ext2 filesystem
11955 #ifdef ENABLE_SWAPFS
11957 struct swap_block_struct
{
11962 struct ext2_inode
*inode
;
11966 * This is a helper function for block_iterate. We mark all of the
11967 * indirect and direct blocks as changed, so that block_iterate will
11970 static int swap_block(ext2_filsys fs
, blk_t
*block_nr
, int blockcnt
,
11975 struct swap_block_struct
*sb
= (struct swap_block_struct
*) priv_data
;
11977 if (sb
->isdir
&& (blockcnt
>= 0) && *block_nr
) {
11978 retval
= ext2fs_read_dir_block(fs
, *block_nr
, sb
->dir_buf
);
11980 sb
->errcode
= retval
;
11981 return BLOCK_ABORT
;
11983 retval
= ext2fs_write_dir_block(fs
, *block_nr
, sb
->dir_buf
);
11985 sb
->errcode
= retval
;
11986 return BLOCK_ABORT
;
11989 if (blockcnt
>= 0) {
11990 if (blockcnt
< EXT2_NDIR_BLOCKS
)
11992 return BLOCK_CHANGED
;
11994 if (blockcnt
== BLOCK_COUNT_IND
) {
11995 if (*block_nr
== sb
->inode
->i_block
[EXT2_IND_BLOCK
])
11997 return BLOCK_CHANGED
;
11999 if (blockcnt
== BLOCK_COUNT_DIND
) {
12000 if (*block_nr
== sb
->inode
->i_block
[EXT2_DIND_BLOCK
])
12002 return BLOCK_CHANGED
;
12004 if (blockcnt
== BLOCK_COUNT_TIND
) {
12005 if (*block_nr
== sb
->inode
->i_block
[EXT2_TIND_BLOCK
])
12007 return BLOCK_CHANGED
;
12009 return BLOCK_CHANGED
;
12013 * This function is responsible for byte-swapping all of the indirect,
12014 * block pointers. It is also responsible for byte-swapping directories.
12016 static void swap_inode_blocks(e2fsck_t ctx
, ext2_ino_t ino
, char *block_buf
,
12017 struct ext2_inode
*inode
)
12020 struct swap_block_struct sb
;
12024 sb
.dir_buf
= block_buf
+ ctx
->fs
->blocksize
*3;
12027 if (LINUX_S_ISDIR(inode
->i_mode
))
12030 retval
= ext2fs_block_iterate(ctx
->fs
, ino
, 0, block_buf
,
12033 bb_error_msg(_("while calling ext2fs_block_iterate"));
12034 ctx
->flags
|= E2F_FLAG_ABORT
;
12038 bb_error_msg(_("while calling iterator function"));
12039 ctx
->flags
|= E2F_FLAG_ABORT
;
12044 static void swap_inodes(e2fsck_t ctx
)
12046 ext2_filsys fs
= ctx
->fs
;
12049 ext2_ino_t ino
= 1;
12050 char *buf
, *block_buf
;
12052 struct ext2_inode
* inode
;
12054 e2fsck_use_inode_shortcuts(ctx
, 1);
12056 retval
= ext2fs_get_mem(fs
->blocksize
* fs
->inode_blocks_per_group
,
12059 bb_error_msg(_("while allocating inode buffer"));
12060 ctx
->flags
|= E2F_FLAG_ABORT
;
12063 block_buf
= (char *) e2fsck_allocate_memory(ctx
, fs
->blocksize
* 4,
12064 "block interate buffer");
12065 for (group
= 0; group
< fs
->group_desc_count
; group
++) {
12066 retval
= io_channel_read_blk(fs
->io
,
12067 fs
->group_desc
[group
].bg_inode_table
,
12068 fs
->inode_blocks_per_group
, buf
);
12070 bb_error_msg(_("while reading inode table (group %d)"),
12072 ctx
->flags
|= E2F_FLAG_ABORT
;
12075 inode
= (struct ext2_inode
*) buf
;
12076 for (i
=0; i
< fs
->super
->s_inodes_per_group
;
12077 i
++, ino
++, inode
++) {
12078 ctx
->stashed_ino
= ino
;
12079 ctx
->stashed_inode
= inode
;
12081 if (fs
->flags
& EXT2_FLAG_SWAP_BYTES_READ
)
12082 ext2fs_swap_inode(fs
, inode
, inode
, 0);
12085 * Skip deleted files.
12087 if (inode
->i_links_count
== 0)
12090 if (LINUX_S_ISDIR(inode
->i_mode
) ||
12091 ((inode
->i_block
[EXT2_IND_BLOCK
] ||
12092 inode
->i_block
[EXT2_DIND_BLOCK
] ||
12093 inode
->i_block
[EXT2_TIND_BLOCK
]) &&
12094 ext2fs_inode_has_valid_blocks(inode
)))
12095 swap_inode_blocks(ctx
, ino
, block_buf
, inode
);
12097 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
12100 if (fs
->flags
& EXT2_FLAG_SWAP_BYTES_WRITE
)
12101 ext2fs_swap_inode(fs
, inode
, inode
, 1);
12103 retval
= io_channel_write_blk(fs
->io
,
12104 fs
->group_desc
[group
].bg_inode_table
,
12105 fs
->inode_blocks_per_group
, buf
);
12107 bb_error_msg(_("while writing inode table (group %d)"),
12109 ctx
->flags
|= E2F_FLAG_ABORT
;
12113 ext2fs_free_mem(&buf
);
12114 ext2fs_free_mem(&block_buf
);
12115 e2fsck_use_inode_shortcuts(ctx
, 0);
12116 ext2fs_flush_icache(fs
);
12119 #if defined(__powerpc__) && BB_BIG_ENDIAN
12121 * On the PowerPC, the big-endian variant of the ext2 filesystem
12122 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12123 * of each word. Thus a bitmap with only bit 0 set would be, as
12124 * a string of bytes, 00 00 00 01 00 ...
12125 * To cope with this, we byte-reverse each word of a bitmap if
12126 * we have a big-endian filesystem, that is, if we are *not*
12127 * byte-swapping other word-sized numbers.
12129 #define EXT2_BIG_ENDIAN_BITMAPS
12132 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12133 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap
)
12135 __u32
*p
= (__u32
*) bmap
->bitmap
;
12136 int n
, nbytes
= (bmap
->end
- bmap
->start
+ 7) / 8;
12138 for (n
= nbytes
/ sizeof(__u32
); n
> 0; --n
, ++p
)
12139 *p
= ext2fs_swab32(*p
);
12144 #ifdef ENABLE_SWAPFS
12145 static void swap_filesys(e2fsck_t ctx
)
12147 ext2_filsys fs
= ctx
->fs
;
12148 if (!(ctx
->options
& E2F_OPT_PREEN
))
12149 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12153 if (fs
->super
->s_mnt_count
) {
12154 fprintf(stderr
, _("%s: the filesystem must be freshly "
12155 "checked using fsck\n"
12156 "and not mounted before trying to "
12157 "byte-swap it.\n"), ctx
->device_name
);
12158 ctx
->flags
|= E2F_FLAG_ABORT
;
12161 if (fs
->flags
& EXT2_FLAG_SWAP_BYTES
) {
12162 fs
->flags
&= ~(EXT2_FLAG_SWAP_BYTES
|
12163 EXT2_FLAG_SWAP_BYTES_WRITE
);
12164 fs
->flags
|= EXT2_FLAG_SWAP_BYTES_READ
;
12166 fs
->flags
&= ~EXT2_FLAG_SWAP_BYTES_READ
;
12167 fs
->flags
|= EXT2_FLAG_SWAP_BYTES_WRITE
;
12170 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
12172 if (fs
->flags
& EXT2_FLAG_SWAP_BYTES_WRITE
)
12173 fs
->flags
|= EXT2_FLAG_SWAP_BYTES
;
12174 fs
->flags
&= ~(EXT2_FLAG_SWAP_BYTES_READ
|
12175 EXT2_FLAG_SWAP_BYTES_WRITE
);
12177 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12178 e2fsck_read_bitmaps(ctx
);
12179 ext2fs_swap_bitmap(fs
->inode_map
);
12180 ext2fs_swap_bitmap(fs
->block_map
);
12181 fs
->flags
|= EXT2_FLAG_BB_DIRTY
| EXT2_FLAG_IB_DIRTY
;
12183 fs
->flags
&= ~EXT2_FLAG_MASTER_SB_ONLY
;
12185 fs
->flags
|= EXT2_FLAG_MASTER_SB_ONLY
;
12187 #endif /* ENABLE_SWAPFS */
12192 * util.c --- miscellaneous utilities
12196 void *e2fsck_allocate_memory(e2fsck_t ctx
EXT2FS_ATTR((unused
)), unsigned int size
,
12197 const char *description
EXT2FS_ATTR((unused
)))
12201 ret
= xzalloc(size
);
12205 static char *string_copy(const char *str
, int len
)
12213 ret
= xmalloc(len
+1);
12214 strncpy(ret
, str
, len
);
12219 #ifndef HAVE_CONIO_H
12220 static int read_a_char(void)
12227 if (e2fsck_global_ctx
&&
12228 (e2fsck_global_ctx
->flags
& E2F_FLAG_CANCEL
)) {
12231 r
= read(0, &c
, 1);
12241 static int ask_yn(const char * string
, int def
)
12244 const char *defstr
;
12245 static const char short_yes
[] = "yY";
12246 static const char short_no
[] = "nN";
12248 #ifdef HAVE_TERMIOS_H
12249 struct termios termios
, tmp
;
12251 tcgetattr (0, &termios
);
12253 tmp
.c_lflag
&= ~(ICANON
| ECHO
);
12254 tmp
.c_cc
[VMIN
] = 1;
12255 tmp
.c_cc
[VTIME
] = 0;
12256 tcsetattr_stdin_TCSANOW(&tmp
);
12265 printf("%s%s? ", string
, defstr
);
12268 if ((c
= read_a_char()) == EOF
)
12271 #ifdef HAVE_TERMIOS_H
12272 tcsetattr_stdin_TCSANOW(&termios
);
12274 if (e2fsck_global_ctx
&&
12275 e2fsck_global_ctx
->flags
& E2F_FLAG_SETJMP_OK
) {
12277 longjmp(e2fsck_global_ctx
->abort_loc
, 1);
12279 puts(_("cancelled!\n"));
12282 if (strchr(short_yes
, (char) c
)) {
12286 else if (strchr(short_no
, (char) c
)) {
12290 else if ((c
== ' ' || c
== '\n') && (def
!= -1))
12297 #ifdef HAVE_TERMIOS_H
12298 tcsetattr_stdin_TCSANOW(&termios
);
12303 int ask (e2fsck_t ctx
, const char * string
, int def
)
12305 if (ctx
->options
& E2F_OPT_NO
) {
12306 printf(_("%s? no\n\n"), string
);
12309 if (ctx
->options
& E2F_OPT_YES
) {
12310 printf(_("%s? yes\n\n"), string
);
12313 if (ctx
->options
& E2F_OPT_PREEN
) {
12314 printf("%s? %s\n\n", string
, def
? _("yes") : _("no"));
12317 return ask_yn(string
, def
);
12320 void e2fsck_read_bitmaps(e2fsck_t ctx
)
12322 ext2_filsys fs
= ctx
->fs
;
12325 if (ctx
->invalid_bitmaps
) {
12326 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12328 bb_error_msg_and_die(0);
12331 ehandler_operation(_("reading inode and block bitmaps"));
12332 retval
= ext2fs_read_bitmaps(fs
);
12333 ehandler_operation(0);
12335 bb_error_msg(_("while retrying to read bitmaps for %s"),
12337 bb_error_msg_and_die(0);
12341 static void e2fsck_write_bitmaps(e2fsck_t ctx
)
12343 ext2_filsys fs
= ctx
->fs
;
12346 if (ext2fs_test_bb_dirty(fs
)) {
12347 ehandler_operation(_("writing block bitmaps"));
12348 retval
= ext2fs_write_block_bitmap(fs
);
12349 ehandler_operation(0);
12351 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12353 bb_error_msg_and_die(0);
12357 if (ext2fs_test_ib_dirty(fs
)) {
12358 ehandler_operation(_("writing inode bitmaps"));
12359 retval
= ext2fs_write_inode_bitmap(fs
);
12360 ehandler_operation(0);
12362 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12364 bb_error_msg_and_die(0);
12369 void preenhalt(e2fsck_t ctx
)
12371 ext2_filsys fs
= ctx
->fs
;
12373 if (!(ctx
->options
& E2F_OPT_PREEN
))
12375 fprintf(stderr
, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12376 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12379 fs
->super
->s_state
|= EXT2_ERROR_FS
;
12380 ext2fs_mark_super_dirty(fs
);
12383 exit(EXIT_UNCORRECTED
);
12386 void e2fsck_read_inode(e2fsck_t ctx
, unsigned long ino
,
12387 struct ext2_inode
* inode
, const char *proc
)
12391 retval
= ext2fs_read_inode(ctx
->fs
, ino
, inode
);
12393 bb_error_msg(_("while reading inode %ld in %s"), ino
, proc
);
12394 bb_error_msg_and_die(0);
12398 extern void e2fsck_write_inode_full(e2fsck_t ctx
, unsigned long ino
,
12399 struct ext2_inode
* inode
, int bufsize
,
12404 retval
= ext2fs_write_inode_full(ctx
->fs
, ino
, inode
, bufsize
);
12406 bb_error_msg(_("while writing inode %ld in %s"), ino
, proc
);
12407 bb_error_msg_and_die(0);
12411 extern void e2fsck_write_inode(e2fsck_t ctx
, unsigned long ino
,
12412 struct ext2_inode
* inode
, const char *proc
)
12416 retval
= ext2fs_write_inode(ctx
->fs
, ino
, inode
);
12418 bb_error_msg(_("while writing inode %ld in %s"), ino
, proc
);
12419 bb_error_msg_and_die(0);
12423 blk_t
get_backup_sb(e2fsck_t ctx
, ext2_filsys fs
, const char *name
,
12424 io_manager manager
)
12426 struct ext2_super_block
*sb
;
12427 io_channel io
= NULL
;
12430 blk_t superblock
, ret_sb
= 8193;
12432 if (fs
&& fs
->super
) {
12433 ret_sb
= (fs
->super
->s_blocks_per_group
+
12434 fs
->super
->s_first_data_block
);
12436 ctx
->superblock
= ret_sb
;
12437 ctx
->blocksize
= fs
->blocksize
;
12443 if (ctx
->blocksize
) {
12444 ret_sb
= ctx
->blocksize
* 8;
12445 if (ctx
->blocksize
== 1024)
12447 ctx
->superblock
= ret_sb
;
12450 ctx
->superblock
= ret_sb
;
12451 ctx
->blocksize
= 1024;
12454 if (!name
|| !manager
)
12457 if (manager
->open(name
, 0, &io
) != 0)
12460 if (ext2fs_get_mem(SUPERBLOCK_SIZE
, &buf
))
12462 sb
= (struct ext2_super_block
*) buf
;
12464 for (blocksize
= EXT2_MIN_BLOCK_SIZE
;
12465 blocksize
<= EXT2_MAX_BLOCK_SIZE
; blocksize
*= 2) {
12466 superblock
= blocksize
*8;
12467 if (blocksize
== 1024)
12469 io_channel_set_blksize(io
, blocksize
);
12470 if (io_channel_read_blk(io
, superblock
,
12471 -SUPERBLOCK_SIZE
, buf
))
12474 if (sb
->s_magic
== ext2fs_swab16(EXT2_SUPER_MAGIC
))
12475 ext2fs_swap_super(sb
);
12477 if (sb
->s_magic
== EXT2_SUPER_MAGIC
) {
12478 ret_sb
= superblock
;
12480 ctx
->superblock
= superblock
;
12481 ctx
->blocksize
= blocksize
;
12489 io_channel_close(io
);
12490 ext2fs_free_mem(&buf
);
12496 * This function runs through the e2fsck passes and calls them all,
12497 * returning restart, abort, or cancel as necessary...
12499 typedef void (*pass_t
)(e2fsck_t ctx
);
12501 static const pass_t e2fsck_passes
[] = {
12502 e2fsck_pass1
, e2fsck_pass2
, e2fsck_pass3
, e2fsck_pass4
,
12505 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12507 static int e2fsck_run(e2fsck_t ctx
)
12510 pass_t e2fsck_pass
;
12512 if (setjmp(ctx
->abort_loc
)) {
12513 ctx
->flags
&= ~E2F_FLAG_SETJMP_OK
;
12514 return (ctx
->flags
& E2F_FLAG_RUN_RETURN
);
12516 ctx
->flags
|= E2F_FLAG_SETJMP_OK
;
12518 for (i
=0; (e2fsck_pass
= e2fsck_passes
[i
]); i
++) {
12519 if (ctx
->flags
& E2F_FLAG_RUN_RETURN
)
12523 (void) (ctx
->progress
)(ctx
, 0, 0, 0);
12525 ctx
->flags
&= ~E2F_FLAG_SETJMP_OK
;
12527 if (ctx
->flags
& E2F_FLAG_RUN_RETURN
)
12528 return (ctx
->flags
& E2F_FLAG_RUN_RETURN
);
12534 * unix.c - The unix-specific code for e2fsck
12538 /* Command line options */
12540 #ifdef ENABLE_SWAPFS
12541 static int normalize_swapfs
;
12543 static int cflag
; /* check disk */
12544 static int show_version_only
;
12545 static int verbose
;
12547 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12549 static void show_stats(e2fsck_t ctx
)
12551 ext2_filsys fs
= ctx
->fs
;
12552 int inodes
, inodes_used
, blocks
, blocks_used
;
12554 int num_files
, num_links
;
12557 dir_links
= 2 * ctx
->fs_directory_count
- 1;
12558 num_files
= ctx
->fs_total_count
- dir_links
;
12559 num_links
= ctx
->fs_links_count
- dir_links
;
12560 inodes
= fs
->super
->s_inodes_count
;
12561 inodes_used
= (fs
->super
->s_inodes_count
-
12562 fs
->super
->s_free_inodes_count
);
12563 blocks
= fs
->super
->s_blocks_count
;
12564 blocks_used
= (fs
->super
->s_blocks_count
-
12565 fs
->super
->s_free_blocks_count
);
12567 frag_percent
= (10000 * ctx
->fs_fragmented
) / inodes_used
;
12568 frag_percent
= (frag_percent
+ 5) / 10;
12571 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12572 ctx
->device_name
, inodes_used
, inodes
,
12573 frag_percent
/ 10, frag_percent
% 10,
12574 blocks_used
, blocks
);
12577 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used
),
12578 100 * inodes_used
/ inodes
);
12579 printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12580 P_E2("", "s", ctx
->fs_fragmented
),
12581 frag_percent
/ 10, frag_percent
% 10);
12582 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12583 ctx
->fs_ind_count
, ctx
->fs_dind_count
, ctx
->fs_tind_count
);
12584 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used
),
12585 (int) ((long long) 100 * blocks_used
/ blocks
));
12586 printf("%8d large file%s\n", P_E2("", "s", ctx
->large_files
));
12587 printf("\n%8d regular file%s\n", P_E2("", "s", ctx
->fs_regular_count
));
12588 printf("%8d director%s\n", P_E2("y", "ies", ctx
->fs_directory_count
));
12589 printf("%8d character device file%s\n", P_E2("", "s", ctx
->fs_chardev_count
));
12590 printf("%8d block device file%s\n", P_E2("", "s", ctx
->fs_blockdev_count
));
12591 printf("%8d fifo%s\n", P_E2("", "s", ctx
->fs_fifo_count
));
12592 printf("%8d link%s\n", P_E2("", "s", ctx
->fs_links_count
- dir_links
));
12593 printf("%8d symbolic link%s", P_E2("", "s", ctx
->fs_symlinks_count
));
12594 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx
->fs_fast_symlinks_count
));
12595 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx
->fs_sockets_count
));
12596 printf("%8d file%s\n", P_E2("", "s", ctx
->fs_total_count
- dir_links
));
12599 static void check_mount(e2fsck_t ctx
)
12604 retval
= ext2fs_check_if_mounted(ctx
->filesystem_name
,
12605 &ctx
->mount_flags
);
12607 bb_error_msg(_("while determining whether %s is mounted"),
12608 ctx
->filesystem_name
);
12613 * If the filesystem isn't mounted, or it's the root filesystem
12614 * and it's mounted read-only, then everything's fine.
12616 if ((!(ctx
->mount_flags
& EXT2_MF_MOUNTED
)) ||
12617 ((ctx
->mount_flags
& EXT2_MF_ISROOT
) &&
12618 (ctx
->mount_flags
& EXT2_MF_READONLY
)))
12621 if (ctx
->options
& E2F_OPT_READONLY
) {
12622 printf(_("Warning! %s is mounted.\n"), ctx
->filesystem_name
);
12626 printf(_("%s is mounted. "), ctx
->filesystem_name
);
12627 if (!ctx
->interactive
)
12628 bb_error_msg_and_die(_("can't continue, aborting"));
12629 printf(_("\n\n\007\007\007\007WARNING!!! "
12630 "Running e2fsck on a mounted filesystem may cause\n"
12631 "SEVERE filesystem damage.\007\007\007\n\n"));
12632 cont
= ask_yn(_("Do you really want to continue"), -1);
12634 printf(_("check aborted.\n"));
12639 static int is_on_batt(void)
12643 char tmp
[80], tmp2
[80], fname
[80];
12644 unsigned int acflag
;
12647 f
= fopen_for_read("/proc/apm");
12649 if (fscanf(f
, "%s %s %s %x", tmp
, tmp
, tmp
, &acflag
) != 4)
12652 return (acflag
!= 1);
12654 d
= opendir("/proc/acpi/ac_adapter");
12656 while ((de
=readdir(d
)) != NULL
) {
12657 if (!strncmp(".", de
->d_name
, 1))
12659 snprintf(fname
, 80, "/proc/acpi/ac_adapter/%s/state",
12661 f
= fopen_for_read(fname
);
12664 if (fscanf(f
, "%s %s", tmp2
, tmp
) != 2)
12667 if (strncmp(tmp
, "off-line", 8) == 0) {
12678 * This routine checks to see if a filesystem can be skipped; if so,
12679 * it will exit with EXIT_OK. Under some conditions it will print a
12680 * message explaining why a check is being forced.
12682 static void check_if_skip(e2fsck_t ctx
)
12684 ext2_filsys fs
= ctx
->fs
;
12685 const char *reason
= NULL
;
12686 unsigned int reason_arg
= 0;
12688 int batt
= is_on_batt();
12689 time_t now
= time(NULL
);
12691 if ((ctx
->options
& E2F_OPT_FORCE
) || cflag
|| swapfs
)
12694 if ((fs
->super
->s_state
& EXT2_ERROR_FS
) ||
12695 !ext2fs_test_valid(fs
))
12696 reason
= _(" contains a file system with errors");
12697 else if ((fs
->super
->s_state
& EXT2_VALID_FS
) == 0)
12698 reason
= _(" was not cleanly unmounted");
12699 else if ((fs
->super
->s_max_mnt_count
> 0) &&
12700 (fs
->super
->s_mnt_count
>=
12701 (unsigned) fs
->super
->s_max_mnt_count
)) {
12702 reason
= _(" has been mounted %u times without being checked");
12703 reason_arg
= fs
->super
->s_mnt_count
;
12704 if (batt
&& (fs
->super
->s_mnt_count
<
12705 (unsigned) fs
->super
->s_max_mnt_count
*2))
12707 } else if (!(ctx
->options
& E2F_OPT_PREEN
) &&
12708 fs
->super
->s_checkinterval
&&
12709 ((now
- fs
->super
->s_lastcheck
) >=
12710 fs
->super
->s_checkinterval
)) {
12711 reason
= _(" has gone %u days without being checked");
12712 reason_arg
= (now
- fs
->super
->s_lastcheck
)/(3600*24);
12713 if (batt
&& ((now
- fs
->super
->s_lastcheck
) <
12714 fs
->super
->s_checkinterval
*2))
12718 fputs(ctx
->device_name
, stdout
);
12719 printf(reason
, reason_arg
);
12720 fputs(_(", check forced.\n"), stdout
);
12723 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx
->device_name
,
12724 fs
->super
->s_inodes_count
- fs
->super
->s_free_inodes_count
,
12725 fs
->super
->s_inodes_count
,
12726 fs
->super
->s_blocks_count
- fs
->super
->s_free_blocks_count
,
12727 fs
->super
->s_blocks_count
);
12728 next_check
= 100000;
12729 if (fs
->super
->s_max_mnt_count
> 0) {
12730 next_check
= fs
->super
->s_max_mnt_count
- fs
->super
->s_mnt_count
;
12731 if (next_check
<= 0)
12734 if (fs
->super
->s_checkinterval
&&
12735 ((now
- fs
->super
->s_lastcheck
) >= fs
->super
->s_checkinterval
))
12737 if (next_check
<= 5) {
12738 if (next_check
== 1)
12739 fputs(_(" (check after next mount)"), stdout
);
12741 printf(_(" (check in %ld mounts)"), next_check
);
12746 e2fsck_free_context(ctx
);
12751 * For completion notice
12753 struct percent_tbl
{
12757 static const struct percent_tbl e2fsck_tbl
= {
12758 5, { 0, 70, 90, 92, 95, 100 }
12761 static char bar
[128], spaces
[128];
12763 static float calc_percent(const struct percent_tbl
*tbl
, int pass
, int curr
,
12770 if (pass
> tbl
->max_pass
|| max
== 0)
12772 percent
= ((float) curr
) / ((float) max
);
12773 return ((percent
* (tbl
->table
[pass
] - tbl
->table
[pass
-1]))
12774 + tbl
->table
[pass
-1]);
12777 void e2fsck_clear_progbar(e2fsck_t ctx
)
12779 if (!(ctx
->flags
& E2F_FLAG_PROG_BAR
))
12782 printf("%s%s\r%s", ctx
->start_meta
, spaces
+ (sizeof(spaces
) - 80),
12785 ctx
->flags
&= ~E2F_FLAG_PROG_BAR
;
12788 int e2fsck_simple_progress(e2fsck_t ctx
, const char *label
, float percent
,
12789 unsigned int dpynum
)
12791 static const char spinner
[] = "\\|/-";
12798 if (ctx
->flags
& E2F_FLAG_PROG_SUPPRESS
)
12802 * Calculate the new progress position. If the
12803 * percentage hasn't changed, then we skip out right
12806 fixed_percent
= (int) ((10 * percent
) + 0.5);
12807 if (ctx
->progress_last_percent
== fixed_percent
)
12809 ctx
->progress_last_percent
= fixed_percent
;
12812 * If we've already updated the spinner once within
12813 * the last 1/8th of a second, no point doing it
12816 gettimeofday(&tv
, NULL
);
12817 tick
= (tv
.tv_sec
<< 3) + (tv
.tv_usec
/ (1000000 / 8));
12818 if ((tick
== ctx
->progress_last_time
) &&
12819 (fixed_percent
!= 0) && (fixed_percent
!= 1000))
12821 ctx
->progress_last_time
= tick
;
12824 * Advance the spinner, and note that the progress bar
12825 * will be on the screen
12827 ctx
->progress_pos
= (ctx
->progress_pos
+1) & 3;
12828 ctx
->flags
|= E2F_FLAG_PROG_BAR
;
12830 dpywidth
= 66 - strlen(label
);
12831 dpywidth
= 8 * (dpywidth
/ 8);
12835 i
= ((percent
* dpywidth
) + 50) / 100;
12836 printf("%s%s: |%s%s", ctx
->start_meta
, label
,
12837 bar
+ (sizeof(bar
) - (i
+1)),
12838 spaces
+ (sizeof(spaces
) - (dpywidth
- i
+ 1)));
12839 if (fixed_percent
== 1000)
12842 bb_putchar(spinner
[ctx
->progress_pos
& 3]);
12843 printf(" %4.1f%% ", percent
);
12845 printf("%u\r", dpynum
);
12847 fputs(" \r", stdout
);
12848 fputs(ctx
->stop_meta
, stdout
);
12850 if (fixed_percent
== 1000)
12851 e2fsck_clear_progbar(ctx
);
12857 static int e2fsck_update_progress(e2fsck_t ctx
, int pass
,
12858 unsigned long cur
, unsigned long max
)
12866 if (ctx
->progress_fd
) {
12867 sprintf(buf
, "%d %lu %lu\n", pass
, cur
, max
);
12868 xwrite_str(ctx
->progress_fd
, buf
);
12870 percent
= calc_percent(&e2fsck_tbl
, pass
, cur
, max
);
12871 e2fsck_simple_progress(ctx
, ctx
->device_name
,
12877 static void reserve_stdio_fds(void)
12882 fd
= open(bb_dev_null
, O_RDWR
);
12886 fprintf(stderr
, _("ERROR: Cannot open "
12887 "/dev/null (%s)\n"),
12895 static void signal_progress_on(int sig
FSCK_ATTR((unused
)))
12897 e2fsck_t ctx
= e2fsck_global_ctx
;
12902 ctx
->progress
= e2fsck_update_progress
;
12903 ctx
->progress_fd
= 0;
12906 static void signal_progress_off(int sig
FSCK_ATTR((unused
)))
12908 e2fsck_t ctx
= e2fsck_global_ctx
;
12913 e2fsck_clear_progbar(ctx
);
12917 static void signal_cancel(int sig
FSCK_ATTR((unused
)))
12919 e2fsck_t ctx
= e2fsck_global_ctx
;
12922 exit(FSCK_CANCELED
);
12924 ctx
->flags
|= E2F_FLAG_CANCEL
;
12927 static void parse_extended_opts(e2fsck_t ctx
, const char *opts
)
12929 char *buf
, *token
, *next
, *p
, *arg
;
12931 int extended_usage
= 0;
12933 buf
= string_copy(opts
, 0);
12934 for (token
= buf
; token
&& *token
; token
= next
) {
12935 p
= strchr(token
, ',');
12941 arg
= strchr(token
, '=');
12946 if (strcmp(token
, "ea_ver") == 0) {
12951 ea_ver
= strtoul(arg
, &p
, 0);
12953 ((ea_ver
!= 1) && (ea_ver
!= 2))) {
12955 _("Invalid EA version.\n"));
12959 ctx
->ext_attr_ver
= ea_ver
;
12961 fprintf(stderr
, _("Unknown extended option: %s\n"),
12966 if (extended_usage
) {
12967 bb_error_msg_and_die(
12968 "Extended options are separated by commas, "
12969 "and may take an argument which\n"
12970 "is set off by an equals ('=') sign. "
12971 "Valid extended options are:\n"
12972 "\tea_ver=<ea_version (1 or 2)>\n\n");
12977 static errcode_t
PRS(int argc
, char **argv
, e2fsck_t
*ret_ctx
)
12983 struct sigaction sa
;
12984 char *extended_opts
= NULL
;
12986 retval
= e2fsck_allocate_context(&ctx
);
12992 setvbuf(stdout
, NULL
, _IONBF
, BUFSIZ
);
12993 setvbuf(stderr
, NULL
, _IONBF
, BUFSIZ
);
12994 if (isatty(0) && isatty(1)) {
12995 ctx
->interactive
= 1;
12997 ctx
->start_meta
[0] = '\001';
12998 ctx
->stop_meta
[0] = '\002';
13000 memset(bar
, '=', sizeof(bar
)-1);
13001 memset(spaces
, ' ', sizeof(spaces
)-1);
13004 ctx
->program_name
= *argv
;
13006 ctx
->program_name
= "e2fsck";
13007 while ((c
= getopt (argc
, argv
, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF
)
13010 ctx
->progress
= e2fsck_update_progress
;
13011 ctx
->progress_fd
= atoi(optarg
);
13012 if (!ctx
->progress_fd
)
13014 /* Validate the file descriptor to avoid disasters */
13015 fd
= dup(ctx
->progress_fd
);
13018 _("Error validating file descriptor %d: %s\n"),
13020 error_message(errno
));
13021 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13026 ctx
->options
|= E2F_OPT_COMPRESS_DIRS
;
13029 extended_opts
= optarg
;
13033 if (ctx
->options
& (E2F_OPT_YES
|E2F_OPT_NO
)) {
13035 bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
13037 ctx
->options
|= E2F_OPT_PREEN
;
13040 if (ctx
->options
& (E2F_OPT_YES
|E2F_OPT_PREEN
))
13042 ctx
->options
|= E2F_OPT_NO
;
13045 if (ctx
->options
& (E2F_OPT_PREEN
|E2F_OPT_NO
))
13047 ctx
->options
|= E2F_OPT_YES
;
13050 /* FIXME - This needs to go away in a future path - will change binary */
13051 fprintf(stderr
, _("The -t option is not "
13052 "supported on this version of e2fsck.\n"));
13056 ctx
->options
|= E2F_OPT_WRITECHECK
;
13057 ctx
->options
|= E2F_OPT_CHECKBLOCKS
;
13060 /* What we do by default, anyway! */
13063 ctx
->use_superblock
= atoi(optarg
);
13064 ctx
->flags
|= E2F_FLAG_SB_SPECIFIED
;
13067 ctx
->blocksize
= atoi(optarg
);
13070 ctx
->inode_buffer_blocks
= atoi(optarg
);
13073 ctx
->journal_name
= string_copy(optarg
, 0);
13076 ctx
->process_inode_size
= atoi(optarg
);
13079 ctx
->options
|= E2F_OPT_DEBUG
;
13082 ctx
->options
|= E2F_OPT_FORCE
;
13091 show_version_only
= 1;
13094 ctx
->device_name
= optarg
;
13096 #ifdef ENABLE_SWAPFS
13098 normalize_swapfs
= 1;
13105 fprintf(stderr
, _("Byte-swapping filesystems "
13106 "not compiled in this version "
13113 if (show_version_only
)
13115 if (optind
!= argc
- 1)
13117 if ((ctx
->options
& E2F_OPT_NO
) &&
13118 !cflag
&& !swapfs
&& !(ctx
->options
& E2F_OPT_COMPRESS_DIRS
))
13119 ctx
->options
|= E2F_OPT_READONLY
;
13120 ctx
->io_options
= strchr(argv
[optind
], '?');
13121 if (ctx
->io_options
)
13122 *ctx
->io_options
++ = 0;
13123 ctx
->filesystem_name
= argv
[optind
];
13124 if (resolve_mount_spec(&ctx
->filesystem_name
) < 0 ||
13125 !ctx
->filesystem_name
) {
13126 bb_error_msg(_("Unable to resolve '%s'"), argv
[optind
]);
13127 bb_error_msg_and_die(0);
13130 parse_extended_opts(ctx
, extended_opts
);
13133 fd
= open(ctx
->filesystem_name
, O_RDONLY
, 0);
13135 bb_error_msg(_("while opening %s for flushing"),
13136 ctx
->filesystem_name
);
13137 bb_error_msg_and_die(0);
13139 if ((retval
= ext2fs_sync_device(fd
, 1))) {
13140 bb_error_msg(_("while trying to flush %s"),
13141 ctx
->filesystem_name
);
13142 bb_error_msg_and_die(0);
13146 #ifdef ENABLE_SWAPFS
13147 if (swapfs
&& cflag
) {
13148 fprintf(stderr
, _("Incompatible options not "
13149 "allowed when byte-swapping.\n"));
13154 * Set up signal action
13156 memset(&sa
, 0, sizeof(struct sigaction
));
13157 sa
.sa_handler
= signal_cancel
;
13158 sigaction(SIGINT
, &sa
, 0);
13159 sigaction(SIGTERM
, &sa
, 0);
13161 sa
.sa_flags
= SA_RESTART
;
13163 e2fsck_global_ctx
= ctx
;
13164 sa
.sa_handler
= signal_progress_on
;
13165 sigaction(SIGUSR1
, &sa
, 0);
13166 sa
.sa_handler
= signal_progress_off
;
13167 sigaction(SIGUSR2
, &sa
, 0);
13169 /* Update our PATH to include /sbin if we need to run badblocks */
13171 e2fs_set_sbin_path();
13175 static const char my_ver_string
[] = E2FSPROGS_VERSION
;
13176 static const char my_ver_date
[] = E2FSPROGS_DATE
;
13178 int e2fsck_main (int argc
, char **argv
);
13179 int e2fsck_main (int argc
, char **argv
)
13182 int exit_value
= EXIT_OK
;
13183 ext2_filsys fs
= 0;
13185 struct ext2_super_block
*sb
;
13186 const char *lib_ver_date
;
13187 int my_ver
, lib_ver
;
13189 struct problem_context pctx
;
13190 int flags
, run_result
;
13192 clear_problem_context(&pctx
);
13194 my_ver
= ext2fs_parse_version_string(my_ver_string
);
13195 lib_ver
= ext2fs_get_library_version(0, &lib_ver_date
);
13196 if (my_ver
> lib_ver
) {
13197 fprintf( stderr
, _("Error: ext2fs library version "
13198 "out of date!\n"));
13199 show_version_only
++;
13202 retval
= PRS(argc
, argv
, &ctx
);
13204 bb_error_msg(_("while trying to initialize program"));
13207 reserve_stdio_fds();
13209 if (!(ctx
->options
& E2F_OPT_PREEN
) || show_version_only
)
13210 fprintf(stderr
, "e2fsck %s (%s)\n", my_ver_string
,
13213 if (show_version_only
) {
13214 fprintf(stderr
, _("\tUsing %s, %s\n"),
13215 error_message(EXT2_ET_BASE
), lib_ver_date
);
13221 if (!(ctx
->options
& E2F_OPT_PREEN
) &&
13222 !(ctx
->options
& E2F_OPT_NO
) &&
13223 !(ctx
->options
& E2F_OPT_YES
)) {
13224 if (!ctx
->interactive
)
13225 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13227 ctx
->superblock
= ctx
->use_superblock
;
13229 #ifdef CONFIG_TESTIO_DEBUG
13230 io_ptr
= test_io_manager
;
13231 test_io_backing_manager
= unix_io_manager
;
13233 io_ptr
= unix_io_manager
;
13236 if ((ctx
->options
& E2F_OPT_READONLY
) == 0)
13237 flags
|= EXT2_FLAG_RW
;
13239 if (ctx
->superblock
&& ctx
->blocksize
) {
13240 retval
= ext2fs_open2(ctx
->filesystem_name
, ctx
->io_options
,
13241 flags
, ctx
->superblock
, ctx
->blocksize
,
13243 } else if (ctx
->superblock
) {
13245 for (blocksize
= EXT2_MIN_BLOCK_SIZE
;
13246 blocksize
<= EXT2_MAX_BLOCK_SIZE
; blocksize
*= 2) {
13247 retval
= ext2fs_open2(ctx
->filesystem_name
,
13248 ctx
->io_options
, flags
,
13249 ctx
->superblock
, blocksize
,
13255 retval
= ext2fs_open2(ctx
->filesystem_name
, ctx
->io_options
,
13256 flags
, 0, 0, io_ptr
, &fs
);
13257 if (!ctx
->superblock
&& !(ctx
->options
& E2F_OPT_PREEN
) &&
13258 !(ctx
->flags
& E2F_FLAG_SB_SPECIFIED
) &&
13259 ((retval
== EXT2_ET_BAD_MAGIC
) ||
13260 ((retval
== 0) && ext2fs_check_desc(fs
)))) {
13261 if (!fs
|| (fs
->group_desc_count
> 1)) {
13262 printf(_("%s trying backup blocks...\n"),
13263 retval
? _("Couldn't find ext2 superblock,") :
13264 _("Group descriptors look bad..."));
13265 get_backup_sb(ctx
, fs
, ctx
->filesystem_name
, io_ptr
);
13272 bb_error_msg(_("while trying to open %s"),
13273 ctx
->filesystem_name
);
13274 if (retval
== EXT2_ET_REV_TOO_HIGH
) {
13275 printf(_("The filesystem revision is apparently "
13276 "too high for this version of e2fsck.\n"
13277 "(Or the filesystem superblock "
13278 "is corrupt)\n\n"));
13279 fix_problem(ctx
, PR_0_SB_CORRUPT
, &pctx
);
13280 } else if (retval
== EXT2_ET_SHORT_READ
)
13281 printf(_("Could this be a zero-length partition?\n"));
13282 else if ((retval
== EPERM
) || (retval
== EACCES
))
13283 printf(_("You must have %s access to the "
13284 "filesystem or be root\n"),
13285 (ctx
->options
& E2F_OPT_READONLY
) ?
13287 else if (retval
== ENXIO
)
13288 printf(_("Possibly non-existent or swap device?\n"));
13290 else if (retval
== EROFS
)
13291 printf(_("Disk write-protected; use the -n option "
13292 "to do a read-only\n"
13293 "check of the device.\n"));
13296 fix_problem(ctx
, PR_0_SB_CORRUPT
, &pctx
);
13297 bb_error_msg_and_die(0);
13300 fs
->priv_data
= ctx
;
13302 if (sb
->s_rev_level
> E2FSCK_CURRENT_REV
) {
13303 bb_error_msg(_("while trying to open %s"),
13304 ctx
->filesystem_name
);
13306 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13310 * Set the device name, which is used whenever we print error
13311 * or informational messages to the user.
13313 if (ctx
->device_name
== 0 &&
13314 (sb
->s_volume_name
[0] != 0)) {
13315 ctx
->device_name
= string_copy(sb
->s_volume_name
,
13316 sizeof(sb
->s_volume_name
));
13318 if (ctx
->device_name
== 0)
13319 ctx
->device_name
= ctx
->filesystem_name
;
13322 * Make sure the ext3 superblock fields are consistent.
13324 retval
= e2fsck_check_ext3_journal(ctx
);
13326 bb_error_msg(_("while checking ext3 journal for %s"),
13328 bb_error_msg_and_die(0);
13332 * Check to see if we need to do ext3-style recovery. If so,
13333 * do it, and then restart the fsck.
13335 if (sb
->s_feature_incompat
& EXT3_FEATURE_INCOMPAT_RECOVER
) {
13336 if (ctx
->options
& E2F_OPT_READONLY
) {
13337 printf(_("Warning: skipping journal recovery "
13338 "because doing a read-only filesystem "
13340 io_channel_flush(ctx
->fs
->io
);
13342 if (ctx
->flags
& E2F_FLAG_RESTARTED
) {
13344 * Whoops, we attempted to run the
13345 * journal twice. This should never
13346 * happen, unless the hardware or
13347 * device driver is being bogus.
13349 bb_error_msg(_("can't set superblock flags on %s"), ctx
->device_name
);
13350 bb_error_msg_and_die(0);
13352 retval
= e2fsck_run_ext3_journal(ctx
);
13354 bb_error_msg(_("while recovering ext3 journal of %s"),
13356 bb_error_msg_and_die(0);
13358 ext2fs_close(ctx
->fs
);
13360 ctx
->flags
|= E2F_FLAG_RESTARTED
;
13366 * Check for compatibility with the feature sets. We need to
13367 * be more stringent than ext2fs_open().
13369 if ((sb
->s_feature_compat
& ~EXT2_LIB_FEATURE_COMPAT_SUPP
) ||
13370 (sb
->s_feature_incompat
& ~EXT2_LIB_FEATURE_INCOMPAT_SUPP
)) {
13371 bb_error_msg("(%s)", ctx
->device_name
);
13374 if (sb
->s_feature_ro_compat
& ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP
) {
13375 bb_error_msg("(%s)", ctx
->device_name
);
13378 #ifdef ENABLE_COMPRESSION
13379 /* FIXME - do we support this at all? */
13380 if (sb
->s_feature_incompat
& EXT2_FEATURE_INCOMPAT_COMPRESSION
)
13381 bb_error_msg(_("warning: compression support is experimental"));
13383 #ifndef ENABLE_HTREE
13384 if (sb
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
) {
13385 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13386 "but filesystem %s has HTREE directories."),
13393 * If the user specified a specific superblock, presumably the
13394 * master superblock has been trashed. So we mark the
13395 * superblock as dirty, so it can be written out.
13397 if (ctx
->superblock
&&
13398 !(ctx
->options
& E2F_OPT_READONLY
))
13399 ext2fs_mark_super_dirty(fs
);
13402 * We only update the master superblock because (a) paranoia;
13403 * we don't want to corrupt the backup superblocks, and (b) we
13404 * don't need to update the mount count and last checked
13405 * fields in the backup superblock (the kernel doesn't
13406 * update the backup superblocks anyway).
13408 fs
->flags
|= EXT2_FLAG_MASTER_SB_ONLY
;
13410 ehandler_init(fs
->io
);
13412 if (ctx
->superblock
)
13413 set_latch_flags(PR_LATCH_RELOC
, PRL_LATCHED
, 0);
13414 ext2fs_mark_valid(fs
);
13415 check_super_block(ctx
);
13416 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
13417 bb_error_msg_and_die(0);
13418 check_if_skip(ctx
);
13419 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
13420 bb_error_msg_and_die(0);
13421 #ifdef ENABLE_SWAPFS
13423 #ifdef WORDS_BIGENDIAN
13424 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13426 #define NATIVE_FLAG 0
13430 if (normalize_swapfs
) {
13431 if ((fs
->flags
& EXT2_FLAG_SWAP_BYTES
) == NATIVE_FLAG
) {
13432 fprintf(stderr
, _("%s: Filesystem byte order "
13433 "already normalized.\n"), ctx
->device_name
);
13434 bb_error_msg_and_die(0);
13439 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
13440 bb_error_msg_and_die(0);
13445 * Mark the system as valid, 'til proven otherwise
13447 ext2fs_mark_valid(fs
);
13449 retval
= ext2fs_read_bb_inode(fs
, &fs
->badblocks
);
13451 bb_error_msg(_("while reading bad blocks inode"));
13453 printf(_("This doesn't bode well,"
13454 " but we'll try to go on...\n"));
13457 run_result
= e2fsck_run(ctx
);
13458 e2fsck_clear_progbar(ctx
);
13459 if (run_result
== E2F_FLAG_RESTART
) {
13460 printf(_("Restarting e2fsck from the beginning...\n"));
13461 retval
= e2fsck_reset_context(ctx
);
13463 bb_error_msg(_("while resetting context"));
13464 bb_error_msg_and_die(0);
13469 if (run_result
& E2F_FLAG_CANCEL
) {
13470 printf(_("%s: e2fsck canceled.\n"), ctx
->device_name
?
13471 ctx
->device_name
: ctx
->filesystem_name
);
13472 exit_value
|= FSCK_CANCELED
;
13474 if (run_result
& E2F_FLAG_ABORT
)
13475 bb_error_msg_and_die(_("aborted"));
13478 if (ext2fs_test_changed(fs
)) {
13479 exit_value
|= EXIT_NONDESTRUCT
;
13480 if (!(ctx
->options
& E2F_OPT_PREEN
))
13481 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13483 if (ctx
->mount_flags
& EXT2_MF_ISROOT
) {
13484 printf(_("%s: ***** REBOOT LINUX *****\n"),
13486 exit_value
|= EXIT_DESTRUCT
;
13489 if (!ext2fs_test_valid(fs
)) {
13490 printf(_("\n%s: ********** WARNING: Filesystem still has "
13491 "errors **********\n\n"), ctx
->device_name
);
13492 exit_value
|= EXIT_UNCORRECTED
;
13493 exit_value
&= ~EXIT_NONDESTRUCT
;
13495 if (exit_value
& FSCK_CANCELED
)
13496 exit_value
&= ~EXIT_NONDESTRUCT
;
13499 if (!(ctx
->options
& E2F_OPT_READONLY
)) {
13500 if (ext2fs_test_valid(fs
)) {
13501 if (!(sb
->s_state
& EXT2_VALID_FS
))
13502 exit_value
|= EXIT_NONDESTRUCT
;
13503 sb
->s_state
= EXT2_VALID_FS
;
13505 sb
->s_state
&= ~EXT2_VALID_FS
;
13506 sb
->s_mnt_count
= 0;
13507 sb
->s_lastcheck
= time(NULL
);
13508 ext2fs_mark_super_dirty(fs
);
13512 e2fsck_write_bitmaps(ctx
);
13516 free(ctx
->filesystem_name
);
13517 free(ctx
->journal_name
);
13518 e2fsck_free_context(ctx
);