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"
38 //usage:#define e2fsck_full_usage "\n\n"
39 //usage: "Check ext2/ext3 file system\n"
41 //usage: "\n -p Automatic repair (no questions)"
42 //usage: "\n -n Make no changes to the filesystem"
43 //usage: "\n -y Assume 'yes' to all questions"
44 //usage: "\n -c Check for bad blocks and add them to the badblock list"
45 //usage: "\n -f Force checking even if filesystem is marked clean"
46 //usage: "\n -v Verbose"
47 //usage: "\n -b superblock Use alternative superblock"
48 //usage: "\n -B blocksize Force blocksize when looking for superblock"
49 //usage: "\n -j journal Set location of the external journal"
50 //usage: "\n -l file Add to badblocks list"
51 //usage: "\n -L file Set badblocks list"
53 //applet:IF_E2FSCK(APPLET(e2fsck, _BB_DIR_SBIN, _BB_SUID_DROP))
54 //applet:IF_E2FSCK(APPLET_ODDNAME(fsck.ext2, e2fsck, _BB_DIR_SBIN, _BB_SUID_DROP, e2fsck))
55 //applet:IF_E2FSCK(APPLET_ODDNAME(fsck.ext3, e2fsck, _BB_DIR_SBIN, _BB_SUID_DROP, e2fsck))
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
);
356 * Verify that the tree contains the given node. This is done by
357 * traversing all of the nodes and comparing their pointers to the
358 * given pointer. Returns 1 if the node is found, otherwise
359 * returns zero. It is intended for debugging purposes.
362 static int verify_dict_has_node(dnode_t
*nil
, dnode_t
*root
, dnode_t
*node
)
366 || verify_dict_has_node(nil
, root
->left
, node
)
367 || verify_dict_has_node(nil
, root
->right
, node
);
374 * Select a different set of node allocator routines.
377 static void dict_set_allocator(dict_t
*dict
, dnode_free_t fr
)
379 assert(dict_count(dict
) == 0);
380 dict
->dict_freenode
= fr
;
384 * Free all the nodes in the dictionary by using the dictionary's
385 * installed free routine. The dictionary is emptied.
388 static void dict_free_nodes(dict_t
*dict
)
390 dnode_t
*nil
= dict_nil(dict
), *root
= dict_root(dict
);
391 free_nodes(dict
, root
, nil
);
392 dict
->dict_nodecount
= 0;
393 dict
->nilnode
.left
= &dict
->nilnode
;
394 dict
->nilnode
.right
= &dict
->nilnode
;
398 * Initialize a user-supplied dictionary object.
401 static dict_t
*dict_init(dict_t
*dict
, dictcount_t maxcount
, dict_comp_t comp
)
403 dict
->compare
= comp
;
404 dict
->dict_freenode
= dnode_free
;
405 dict
->dict_nodecount
= 0;
406 dict
->maxcount
= maxcount
;
407 dict
->nilnode
.left
= &dict
->nilnode
;
408 dict
->nilnode
.right
= &dict
->nilnode
;
409 dict
->nilnode
.parent
= &dict
->nilnode
;
410 dict
->nilnode
.color
= dnode_black
;
416 * Locate a node in the dictionary having the given key.
417 * If the node is not found, a null a pointer is returned (rather than
418 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
419 * located node is returned.
422 static dnode_t
*dict_lookup(dict_t
*dict
, const void *key
)
424 dnode_t
*root
= dict_root(dict
);
425 dnode_t
*nil
= dict_nil(dict
);
429 /* simple binary search adapted for trees that contain duplicate keys */
431 while (root
!= nil
) {
432 result
= dict
->compare(key
, root
->key
);
438 if (!dict
->dupes
) { /* no duplicates, return match */
440 } else { /* could be dupes, find leftmost one */
444 while (root
!= nil
&& dict
->compare(key
, root
->key
))
446 } while (root
!= nil
);
456 * Insert a node into the dictionary. The node should have been
457 * initialized with a data field. All other fields are ignored.
458 * The behavior is undefined if the user attempts to insert into
459 * a dictionary that is already full (for which the dict_isfull()
460 * function returns true).
463 static void dict_insert(dict_t
*dict
, dnode_t
*node
, const void *key
)
465 dnode_t
*where
= dict_root(dict
), *nil
= dict_nil(dict
);
466 dnode_t
*parent
= nil
, *uncle
, *grandpa
;
471 /* basic binary tree insert */
473 while (where
!= nil
) {
475 result
= dict
->compare(key
, where
->key
);
476 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
477 assert(dict
->dupes
|| result
!= 0);
481 where
= where
->right
;
484 assert(where
== nil
);
489 parent
->right
= node
;
491 node
->parent
= parent
;
495 dict
->dict_nodecount
++;
497 /* red black adjustments */
499 node
->color
= dnode_red
;
501 while (parent
->color
== dnode_red
) {
502 grandpa
= parent
->parent
;
503 if (parent
== grandpa
->left
) {
504 uncle
= grandpa
->right
;
505 if (uncle
->color
== dnode_red
) { /* red parent, red uncle */
506 parent
->color
= dnode_black
;
507 uncle
->color
= dnode_black
;
508 grandpa
->color
= dnode_red
;
510 parent
= grandpa
->parent
;
511 } else { /* red parent, black uncle */
512 if (node
== parent
->right
) {
515 assert (grandpa
== parent
->parent
);
516 /* rotation between parent and child preserves grandpa */
518 parent
->color
= dnode_black
;
519 grandpa
->color
= dnode_red
;
520 rotate_right(grandpa
);
523 } else { /* symmetric cases: parent == parent->parent->right */
524 uncle
= grandpa
->left
;
525 if (uncle
->color
== dnode_red
) {
526 parent
->color
= dnode_black
;
527 uncle
->color
= dnode_black
;
528 grandpa
->color
= dnode_red
;
530 parent
= grandpa
->parent
;
532 if (node
== parent
->left
) {
533 rotate_right(parent
);
535 assert (grandpa
== parent
->parent
);
537 parent
->color
= dnode_black
;
538 grandpa
->color
= dnode_red
;
539 rotate_left(grandpa
);
545 dict_root(dict
)->color
= dnode_black
;
549 * Allocate a node using the dictionary's allocator routine, give it
553 static dnode_t
*dnode_init(dnode_t
*dnode
, void *data
)
556 dnode
->parent
= NULL
;
562 static int dict_alloc_insert(dict_t
*dict
, const void *key
, void *data
)
564 dnode_t
*node
= xmalloc(sizeof(dnode_t
));
566 dnode_init(node
, data
);
567 dict_insert(dict
, node
, key
);
572 * Return the node with the lowest (leftmost) key. If the dictionary is empty
573 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
576 static dnode_t
*dict_first(dict_t
*dict
)
578 dnode_t
*nil
= dict_nil(dict
), *root
= dict_root(dict
), *left
;
581 while ((left
= root
->left
) != nil
)
584 return (root
== nil
) ? NULL
: root
;
588 * Return the given node's successor node---the node which has the
589 * next key in the the left to right ordering. If the node has
590 * no successor, a null pointer is returned rather than a pointer to
594 static dnode_t
*dict_next(dict_t
*dict
, dnode_t
*curr
)
596 dnode_t
*nil
= dict_nil(dict
), *parent
, *left
;
598 if (curr
->right
!= nil
) {
600 while ((left
= curr
->left
) != nil
)
605 parent
= curr
->parent
;
607 while (parent
!= nil
&& curr
== parent
->right
) {
609 parent
= curr
->parent
;
612 return (parent
== nil
) ? NULL
: parent
;
616 static void dnode_free(dnode_t
*node
)
636 * dirinfo.c --- maintains the directory information table for e2fsck.
640 * This subroutine is called during pass1 to create a directory info
641 * entry. During pass1, the passed-in parent is 0; it will get filled
644 static void e2fsck_add_dir_info(e2fsck_t ctx
, ext2_ino_t ino
, ext2_ino_t parent
)
646 struct dir_info
*dir
;
650 unsigned long old_size
;
652 if (!ctx
->dir_info
) {
653 ctx
->dir_info_count
= 0;
654 retval
= ext2fs_get_num_dirs(ctx
->fs
, &num_dirs
);
656 num_dirs
= 1024; /* Guess */
657 ctx
->dir_info_size
= num_dirs
+ 10;
658 ctx
->dir_info
= (struct dir_info
*)
659 e2fsck_allocate_memory(ctx
, ctx
->dir_info_size
660 * sizeof (struct dir_info
),
664 if (ctx
->dir_info_count
>= ctx
->dir_info_size
) {
665 old_size
= ctx
->dir_info_size
* sizeof(struct dir_info
);
666 ctx
->dir_info_size
+= 10;
667 retval
= ext2fs_resize_mem(old_size
, ctx
->dir_info_size
*
668 sizeof(struct dir_info
),
671 ctx
->dir_info_size
-= 10;
677 * Normally, add_dir_info is called with each inode in
678 * sequential order; but once in a while (like when pass 3
679 * needs to recreate the root directory or lost+found
680 * directory) it is called out of order. In those cases, we
681 * need to move the dir_info entries down to make room, since
682 * the dir_info array needs to be sorted by inode number for
683 * get_dir_info()'s sake.
685 if (ctx
->dir_info_count
&&
686 ctx
->dir_info
[ctx
->dir_info_count
-1].ino
>= ino
) {
687 for (i
= ctx
->dir_info_count
-1; i
> 0; i
--)
688 if (ctx
->dir_info
[i
-1].ino
< ino
)
690 dir
= &ctx
->dir_info
[i
];
692 for (j
= ctx
->dir_info_count
++; j
> i
; j
--)
693 ctx
->dir_info
[j
] = ctx
->dir_info
[j
-1];
695 dir
= &ctx
->dir_info
[ctx
->dir_info_count
++];
698 dir
->dotdot
= parent
;
699 dir
->parent
= parent
;
703 * get_dir_info() --- given an inode number, try to find the directory
704 * information entry for it.
706 static struct dir_info
*e2fsck_get_dir_info(e2fsck_t ctx
, ext2_ino_t ino
)
711 high
= ctx
->dir_info_count
-1;
714 if (ino
== ctx
->dir_info
[low
].ino
)
715 return &ctx
->dir_info
[low
];
716 if (ino
== ctx
->dir_info
[high
].ino
)
717 return &ctx
->dir_info
[high
];
721 if (mid
== low
|| mid
== high
)
723 if (ino
== ctx
->dir_info
[mid
].ino
)
724 return &ctx
->dir_info
[mid
];
725 if (ino
< ctx
->dir_info
[mid
].ino
)
734 * Free the dir_info structure when it isn't needed any more.
736 static void e2fsck_free_dir_info(e2fsck_t ctx
)
738 ext2fs_free_mem(&ctx
->dir_info
);
739 ctx
->dir_info_size
= 0;
740 ctx
->dir_info_count
= 0;
744 * Return the count of number of directories in the dir_info structure
746 static int e2fsck_get_num_dirinfo(e2fsck_t ctx
)
748 return ctx
->dir_info_count
;
752 * A simple interator function
754 static struct dir_info
*e2fsck_dir_info_iter(e2fsck_t ctx
, int *control
)
756 if (*control
>= ctx
->dir_info_count
)
759 return ctx
->dir_info
+ (*control
)++;
763 * dirinfo.c --- maintains the directory information table for e2fsck.
770 * This subroutine is called during pass1 to create a directory info
771 * entry. During pass1, the passed-in parent is 0; it will get filled
774 static void e2fsck_add_dx_dir(e2fsck_t ctx
, ext2_ino_t ino
, int num_blocks
)
776 struct dx_dir_info
*dir
;
779 unsigned long old_size
;
781 if (!ctx
->dx_dir_info
) {
782 ctx
->dx_dir_info_count
= 0;
783 ctx
->dx_dir_info_size
= 100; /* Guess */
784 ctx
->dx_dir_info
= (struct dx_dir_info
*)
785 e2fsck_allocate_memory(ctx
, ctx
->dx_dir_info_size
786 * sizeof (struct dx_dir_info
),
790 if (ctx
->dx_dir_info_count
>= ctx
->dx_dir_info_size
) {
791 old_size
= ctx
->dx_dir_info_size
* sizeof(struct dx_dir_info
);
792 ctx
->dx_dir_info_size
+= 10;
793 retval
= ext2fs_resize_mem(old_size
, ctx
->dx_dir_info_size
*
794 sizeof(struct dx_dir_info
),
797 ctx
->dx_dir_info_size
-= 10;
803 * Normally, add_dx_dir_info is called with each inode in
804 * sequential order; but once in a while (like when pass 3
805 * needs to recreate the root directory or lost+found
806 * directory) it is called out of order. In those cases, we
807 * need to move the dx_dir_info entries down to make room, since
808 * the dx_dir_info array needs to be sorted by inode number for
809 * get_dx_dir_info()'s sake.
811 if (ctx
->dx_dir_info_count
&&
812 ctx
->dx_dir_info
[ctx
->dx_dir_info_count
-1].ino
>= ino
) {
813 for (i
= ctx
->dx_dir_info_count
-1; i
> 0; i
--)
814 if (ctx
->dx_dir_info
[i
-1].ino
< ino
)
816 dir
= &ctx
->dx_dir_info
[i
];
818 for (j
= ctx
->dx_dir_info_count
++; j
> i
; j
--)
819 ctx
->dx_dir_info
[j
] = ctx
->dx_dir_info
[j
-1];
821 dir
= &ctx
->dx_dir_info
[ctx
->dx_dir_info_count
++];
824 dir
->numblocks
= num_blocks
;
825 dir
->hashversion
= 0;
826 dir
->dx_block
= e2fsck_allocate_memory(ctx
, num_blocks
827 * sizeof (struct dx_dirblock_info
),
828 "dx_block info array");
832 * get_dx_dir_info() --- given an inode number, try to find the directory
833 * information entry for it.
835 static struct dx_dir_info
*e2fsck_get_dx_dir_info(e2fsck_t ctx
, ext2_ino_t ino
)
840 high
= ctx
->dx_dir_info_count
-1;
841 if (!ctx
->dx_dir_info
)
843 if (ino
== ctx
->dx_dir_info
[low
].ino
)
844 return &ctx
->dx_dir_info
[low
];
845 if (ino
== ctx
->dx_dir_info
[high
].ino
)
846 return &ctx
->dx_dir_info
[high
];
850 if (mid
== low
|| mid
== high
)
852 if (ino
== ctx
->dx_dir_info
[mid
].ino
)
853 return &ctx
->dx_dir_info
[mid
];
854 if (ino
< ctx
->dx_dir_info
[mid
].ino
)
863 * Free the dx_dir_info structure when it isn't needed any more.
865 static void e2fsck_free_dx_dir_info(e2fsck_t ctx
)
868 struct dx_dir_info
*dir
;
870 if (ctx
->dx_dir_info
) {
871 dir
= ctx
->dx_dir_info
;
872 for (i
=0; i
< ctx
->dx_dir_info_count
; i
++) {
873 ext2fs_free_mem(&dir
->dx_block
);
875 ext2fs_free_mem(&ctx
->dx_dir_info
);
877 ctx
->dx_dir_info_size
= 0;
878 ctx
->dx_dir_info_count
= 0;
882 * A simple interator function
884 static struct dx_dir_info
*e2fsck_dx_dir_info_iter(e2fsck_t ctx
, int *control
)
886 if (*control
>= ctx
->dx_dir_info_count
)
889 return ctx
->dx_dir_info
+ (*control
)++;
892 #endif /* ENABLE_HTREE */
894 * e2fsck.c - a consistency checker for the new extended file system.
899 * This function allocates an e2fsck context
901 static errcode_t
e2fsck_allocate_context(e2fsck_t
*ret
)
906 retval
= ext2fs_get_mem(sizeof(struct e2fsck_struct
), &context
);
910 memset(context
, 0, sizeof(struct e2fsck_struct
));
912 context
->process_inode_size
= 256;
913 context
->ext_attr_ver
= 2;
919 struct ea_refcount_el
{
928 struct ea_refcount_el
*list
;
931 static void ea_refcount_free(ext2_refcount_t refcount
)
936 ext2fs_free_mem(&refcount
->list
);
937 ext2fs_free_mem(&refcount
);
941 * This function resets an e2fsck context; it is called when e2fsck
942 * needs to be restarted.
944 static errcode_t
e2fsck_reset_context(e2fsck_t ctx
)
947 ctx
->lost_and_found
= 0;
948 ctx
->bad_lost_and_found
= 0;
949 ext2fs_free_inode_bitmap(ctx
->inode_used_map
);
950 ctx
->inode_used_map
= 0;
951 ext2fs_free_inode_bitmap(ctx
->inode_dir_map
);
952 ctx
->inode_dir_map
= 0;
953 ext2fs_free_inode_bitmap(ctx
->inode_reg_map
);
954 ctx
->inode_reg_map
= 0;
955 ext2fs_free_block_bitmap(ctx
->block_found_map
);
956 ctx
->block_found_map
= 0;
957 ext2fs_free_icount(ctx
->inode_link_info
);
958 ctx
->inode_link_info
= 0;
959 if (ctx
->journal_io
) {
960 if (ctx
->fs
&& ctx
->fs
->io
!= ctx
->journal_io
)
961 io_channel_close(ctx
->journal_io
);
965 ext2fs_free_dblist(ctx
->fs
->dblist
);
968 e2fsck_free_dir_info(ctx
);
970 e2fsck_free_dx_dir_info(ctx
);
972 ea_refcount_free(ctx
->refcount
);
974 ea_refcount_free(ctx
->refcount_extra
);
975 ctx
->refcount_extra
= 0;
976 ext2fs_free_block_bitmap(ctx
->block_dup_map
);
977 ctx
->block_dup_map
= 0;
978 ext2fs_free_block_bitmap(ctx
->block_ea_map
);
979 ctx
->block_ea_map
= 0;
980 ext2fs_free_inode_bitmap(ctx
->inode_bad_map
);
981 ctx
->inode_bad_map
= 0;
982 ext2fs_free_inode_bitmap(ctx
->inode_imagic_map
);
983 ctx
->inode_imagic_map
= 0;
984 ext2fs_u32_list_free(ctx
->dirs_to_hash
);
985 ctx
->dirs_to_hash
= 0;
988 * Clear the array of invalid meta-data flags
990 ext2fs_free_mem(&ctx
->invalid_inode_bitmap_flag
);
991 ext2fs_free_mem(&ctx
->invalid_block_bitmap_flag
);
992 ext2fs_free_mem(&ctx
->invalid_inode_table_flag
);
994 /* Clear statistic counters */
995 ctx
->fs_directory_count
= 0;
996 ctx
->fs_regular_count
= 0;
997 ctx
->fs_blockdev_count
= 0;
998 ctx
->fs_chardev_count
= 0;
999 ctx
->fs_links_count
= 0;
1000 ctx
->fs_symlinks_count
= 0;
1001 ctx
->fs_fast_symlinks_count
= 0;
1002 ctx
->fs_fifo_count
= 0;
1003 ctx
->fs_total_count
= 0;
1004 ctx
->fs_sockets_count
= 0;
1005 ctx
->fs_ind_count
= 0;
1006 ctx
->fs_dind_count
= 0;
1007 ctx
->fs_tind_count
= 0;
1008 ctx
->fs_fragmented
= 0;
1009 ctx
->large_files
= 0;
1011 /* Reset the superblock to the user's requested value */
1012 ctx
->superblock
= ctx
->use_superblock
;
1017 static void e2fsck_free_context(e2fsck_t ctx
)
1022 e2fsck_reset_context(ctx
);
1024 ext2fs_free_mem(&ctx
);
1032 * The strategy we use for keeping track of EA refcounts is as
1033 * follows. We keep a sorted array of first EA blocks and its
1034 * reference counts. Once the refcount has dropped to zero, it is
1035 * removed from the array to save memory space. Once the EA block is
1036 * checked, its bit is set in the block_ea_map bitmap.
1040 static errcode_t
ea_refcount_create(int size
, ext2_refcount_t
*ret
)
1042 ext2_refcount_t refcount
;
1046 retval
= ext2fs_get_mem(sizeof(struct ea_refcount
), &refcount
);
1049 memset(refcount
, 0, sizeof(struct ea_refcount
));
1053 refcount
->size
= size
;
1054 bytes
= (size_t) (size
* sizeof(struct ea_refcount_el
));
1056 printf("Refcount allocated %d entries, %d bytes.\n",
1057 refcount
->size
, bytes
);
1059 retval
= ext2fs_get_mem(bytes
, &refcount
->list
);
1062 memset(refcount
->list
, 0, bytes
);
1064 refcount
->count
= 0;
1065 refcount
->cursor
= 0;
1071 ea_refcount_free(refcount
);
1076 * collapse_refcount() --- go through the refcount array, and get rid
1077 * of any count == zero entries
1079 static void refcount_collapse(ext2_refcount_t refcount
)
1082 struct ea_refcount_el
*list
;
1084 list
= refcount
->list
;
1085 for (i
= 0, j
= 0; i
< refcount
->count
; i
++) {
1086 if (list
[i
].ea_count
) {
1092 #if defined(DEBUG) || defined(TEST_PROGRAM)
1093 printf("Refcount_collapse: size was %d, now %d\n",
1094 refcount
->count
, j
);
1096 refcount
->count
= j
;
1101 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1102 * specified position.
1104 static struct ea_refcount_el
*insert_refcount_el(ext2_refcount_t refcount
,
1107 struct ea_refcount_el
*el
;
1112 if (refcount
->count
>= refcount
->size
) {
1113 new_size
= refcount
->size
+ 100;
1115 printf("Reallocating refcount %d entries...\n", new_size
);
1117 retval
= ext2fs_resize_mem((size_t) refcount
->size
*
1118 sizeof(struct ea_refcount_el
),
1120 sizeof(struct ea_refcount_el
),
1124 refcount
->size
= new_size
;
1126 num
= (int) refcount
->count
- pos
;
1128 return 0; /* should never happen */
1130 memmove(&refcount
->list
[pos
+1], &refcount
->list
[pos
],
1131 sizeof(struct ea_refcount_el
) * num
);
1134 el
= &refcount
->list
[pos
];
1142 * get_refcount_el() --- given an block number, try to find refcount
1143 * information in the sorted list. If the create flag is set,
1144 * and we can't find an entry, create one in the sorted list.
1146 static struct ea_refcount_el
*get_refcount_el(ext2_refcount_t refcount
,
1147 blk_t blk
, int create
)
1151 blk_t lowval
, highval
;
1153 if (!refcount
|| !refcount
->list
)
1157 high
= (int) refcount
->count
-1;
1158 if (create
&& ((refcount
->count
== 0) ||
1159 (blk
> refcount
->list
[high
].ea_blk
))) {
1160 if (refcount
->count
>= refcount
->size
)
1161 refcount_collapse(refcount
);
1163 return insert_refcount_el(refcount
, blk
,
1164 (unsigned) refcount
->count
);
1166 if (refcount
->count
== 0)
1169 if (refcount
->cursor
>= refcount
->count
)
1170 refcount
->cursor
= 0;
1171 if (blk
== refcount
->list
[refcount
->cursor
].ea_blk
)
1172 return &refcount
->list
[refcount
->cursor
++];
1174 printf("Non-cursor get_refcount_el: %u\n", blk
);
1176 while (low
<= high
) {
1180 /* Interpolate for efficiency */
1181 lowval
= refcount
->list
[low
].ea_blk
;
1182 highval
= refcount
->list
[high
].ea_blk
;
1186 else if (blk
> highval
)
1189 range
= ((float) (blk
- lowval
)) /
1191 mid
= low
+ ((int) (range
* (high
-low
)));
1194 if (blk
== refcount
->list
[mid
].ea_blk
) {
1195 refcount
->cursor
= mid
+1;
1196 return &refcount
->list
[mid
];
1198 if (blk
< refcount
->list
[mid
].ea_blk
)
1204 * If we need to create a new entry, it should be right at
1205 * low (where high will be left at low-1).
1208 if (refcount
->count
>= refcount
->size
) {
1209 refcount_collapse(refcount
);
1210 if (refcount
->count
< refcount
->size
)
1213 return insert_refcount_el(refcount
, blk
, low
);
1219 ea_refcount_increment(ext2_refcount_t refcount
, blk_t blk
, int *ret
)
1221 struct ea_refcount_el
*el
;
1223 el
= get_refcount_el(refcount
, blk
, 1);
1225 return EXT2_ET_NO_MEMORY
;
1229 *ret
= el
->ea_count
;
1234 ea_refcount_decrement(ext2_refcount_t refcount
, blk_t blk
, int *ret
)
1236 struct ea_refcount_el
*el
;
1238 el
= get_refcount_el(refcount
, blk
, 0);
1239 if (!el
|| el
->ea_count
== 0)
1240 return EXT2_ET_INVALID_ARGUMENT
;
1245 *ret
= el
->ea_count
;
1250 ea_refcount_store(ext2_refcount_t refcount
, blk_t blk
, int count
)
1252 struct ea_refcount_el
*el
;
1255 * Get the refcount element
1257 el
= get_refcount_el(refcount
, blk
, count
? 1 : 0);
1259 return count
? EXT2_ET_NO_MEMORY
: 0;
1260 el
->ea_count
= count
;
1264 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount
)
1266 refcount
->cursor
= 0;
1270 static blk_t
ea_refcount_intr_next(ext2_refcount_t refcount
, int *ret
)
1272 struct ea_refcount_el
*list
;
1275 if (refcount
->cursor
>= refcount
->count
)
1277 list
= refcount
->list
;
1278 if (list
[refcount
->cursor
].ea_count
) {
1280 *ret
= list
[refcount
->cursor
].ea_count
;
1281 return list
[refcount
->cursor
++].ea_blk
;
1289 * ehandler.c --- handle bad block errors which come up during the
1290 * course of an e2fsck session.
1294 static const char *operation
;
1297 e2fsck_handle_read_error(io_channel channel
, unsigned long block
, int count
,
1298 void *data
, size_t size
FSCK_ATTR((unused
)),
1299 int actual
FSCK_ATTR((unused
)), errcode_t error
)
1303 ext2_filsys fs
= (ext2_filsys
) channel
->app_data
;
1306 ctx
= (e2fsck_t
) fs
->priv_data
;
1309 * If more than one block was read, try reading each block
1310 * separately. We could use the actual bytes read to figure
1311 * out where to start, but we don't bother.
1315 for (i
=0; i
< count
; i
++, p
+= channel
->block_size
, block
++) {
1316 error
= io_channel_read_blk(channel
, block
,
1324 printf(_("Error reading block %lu (%s) while %s. "), block
,
1325 error_message(error
), operation
);
1327 printf(_("Error reading block %lu (%s). "), block
,
1328 error_message(error
));
1330 if (ask(ctx
, _("Ignore error"), 1)) {
1331 if (ask(ctx
, _("Force rewrite"), 1))
1332 io_channel_write_blk(channel
, block
, 1, data
);
1340 e2fsck_handle_write_error(io_channel channel
, unsigned long block
, int count
,
1341 const void *data
, size_t size
FSCK_ATTR((unused
)),
1342 int actual
FSCK_ATTR((unused
)), errcode_t error
)
1346 ext2_filsys fs
= (ext2_filsys
) channel
->app_data
;
1349 ctx
= (e2fsck_t
) fs
->priv_data
;
1352 * If more than one block was written, try writing each block
1353 * separately. We could use the actual bytes read to figure
1354 * out where to start, but we don't bother.
1357 p
= (const char *) data
;
1358 for (i
=0; i
< count
; i
++, p
+= channel
->block_size
, block
++) {
1359 error
= io_channel_write_blk(channel
, block
,
1368 printf(_("Error writing block %lu (%s) while %s. "), block
,
1369 error_message(error
), operation
);
1371 printf(_("Error writing block %lu (%s). "), block
,
1372 error_message(error
));
1374 if (ask(ctx
, _("Ignore error"), 1))
1380 static const char *ehandler_operation(const char *op
)
1382 const char *ret
= operation
;
1388 static void ehandler_init(io_channel channel
)
1390 channel
->read_error
= e2fsck_handle_read_error
;
1391 channel
->write_error
= e2fsck_handle_write_error
;
1395 * journal.c --- code for handling the "ext3" journal
1397 * Copyright (C) 2000 Andreas Dilger
1398 * Copyright (C) 2000 Theodore Ts'o
1400 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1401 * Copyright (C) 1999 Red Hat Software
1403 * This file may be redistributed under the terms of the
1404 * GNU General Public License version 2 or at your discretion
1405 * any later version.
1409 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1410 * This creates a larger static binary, and a smaller binary using
1411 * shared libraries. It's also probably slightly less CPU-efficient,
1412 * which is why it's not on by default. But, it's a good way of
1413 * testing the functions in inode_io.c and fileio.c.
1417 /* Kernel compatibility functions for handling the journal. These allow us
1418 * to use the recovery.c file virtually unchanged from the kernel, so we
1419 * don't have to do much to keep kernel and user recovery in sync.
1421 static int journal_bmap(journal_t
*journal
, blk_t block
, unsigned long *phys
)
1427 struct inode
*inode
= journal
->j_inode
;
1436 retval
= ext2fs_bmap(inode
->i_ctx
->fs
, inode
->i_ino
,
1437 &inode
->i_ext2
, NULL
, 0, block
, &pblk
);
1443 static struct buffer_head
*getblk(kdev_t kdev
, blk_t blocknr
, int blocksize
)
1445 struct buffer_head
*bh
;
1447 bh
= e2fsck_allocate_memory(kdev
->k_ctx
, sizeof(*bh
), "block buffer");
1451 bh
->b_ctx
= kdev
->k_ctx
;
1452 if (kdev
->k_dev
== K_DEV_FS
)
1453 bh
->b_io
= kdev
->k_ctx
->fs
->io
;
1455 bh
->b_io
= kdev
->k_ctx
->journal_io
;
1456 bh
->b_size
= blocksize
;
1457 bh
->b_blocknr
= blocknr
;
1462 static void sync_blockdev(kdev_t kdev
)
1466 if (kdev
->k_dev
== K_DEV_FS
)
1467 io
= kdev
->k_ctx
->fs
->io
;
1469 io
= kdev
->k_ctx
->journal_io
;
1471 io_channel_flush(io
);
1474 static void ll_rw_block(int rw
, int nr
, struct buffer_head
*bhp
[])
1477 struct buffer_head
*bh
;
1479 for (; nr
> 0; --nr
) {
1481 if (rw
== READ
&& !bh
->b_uptodate
) {
1482 retval
= io_channel_read_blk(bh
->b_io
,
1486 bb_error_msg("while reading block %lu",
1487 (unsigned long) bh
->b_blocknr
);
1492 } else if (rw
== WRITE
&& bh
->b_dirty
) {
1493 retval
= io_channel_write_blk(bh
->b_io
,
1497 bb_error_msg("while writing block %lu",
1498 (unsigned long) bh
->b_blocknr
);
1508 static void mark_buffer_dirty(struct buffer_head
*bh
)
1513 static inline void mark_buffer_clean(struct buffer_head
* bh
)
1518 static void brelse(struct buffer_head
*bh
)
1521 ll_rw_block(WRITE
, 1, &bh
);
1522 ext2fs_free_mem(&bh
);
1525 static int buffer_uptodate(struct buffer_head
*bh
)
1527 return bh
->b_uptodate
;
1530 static inline void mark_buffer_uptodate(struct buffer_head
*bh
, int val
)
1532 bh
->b_uptodate
= val
;
1535 static void wait_on_buffer(struct buffer_head
*bh
)
1537 if (!bh
->b_uptodate
)
1538 ll_rw_block(READ
, 1, &bh
);
1542 static void e2fsck_clear_recover(e2fsck_t ctx
, int error
)
1544 ctx
->fs
->super
->s_feature_incompat
&= ~EXT3_FEATURE_INCOMPAT_RECOVER
;
1546 /* if we had an error doing journal recovery, we need a full fsck */
1548 ctx
->fs
->super
->s_state
&= ~EXT2_VALID_FS
;
1549 ext2fs_mark_super_dirty(ctx
->fs
);
1552 static errcode_t
e2fsck_get_journal(e2fsck_t ctx
, journal_t
**ret_journal
)
1554 struct ext2_super_block
*sb
= ctx
->fs
->super
;
1555 struct ext2_super_block jsuper
;
1556 struct problem_context pctx
;
1557 struct buffer_head
*bh
;
1558 struct inode
*j_inode
= NULL
;
1559 struct kdev_s
*dev_fs
= NULL
, *dev_journal
;
1560 const char *journal_name
= NULL
;
1561 journal_t
*journal
= NULL
;
1562 errcode_t retval
= 0;
1563 io_manager io_ptr
= 0;
1564 unsigned long start
= 0;
1566 int ext_journal
= 0;
1567 int tried_backup_jnl
= 0;
1570 clear_problem_context(&pctx
);
1572 journal
= e2fsck_allocate_memory(ctx
, sizeof(journal_t
), "journal");
1574 return EXT2_ET_NO_MEMORY
;
1577 dev_fs
= e2fsck_allocate_memory(ctx
, 2*sizeof(struct kdev_s
), "kdev");
1579 retval
= EXT2_ET_NO_MEMORY
;
1582 dev_journal
= dev_fs
+1;
1584 dev_fs
->k_ctx
= dev_journal
->k_ctx
= ctx
;
1585 dev_fs
->k_dev
= K_DEV_FS
;
1586 dev_journal
->k_dev
= K_DEV_JOURNAL
;
1588 journal
->j_dev
= dev_journal
;
1589 journal
->j_fs_dev
= dev_fs
;
1590 journal
->j_inode
= NULL
;
1591 journal
->j_blocksize
= ctx
->fs
->blocksize
;
1593 if (uuid_is_null(sb
->s_journal_uuid
)) {
1594 if (!sb
->s_journal_inum
)
1595 return EXT2_ET_BAD_INODE_NUM
;
1596 j_inode
= e2fsck_allocate_memory(ctx
, sizeof(*j_inode
),
1599 retval
= EXT2_ET_NO_MEMORY
;
1603 j_inode
->i_ctx
= ctx
;
1604 j_inode
->i_ino
= sb
->s_journal_inum
;
1606 if ((retval
= ext2fs_read_inode(ctx
->fs
,
1608 &j_inode
->i_ext2
))) {
1610 if (sb
->s_jnl_backup_type
!= EXT3_JNL_BACKUP_BLOCKS
||
1613 memset(&j_inode
->i_ext2
, 0, sizeof(struct ext2_inode
));
1614 memcpy(&j_inode
->i_ext2
.i_block
[0], sb
->s_jnl_blocks
,
1616 j_inode
->i_ext2
.i_size
= sb
->s_jnl_blocks
[16];
1617 j_inode
->i_ext2
.i_links_count
= 1;
1618 j_inode
->i_ext2
.i_mode
= LINUX_S_IFREG
| 0600;
1621 if (!j_inode
->i_ext2
.i_links_count
||
1622 !LINUX_S_ISREG(j_inode
->i_ext2
.i_mode
)) {
1623 retval
= EXT2_ET_NO_JOURNAL
;
1624 goto try_backup_journal
;
1626 if (j_inode
->i_ext2
.i_size
/ journal
->j_blocksize
<
1627 JFS_MIN_JOURNAL_BLOCKS
) {
1628 retval
= EXT2_ET_JOURNAL_TOO_SMALL
;
1629 goto try_backup_journal
;
1631 for (i
=0; i
< EXT2_N_BLOCKS
; i
++) {
1632 blk
= j_inode
->i_ext2
.i_block
[i
];
1634 if (i
< EXT2_NDIR_BLOCKS
) {
1635 retval
= EXT2_ET_JOURNAL_TOO_SMALL
;
1636 goto try_backup_journal
;
1640 if (blk
< sb
->s_first_data_block
||
1641 blk
>= sb
->s_blocks_count
) {
1642 retval
= EXT2_ET_BAD_BLOCK_NUM
;
1643 goto try_backup_journal
;
1646 journal
->j_maxlen
= j_inode
->i_ext2
.i_size
/ journal
->j_blocksize
;
1649 retval
= ext2fs_inode_io_intern2(ctx
->fs
, sb
->s_journal_inum
,
1655 io_ptr
= inode_io_manager
;
1657 journal
->j_inode
= j_inode
;
1658 ctx
->journal_io
= ctx
->fs
->io
;
1659 if ((retval
= journal_bmap(journal
, 0, &start
)) != 0)
1664 if (!ctx
->journal_name
) {
1667 unparse_uuid(sb
->s_journal_uuid
, uuid
);
1668 ctx
->journal_name
= get_devname_from_uuid(uuid
);
1669 if (!ctx
->journal_name
)
1670 ctx
->journal_name
= get_devname_from_device(sb
->s_journal_dev
);
1672 journal_name
= ctx
->journal_name
;
1674 if (!journal_name
) {
1675 fix_problem(ctx
, PR_0_CANT_FIND_JOURNAL
, &pctx
);
1676 return EXT2_ET_LOAD_EXT_JOURNAL
;
1679 io_ptr
= unix_io_manager
;
1682 #ifndef USE_INODE_IO
1685 retval
= io_ptr
->open(journal_name
, IO_FLAG_RW
,
1690 io_channel_set_blksize(ctx
->journal_io
, ctx
->fs
->blocksize
);
1693 if (ctx
->fs
->blocksize
== 1024)
1695 bh
= getblk(dev_journal
, start
, ctx
->fs
->blocksize
);
1697 retval
= EXT2_ET_NO_MEMORY
;
1700 ll_rw_block(READ
, 1, &bh
);
1701 if ((retval
= bh
->b_err
) != 0)
1703 memcpy(&jsuper
, start
? bh
->b_data
: bh
->b_data
+ 1024,
1707 if (jsuper
.s_magic
== ext2fs_swab16(EXT2_SUPER_MAGIC
))
1708 ext2fs_swap_super(&jsuper
);
1710 if (jsuper
.s_magic
!= EXT2_SUPER_MAGIC
||
1711 !(jsuper
.s_feature_incompat
& EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
)) {
1712 fix_problem(ctx
, PR_0_EXT_JOURNAL_BAD_SUPER
, &pctx
);
1713 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
1716 /* Make sure the journal UUID is correct */
1717 if (memcmp(jsuper
.s_uuid
, ctx
->fs
->super
->s_journal_uuid
,
1718 sizeof(jsuper
.s_uuid
))) {
1719 fix_problem(ctx
, PR_0_JOURNAL_BAD_UUID
, &pctx
);
1720 retval
= EXT2_ET_LOAD_EXT_JOURNAL
;
1724 journal
->j_maxlen
= jsuper
.s_blocks_count
;
1728 if (!(bh
= getblk(dev_journal
, start
, journal
->j_blocksize
))) {
1729 retval
= EXT2_ET_NO_MEMORY
;
1733 journal
->j_sb_buffer
= bh
;
1734 journal
->j_superblock
= (journal_superblock_t
*)bh
->b_data
;
1737 ext2fs_free_mem(&j_inode
);
1740 *ret_journal
= journal
;
1744 ext2fs_free_mem(&dev_fs
);
1745 ext2fs_free_mem(&j_inode
);
1746 ext2fs_free_mem(&journal
);
1750 static errcode_t
e2fsck_journal_fix_bad_inode(e2fsck_t ctx
,
1751 struct problem_context
*pctx
)
1753 struct ext2_super_block
*sb
= ctx
->fs
->super
;
1754 int recover
= ctx
->fs
->super
->s_feature_incompat
&
1755 EXT3_FEATURE_INCOMPAT_RECOVER
;
1756 int has_journal
= ctx
->fs
->super
->s_feature_compat
&
1757 EXT3_FEATURE_COMPAT_HAS_JOURNAL
;
1759 if (has_journal
|| sb
->s_journal_inum
) {
1760 /* The journal inode is bogus, remove and force full fsck */
1761 pctx
->ino
= sb
->s_journal_inum
;
1762 if (fix_problem(ctx
, PR_0_JOURNAL_BAD_INODE
, pctx
)) {
1763 if (has_journal
&& sb
->s_journal_inum
)
1764 printf("*** ext3 journal has been deleted - "
1765 "filesystem is now ext2 only ***\n\n");
1766 sb
->s_feature_compat
&= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL
;
1767 sb
->s_journal_inum
= 0;
1768 ctx
->flags
|= E2F_FLAG_JOURNAL_INODE
; /* FIXME: todo */
1769 e2fsck_clear_recover(ctx
, 1);
1772 return EXT2_ET_BAD_INODE_NUM
;
1773 } else if (recover
) {
1774 if (fix_problem(ctx
, PR_0_JOURNAL_RECOVER_SET
, pctx
)) {
1775 e2fsck_clear_recover(ctx
, 1);
1778 return EXT2_ET_UNSUPP_FEATURE
;
1783 #define V1_SB_SIZE 0x0024
1784 static void clear_v2_journal_fields(journal_t
*journal
)
1786 e2fsck_t ctx
= journal
->j_dev
->k_ctx
;
1787 struct problem_context pctx
;
1789 clear_problem_context(&pctx
);
1791 if (!fix_problem(ctx
, PR_0_CLEAR_V2_JOURNAL
, &pctx
))
1794 memset(((char *) journal
->j_superblock
) + V1_SB_SIZE
, 0,
1795 ctx
->fs
->blocksize
-V1_SB_SIZE
);
1796 mark_buffer_dirty(journal
->j_sb_buffer
);
1800 static errcode_t
e2fsck_journal_load(journal_t
*journal
)
1802 e2fsck_t ctx
= journal
->j_dev
->k_ctx
;
1803 journal_superblock_t
*jsb
;
1804 struct buffer_head
*jbh
= journal
->j_sb_buffer
;
1805 struct problem_context pctx
;
1807 clear_problem_context(&pctx
);
1809 ll_rw_block(READ
, 1, &jbh
);
1811 bb_error_msg(_("reading journal superblock"));
1815 jsb
= journal
->j_superblock
;
1816 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1817 if (jsb
->s_header
.h_magic
!= htonl(JFS_MAGIC_NUMBER
))
1818 return e2fsck_journal_fix_bad_inode(ctx
, &pctx
);
1820 switch (ntohl(jsb
->s_header
.h_blocktype
)) {
1821 case JFS_SUPERBLOCK_V1
:
1822 journal
->j_format_version
= 1;
1823 if (jsb
->s_feature_compat
||
1824 jsb
->s_feature_incompat
||
1825 jsb
->s_feature_ro_compat
||
1827 clear_v2_journal_fields(journal
);
1830 case JFS_SUPERBLOCK_V2
:
1831 journal
->j_format_version
= 2;
1832 if (ntohl(jsb
->s_nr_users
) > 1 &&
1833 uuid_is_null(ctx
->fs
->super
->s_journal_uuid
))
1834 clear_v2_journal_fields(journal
);
1835 if (ntohl(jsb
->s_nr_users
) > 1) {
1836 fix_problem(ctx
, PR_0_JOURNAL_UNSUPP_MULTIFS
, &pctx
);
1837 return EXT2_ET_JOURNAL_UNSUPP_VERSION
;
1842 * These should never appear in a journal super block, so if
1843 * they do, the journal is badly corrupted.
1845 case JFS_DESCRIPTOR_BLOCK
:
1846 case JFS_COMMIT_BLOCK
:
1847 case JFS_REVOKE_BLOCK
:
1848 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1850 /* If we don't understand the superblock major type, but there
1851 * is a magic number, then it is likely to be a new format we
1852 * just don't understand, so leave it alone. */
1854 return EXT2_ET_JOURNAL_UNSUPP_VERSION
;
1857 if (JFS_HAS_INCOMPAT_FEATURE(journal
, ~JFS_KNOWN_INCOMPAT_FEATURES
))
1858 return EXT2_ET_UNSUPP_FEATURE
;
1860 if (JFS_HAS_RO_COMPAT_FEATURE(journal
, ~JFS_KNOWN_ROCOMPAT_FEATURES
))
1861 return EXT2_ET_RO_UNSUPP_FEATURE
;
1863 /* We have now checked whether we know enough about the journal
1864 * format to be able to proceed safely, so any other checks that
1865 * fail we should attempt to recover from. */
1866 if (jsb
->s_blocksize
!= htonl(journal
->j_blocksize
)) {
1867 bb_error_msg(_("%s: no valid journal superblock found"),
1869 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1872 if (ntohl(jsb
->s_maxlen
) < journal
->j_maxlen
)
1873 journal
->j_maxlen
= ntohl(jsb
->s_maxlen
);
1874 else if (ntohl(jsb
->s_maxlen
) > journal
->j_maxlen
) {
1875 bb_error_msg(_("%s: journal too short"),
1877 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1880 journal
->j_tail_sequence
= ntohl(jsb
->s_sequence
);
1881 journal
->j_transaction_sequence
= journal
->j_tail_sequence
;
1882 journal
->j_tail
= ntohl(jsb
->s_start
);
1883 journal
->j_first
= ntohl(jsb
->s_first
);
1884 journal
->j_last
= ntohl(jsb
->s_maxlen
);
1889 static void e2fsck_journal_reset_super(e2fsck_t ctx
, journal_superblock_t
*jsb
,
1900 /* Leave a valid existing V1 superblock signature alone.
1901 * Anything unrecognizable we overwrite with a new V2
1904 if (jsb
->s_header
.h_magic
!= htonl(JFS_MAGIC_NUMBER
) ||
1905 jsb
->s_header
.h_blocktype
!= htonl(JFS_SUPERBLOCK_V1
)) {
1906 jsb
->s_header
.h_magic
= htonl(JFS_MAGIC_NUMBER
);
1907 jsb
->s_header
.h_blocktype
= htonl(JFS_SUPERBLOCK_V2
);
1910 /* Zero out everything else beyond the superblock header */
1912 p
= ((char *) jsb
) + sizeof(journal_header_t
);
1913 memset (p
, 0, ctx
->fs
->blocksize
-sizeof(journal_header_t
));
1915 jsb
->s_blocksize
= htonl(ctx
->fs
->blocksize
);
1916 jsb
->s_maxlen
= htonl(journal
->j_maxlen
);
1917 jsb
->s_first
= htonl(1);
1919 /* Initialize the journal sequence number so that there is "no"
1920 * chance we will find old "valid" transactions in the journal.
1921 * This avoids the need to zero the whole journal (slow to do,
1922 * and risky when we are just recovering the filesystem).
1924 generate_uuid(u
.uuid
);
1925 for (i
= 0; i
< 4; i
++)
1926 new_seq
^= u
.val
[i
];
1927 jsb
->s_sequence
= htonl(new_seq
);
1929 mark_buffer_dirty(journal
->j_sb_buffer
);
1930 ll_rw_block(WRITE
, 1, &journal
->j_sb_buffer
);
1933 static errcode_t
e2fsck_journal_fix_corrupt_super(e2fsck_t ctx
,
1935 struct problem_context
*pctx
)
1937 struct ext2_super_block
*sb
= ctx
->fs
->super
;
1938 int recover
= ctx
->fs
->super
->s_feature_incompat
&
1939 EXT3_FEATURE_INCOMPAT_RECOVER
;
1941 if (sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
) {
1942 if (fix_problem(ctx
, PR_0_JOURNAL_BAD_SUPER
, pctx
)) {
1943 e2fsck_journal_reset_super(ctx
, journal
->j_superblock
,
1945 journal
->j_transaction_sequence
= 1;
1946 e2fsck_clear_recover(ctx
, recover
);
1949 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1950 } else if (e2fsck_journal_fix_bad_inode(ctx
, pctx
))
1951 return EXT2_ET_CORRUPT_SUPERBLOCK
;
1956 static void e2fsck_journal_release(e2fsck_t ctx
, journal_t
*journal
,
1957 int reset
, int drop
)
1959 journal_superblock_t
*jsb
;
1962 mark_buffer_clean(journal
->j_sb_buffer
);
1963 else if (!(ctx
->options
& E2F_OPT_READONLY
)) {
1964 jsb
= journal
->j_superblock
;
1965 jsb
->s_sequence
= htonl(journal
->j_transaction_sequence
);
1967 jsb
->s_start
= 0; /* this marks the journal as empty */
1968 mark_buffer_dirty(journal
->j_sb_buffer
);
1970 brelse(journal
->j_sb_buffer
);
1972 if (ctx
->journal_io
) {
1973 if (ctx
->fs
&& ctx
->fs
->io
!= ctx
->journal_io
)
1974 io_channel_close(ctx
->journal_io
);
1975 ctx
->journal_io
= 0;
1978 #ifndef USE_INODE_IO
1979 ext2fs_free_mem(&journal
->j_inode
);
1981 ext2fs_free_mem(&journal
->j_fs_dev
);
1982 ext2fs_free_mem(&journal
);
1986 * This function makes sure that the superblock fields regarding the
1987 * journal are consistent.
1989 static int e2fsck_check_ext3_journal(e2fsck_t ctx
)
1991 struct ext2_super_block
*sb
= ctx
->fs
->super
;
1993 int recover
= ctx
->fs
->super
->s_feature_incompat
&
1994 EXT3_FEATURE_INCOMPAT_RECOVER
;
1995 struct problem_context pctx
;
1997 int reset
= 0, force_fsck
= 0;
2000 /* If we don't have any journal features, don't do anything more */
2001 if (!(sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
) &&
2002 !recover
&& sb
->s_journal_inum
== 0 && sb
->s_journal_dev
== 0 &&
2003 uuid_is_null(sb
->s_journal_uuid
))
2006 clear_problem_context(&pctx
);
2007 pctx
.num
= sb
->s_journal_inum
;
2009 retval
= e2fsck_get_journal(ctx
, &journal
);
2011 if ((retval
== EXT2_ET_BAD_INODE_NUM
) ||
2012 (retval
== EXT2_ET_BAD_BLOCK_NUM
) ||
2013 (retval
== EXT2_ET_JOURNAL_TOO_SMALL
) ||
2014 (retval
== EXT2_ET_NO_JOURNAL
))
2015 return e2fsck_journal_fix_bad_inode(ctx
, &pctx
);
2019 retval
= e2fsck_journal_load(journal
);
2021 if ((retval
== EXT2_ET_CORRUPT_SUPERBLOCK
) ||
2022 ((retval
== EXT2_ET_UNSUPP_FEATURE
) &&
2023 (!fix_problem(ctx
, PR_0_JOURNAL_UNSUPP_INCOMPAT
,
2025 ((retval
== EXT2_ET_RO_UNSUPP_FEATURE
) &&
2026 (!fix_problem(ctx
, PR_0_JOURNAL_UNSUPP_ROCOMPAT
,
2028 ((retval
== EXT2_ET_JOURNAL_UNSUPP_VERSION
) &&
2029 (!fix_problem(ctx
, PR_0_JOURNAL_UNSUPP_VERSION
, &pctx
))))
2030 retval
= e2fsck_journal_fix_corrupt_super(ctx
, journal
,
2032 e2fsck_journal_release(ctx
, journal
, 0, 1);
2037 * We want to make the flags consistent here. We will not leave with
2038 * needs_recovery set but has_journal clear. We can't get in a loop
2039 * with -y, -n, or -p, only if a user isn't making up their mind.
2042 if (!(sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
)) {
2043 recover
= sb
->s_feature_incompat
& EXT3_FEATURE_INCOMPAT_RECOVER
;
2045 if (fix_problem(ctx
, PR_0_JOURNAL_HAS_JOURNAL
, &pctx
)) {
2047 !fix_problem(ctx
, PR_0_JOURNAL_RECOVER_SET
, &pctx
))
2048 goto no_has_journal
;
2050 * Need a full fsck if we are releasing a
2051 * journal stored on a reserved inode.
2053 force_fsck
= recover
||
2054 (sb
->s_journal_inum
< EXT2_FIRST_INODE(sb
));
2055 /* Clear all of the journal fields */
2056 sb
->s_journal_inum
= 0;
2057 sb
->s_journal_dev
= 0;
2058 memset(sb
->s_journal_uuid
, 0,
2059 sizeof(sb
->s_journal_uuid
));
2060 e2fsck_clear_recover(ctx
, force_fsck
);
2061 } else if (!(ctx
->options
& E2F_OPT_READONLY
)) {
2062 sb
->s_feature_compat
|= EXT3_FEATURE_COMPAT_HAS_JOURNAL
;
2063 ext2fs_mark_super_dirty(ctx
->fs
);
2067 if (sb
->s_feature_compat
& EXT3_FEATURE_COMPAT_HAS_JOURNAL
&&
2068 !(sb
->s_feature_incompat
& EXT3_FEATURE_INCOMPAT_RECOVER
) &&
2069 journal
->j_superblock
->s_start
!= 0) {
2070 /* Print status information */
2071 fix_problem(ctx
, PR_0_JOURNAL_RECOVERY_CLEAR
, &pctx
);
2072 if (ctx
->superblock
)
2073 problem
= PR_0_JOURNAL_RUN_DEFAULT
;
2075 problem
= PR_0_JOURNAL_RUN
;
2076 if (fix_problem(ctx
, problem
, &pctx
)) {
2077 ctx
->options
|= E2F_OPT_FORCE
;
2078 sb
->s_feature_incompat
|=
2079 EXT3_FEATURE_INCOMPAT_RECOVER
;
2080 ext2fs_mark_super_dirty(ctx
->fs
);
2081 } else if (fix_problem(ctx
,
2082 PR_0_JOURNAL_RESET_JOURNAL
, &pctx
)) {
2084 sb
->s_state
&= ~EXT2_VALID_FS
;
2085 ext2fs_mark_super_dirty(ctx
->fs
);
2088 * If the user answers no to the above question, we
2089 * ignore the fact that journal apparently has data;
2090 * accidentally replaying over valid data would be far
2091 * worse than skipping a questionable recovery.
2093 * XXX should we abort with a fatal error here? What
2094 * will the ext3 kernel code do if a filesystem with
2095 * !NEEDS_RECOVERY but with a non-zero
2096 * journal->j_superblock->s_start is mounted?
2100 e2fsck_journal_release(ctx
, journal
, reset
, 0);
2104 static errcode_t
recover_ext3_journal(e2fsck_t ctx
)
2109 journal_init_revoke_caches();
2110 retval
= e2fsck_get_journal(ctx
, &journal
);
2114 retval
= e2fsck_journal_load(journal
);
2118 retval
= journal_init_revoke(journal
, 1024);
2122 retval
= -journal_recover(journal
);
2126 if (journal
->j_superblock
->s_errno
) {
2127 ctx
->fs
->super
->s_state
|= EXT2_ERROR_FS
;
2128 ext2fs_mark_super_dirty(ctx
->fs
);
2129 journal
->j_superblock
->s_errno
= 0;
2130 mark_buffer_dirty(journal
->j_sb_buffer
);
2134 journal_destroy_revoke(journal
);
2135 journal_destroy_revoke_caches();
2136 e2fsck_journal_release(ctx
, journal
, 1, 0);
2140 static int e2fsck_run_ext3_journal(e2fsck_t ctx
)
2142 io_manager io_ptr
= ctx
->fs
->io
->manager
;
2143 int blocksize
= ctx
->fs
->blocksize
;
2144 errcode_t retval
, recover_retval
;
2146 printf(_("%s: recovering journal\n"), ctx
->device_name
);
2147 if (ctx
->options
& E2F_OPT_READONLY
) {
2148 printf(_("%s: won't do journal recovery while read-only\n"),
2150 return EXT2_ET_FILE_RO
;
2153 if (ctx
->fs
->flags
& EXT2_FLAG_DIRTY
)
2154 ext2fs_flush(ctx
->fs
); /* Force out any modifications */
2156 recover_retval
= recover_ext3_journal(ctx
);
2159 * Reload the filesystem context to get up-to-date data from disk
2160 * because journal recovery will change the filesystem under us.
2162 ext2fs_close(ctx
->fs
);
2163 retval
= ext2fs_open(ctx
->filesystem_name
, EXT2_FLAG_RW
,
2164 ctx
->superblock
, blocksize
, io_ptr
,
2168 bb_error_msg_and_die(_("while trying to re-open %s"),
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_INODE
)) {
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_INODE
)
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_INODE
)) {
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_and_die(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12330 ehandler_operation(_("reading inode and block bitmaps"));
12331 retval
= ext2fs_read_bitmaps(fs
);
12332 ehandler_operation(0);
12334 bb_error_msg_and_die(_("while retrying to read bitmaps for %s"),
12339 static void e2fsck_write_bitmaps(e2fsck_t ctx
)
12341 ext2_filsys fs
= ctx
->fs
;
12344 if (ext2fs_test_bb_dirty(fs
)) {
12345 ehandler_operation(_("writing block bitmaps"));
12346 retval
= ext2fs_write_block_bitmap(fs
);
12347 ehandler_operation(0);
12349 bb_error_msg_and_die(_("while retrying to write block bitmaps for %s"),
12354 if (ext2fs_test_ib_dirty(fs
)) {
12355 ehandler_operation(_("writing inode bitmaps"));
12356 retval
= ext2fs_write_inode_bitmap(fs
);
12357 ehandler_operation(0);
12359 bb_error_msg_and_die(_("while retrying to write inode bitmaps for %s"),
12365 void preenhalt(e2fsck_t ctx
)
12367 ext2_filsys fs
= ctx
->fs
;
12369 if (!(ctx
->options
& E2F_OPT_PREEN
))
12371 fprintf(stderr
, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12372 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12375 fs
->super
->s_state
|= EXT2_ERROR_FS
;
12376 ext2fs_mark_super_dirty(fs
);
12379 exit(EXIT_UNCORRECTED
);
12382 void e2fsck_read_inode(e2fsck_t ctx
, unsigned long ino
,
12383 struct ext2_inode
* inode
, const char *proc
)
12387 retval
= ext2fs_read_inode(ctx
->fs
, ino
, inode
);
12389 bb_error_msg_and_die(_("while reading inode %ld in %s"), ino
, proc
);
12393 extern void e2fsck_write_inode_full(e2fsck_t ctx
, unsigned long ino
,
12394 struct ext2_inode
* inode
, int bufsize
,
12399 retval
= ext2fs_write_inode_full(ctx
->fs
, ino
, inode
, bufsize
);
12401 bb_error_msg_and_die(_("while writing inode %ld in %s"), ino
, proc
);
12405 extern void e2fsck_write_inode(e2fsck_t ctx
, unsigned long ino
,
12406 struct ext2_inode
* inode
, const char *proc
)
12410 retval
= ext2fs_write_inode(ctx
->fs
, ino
, inode
);
12412 bb_error_msg_and_die(_("while writing inode %ld in %s"), ino
, proc
);
12416 blk_t
get_backup_sb(e2fsck_t ctx
, ext2_filsys fs
, const char *name
,
12417 io_manager manager
)
12419 struct ext2_super_block
*sb
;
12420 io_channel io
= NULL
;
12423 blk_t superblock
, ret_sb
= 8193;
12425 if (fs
&& fs
->super
) {
12426 ret_sb
= (fs
->super
->s_blocks_per_group
+
12427 fs
->super
->s_first_data_block
);
12429 ctx
->superblock
= ret_sb
;
12430 ctx
->blocksize
= fs
->blocksize
;
12436 if (ctx
->blocksize
) {
12437 ret_sb
= ctx
->blocksize
* 8;
12438 if (ctx
->blocksize
== 1024)
12440 ctx
->superblock
= ret_sb
;
12443 ctx
->superblock
= ret_sb
;
12444 ctx
->blocksize
= 1024;
12447 if (!name
|| !manager
)
12450 if (manager
->open(name
, 0, &io
) != 0)
12453 if (ext2fs_get_mem(SUPERBLOCK_SIZE
, &buf
))
12455 sb
= (struct ext2_super_block
*) buf
;
12457 for (blocksize
= EXT2_MIN_BLOCK_SIZE
;
12458 blocksize
<= EXT2_MAX_BLOCK_SIZE
; blocksize
*= 2) {
12459 superblock
= blocksize
*8;
12460 if (blocksize
== 1024)
12462 io_channel_set_blksize(io
, blocksize
);
12463 if (io_channel_read_blk(io
, superblock
,
12464 -SUPERBLOCK_SIZE
, buf
))
12467 if (sb
->s_magic
== ext2fs_swab16(EXT2_SUPER_MAGIC
))
12468 ext2fs_swap_super(sb
);
12470 if (sb
->s_magic
== EXT2_SUPER_MAGIC
) {
12471 ret_sb
= superblock
;
12473 ctx
->superblock
= superblock
;
12474 ctx
->blocksize
= blocksize
;
12482 io_channel_close(io
);
12483 ext2fs_free_mem(&buf
);
12489 * This function runs through the e2fsck passes and calls them all,
12490 * returning restart, abort, or cancel as necessary...
12492 typedef void (*pass_t
)(e2fsck_t ctx
);
12494 static const pass_t e2fsck_passes
[] = {
12495 e2fsck_pass1
, e2fsck_pass2
, e2fsck_pass3
, e2fsck_pass4
,
12498 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12500 static int e2fsck_run(e2fsck_t ctx
)
12503 pass_t e2fsck_pass
;
12505 if (setjmp(ctx
->abort_loc
)) {
12506 ctx
->flags
&= ~E2F_FLAG_SETJMP_OK
;
12507 return (ctx
->flags
& E2F_FLAG_RUN_RETURN
);
12509 ctx
->flags
|= E2F_FLAG_SETJMP_OK
;
12511 for (i
=0; (e2fsck_pass
= e2fsck_passes
[i
]); i
++) {
12512 if (ctx
->flags
& E2F_FLAG_RUN_RETURN
)
12516 (void) (ctx
->progress
)(ctx
, 0, 0, 0);
12518 ctx
->flags
&= ~E2F_FLAG_SETJMP_OK
;
12520 if (ctx
->flags
& E2F_FLAG_RUN_RETURN
)
12521 return (ctx
->flags
& E2F_FLAG_RUN_RETURN
);
12527 * unix.c - The unix-specific code for e2fsck
12531 /* Command line options */
12533 #ifdef ENABLE_SWAPFS
12534 static int normalize_swapfs
;
12536 static int cflag
; /* check disk */
12537 static int show_version_only
;
12538 static int verbose
;
12540 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12542 static void show_stats(e2fsck_t ctx
)
12544 ext2_filsys fs
= ctx
->fs
;
12545 int inodes
, inodes_used
, blocks
, blocks_used
;
12547 int num_files
, num_links
;
12550 dir_links
= 2 * ctx
->fs_directory_count
- 1;
12551 num_files
= ctx
->fs_total_count
- dir_links
;
12552 num_links
= ctx
->fs_links_count
- dir_links
;
12553 inodes
= fs
->super
->s_inodes_count
;
12554 inodes_used
= (fs
->super
->s_inodes_count
-
12555 fs
->super
->s_free_inodes_count
);
12556 blocks
= fs
->super
->s_blocks_count
;
12557 blocks_used
= (fs
->super
->s_blocks_count
-
12558 fs
->super
->s_free_blocks_count
);
12560 frag_percent
= (10000 * ctx
->fs_fragmented
) / inodes_used
;
12561 frag_percent
= (frag_percent
+ 5) / 10;
12564 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12565 ctx
->device_name
, inodes_used
, inodes
,
12566 frag_percent
/ 10, frag_percent
% 10,
12567 blocks_used
, blocks
);
12570 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used
),
12571 100 * inodes_used
/ inodes
);
12572 printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12573 P_E2("", "s", ctx
->fs_fragmented
),
12574 frag_percent
/ 10, frag_percent
% 10);
12575 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12576 ctx
->fs_ind_count
, ctx
->fs_dind_count
, ctx
->fs_tind_count
);
12577 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used
),
12578 (int) ((long long) 100 * blocks_used
/ blocks
));
12579 printf("%8d large file%s\n", P_E2("", "s", ctx
->large_files
));
12580 printf("\n%8d regular file%s\n", P_E2("", "s", ctx
->fs_regular_count
));
12581 printf("%8d director%s\n", P_E2("y", "ies", ctx
->fs_directory_count
));
12582 printf("%8d character device file%s\n", P_E2("", "s", ctx
->fs_chardev_count
));
12583 printf("%8d block device file%s\n", P_E2("", "s", ctx
->fs_blockdev_count
));
12584 printf("%8d fifo%s\n", P_E2("", "s", ctx
->fs_fifo_count
));
12585 printf("%8d link%s\n", P_E2("", "s", ctx
->fs_links_count
- dir_links
));
12586 printf("%8d symbolic link%s", P_E2("", "s", ctx
->fs_symlinks_count
));
12587 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx
->fs_fast_symlinks_count
));
12588 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx
->fs_sockets_count
));
12589 printf("%8d file%s\n", P_E2("", "s", ctx
->fs_total_count
- dir_links
));
12592 static void check_mount(e2fsck_t ctx
)
12597 retval
= ext2fs_check_if_mounted(ctx
->filesystem_name
,
12598 &ctx
->mount_flags
);
12600 bb_error_msg(_("while determining whether %s is mounted"),
12601 ctx
->filesystem_name
);
12606 * If the filesystem isn't mounted, or it's the root filesystem
12607 * and it's mounted read-only, then everything's fine.
12609 if ((!(ctx
->mount_flags
& EXT2_MF_MOUNTED
)) ||
12610 ((ctx
->mount_flags
& EXT2_MF_ISROOT
) &&
12611 (ctx
->mount_flags
& EXT2_MF_READONLY
)))
12614 if (ctx
->options
& E2F_OPT_READONLY
) {
12615 printf(_("Warning! %s is mounted.\n"), ctx
->filesystem_name
);
12619 printf(_("%s is mounted. "), ctx
->filesystem_name
);
12620 if (!ctx
->interactive
)
12621 bb_error_msg_and_die(_("can't continue, aborting"));
12622 printf(_("\n\n\007\007\007\007WARNING!!! "
12623 "Running e2fsck on a mounted filesystem may cause\n"
12624 "SEVERE filesystem damage.\007\007\007\n\n"));
12625 cont
= ask_yn(_("Do you really want to continue"), -1);
12627 printf(_("check aborted.\n"));
12632 static int is_on_batt(void)
12636 char tmp
[80], tmp2
[80], fname
[80];
12637 unsigned int acflag
;
12640 f
= fopen_for_read("/proc/apm");
12642 if (fscanf(f
, "%s %s %s %x", tmp
, tmp
, tmp
, &acflag
) != 4)
12645 return (acflag
!= 1);
12647 d
= opendir("/proc/acpi/ac_adapter");
12649 while ((de
=readdir(d
)) != NULL
) {
12650 if (!strncmp(".", de
->d_name
, 1))
12652 snprintf(fname
, 80, "/proc/acpi/ac_adapter/%s/state",
12654 f
= fopen_for_read(fname
);
12657 if (fscanf(f
, "%s %s", tmp2
, tmp
) != 2)
12660 if (strncmp(tmp
, "off-line", 8) == 0) {
12671 * This routine checks to see if a filesystem can be skipped; if so,
12672 * it will exit with EXIT_OK. Under some conditions it will print a
12673 * message explaining why a check is being forced.
12675 static void check_if_skip(e2fsck_t ctx
)
12677 ext2_filsys fs
= ctx
->fs
;
12678 const char *reason
= NULL
;
12679 unsigned int reason_arg
= 0;
12681 int batt
= is_on_batt();
12682 time_t now
= time(NULL
);
12684 if ((ctx
->options
& E2F_OPT_FORCE
) || cflag
|| swapfs
)
12687 if ((fs
->super
->s_state
& EXT2_ERROR_FS
) ||
12688 !ext2fs_test_valid(fs
))
12689 reason
= _(" contains a file system with errors");
12690 else if ((fs
->super
->s_state
& EXT2_VALID_FS
) == 0)
12691 reason
= _(" was not cleanly unmounted");
12692 else if ((fs
->super
->s_max_mnt_count
> 0) &&
12693 (fs
->super
->s_mnt_count
>=
12694 (unsigned) fs
->super
->s_max_mnt_count
)) {
12695 reason
= _(" has been mounted %u times without being checked");
12696 reason_arg
= fs
->super
->s_mnt_count
;
12697 if (batt
&& (fs
->super
->s_mnt_count
<
12698 (unsigned) fs
->super
->s_max_mnt_count
*2))
12700 } else if (!(ctx
->options
& E2F_OPT_PREEN
) &&
12701 fs
->super
->s_checkinterval
&&
12702 ((now
- fs
->super
->s_lastcheck
) >=
12703 fs
->super
->s_checkinterval
)) {
12704 reason
= _(" has gone %u days without being checked");
12705 reason_arg
= (now
- fs
->super
->s_lastcheck
)/(3600*24);
12706 if (batt
&& ((now
- fs
->super
->s_lastcheck
) <
12707 fs
->super
->s_checkinterval
*2))
12711 fputs(ctx
->device_name
, stdout
);
12712 printf(reason
, reason_arg
);
12713 fputs(_(", check forced.\n"), stdout
);
12716 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx
->device_name
,
12717 fs
->super
->s_inodes_count
- fs
->super
->s_free_inodes_count
,
12718 fs
->super
->s_inodes_count
,
12719 fs
->super
->s_blocks_count
- fs
->super
->s_free_blocks_count
,
12720 fs
->super
->s_blocks_count
);
12721 next_check
= 100000;
12722 if (fs
->super
->s_max_mnt_count
> 0) {
12723 next_check
= fs
->super
->s_max_mnt_count
- fs
->super
->s_mnt_count
;
12724 if (next_check
<= 0)
12727 if (fs
->super
->s_checkinterval
&&
12728 ((now
- fs
->super
->s_lastcheck
) >= fs
->super
->s_checkinterval
))
12730 if (next_check
<= 5) {
12731 if (next_check
== 1)
12732 fputs(_(" (check after next mount)"), stdout
);
12734 printf(_(" (check in %ld mounts)"), next_check
);
12739 e2fsck_free_context(ctx
);
12744 * For completion notice
12746 struct percent_tbl
{
12750 static const struct percent_tbl e2fsck_tbl
= {
12751 5, { 0, 70, 90, 92, 95, 100 }
12754 static char bar
[128], spaces
[128];
12756 static float calc_percent(const struct percent_tbl
*tbl
, int pass
, int curr
,
12763 if (pass
> tbl
->max_pass
|| max
== 0)
12765 percent
= ((float) curr
) / ((float) max
);
12766 return ((percent
* (tbl
->table
[pass
] - tbl
->table
[pass
-1]))
12767 + tbl
->table
[pass
-1]);
12770 void e2fsck_clear_progbar(e2fsck_t ctx
)
12772 if (!(ctx
->flags
& E2F_FLAG_PROG_BAR
))
12775 printf("%s%s\r%s", ctx
->start_meta
, spaces
+ (sizeof(spaces
) - 80),
12778 ctx
->flags
&= ~E2F_FLAG_PROG_BAR
;
12781 int e2fsck_simple_progress(e2fsck_t ctx
, const char *label
, float percent
,
12782 unsigned int dpynum
)
12784 static const char spinner
[] = "\\|/-";
12791 if (ctx
->flags
& E2F_FLAG_PROG_SUPPRESS
)
12795 * Calculate the new progress position. If the
12796 * percentage hasn't changed, then we skip out right
12799 fixed_percent
= (int) ((10 * percent
) + 0.5);
12800 if (ctx
->progress_last_percent
== fixed_percent
)
12802 ctx
->progress_last_percent
= fixed_percent
;
12805 * If we've already updated the spinner once within
12806 * the last 1/8th of a second, no point doing it
12809 gettimeofday(&tv
, NULL
);
12810 tick
= (tv
.tv_sec
<< 3) + (tv
.tv_usec
/ (1000000 / 8));
12811 if ((tick
== ctx
->progress_last_time
) &&
12812 (fixed_percent
!= 0) && (fixed_percent
!= 1000))
12814 ctx
->progress_last_time
= tick
;
12817 * Advance the spinner, and note that the progress bar
12818 * will be on the screen
12820 ctx
->progress_pos
= (ctx
->progress_pos
+1) & 3;
12821 ctx
->flags
|= E2F_FLAG_PROG_BAR
;
12823 dpywidth
= 66 - strlen(label
);
12824 dpywidth
= 8 * (dpywidth
/ 8);
12828 i
= ((percent
* dpywidth
) + 50) / 100;
12829 printf("%s%s: |%s%s", ctx
->start_meta
, label
,
12830 bar
+ (sizeof(bar
) - (i
+1)),
12831 spaces
+ (sizeof(spaces
) - (dpywidth
- i
+ 1)));
12832 if (fixed_percent
== 1000)
12835 bb_putchar(spinner
[ctx
->progress_pos
& 3]);
12836 printf(" %4.1f%% ", percent
);
12838 printf("%u\r", dpynum
);
12840 fputs(" \r", stdout
);
12841 fputs(ctx
->stop_meta
, stdout
);
12843 if (fixed_percent
== 1000)
12844 e2fsck_clear_progbar(ctx
);
12850 static int e2fsck_update_progress(e2fsck_t ctx
, int pass
,
12851 unsigned long cur
, unsigned long max
)
12859 if (ctx
->progress_fd
) {
12860 sprintf(buf
, "%d %lu %lu\n", pass
, cur
, max
);
12861 xwrite_str(ctx
->progress_fd
, buf
);
12863 percent
= calc_percent(&e2fsck_tbl
, pass
, cur
, max
);
12864 e2fsck_simple_progress(ctx
, ctx
->device_name
,
12870 static void reserve_stdio_fds(void)
12875 fd
= open(bb_dev_null
, O_RDWR
);
12879 fprintf(stderr
, _("ERROR: Cannot open "
12880 "/dev/null (%s)\n"),
12888 static void signal_progress_on(int sig
FSCK_ATTR((unused
)))
12890 e2fsck_t ctx
= e2fsck_global_ctx
;
12895 ctx
->progress
= e2fsck_update_progress
;
12896 ctx
->progress_fd
= 0;
12899 static void signal_progress_off(int sig
FSCK_ATTR((unused
)))
12901 e2fsck_t ctx
= e2fsck_global_ctx
;
12906 e2fsck_clear_progbar(ctx
);
12910 static void signal_cancel(int sig
FSCK_ATTR((unused
)))
12912 e2fsck_t ctx
= e2fsck_global_ctx
;
12915 exit(FSCK_CANCELED
);
12917 ctx
->flags
|= E2F_FLAG_CANCEL
;
12920 static void parse_extended_opts(e2fsck_t ctx
, const char *opts
)
12922 char *buf
, *token
, *next
, *p
, *arg
;
12924 int extended_usage
= 0;
12926 buf
= string_copy(opts
, 0);
12927 for (token
= buf
; token
&& *token
; token
= next
) {
12928 p
= strchr(token
, ',');
12934 arg
= strchr(token
, '=');
12939 if (strcmp(token
, "ea_ver") == 0) {
12944 ea_ver
= strtoul(arg
, &p
, 0);
12946 ((ea_ver
!= 1) && (ea_ver
!= 2))) {
12948 _("Invalid EA version.\n"));
12952 ctx
->ext_attr_ver
= ea_ver
;
12954 fprintf(stderr
, _("Unknown extended option: %s\n"),
12959 if (extended_usage
) {
12960 bb_error_msg_and_die(
12961 "Extended options are separated by commas, "
12962 "and may take an argument which\n"
12963 "is set off by an equals ('=') sign. "
12964 "Valid extended options are:\n"
12965 "\tea_ver=<ea_version (1 or 2)>\n\n");
12970 static errcode_t
PRS(int argc
, char **argv
, e2fsck_t
*ret_ctx
)
12976 struct sigaction sa
;
12977 char *extended_opts
= NULL
;
12979 retval
= e2fsck_allocate_context(&ctx
);
12985 setvbuf(stdout
, NULL
, _IONBF
, BUFSIZ
);
12986 setvbuf(stderr
, NULL
, _IONBF
, BUFSIZ
);
12987 if (isatty(0) && isatty(1)) {
12988 ctx
->interactive
= 1;
12990 ctx
->start_meta
[0] = '\001';
12991 ctx
->stop_meta
[0] = '\002';
12993 memset(bar
, '=', sizeof(bar
)-1);
12994 memset(spaces
, ' ', sizeof(spaces
)-1);
12997 ctx
->program_name
= *argv
;
12999 ctx
->program_name
= "e2fsck";
13000 while ((c
= getopt (argc
, argv
, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF
)
13003 ctx
->progress
= e2fsck_update_progress
;
13004 ctx
->progress_fd
= atoi(optarg
);
13005 if (!ctx
->progress_fd
)
13007 /* Validate the file descriptor to avoid disasters */
13008 fd
= dup(ctx
->progress_fd
);
13011 _("Error validating file descriptor %d: %s\n"),
13013 error_message(errno
));
13014 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13019 ctx
->options
|= E2F_OPT_COMPRESS_DIRS
;
13022 extended_opts
= optarg
;
13026 if (ctx
->options
& (E2F_OPT_YES
|E2F_OPT_NO
)) {
13028 bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
13030 ctx
->options
|= E2F_OPT_PREEN
;
13033 if (ctx
->options
& (E2F_OPT_YES
|E2F_OPT_PREEN
))
13035 ctx
->options
|= E2F_OPT_NO
;
13038 if (ctx
->options
& (E2F_OPT_PREEN
|E2F_OPT_NO
))
13040 ctx
->options
|= E2F_OPT_YES
;
13043 /* FIXME - This needs to go away in a future path - will change binary */
13044 fprintf(stderr
, _("The -t option is not "
13045 "supported on this version of e2fsck.\n"));
13049 ctx
->options
|= E2F_OPT_WRITECHECK
;
13050 ctx
->options
|= E2F_OPT_CHECKBLOCKS
;
13053 /* What we do by default, anyway! */
13056 ctx
->use_superblock
= atoi(optarg
);
13057 ctx
->flags
|= E2F_FLAG_SB_SPECIFIED
;
13060 ctx
->blocksize
= atoi(optarg
);
13063 ctx
->inode_buffer_blocks
= atoi(optarg
);
13066 ctx
->journal_name
= string_copy(optarg
, 0);
13069 ctx
->process_inode_size
= atoi(optarg
);
13072 ctx
->options
|= E2F_OPT_DEBUG
;
13075 ctx
->options
|= E2F_OPT_FORCE
;
13084 show_version_only
= 1;
13087 ctx
->device_name
= optarg
;
13089 #ifdef ENABLE_SWAPFS
13091 normalize_swapfs
= 1;
13098 fprintf(stderr
, _("Byte-swapping filesystems "
13099 "not compiled in this version "
13106 if (show_version_only
)
13108 if (optind
!= argc
- 1)
13110 if ((ctx
->options
& E2F_OPT_NO
) &&
13111 !cflag
&& !swapfs
&& !(ctx
->options
& E2F_OPT_COMPRESS_DIRS
))
13112 ctx
->options
|= E2F_OPT_READONLY
;
13113 ctx
->io_options
= strchr(argv
[optind
], '?');
13114 if (ctx
->io_options
)
13115 *ctx
->io_options
++ = 0;
13116 ctx
->filesystem_name
= argv
[optind
];
13117 if (resolve_mount_spec(&ctx
->filesystem_name
) < 0 ||
13118 !ctx
->filesystem_name
) {
13119 bb_error_msg_and_die(_("Unable to resolve '%s'"), argv
[optind
]);
13122 parse_extended_opts(ctx
, extended_opts
);
13125 fd
= open(ctx
->filesystem_name
, O_RDONLY
, 0);
13127 bb_error_msg_and_die(_("while opening %s for flushing"),
13128 ctx
->filesystem_name
);
13130 if ((retval
= ext2fs_sync_device(fd
, 1))) {
13131 bb_error_msg_and_die(_("while trying to flush %s"),
13132 ctx
->filesystem_name
);
13136 #ifdef ENABLE_SWAPFS
13137 if (swapfs
&& cflag
) {
13138 fprintf(stderr
, _("Incompatible options not "
13139 "allowed when byte-swapping.\n"));
13144 * Set up signal action
13146 memset(&sa
, 0, sizeof(struct sigaction
));
13147 sa
.sa_handler
= signal_cancel
;
13148 sigaction(SIGINT
, &sa
, 0);
13149 sigaction(SIGTERM
, &sa
, 0);
13151 sa
.sa_flags
= SA_RESTART
;
13153 e2fsck_global_ctx
= ctx
;
13154 sa
.sa_handler
= signal_progress_on
;
13155 sigaction(SIGUSR1
, &sa
, 0);
13156 sa
.sa_handler
= signal_progress_off
;
13157 sigaction(SIGUSR2
, &sa
, 0);
13159 /* Update our PATH to include /sbin if we need to run badblocks */
13161 e2fs_set_sbin_path();
13165 static const char my_ver_string
[] = E2FSPROGS_VERSION
;
13166 static const char my_ver_date
[] = E2FSPROGS_DATE
;
13168 int e2fsck_main (int argc
, char **argv
) MAIN_EXTERNALLY_VISIBLE
;
13169 int e2fsck_main (int argc
, char **argv
)
13172 int exit_value
= EXIT_OK
;
13173 ext2_filsys fs
= 0;
13175 struct ext2_super_block
*sb
;
13176 const char *lib_ver_date
;
13177 int my_ver
, lib_ver
;
13179 struct problem_context pctx
;
13180 int flags
, run_result
;
13182 clear_problem_context(&pctx
);
13184 my_ver
= ext2fs_parse_version_string(my_ver_string
);
13185 lib_ver
= ext2fs_get_library_version(0, &lib_ver_date
);
13186 if (my_ver
> lib_ver
) {
13187 fprintf( stderr
, _("Error: ext2fs library version "
13188 "out of date!\n"));
13189 show_version_only
++;
13192 retval
= PRS(argc
, argv
, &ctx
);
13194 bb_error_msg(_("while trying to initialize program"));
13197 reserve_stdio_fds();
13199 if (!(ctx
->options
& E2F_OPT_PREEN
) || show_version_only
)
13200 fprintf(stderr
, "e2fsck %s (%s)\n", my_ver_string
,
13203 if (show_version_only
) {
13204 fprintf(stderr
, _("\tUsing %s, %s\n"),
13205 error_message(EXT2_ET_BASE
), lib_ver_date
);
13211 if (!(ctx
->options
& E2F_OPT_PREEN
) &&
13212 !(ctx
->options
& E2F_OPT_NO
) &&
13213 !(ctx
->options
& E2F_OPT_YES
)) {
13214 if (!ctx
->interactive
)
13215 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13217 ctx
->superblock
= ctx
->use_superblock
;
13219 #ifdef CONFIG_TESTIO_DEBUG
13220 io_ptr
= test_io_manager
;
13221 test_io_backing_manager
= unix_io_manager
;
13223 io_ptr
= unix_io_manager
;
13226 if ((ctx
->options
& E2F_OPT_READONLY
) == 0)
13227 flags
|= EXT2_FLAG_RW
;
13229 if (ctx
->superblock
&& ctx
->blocksize
) {
13230 retval
= ext2fs_open2(ctx
->filesystem_name
, ctx
->io_options
,
13231 flags
, ctx
->superblock
, ctx
->blocksize
,
13233 } else if (ctx
->superblock
) {
13235 for (blocksize
= EXT2_MIN_BLOCK_SIZE
;
13236 blocksize
<= EXT2_MAX_BLOCK_SIZE
; blocksize
*= 2) {
13237 retval
= ext2fs_open2(ctx
->filesystem_name
,
13238 ctx
->io_options
, flags
,
13239 ctx
->superblock
, blocksize
,
13245 retval
= ext2fs_open2(ctx
->filesystem_name
, ctx
->io_options
,
13246 flags
, 0, 0, io_ptr
, &fs
);
13247 if (!ctx
->superblock
&& !(ctx
->options
& E2F_OPT_PREEN
) &&
13248 !(ctx
->flags
& E2F_FLAG_SB_SPECIFIED
) &&
13249 ((retval
== EXT2_ET_BAD_MAGIC
) ||
13250 ((retval
== 0) && ext2fs_check_desc(fs
)))) {
13251 if (!fs
|| (fs
->group_desc_count
> 1)) {
13252 printf(_("%s trying backup blocks...\n"),
13253 retval
? _("Couldn't find ext2 superblock,") :
13254 _("Group descriptors look bad..."));
13255 get_backup_sb(ctx
, fs
, ctx
->filesystem_name
, io_ptr
);
13262 bb_error_msg(_("while trying to open %s"),
13263 ctx
->filesystem_name
);
13264 if (retval
== EXT2_ET_REV_TOO_HIGH
) {
13265 printf(_("The filesystem revision is apparently "
13266 "too high for this version of e2fsck.\n"
13267 "(Or the filesystem superblock "
13268 "is corrupt)\n\n"));
13269 fix_problem(ctx
, PR_0_SB_CORRUPT
, &pctx
);
13270 } else if (retval
== EXT2_ET_SHORT_READ
)
13271 printf(_("Could this be a zero-length partition?\n"));
13272 else if ((retval
== EPERM
) || (retval
== EACCES
))
13273 printf(_("You must have %s access to the "
13274 "filesystem or be root\n"),
13275 (ctx
->options
& E2F_OPT_READONLY
) ?
13277 else if (retval
== ENXIO
)
13278 printf(_("Possibly non-existent or swap device?\n"));
13280 else if (retval
== EROFS
)
13281 printf(_("Disk write-protected; use the -n option "
13282 "to do a read-only\n"
13283 "check of the device.\n"));
13286 fix_problem(ctx
, PR_0_SB_CORRUPT
, &pctx
);
13287 bb_error_msg_and_die(0);
13290 fs
->priv_data
= ctx
;
13292 if (sb
->s_rev_level
> E2FSCK_CURRENT_REV
) {
13293 bb_error_msg(_("while trying to open %s"),
13294 ctx
->filesystem_name
);
13296 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13300 * Set the device name, which is used whenever we print error
13301 * or informational messages to the user.
13303 if (ctx
->device_name
== 0 &&
13304 (sb
->s_volume_name
[0] != 0)) {
13305 ctx
->device_name
= string_copy(sb
->s_volume_name
,
13306 sizeof(sb
->s_volume_name
));
13308 if (ctx
->device_name
== 0)
13309 ctx
->device_name
= ctx
->filesystem_name
;
13312 * Make sure the ext3 superblock fields are consistent.
13314 retval
= e2fsck_check_ext3_journal(ctx
);
13316 bb_error_msg_and_die(_("while checking ext3 journal for %s"),
13321 * Check to see if we need to do ext3-style recovery. If so,
13322 * do it, and then restart the fsck.
13324 if (sb
->s_feature_incompat
& EXT3_FEATURE_INCOMPAT_RECOVER
) {
13325 if (ctx
->options
& E2F_OPT_READONLY
) {
13326 printf(_("Warning: skipping journal recovery "
13327 "because doing a read-only filesystem "
13329 io_channel_flush(ctx
->fs
->io
);
13331 if (ctx
->flags
& E2F_FLAG_RESTARTED
) {
13333 * Whoops, we attempted to run the
13334 * journal twice. This should never
13335 * happen, unless the hardware or
13336 * device driver is being bogus.
13338 bb_error_msg_and_die(_("can't set superblock flags on %s"), ctx
->device_name
);
13340 retval
= e2fsck_run_ext3_journal(ctx
);
13342 bb_error_msg_and_die(_("while recovering ext3 journal of %s"),
13345 ext2fs_close(ctx
->fs
);
13347 ctx
->flags
|= E2F_FLAG_RESTARTED
;
13353 * Check for compatibility with the feature sets. We need to
13354 * be more stringent than ext2fs_open().
13356 if ((sb
->s_feature_compat
& ~EXT2_LIB_FEATURE_COMPAT_SUPP
) ||
13357 (sb
->s_feature_incompat
& ~EXT2_LIB_FEATURE_INCOMPAT_SUPP
)) {
13358 bb_error_msg("(%s)", ctx
->device_name
);
13361 if (sb
->s_feature_ro_compat
& ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP
) {
13362 bb_error_msg("(%s)", ctx
->device_name
);
13365 #ifdef ENABLE_COMPRESSION
13366 /* FIXME - do we support this at all? */
13367 if (sb
->s_feature_incompat
& EXT2_FEATURE_INCOMPAT_COMPRESSION
)
13368 bb_error_msg(_("warning: compression support is experimental"));
13370 #ifndef ENABLE_HTREE
13371 if (sb
->s_feature_compat
& EXT2_FEATURE_COMPAT_DIR_INDEX
) {
13372 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13373 "but filesystem %s has HTREE directories."),
13380 * If the user specified a specific superblock, presumably the
13381 * master superblock has been trashed. So we mark the
13382 * superblock as dirty, so it can be written out.
13384 if (ctx
->superblock
&&
13385 !(ctx
->options
& E2F_OPT_READONLY
))
13386 ext2fs_mark_super_dirty(fs
);
13389 * We only update the master superblock because (a) paranoia;
13390 * we don't want to corrupt the backup superblocks, and (b) we
13391 * don't need to update the mount count and last checked
13392 * fields in the backup superblock (the kernel doesn't
13393 * update the backup superblocks anyway).
13395 fs
->flags
|= EXT2_FLAG_MASTER_SB_ONLY
;
13397 ehandler_init(fs
->io
);
13399 if (ctx
->superblock
)
13400 set_latch_flags(PR_LATCH_RELOC
, PRL_LATCHED
, 0);
13401 ext2fs_mark_valid(fs
);
13402 check_super_block(ctx
);
13403 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
13404 bb_error_msg_and_die(0);
13405 check_if_skip(ctx
);
13406 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
13407 bb_error_msg_and_die(0);
13408 #ifdef ENABLE_SWAPFS
13410 #ifdef WORDS_BIGENDIAN
13411 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13413 #define NATIVE_FLAG 0
13417 if (normalize_swapfs
) {
13418 if ((fs
->flags
& EXT2_FLAG_SWAP_BYTES
) == NATIVE_FLAG
) {
13419 fprintf(stderr
, _("%s: Filesystem byte order "
13420 "already normalized.\n"), ctx
->device_name
);
13421 bb_error_msg_and_die(0);
13426 if (ctx
->flags
& E2F_FLAG_SIGNAL_MASK
)
13427 bb_error_msg_and_die(0);
13432 * Mark the system as valid, 'til proven otherwise
13434 ext2fs_mark_valid(fs
);
13436 retval
= ext2fs_read_bb_inode(fs
, &fs
->badblocks
);
13438 bb_error_msg(_("while reading bad blocks inode"));
13440 printf(_("This doesn't bode well,"
13441 " but we'll try to go on...\n"));
13444 run_result
= e2fsck_run(ctx
);
13445 e2fsck_clear_progbar(ctx
);
13446 if (run_result
== E2F_FLAG_RESTART
) {
13447 printf(_("Restarting e2fsck from the beginning...\n"));
13448 retval
= e2fsck_reset_context(ctx
);
13450 bb_error_msg_and_die(_("while resetting context"));
13455 if (run_result
& E2F_FLAG_CANCEL
) {
13456 printf(_("%s: e2fsck canceled.\n"), ctx
->device_name
?
13457 ctx
->device_name
: ctx
->filesystem_name
);
13458 exit_value
|= FSCK_CANCELED
;
13460 if (run_result
& E2F_FLAG_ABORT
)
13461 bb_error_msg_and_die(_("aborted"));
13464 if (ext2fs_test_changed(fs
)) {
13465 exit_value
|= EXIT_NONDESTRUCT
;
13466 if (!(ctx
->options
& E2F_OPT_PREEN
))
13467 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13469 if (ctx
->mount_flags
& EXT2_MF_ISROOT
) {
13470 printf(_("%s: ***** REBOOT LINUX *****\n"),
13472 exit_value
|= EXIT_DESTRUCT
;
13475 if (!ext2fs_test_valid(fs
)) {
13476 printf(_("\n%s: ********** WARNING: Filesystem still has "
13477 "errors **********\n\n"), ctx
->device_name
);
13478 exit_value
|= EXIT_UNCORRECTED
;
13479 exit_value
&= ~EXIT_NONDESTRUCT
;
13481 if (exit_value
& FSCK_CANCELED
)
13482 exit_value
&= ~EXIT_NONDESTRUCT
;
13485 if (!(ctx
->options
& E2F_OPT_READONLY
)) {
13486 if (ext2fs_test_valid(fs
)) {
13487 if (!(sb
->s_state
& EXT2_VALID_FS
))
13488 exit_value
|= EXIT_NONDESTRUCT
;
13489 sb
->s_state
= EXT2_VALID_FS
;
13491 sb
->s_state
&= ~EXT2_VALID_FS
;
13492 sb
->s_mnt_count
= 0;
13493 sb
->s_lastcheck
= time(NULL
);
13494 ext2fs_mark_super_dirty(fs
);
13498 e2fsck_write_bitmaps(ctx
);
13502 if (ENABLE_FEATURE_CLEAN_UP
) {
13503 free(ctx
->filesystem_name
);
13504 free(ctx
->journal_name
);
13506 e2fsck_free_context(ctx
);