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.
33 //usage:#define e2fsck_trivial_usage
34 //usage: "[-panyrcdfvstDFSV] [-b superblock] [-B blocksize] "
35 //usage: "[-I inode_buffer_blocks] [-P process_inode_size] "
36 //usage: "[-l|-L bad_blocks_file] [-C fd] [-j external_journal] "
37 //usage: "[-E extended-options] device"
38 //usage:#define e2fsck_full_usage "\n\n"
39 //usage: "Check ext2/ext3 file system\n"
40 //usage: "\n -p Automatic repair (no questions)"
41 //usage: "\n -n Make no changes to the filesystem"
42 //usage: "\n -y Assume 'yes' to all questions"
43 //usage: "\n -c Check for bad blocks and add them to the badblock list"
44 //usage: "\n -f Force checking even if filesystem is marked clean"
45 //usage: "\n -v Verbose"
46 //usage: "\n -b superblock Use alternative superblock"
47 //usage: "\n -B blocksize Force blocksize when looking for superblock"
48 //usage: "\n -j journal Set location of the external journal"
49 //usage: "\n -l file Add to badblocks list"
50 //usage: "\n -L file Set badblocks list"
53 #include "e2fsck.h" /*Put all of our defines here to clean things up*/
59 * Procedure declarations
62 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
65 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
68 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
69 ext2_ino_t ino, char *buf);
72 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
73 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
74 int num, int gauranteed_size);
75 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
76 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
80 static void e2fsck_rehash_directories(e2fsck_t ctx);
83 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
84 const char *description);
85 static int ask(e2fsck_t ctx, const char * string, int def);
86 static void e2fsck_read_bitmaps(e2fsck_t ctx);
87 static void preenhalt(e2fsck_t ctx);
88 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
89 struct ext2_inode * inode, const char * proc);
90 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
91 struct ext2_inode * inode, const char * proc);
92 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
93 const char *name, io_manager manager);
96 static void e2fsck_clear_progbar(e2fsck_t ctx);
97 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
98 float percent, unsigned int dpynum);
102 * problem.h --- e2fsck problem error codes
105 typedef __u32 problem_t;
107 struct problem_context {
109 ext2_ino_t ino, ino2, dir;
110 struct ext2_inode *inode;
111 struct ext2_dir_entry *dirent;
113 e2_blkcnt_t blkcount;
121 * Function declarations
123 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
124 static int end_problem_latch(e2fsck_t ctx, int mask);
125 static int set_latch_flags(int mask, int setflags, int clearflags);
126 static void clear_problem_context(struct problem_context *ctx);
129 * Dictionary Abstract Data Type
130 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
132 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
140 * Blurb for inclusion into C++ translation units
143 typedef unsigned long dictcount_t;
144 #define DICTCOUNT_T_MAX ULONG_MAX
147 * The dictionary is implemented as a red-black tree
150 typedef enum { dnode_red, dnode_black } dnode_color_t;
152 typedef struct dnode_t {
153 struct dnode_t *dict_left;
154 struct dnode_t *dict_right;
155 struct dnode_t *dict_parent;
156 dnode_color_t dict_color;
157 const void *dict_key;
161 typedef int (*dict_comp_t)(const void *, const void *);
162 typedef void (*dnode_free_t)(dnode_t *);
164 typedef struct dict_t {
165 dnode_t dict_nilnode;
166 dictcount_t dict_nodecount;
167 dictcount_t dict_maxcount;
168 dict_comp_t dict_compare;
169 dnode_free_t dict_freenode;
173 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
175 typedef struct dict_load_t {
176 dict_t *dict_dictptr;
177 dnode_t dict_nilnode;
180 #define dict_count(D) ((D)->dict_nodecount)
181 #define dnode_get(N) ((N)->dict_data)
182 #define dnode_getkey(N) ((N)->dict_key)
187 * Compatibility header file for e2fsck which should be included
188 * instead of linux/jfs.h
190 * Copyright (C) 2000 Stephen C. Tweedie
194 * Pull in the definition of the e2fsck context structure
210 #define K_DEV_JOURNAL 2
212 #define lock_buffer(bh) do {} while (0)
213 #define unlock_buffer(bh) do {} while (0)
214 #define buffer_req(bh) 1
215 #define do_readahead(journal, start) do {} while (0)
217 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
223 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
226 * We use the standard libext2fs portability tricks for inline
230 static kmem_cache_t * do_cache_create(int len)
232 kmem_cache_t *new_cache;
234 new_cache = xmalloc(sizeof(*new_cache));
235 new_cache->object_length = len;
239 static void do_cache_destroy(kmem_cache_t *cache)
246 * Dictionary Abstract Data Type
251 * These macros provide short convenient names for structure members,
252 * which are embellished with dict_ prefixes so that they are
253 * properly confined to the documented namespace. It's legal for a
254 * program which uses dict to define, for instance, a macro called ``parent''.
255 * Such a macro would interfere with the dnode_t struct definition.
256 * In general, highly portable and reusable C modules which expose their
257 * structures need to confine structure member names to well-defined spaces.
258 * The resulting identifiers aren't necessarily convenient to use, nor
259 * readable, in the implementation, however!
262 #define left dict_left
263 #define right dict_right
264 #define parent dict_parent
265 #define color dict_color
267 #define data dict_data
269 #define nilnode dict_nilnode
270 #define maxcount dict_maxcount
271 #define compare dict_compare
272 #define dupes dict_dupes
274 #define dict_root(D) ((D)->nilnode.left)
275 #define dict_nil(D) (&(D)->nilnode)
277 static void dnode_free(dnode_t *node);
280 * Perform a ``left rotation'' adjustment on the tree. The given node P and
281 * its right child C are rearranged so that the P instead becomes the left
282 * child of C. The left subtree of C is inherited as the new right subtree
283 * for P. The ordering of the keys within the tree is thus preserved.
286 static void rotate_left(dnode_t *upper)
288 dnode_t *lower, *lowleft, *upparent;
290 lower = upper->right;
291 upper->right = lowleft = lower->left;
292 lowleft->parent = upper;
294 lower->parent = upparent = upper->parent;
296 /* don't need to check for root node here because root->parent is
297 the sentinel nil node, and root->parent->left points back to root */
299 if (upper == upparent->left) {
300 upparent->left = lower;
302 assert (upper == upparent->right);
303 upparent->right = lower;
307 upper->parent = lower;
311 * This operation is the ``mirror'' image of rotate_left. It is
312 * the same procedure, but with left and right interchanged.
315 static void rotate_right(dnode_t *upper)
317 dnode_t *lower, *lowright, *upparent;
320 upper->left = lowright = lower->right;
321 lowright->parent = upper;
323 lower->parent = upparent = upper->parent;
325 if (upper == upparent->right) {
326 upparent->right = lower;
328 assert (upper == upparent->left);
329 upparent->left = lower;
332 lower->right = upper;
333 upper->parent = lower;
337 * Do a postorder traversal of the tree rooted at the specified
338 * node and free everything under it. Used by dict_free().
341 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
345 free_nodes(dict, node->left, nil);
346 free_nodes(dict, node->right, nil);
347 dict->dict_freenode(node);
351 * Verify that the tree contains the given node. This is done by
352 * traversing all of the nodes and comparing their pointers to the
353 * given pointer. Returns 1 if the node is found, otherwise
354 * returns zero. It is intended for debugging purposes.
357 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
361 || verify_dict_has_node(nil, root->left, node)
362 || verify_dict_has_node(nil, root->right, node);
369 * Select a different set of node allocator routines.
372 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
374 assert(dict_count(dict) == 0);
375 dict->dict_freenode = fr;
379 * Free all the nodes in the dictionary by using the dictionary's
380 * installed free routine. The dictionary is emptied.
383 static void dict_free_nodes(dict_t *dict)
385 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
386 free_nodes(dict, root, nil);
387 dict->dict_nodecount = 0;
388 dict->nilnode.left = &dict->nilnode;
389 dict->nilnode.right = &dict->nilnode;
393 * Initialize a user-supplied dictionary object.
396 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
398 dict->compare = comp;
399 dict->dict_freenode = dnode_free;
400 dict->dict_nodecount = 0;
401 dict->maxcount = maxcount;
402 dict->nilnode.left = &dict->nilnode;
403 dict->nilnode.right = &dict->nilnode;
404 dict->nilnode.parent = &dict->nilnode;
405 dict->nilnode.color = dnode_black;
411 * Locate a node in the dictionary having the given key.
412 * If the node is not found, a null a pointer is returned (rather than
413 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
414 * located node is returned.
417 static dnode_t *dict_lookup(dict_t *dict, const void *key)
419 dnode_t *root = dict_root(dict);
420 dnode_t *nil = dict_nil(dict);
424 /* simple binary search adapted for trees that contain duplicate keys */
426 while (root != nil) {
427 result = dict->compare(key, root->key);
433 if (!dict->dupes) { /* no duplicates, return match */
435 } else { /* could be dupes, find leftmost one */
439 while (root != nil && dict->compare(key, root->key))
441 } while (root != nil);
451 * Insert a node into the dictionary. The node should have been
452 * initialized with a data field. All other fields are ignored.
453 * The behavior is undefined if the user attempts to insert into
454 * a dictionary that is already full (for which the dict_isfull()
455 * function returns true).
458 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
460 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
461 dnode_t *parent = nil, *uncle, *grandpa;
466 /* basic binary tree insert */
468 while (where != nil) {
470 result = dict->compare(key, where->key);
471 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
472 assert(dict->dupes || result != 0);
476 where = where->right;
479 assert(where == nil);
484 parent->right = node;
486 node->parent = parent;
490 dict->dict_nodecount++;
492 /* red black adjustments */
494 node->color = dnode_red;
496 while (parent->color == dnode_red) {
497 grandpa = parent->parent;
498 if (parent == grandpa->left) {
499 uncle = grandpa->right;
500 if (uncle->color == dnode_red) { /* red parent, red uncle */
501 parent->color = dnode_black;
502 uncle->color = dnode_black;
503 grandpa->color = dnode_red;
505 parent = grandpa->parent;
506 } else { /* red parent, black uncle */
507 if (node == parent->right) {
510 assert (grandpa == parent->parent);
511 /* rotation between parent and child preserves grandpa */
513 parent->color = dnode_black;
514 grandpa->color = dnode_red;
515 rotate_right(grandpa);
518 } else { /* symmetric cases: parent == parent->parent->right */
519 uncle = grandpa->left;
520 if (uncle->color == dnode_red) {
521 parent->color = dnode_black;
522 uncle->color = dnode_black;
523 grandpa->color = dnode_red;
525 parent = grandpa->parent;
527 if (node == parent->left) {
528 rotate_right(parent);
530 assert (grandpa == parent->parent);
532 parent->color = dnode_black;
533 grandpa->color = dnode_red;
534 rotate_left(grandpa);
540 dict_root(dict)->color = dnode_black;
544 * Allocate a node using the dictionary's allocator routine, give it
548 static dnode_t *dnode_init(dnode_t *dnode, void *data)
551 dnode->parent = NULL;
557 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
559 dnode_t *node = xmalloc(sizeof(dnode_t));
561 dnode_init(node, data);
562 dict_insert(dict, node, key);
567 * Return the node with the lowest (leftmost) key. If the dictionary is empty
568 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
571 static dnode_t *dict_first(dict_t *dict)
573 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
576 while ((left = root->left) != nil)
579 return (root == nil) ? NULL : root;
583 * Return the given node's successor node---the node which has the
584 * next key in the left to right ordering. If the node has
585 * no successor, a null pointer is returned rather than a pointer to
589 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
591 dnode_t *nil = dict_nil(dict), *parent, *left;
593 if (curr->right != nil) {
595 while ((left = curr->left) != nil)
600 parent = curr->parent;
602 while (parent != nil && curr == parent->right) {
604 parent = curr->parent;
607 return (parent == nil) ? NULL : parent;
611 static void dnode_free(dnode_t *node)
631 * dirinfo.c --- maintains the directory information table for e2fsck.
635 * This subroutine is called during pass1 to create a directory info
636 * entry. During pass1, the passed-in parent is 0; it will get filled
639 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
641 struct dir_info *dir;
645 unsigned long old_size;
647 if (!ctx->dir_info) {
648 ctx->dir_info_count = 0;
649 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
651 num_dirs = 1024; /* Guess */
652 ctx->dir_info_size = num_dirs + 10;
653 ctx->dir_info = (struct dir_info *)
654 e2fsck_allocate_memory(ctx, ctx->dir_info_size
655 * sizeof (struct dir_info),
659 if (ctx->dir_info_count >= ctx->dir_info_size) {
660 old_size = ctx->dir_info_size * sizeof(struct dir_info);
661 ctx->dir_info_size += 10;
662 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
663 sizeof(struct dir_info),
666 ctx->dir_info_size -= 10;
672 * Normally, add_dir_info is called with each inode in
673 * sequential order; but once in a while (like when pass 3
674 * needs to recreate the root directory or lost+found
675 * directory) it is called out of order. In those cases, we
676 * need to move the dir_info entries down to make room, since
677 * the dir_info array needs to be sorted by inode number for
678 * get_dir_info()'s sake.
680 if (ctx->dir_info_count &&
681 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
682 for (i = ctx->dir_info_count-1; i > 0; i--)
683 if (ctx->dir_info[i-1].ino < ino)
685 dir = &ctx->dir_info[i];
687 for (j = ctx->dir_info_count++; j > i; j--)
688 ctx->dir_info[j] = ctx->dir_info[j-1];
690 dir = &ctx->dir_info[ctx->dir_info_count++];
693 dir->dotdot = parent;
694 dir->parent = parent;
698 * get_dir_info() --- given an inode number, try to find the directory
699 * information entry for it.
701 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
706 high = ctx->dir_info_count-1;
709 if (ino == ctx->dir_info[low].ino)
710 return &ctx->dir_info[low];
711 if (ino == ctx->dir_info[high].ino)
712 return &ctx->dir_info[high];
716 if (mid == low || mid == high)
718 if (ino == ctx->dir_info[mid].ino)
719 return &ctx->dir_info[mid];
720 if (ino < ctx->dir_info[mid].ino)
729 * Free the dir_info structure when it isn't needed any more.
731 static void e2fsck_free_dir_info(e2fsck_t ctx)
733 ext2fs_free_mem(&ctx->dir_info);
734 ctx->dir_info_size = 0;
735 ctx->dir_info_count = 0;
739 * Return the count of number of directories in the dir_info structure
741 static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
743 return ctx->dir_info_count;
747 * A simple interator function
749 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
751 if (*control >= ctx->dir_info_count)
754 return ctx->dir_info + (*control)++;
758 * dirinfo.c --- maintains the directory information table for e2fsck.
765 * This subroutine is called during pass1 to create a directory info
766 * entry. During pass1, the passed-in parent is 0; it will get filled
769 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
771 struct dx_dir_info *dir;
774 unsigned long old_size;
776 if (!ctx->dx_dir_info) {
777 ctx->dx_dir_info_count = 0;
778 ctx->dx_dir_info_size = 100; /* Guess */
779 ctx->dx_dir_info = (struct dx_dir_info *)
780 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
781 * sizeof (struct dx_dir_info),
785 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
786 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
787 ctx->dx_dir_info_size += 10;
788 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
789 sizeof(struct dx_dir_info),
792 ctx->dx_dir_info_size -= 10;
798 * Normally, add_dx_dir_info is called with each inode in
799 * sequential order; but once in a while (like when pass 3
800 * needs to recreate the root directory or lost+found
801 * directory) it is called out of order. In those cases, we
802 * need to move the dx_dir_info entries down to make room, since
803 * the dx_dir_info array needs to be sorted by inode number for
804 * get_dx_dir_info()'s sake.
806 if (ctx->dx_dir_info_count &&
807 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
808 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
809 if (ctx->dx_dir_info[i-1].ino < ino)
811 dir = &ctx->dx_dir_info[i];
813 for (j = ctx->dx_dir_info_count++; j > i; j--)
814 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
816 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
819 dir->numblocks = num_blocks;
820 dir->hashversion = 0;
821 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
822 * sizeof (struct dx_dirblock_info),
823 "dx_block info array");
827 * get_dx_dir_info() --- given an inode number, try to find the directory
828 * information entry for it.
830 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
835 high = ctx->dx_dir_info_count-1;
836 if (!ctx->dx_dir_info)
838 if (ino == ctx->dx_dir_info[low].ino)
839 return &ctx->dx_dir_info[low];
840 if (ino == ctx->dx_dir_info[high].ino)
841 return &ctx->dx_dir_info[high];
845 if (mid == low || mid == high)
847 if (ino == ctx->dx_dir_info[mid].ino)
848 return &ctx->dx_dir_info[mid];
849 if (ino < ctx->dx_dir_info[mid].ino)
858 * Free the dx_dir_info structure when it isn't needed any more.
860 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
863 struct dx_dir_info *dir;
865 if (ctx->dx_dir_info) {
866 dir = ctx->dx_dir_info;
867 for (i=0; i < ctx->dx_dir_info_count; i++) {
868 ext2fs_free_mem(&dir->dx_block);
870 ext2fs_free_mem(&ctx->dx_dir_info);
872 ctx->dx_dir_info_size = 0;
873 ctx->dx_dir_info_count = 0;
877 * A simple interator function
879 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
881 if (*control >= ctx->dx_dir_info_count)
884 return ctx->dx_dir_info + (*control)++;
887 #endif /* ENABLE_HTREE */
889 * e2fsck.c - a consistency checker for the new extended file system.
894 * This function allocates an e2fsck context
896 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
901 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
905 memset(context, 0, sizeof(struct e2fsck_struct));
907 context->process_inode_size = 256;
908 context->ext_attr_ver = 2;
914 struct ea_refcount_el {
923 struct ea_refcount_el *list;
926 static void ea_refcount_free(ext2_refcount_t refcount)
931 ext2fs_free_mem(&refcount->list);
932 ext2fs_free_mem(&refcount);
936 * This function resets an e2fsck context; it is called when e2fsck
937 * needs to be restarted.
939 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
942 ctx->lost_and_found = 0;
943 ctx->bad_lost_and_found = 0;
944 ext2fs_free_inode_bitmap(ctx->inode_used_map);
945 ctx->inode_used_map = 0;
946 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
947 ctx->inode_dir_map = 0;
948 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
949 ctx->inode_reg_map = 0;
950 ext2fs_free_block_bitmap(ctx->block_found_map);
951 ctx->block_found_map = 0;
952 ext2fs_free_icount(ctx->inode_link_info);
953 ctx->inode_link_info = 0;
954 if (ctx->journal_io) {
955 if (ctx->fs && ctx->fs->io != ctx->journal_io)
956 io_channel_close(ctx->journal_io);
960 ext2fs_free_dblist(ctx->fs->dblist);
963 e2fsck_free_dir_info(ctx);
965 e2fsck_free_dx_dir_info(ctx);
967 ea_refcount_free(ctx->refcount);
969 ea_refcount_free(ctx->refcount_extra);
970 ctx->refcount_extra = 0;
971 ext2fs_free_block_bitmap(ctx->block_dup_map);
972 ctx->block_dup_map = 0;
973 ext2fs_free_block_bitmap(ctx->block_ea_map);
974 ctx->block_ea_map = 0;
975 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
976 ctx->inode_bad_map = 0;
977 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
978 ctx->inode_imagic_map = 0;
979 ext2fs_u32_list_free(ctx->dirs_to_hash);
980 ctx->dirs_to_hash = 0;
983 * Clear the array of invalid meta-data flags
985 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
986 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
987 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
989 /* Clear statistic counters */
990 ctx->fs_directory_count = 0;
991 ctx->fs_regular_count = 0;
992 ctx->fs_blockdev_count = 0;
993 ctx->fs_chardev_count = 0;
994 ctx->fs_links_count = 0;
995 ctx->fs_symlinks_count = 0;
996 ctx->fs_fast_symlinks_count = 0;
997 ctx->fs_fifo_count = 0;
998 ctx->fs_total_count = 0;
999 ctx->fs_sockets_count = 0;
1000 ctx->fs_ind_count = 0;
1001 ctx->fs_dind_count = 0;
1002 ctx->fs_tind_count = 0;
1003 ctx->fs_fragmented = 0;
1004 ctx->large_files = 0;
1006 /* Reset the superblock to the user's requested value */
1007 ctx->superblock = ctx->use_superblock;
1012 static void e2fsck_free_context(e2fsck_t ctx)
1017 e2fsck_reset_context(ctx);
1019 blkid_put_cache(ctx->blkid);
1021 ext2fs_free_mem(&ctx);
1029 * The strategy we use for keeping track of EA refcounts is as
1030 * follows. We keep a sorted array of first EA blocks and its
1031 * reference counts. Once the refcount has dropped to zero, it is
1032 * removed from the array to save memory space. Once the EA block is
1033 * checked, its bit is set in the block_ea_map bitmap.
1037 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1039 ext2_refcount_t refcount;
1043 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1046 memset(refcount, 0, sizeof(struct ea_refcount));
1050 refcount->size = size;
1051 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1053 printf("Refcount allocated %d entries, %d bytes.\n",
1054 refcount->size, bytes);
1056 retval = ext2fs_get_mem(bytes, &refcount->list);
1059 memset(refcount->list, 0, bytes);
1061 refcount->count = 0;
1062 refcount->cursor = 0;
1068 ea_refcount_free(refcount);
1073 * collapse_refcount() --- go through the refcount array, and get rid
1074 * of any count == zero entries
1076 static void refcount_collapse(ext2_refcount_t refcount)
1079 struct ea_refcount_el *list;
1081 list = refcount->list;
1082 for (i = 0, j = 0; i < refcount->count; i++) {
1083 if (list[i].ea_count) {
1089 #if defined(DEBUG) || defined(TEST_PROGRAM)
1090 printf("Refcount_collapse: size was %d, now %d\n",
1091 refcount->count, j);
1093 refcount->count = j;
1098 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1099 * specified position.
1101 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1104 struct ea_refcount_el *el;
1109 if (refcount->count >= refcount->size) {
1110 new_size = refcount->size + 100;
1112 printf("Reallocating refcount %d entries...\n", new_size);
1114 retval = ext2fs_resize_mem((size_t) refcount->size *
1115 sizeof(struct ea_refcount_el),
1117 sizeof(struct ea_refcount_el),
1121 refcount->size = new_size;
1123 num = (int) refcount->count - pos;
1125 return 0; /* should never happen */
1127 memmove(&refcount->list[pos+1], &refcount->list[pos],
1128 sizeof(struct ea_refcount_el) * num);
1131 el = &refcount->list[pos];
1139 * get_refcount_el() --- given an block number, try to find refcount
1140 * information in the sorted list. If the create flag is set,
1141 * and we can't find an entry, create one in the sorted list.
1143 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1144 blk_t blk, int create)
1148 blk_t lowval, highval;
1150 if (!refcount || !refcount->list)
1154 high = (int) refcount->count-1;
1155 if (create && ((refcount->count == 0) ||
1156 (blk > refcount->list[high].ea_blk))) {
1157 if (refcount->count >= refcount->size)
1158 refcount_collapse(refcount);
1160 return insert_refcount_el(refcount, blk,
1161 (unsigned) refcount->count);
1163 if (refcount->count == 0)
1166 if (refcount->cursor >= refcount->count)
1167 refcount->cursor = 0;
1168 if (blk == refcount->list[refcount->cursor].ea_blk)
1169 return &refcount->list[refcount->cursor++];
1171 printf("Non-cursor get_refcount_el: %u\n", blk);
1173 while (low <= high) {
1177 /* Interpolate for efficiency */
1178 lowval = refcount->list[low].ea_blk;
1179 highval = refcount->list[high].ea_blk;
1183 else if (blk > highval)
1186 range = ((float) (blk - lowval)) /
1188 mid = low + ((int) (range * (high-low)));
1191 if (blk == refcount->list[mid].ea_blk) {
1192 refcount->cursor = mid+1;
1193 return &refcount->list[mid];
1195 if (blk < refcount->list[mid].ea_blk)
1201 * If we need to create a new entry, it should be right at
1202 * low (where high will be left at low-1).
1205 if (refcount->count >= refcount->size) {
1206 refcount_collapse(refcount);
1207 if (refcount->count < refcount->size)
1210 return insert_refcount_el(refcount, blk, low);
1216 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1218 struct ea_refcount_el *el;
1220 el = get_refcount_el(refcount, blk, 1);
1222 return EXT2_ET_NO_MEMORY;
1226 *ret = el->ea_count;
1231 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1233 struct ea_refcount_el *el;
1235 el = get_refcount_el(refcount, blk, 0);
1236 if (!el || el->ea_count == 0)
1237 return EXT2_ET_INVALID_ARGUMENT;
1242 *ret = el->ea_count;
1247 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1249 struct ea_refcount_el *el;
1252 * Get the refcount element
1254 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1256 return count ? EXT2_ET_NO_MEMORY : 0;
1257 el->ea_count = count;
1261 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1263 refcount->cursor = 0;
1267 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1269 struct ea_refcount_el *list;
1272 if (refcount->cursor >= refcount->count)
1274 list = refcount->list;
1275 if (list[refcount->cursor].ea_count) {
1277 *ret = list[refcount->cursor].ea_count;
1278 return list[refcount->cursor++].ea_blk;
1286 * ehandler.c --- handle bad block errors which come up during the
1287 * course of an e2fsck session.
1291 static const char *operation;
1294 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1295 void *data, size_t size FSCK_ATTR((unused)),
1296 int actual FSCK_ATTR((unused)), errcode_t error)
1300 ext2_filsys fs = (ext2_filsys) channel->app_data;
1303 ctx = (e2fsck_t) fs->priv_data;
1306 * If more than one block was read, try reading each block
1307 * separately. We could use the actual bytes read to figure
1308 * out where to start, but we don't bother.
1312 for (i=0; i < count; i++, p += channel->block_size, block++) {
1313 error = io_channel_read_blk(channel, block,
1321 printf(_("Error reading block %lu (%s) while %s. "), block,
1322 error_message(error), operation);
1324 printf(_("Error reading block %lu (%s). "), block,
1325 error_message(error));
1327 if (ask(ctx, _("Ignore error"), 1)) {
1328 if (ask(ctx, _("Force rewrite"), 1))
1329 io_channel_write_blk(channel, block, 1, data);
1337 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1338 const void *data, size_t size FSCK_ATTR((unused)),
1339 int actual FSCK_ATTR((unused)), errcode_t error)
1343 ext2_filsys fs = (ext2_filsys) channel->app_data;
1346 ctx = (e2fsck_t) fs->priv_data;
1349 * If more than one block was written, try writing each block
1350 * separately. We could use the actual bytes read to figure
1351 * out where to start, but we don't bother.
1354 p = (const char *) data;
1355 for (i=0; i < count; i++, p += channel->block_size, block++) {
1356 error = io_channel_write_blk(channel, block,
1365 printf(_("Error writing block %lu (%s) while %s. "), block,
1366 error_message(error), operation);
1368 printf(_("Error writing block %lu (%s). "), block,
1369 error_message(error));
1371 if (ask(ctx, _("Ignore error"), 1))
1377 static const char *ehandler_operation(const char *op)
1379 const char *ret = operation;
1385 static void ehandler_init(io_channel channel)
1387 channel->read_error = e2fsck_handle_read_error;
1388 channel->write_error = e2fsck_handle_write_error;
1392 * journal.c --- code for handling the "ext3" journal
1394 * Copyright (C) 2000 Andreas Dilger
1395 * Copyright (C) 2000 Theodore Ts'o
1397 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1398 * Copyright (C) 1999 Red Hat Software
1400 * This file may be redistributed under the terms of the
1401 * GNU General Public License version 2 or at your discretion
1402 * any later version.
1406 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1407 * This creates a larger static binary, and a smaller binary using
1408 * shared libraries. It's also probably slightly less CPU-efficient,
1409 * which is why it's not on by default. But, it's a good way of
1410 * testing the functions in inode_io.c and fileio.c.
1414 /* Kernel compatibility functions for handling the journal. These allow us
1415 * to use the recovery.c file virtually unchanged from the kernel, so we
1416 * don't have to do much to keep kernel and user recovery in sync.
1418 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1424 struct inode *inode = journal->j_inode;
1433 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1434 &inode->i_ext2, NULL, 0, block, &pblk);
1440 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1442 struct buffer_head *bh;
1444 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1448 bh->b_ctx = kdev->k_ctx;
1449 if (kdev->k_dev == K_DEV_FS)
1450 bh->b_io = kdev->k_ctx->fs->io;
1452 bh->b_io = kdev->k_ctx->journal_io;
1453 bh->b_size = blocksize;
1454 bh->b_blocknr = blocknr;
1459 static void sync_blockdev(kdev_t kdev)
1463 if (kdev->k_dev == K_DEV_FS)
1464 io = kdev->k_ctx->fs->io;
1466 io = kdev->k_ctx->journal_io;
1468 io_channel_flush(io);
1471 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1474 struct buffer_head *bh;
1476 for (; nr > 0; --nr) {
1478 if (rw == READ && !bh->b_uptodate) {
1479 retval = io_channel_read_blk(bh->b_io,
1483 bb_error_msg("while reading block %lu",
1484 (unsigned long) bh->b_blocknr);
1489 } else if (rw == WRITE && bh->b_dirty) {
1490 retval = io_channel_write_blk(bh->b_io,
1494 bb_error_msg("while writing block %lu",
1495 (unsigned long) bh->b_blocknr);
1505 static void mark_buffer_dirty(struct buffer_head *bh)
1510 static inline void mark_buffer_clean(struct buffer_head * bh)
1515 static void brelse(struct buffer_head *bh)
1518 ll_rw_block(WRITE, 1, &bh);
1519 ext2fs_free_mem(&bh);
1522 static int buffer_uptodate(struct buffer_head *bh)
1524 return bh->b_uptodate;
1527 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1529 bh->b_uptodate = val;
1532 static void wait_on_buffer(struct buffer_head *bh)
1534 if (!bh->b_uptodate)
1535 ll_rw_block(READ, 1, &bh);
1539 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1541 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1543 /* if we had an error doing journal recovery, we need a full fsck */
1545 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1546 ext2fs_mark_super_dirty(ctx->fs);
1549 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1551 struct ext2_super_block *sb = ctx->fs->super;
1552 struct ext2_super_block jsuper;
1553 struct problem_context pctx;
1554 struct buffer_head *bh;
1555 struct inode *j_inode = NULL;
1556 struct kdev_s *dev_fs = NULL, *dev_journal;
1557 const char *journal_name = NULL;
1558 journal_t *journal = NULL;
1559 errcode_t retval = 0;
1560 io_manager io_ptr = 0;
1561 unsigned long start = 0;
1563 int ext_journal = 0;
1564 int tried_backup_jnl = 0;
1567 clear_problem_context(&pctx);
1569 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1571 return EXT2_ET_NO_MEMORY;
1574 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1576 retval = EXT2_ET_NO_MEMORY;
1579 dev_journal = dev_fs+1;
1581 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1582 dev_fs->k_dev = K_DEV_FS;
1583 dev_journal->k_dev = K_DEV_JOURNAL;
1585 journal->j_dev = dev_journal;
1586 journal->j_fs_dev = dev_fs;
1587 journal->j_inode = NULL;
1588 journal->j_blocksize = ctx->fs->blocksize;
1590 if (uuid_is_null(sb->s_journal_uuid)) {
1591 if (!sb->s_journal_inum)
1592 return EXT2_ET_BAD_INODE_NUM;
1593 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1596 retval = EXT2_ET_NO_MEMORY;
1600 j_inode->i_ctx = ctx;
1601 j_inode->i_ino = sb->s_journal_inum;
1603 if ((retval = ext2fs_read_inode(ctx->fs,
1605 &j_inode->i_ext2))) {
1607 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1610 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1611 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1613 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1614 j_inode->i_ext2.i_links_count = 1;
1615 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1618 if (!j_inode->i_ext2.i_links_count ||
1619 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1620 retval = EXT2_ET_NO_JOURNAL;
1621 goto try_backup_journal;
1623 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1624 JFS_MIN_JOURNAL_BLOCKS) {
1625 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1626 goto try_backup_journal;
1628 for (i=0; i < EXT2_N_BLOCKS; i++) {
1629 blk = j_inode->i_ext2.i_block[i];
1631 if (i < EXT2_NDIR_BLOCKS) {
1632 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1633 goto try_backup_journal;
1637 if (blk < sb->s_first_data_block ||
1638 blk >= sb->s_blocks_count) {
1639 retval = EXT2_ET_BAD_BLOCK_NUM;
1640 goto try_backup_journal;
1643 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1646 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1652 io_ptr = inode_io_manager;
1654 journal->j_inode = j_inode;
1655 ctx->journal_io = ctx->fs->io;
1656 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1661 if (!ctx->journal_name) {
1664 uuid_unparse(sb->s_journal_uuid, uuid);
1665 ctx->journal_name = blkid_get_devname(ctx->blkid,
1667 if (!ctx->journal_name)
1668 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1670 journal_name = ctx->journal_name;
1672 if (!journal_name) {
1673 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1674 return EXT2_ET_LOAD_EXT_JOURNAL;
1677 io_ptr = unix_io_manager;
1680 #ifndef USE_INODE_IO
1683 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1688 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1691 if (ctx->fs->blocksize == 1024)
1693 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1695 retval = EXT2_ET_NO_MEMORY;
1698 ll_rw_block(READ, 1, &bh);
1699 if ((retval = bh->b_err) != 0)
1701 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1705 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1706 ext2fs_swap_super(&jsuper);
1708 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1709 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1710 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1711 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1714 /* Make sure the journal UUID is correct */
1715 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1716 sizeof(jsuper.s_uuid))) {
1717 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1718 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1722 journal->j_maxlen = jsuper.s_blocks_count;
1726 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1727 retval = EXT2_ET_NO_MEMORY;
1731 journal->j_sb_buffer = bh;
1732 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1735 ext2fs_free_mem(&j_inode);
1738 *ret_journal = journal;
1742 ext2fs_free_mem(&dev_fs);
1743 ext2fs_free_mem(&j_inode);
1744 ext2fs_free_mem(&journal);
1748 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1749 struct problem_context *pctx)
1751 struct ext2_super_block *sb = ctx->fs->super;
1752 int recover = ctx->fs->super->s_feature_incompat &
1753 EXT3_FEATURE_INCOMPAT_RECOVER;
1754 int has_journal = ctx->fs->super->s_feature_compat &
1755 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1757 if (has_journal || sb->s_journal_inum) {
1758 /* The journal inode is bogus, remove and force full fsck */
1759 pctx->ino = sb->s_journal_inum;
1760 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1761 if (has_journal && sb->s_journal_inum)
1762 printf("*** ext3 journal has been deleted - "
1763 "filesystem is now ext2 only ***\n\n");
1764 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1765 sb->s_journal_inum = 0;
1766 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1767 e2fsck_clear_recover(ctx, 1);
1770 return EXT2_ET_BAD_INODE_NUM;
1771 } else if (recover) {
1772 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1773 e2fsck_clear_recover(ctx, 1);
1776 return EXT2_ET_UNSUPP_FEATURE;
1781 #define V1_SB_SIZE 0x0024
1782 static void clear_v2_journal_fields(journal_t *journal)
1784 e2fsck_t ctx = journal->j_dev->k_ctx;
1785 struct problem_context pctx;
1787 clear_problem_context(&pctx);
1789 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1792 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1793 ctx->fs->blocksize-V1_SB_SIZE);
1794 mark_buffer_dirty(journal->j_sb_buffer);
1798 static errcode_t e2fsck_journal_load(journal_t *journal)
1800 e2fsck_t ctx = journal->j_dev->k_ctx;
1801 journal_superblock_t *jsb;
1802 struct buffer_head *jbh = journal->j_sb_buffer;
1803 struct problem_context pctx;
1805 clear_problem_context(&pctx);
1807 ll_rw_block(READ, 1, &jbh);
1809 bb_error_msg(_("reading journal superblock"));
1813 jsb = journal->j_superblock;
1814 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1815 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1816 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1818 switch (ntohl(jsb->s_header.h_blocktype)) {
1819 case JFS_SUPERBLOCK_V1:
1820 journal->j_format_version = 1;
1821 if (jsb->s_feature_compat ||
1822 jsb->s_feature_incompat ||
1823 jsb->s_feature_ro_compat ||
1825 clear_v2_journal_fields(journal);
1828 case JFS_SUPERBLOCK_V2:
1829 journal->j_format_version = 2;
1830 if (ntohl(jsb->s_nr_users) > 1 &&
1831 uuid_is_null(ctx->fs->super->s_journal_uuid))
1832 clear_v2_journal_fields(journal);
1833 if (ntohl(jsb->s_nr_users) > 1) {
1834 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1835 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1840 * These should never appear in a journal super block, so if
1841 * they do, the journal is badly corrupted.
1843 case JFS_DESCRIPTOR_BLOCK:
1844 case JFS_COMMIT_BLOCK:
1845 case JFS_REVOKE_BLOCK:
1846 return EXT2_ET_CORRUPT_SUPERBLOCK;
1848 /* If we don't understand the superblock major type, but there
1849 * is a magic number, then it is likely to be a new format we
1850 * just don't understand, so leave it alone. */
1852 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1855 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1856 return EXT2_ET_UNSUPP_FEATURE;
1858 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1859 return EXT2_ET_RO_UNSUPP_FEATURE;
1861 /* We have now checked whether we know enough about the journal
1862 * format to be able to proceed safely, so any other checks that
1863 * fail we should attempt to recover from. */
1864 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1865 bb_error_msg(_("%s: no valid journal superblock found"),
1867 return EXT2_ET_CORRUPT_SUPERBLOCK;
1870 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1871 journal->j_maxlen = ntohl(jsb->s_maxlen);
1872 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1873 bb_error_msg(_("%s: journal too short"),
1875 return EXT2_ET_CORRUPT_SUPERBLOCK;
1878 journal->j_tail_sequence = ntohl(jsb->s_sequence);
1879 journal->j_transaction_sequence = journal->j_tail_sequence;
1880 journal->j_tail = ntohl(jsb->s_start);
1881 journal->j_first = ntohl(jsb->s_first);
1882 journal->j_last = ntohl(jsb->s_maxlen);
1887 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
1898 /* Leave a valid existing V1 superblock signature alone.
1899 * Anything unrecognizable we overwrite with a new V2
1902 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
1903 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
1904 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
1905 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
1908 /* Zero out everything else beyond the superblock header */
1910 p = ((char *) jsb) + sizeof(journal_header_t);
1911 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
1913 jsb->s_blocksize = htonl(ctx->fs->blocksize);
1914 jsb->s_maxlen = htonl(journal->j_maxlen);
1915 jsb->s_first = htonl(1);
1917 /* Initialize the journal sequence number so that there is "no"
1918 * chance we will find old "valid" transactions in the journal.
1919 * This avoids the need to zero the whole journal (slow to do,
1920 * and risky when we are just recovering the filesystem).
1922 uuid_generate(u.uuid);
1923 for (i = 0; i < 4; i ++)
1924 new_seq ^= u.val[i];
1925 jsb->s_sequence = htonl(new_seq);
1927 mark_buffer_dirty(journal->j_sb_buffer);
1928 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
1931 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
1933 struct problem_context *pctx)
1935 struct ext2_super_block *sb = ctx->fs->super;
1936 int recover = ctx->fs->super->s_feature_incompat &
1937 EXT3_FEATURE_INCOMPAT_RECOVER;
1939 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
1940 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
1941 e2fsck_journal_reset_super(ctx, journal->j_superblock,
1943 journal->j_transaction_sequence = 1;
1944 e2fsck_clear_recover(ctx, recover);
1947 return EXT2_ET_CORRUPT_SUPERBLOCK;
1948 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
1949 return EXT2_ET_CORRUPT_SUPERBLOCK;
1954 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
1955 int reset, int drop)
1957 journal_superblock_t *jsb;
1960 mark_buffer_clean(journal->j_sb_buffer);
1961 else if (!(ctx->options & E2F_OPT_READONLY)) {
1962 jsb = journal->j_superblock;
1963 jsb->s_sequence = htonl(journal->j_transaction_sequence);
1965 jsb->s_start = 0; /* this marks the journal as empty */
1966 mark_buffer_dirty(journal->j_sb_buffer);
1968 brelse(journal->j_sb_buffer);
1970 if (ctx->journal_io) {
1971 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1972 io_channel_close(ctx->journal_io);
1973 ctx->journal_io = 0;
1976 #ifndef USE_INODE_IO
1977 ext2fs_free_mem(&journal->j_inode);
1979 ext2fs_free_mem(&journal->j_fs_dev);
1980 ext2fs_free_mem(&journal);
1984 * This function makes sure that the superblock fields regarding the
1985 * journal are consistent.
1987 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
1989 struct ext2_super_block *sb = ctx->fs->super;
1991 int recover = ctx->fs->super->s_feature_incompat &
1992 EXT3_FEATURE_INCOMPAT_RECOVER;
1993 struct problem_context pctx;
1995 int reset = 0, force_fsck = 0;
1998 /* If we don't have any journal features, don't do anything more */
1999 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
2000 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
2001 uuid_is_null(sb->s_journal_uuid))
2004 clear_problem_context(&pctx);
2005 pctx.num = sb->s_journal_inum;
2007 retval = e2fsck_get_journal(ctx, &journal);
2009 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2010 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2011 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2012 (retval == EXT2_ET_NO_JOURNAL))
2013 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2017 retval = e2fsck_journal_load(journal);
2019 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2020 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2021 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2023 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2024 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2026 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2027 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2028 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2030 e2fsck_journal_release(ctx, journal, 0, 1);
2035 * We want to make the flags consistent here. We will not leave with
2036 * needs_recovery set but has_journal clear. We can't get in a loop
2037 * with -y, -n, or -p, only if a user isn't making up their mind.
2040 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2041 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2043 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2045 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2046 goto no_has_journal;
2048 * Need a full fsck if we are releasing a
2049 * journal stored on a reserved inode.
2051 force_fsck = recover ||
2052 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2053 /* Clear all of the journal fields */
2054 sb->s_journal_inum = 0;
2055 sb->s_journal_dev = 0;
2056 memset(sb->s_journal_uuid, 0,
2057 sizeof(sb->s_journal_uuid));
2058 e2fsck_clear_recover(ctx, force_fsck);
2059 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2060 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2061 ext2fs_mark_super_dirty(ctx->fs);
2065 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2066 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2067 journal->j_superblock->s_start != 0) {
2068 /* Print status information */
2069 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2070 if (ctx->superblock)
2071 problem = PR_0_JOURNAL_RUN_DEFAULT;
2073 problem = PR_0_JOURNAL_RUN;
2074 if (fix_problem(ctx, problem, &pctx)) {
2075 ctx->options |= E2F_OPT_FORCE;
2076 sb->s_feature_incompat |=
2077 EXT3_FEATURE_INCOMPAT_RECOVER;
2078 ext2fs_mark_super_dirty(ctx->fs);
2079 } else if (fix_problem(ctx,
2080 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2082 sb->s_state &= ~EXT2_VALID_FS;
2083 ext2fs_mark_super_dirty(ctx->fs);
2086 * If the user answers no to the above question, we
2087 * ignore the fact that journal apparently has data;
2088 * accidentally replaying over valid data would be far
2089 * worse than skipping a questionable recovery.
2091 * XXX should we abort with a fatal error here? What
2092 * will the ext3 kernel code do if a filesystem with
2093 * !NEEDS_RECOVERY but with a non-zero
2094 * journal->j_superblock->s_start is mounted?
2098 e2fsck_journal_release(ctx, journal, reset, 0);
2102 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2107 journal_init_revoke_caches();
2108 retval = e2fsck_get_journal(ctx, &journal);
2112 retval = e2fsck_journal_load(journal);
2116 retval = journal_init_revoke(journal, 1024);
2120 retval = -journal_recover(journal);
2124 if (journal->j_superblock->s_errno) {
2125 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2126 ext2fs_mark_super_dirty(ctx->fs);
2127 journal->j_superblock->s_errno = 0;
2128 mark_buffer_dirty(journal->j_sb_buffer);
2132 journal_destroy_revoke(journal);
2133 journal_destroy_revoke_caches();
2134 e2fsck_journal_release(ctx, journal, 1, 0);
2138 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2140 io_manager io_ptr = ctx->fs->io->manager;
2141 int blocksize = ctx->fs->blocksize;
2142 errcode_t retval, recover_retval;
2144 printf(_("%s: recovering journal\n"), ctx->device_name);
2145 if (ctx->options & E2F_OPT_READONLY) {
2146 printf(_("%s: won't do journal recovery while read-only\n"),
2148 return EXT2_ET_FILE_RO;
2151 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2152 ext2fs_flush(ctx->fs); /* Force out any modifications */
2154 recover_retval = recover_ext3_journal(ctx);
2157 * Reload the filesystem context to get up-to-date data from disk
2158 * because journal recovery will change the filesystem under us.
2160 ext2fs_close(ctx->fs);
2161 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2162 ctx->superblock, blocksize, io_ptr,
2166 bb_error_msg(_("while trying to re-open %s"),
2168 bb_error_msg_and_die(0);
2170 ctx->fs->priv_data = ctx;
2172 /* Set the superblock flags */
2173 e2fsck_clear_recover(ctx, recover_retval);
2174 return recover_retval;
2178 * This function will move the journal inode from a visible file in
2179 * the filesystem directory hierarchy to the reserved inode if necessary.
2181 static const char *const journal_names[] = {
2182 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2184 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2186 struct ext2_super_block *sb = ctx->fs->super;
2187 struct problem_context pctx;
2188 struct ext2_inode inode;
2189 ext2_filsys fs = ctx->fs;
2192 const char *const * cpp;
2193 int group, mount_flags;
2195 clear_problem_context(&pctx);
2198 * If the filesystem is opened read-only, or there is no
2199 * journal, then do nothing.
2201 if ((ctx->options & E2F_OPT_READONLY) ||
2202 (sb->s_journal_inum == 0) ||
2203 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2207 * Read in the journal inode
2209 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2213 * If it's necessary to backup the journal inode, do so.
2215 if ((sb->s_jnl_backup_type == 0) ||
2216 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2217 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2218 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2219 memcpy(sb->s_jnl_blocks, inode.i_block,
2221 sb->s_jnl_blocks[16] = inode.i_size;
2222 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2223 ext2fs_mark_super_dirty(fs);
2224 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2229 * If the journal is already the hidden inode, then do nothing
2231 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2235 * The journal inode had better have only one link and not be readable.
2237 if (inode.i_links_count != 1)
2241 * If the filesystem is mounted, or we can't tell whether
2242 * or not it's mounted, do nothing.
2244 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2245 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2249 * If we can't find the name of the journal inode, then do
2252 for (cpp = journal_names; *cpp; cpp++) {
2253 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2254 strlen(*cpp), 0, &ino);
2255 if ((retval == 0) && (ino == sb->s_journal_inum))
2261 /* We need the inode bitmap to be loaded */
2262 retval = ext2fs_read_bitmaps(fs);
2267 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2271 * OK, we've done all the checks, let's actually move the
2272 * journal inode. Errors at this point mean we need to force
2273 * an ext2 filesystem check.
2275 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2277 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2279 sb->s_journal_inum = EXT2_JOURNAL_INO;
2280 ext2fs_mark_super_dirty(fs);
2281 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2282 inode.i_links_count = 0;
2283 inode.i_dtime = time(NULL);
2284 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2287 group = ext2fs_group_of_ino(fs, ino);
2288 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2289 ext2fs_mark_ib_dirty(fs);
2290 fs->group_desc[group].bg_free_inodes_count++;
2291 fs->super->s_free_inodes_count++;
2295 pctx.errcode = retval;
2296 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2297 fs->super->s_state &= ~EXT2_VALID_FS;
2298 ext2fs_mark_super_dirty(fs);
2302 * message.c --- print e2fsck messages (with compression)
2304 * print_e2fsck_message() prints a message to the user, using
2305 * compression techniques and expansions of abbreviations.
2307 * The following % expansions are supported:
2309 * %b <blk> block number
2310 * %B <blkcount> integer
2311 * %c <blk2> block number
2312 * %Di <dirent>->ino inode number
2313 * %Dn <dirent>->name string
2314 * %Dr <dirent>->rec_len
2315 * %Dl <dirent>->name_len
2316 * %Dt <dirent>->filetype
2317 * %d <dir> inode number
2318 * %g <group> integer
2319 * %i <ino> inode number
2320 * %Is <inode> -> i_size
2321 * %IS <inode> -> i_extra_isize
2322 * %Ib <inode> -> i_blocks
2323 * %Il <inode> -> i_links_count
2324 * %Im <inode> -> i_mode
2325 * %IM <inode> -> i_mtime
2326 * %IF <inode> -> i_faddr
2327 * %If <inode> -> i_file_acl
2328 * %Id <inode> -> i_dir_acl
2329 * %Iu <inode> -> i_uid
2330 * %Ig <inode> -> i_gid
2331 * %j <ino2> inode number
2332 * %m <com_err error message>
2334 * %p ext2fs_get_pathname of directory <ino>
2335 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2336 * the containing directory. (If dirent is NULL
2337 * then return the pathname of directory <ino2>)
2338 * %q ext2fs_get_pathname of directory <dir>
2339 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2340 * the containing directory.
2341 * %s <str> miscellaneous string
2342 * %S backup superblock
2343 * %X <num> hexadecimal format
2345 * The following '@' expansions are supported:
2347 * @a extended attribute
2348 * @A error allocating
2352 * @C conflicts with some other fs block
2356 * @E Entry '%Dn' in %p (%i)
2358 * @F for @i %i (%Q) is
2360 * @h HTREE directory inode
2366 * @m multiply-claimed
2380 * This structure defines the abbreviations used by the text strings
2381 * below. The first character in the string is the index letter. An
2382 * abbreviation of the form '@<i>' is expanded by looking up the index
2383 * letter <i> in the table below.
2385 static const char *const abbrevs[] = {
2386 N_("aextended attribute"),
2387 N_("Aerror allocating"),
2391 N_("Cconflicts with some other fs @b"),
2398 N_("E@e '%Dn' in %p (%i)"),
2400 N_("Ffor @i %i (%Q) is"),
2405 N_("mmultiply-claimed"),
2420 * Give more user friendly names to the "special" inodes.
2422 #define num_special_inodes 11
2423 static const char *const special_inode_name[] =
2425 N_("<The NULL inode>"), /* 0 */
2426 N_("<The bad blocks inode>"), /* 1 */
2428 N_("<The ACL index inode>"), /* 3 */
2429 N_("<The ACL data inode>"), /* 4 */
2430 N_("<The boot loader inode>"), /* 5 */
2431 N_("<The undelete directory inode>"), /* 6 */
2432 N_("<The group descriptor inode>"), /* 7 */
2433 N_("<The journal inode>"), /* 8 */
2434 N_("<Reserved inode 9>"), /* 9 */
2435 N_("<Reserved inode 10>"), /* 10 */
2439 * This function does "safe" printing. It will convert non-printable
2440 * ASCII characters using '^' and M- notation.
2442 static void safe_print(const char *cp, int len)
2452 fputs("M-", stdout);
2455 if ((ch < 32) || (ch == 0x7f)) {
2457 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2465 * This function prints a pathname, using the ext2fs_get_pathname
2468 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2473 if (!dir && (ino < num_special_inodes)) {
2474 fputs(_(special_inode_name[ino]), stdout);
2478 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2480 fputs("???", stdout);
2482 safe_print(path, -1);
2483 ext2fs_free_mem(&path);
2487 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2488 struct problem_context *pctx, int first);
2490 * This function handles the '@' expansion. We allow recursive
2491 * expansion; an @ expression can contain further '@' and '%'
2494 static void expand_at_expression(e2fsck_t ctx, char ch,
2495 struct problem_context *pctx,
2498 const char *const *cpp;
2501 /* Search for the abbreviation */
2502 for (cpp = abbrevs; *cpp; cpp++) {
2508 if (*first && islower(*str)) {
2510 bb_putchar(toupper(*str++));
2512 print_e2fsck_message(ctx, str, pctx, *first);
2518 * This function expands '%IX' expressions
2520 static void expand_inode_expression(char ch,
2521 struct problem_context *ctx)
2523 struct ext2_inode *inode;
2524 struct ext2_inode_large *large_inode;
2529 if (!ctx || !ctx->inode)
2533 large_inode = (struct ext2_inode_large *) inode;
2537 if (LINUX_S_ISDIR(inode->i_mode))
2538 printf("%u", inode->i_size);
2540 printf("%"PRIu64, (inode->i_size |
2541 ((uint64_t) inode->i_size_high << 32)));
2545 printf("%u", large_inode->i_extra_isize);
2548 printf("%u", inode->i_blocks);
2551 printf("%d", inode->i_links_count);
2554 printf("0%o", inode->i_mode);
2557 /* The diet libc doesn't respect the TZ environemnt variable */
2559 time_str = getenv("TZ");
2562 do_gmt = !strcmp(time_str, "GMT");
2565 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2566 printf("%.24s", time_str);
2569 printf("%u", inode->i_faddr);
2572 printf("%u", inode->i_file_acl);
2575 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2576 inode->i_dir_acl : 0));
2579 printf("%d", (inode->i_uid |
2580 (inode->osd2.linux2.l_i_uid_high << 16)));
2583 printf("%d", (inode->i_gid |
2584 (inode->osd2.linux2.l_i_gid_high << 16)));
2588 printf("%%I%c", ch);
2594 * This function expands '%dX' expressions
2596 static void expand_dirent_expression(char ch,
2597 struct problem_context *ctx)
2599 struct ext2_dir_entry *dirent;
2602 if (!ctx || !ctx->dirent)
2605 dirent = ctx->dirent;
2609 printf("%u", dirent->inode);
2612 len = dirent->name_len & 0xFF;
2613 if (len > EXT2_NAME_LEN)
2614 len = EXT2_NAME_LEN;
2615 if (len > dirent->rec_len)
2616 len = dirent->rec_len;
2617 safe_print(dirent->name, len);
2620 printf("%u", dirent->rec_len);
2623 printf("%u", dirent->name_len & 0xFF);
2626 printf("%u", dirent->name_len >> 8);
2630 printf("%%D%c", ch);
2635 static void expand_percent_expression(ext2_filsys fs, char ch,
2636 struct problem_context *ctx)
2646 printf("%u", ctx->blk);
2649 printf("%"PRIi64, ctx->blkcount);
2652 printf("%u", ctx->blk2);
2655 printf("%u", ctx->dir);
2658 printf("%d", ctx->group);
2661 printf("%u", ctx->ino);
2664 printf("%u", ctx->ino2);
2667 fputs(error_message(ctx->errcode), stdout);
2670 printf("%"PRIi64, ctx->num);
2673 print_pathname(fs, ctx->ino, 0);
2676 print_pathname(fs, ctx->ino2,
2677 ctx->dirent ? ctx->dirent->inode : 0);
2680 print_pathname(fs, ctx->dir, 0);
2683 print_pathname(fs, ctx->dir, ctx->ino);
2686 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2689 fputs((ctx->str ? ctx->str : "NULL"), stdout);
2692 printf("0x%"PRIi64, ctx->num);
2702 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2703 struct problem_context *pctx, int first)
2705 ext2_filsys fs = ctx->fs;
2709 e2fsck_clear_progbar(ctx);
2710 for (cp = msg; *cp; cp++) {
2713 expand_at_expression(ctx, *cp, pctx, &first);
2714 } else if (cp[0] == '%' && cp[1] == 'I') {
2716 expand_inode_expression(*cp, pctx);
2717 } else if (cp[0] == '%' && cp[1] == 'D') {
2719 expand_dirent_expression(*cp, pctx);
2720 } else if ((cp[0] == '%')) {
2722 expand_percent_expression(fs, *cp, pctx);
2724 for (i=0; cp[i]; i++)
2725 if ((cp[i] == '@') || cp[i] == '%')
2727 printf("%.*s", i, cp);
2736 * region.c --- code which manages allocations within a region.
2740 region_addr_t start;
2742 struct region_el *next;
2745 struct region_struct {
2748 struct region_el *allocated;
2751 static region_t region_create(region_addr_t min, region_addr_t max)
2755 region = xzalloc(sizeof(struct region_struct));
2761 static void region_free(region_t region)
2763 struct region_el *r, *next;
2765 for (r = region->allocated; r; r = next) {
2769 memset(region, 0, sizeof(struct region_struct));
2773 static int region_allocate(region_t region, region_addr_t start, int n)
2775 struct region_el *r, *new_region, *prev, *next;
2779 if ((start < region->min) || (end > region->max))
2785 * Search through the linked list. If we find that it
2786 * conflicts witih something that's already allocated, return
2787 * 1; if we can find an existing region which we can grow, do
2788 * so. Otherwise, stop when we find the appropriate place
2789 * insert a new region element into the linked list.
2791 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2792 if (((start >= r->start) && (start < r->end)) ||
2793 ((end > r->start) && (end <= r->end)) ||
2794 ((start <= r->start) && (end >= r->end)))
2796 if (end == r->start) {
2800 if (start == r->end) {
2801 if ((next = r->next)) {
2802 if (end > next->start)
2804 if (end == next->start) {
2806 r->next = next->next;
2814 if (start < r->start)
2818 * Insert a new region element structure into the linked list
2820 new_region = xmalloc(sizeof(struct region_el));
2821 new_region->start = start;
2822 new_region->end = start + n;
2823 new_region->next = r;
2825 prev->next = new_region;
2827 region->allocated = new_region;
2832 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2834 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2835 * and applies the following tests to each inode:
2837 * - The mode field of the inode must be legal.
2838 * - The size and block count fields of the inode are correct.
2839 * - A data block must not be used by another inode
2841 * Pass 1 also gathers the collects the following information:
2843 * - A bitmap of which inodes are in use. (inode_used_map)
2844 * - A bitmap of which inodes are directories. (inode_dir_map)
2845 * - A bitmap of which inodes are regular files. (inode_reg_map)
2846 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2847 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2848 * - A bitmap of which blocks are in use. (block_found_map)
2849 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2850 * - The data blocks of the directory inodes. (dir_map)
2852 * Pass 1 is designed to stash away enough information so that the
2853 * other passes should not need to read in the inode information
2854 * during the normal course of a filesystem check. (Althogh if an
2855 * inconsistency is detected, other passes may need to read in an
2858 * Note that pass 1B will be invoked if there are any duplicate blocks
2863 static int process_block(ext2_filsys fs, blk_t *blocknr,
2864 e2_blkcnt_t blockcnt, blk_t ref_blk,
2865 int ref_offset, void *priv_data);
2866 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2867 e2_blkcnt_t blockcnt, blk_t ref_blk,
2868 int ref_offset, void *priv_data);
2869 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2871 static void mark_table_blocks(e2fsck_t ctx);
2872 static void alloc_imagic_map(e2fsck_t ctx);
2873 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2874 static void handle_fs_bad_blocks(e2fsck_t ctx);
2875 static void process_inodes(e2fsck_t ctx, char *block_buf);
2876 static int process_inode_cmp(const void *a, const void *b);
2877 static errcode_t scan_callback(ext2_filsys fs,
2878 dgrp_t group, void * priv_data);
2879 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2880 char *block_buf, int adjust_sign);
2881 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2883 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2884 struct ext2_inode * inode, int bufsize,
2887 struct process_block_struct_1 {
2889 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
2890 fragmented:1, compressed:1, bbcheck:1;
2893 e2_blkcnt_t last_block;
2894 int num_illegal_blocks;
2895 blk_t previous_block;
2896 struct ext2_inode *inode;
2897 struct problem_context *pctx;
2898 ext2fs_block_bitmap fs_meta_blocks;
2902 struct process_inode_block {
2904 struct ext2_inode inode;
2907 struct scan_callback_struct {
2913 * For the inodes to process list.
2915 static struct process_inode_block *inodes_to_process;
2916 static int process_inode_count;
2918 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2919 EXT2_MIN_BLOCK_LOG_SIZE + 1];
2922 * Free all memory allocated by pass1 in preparation for restarting
2925 static void unwind_pass1(void)
2927 ext2fs_free_mem(&inodes_to_process);
2931 * Check to make sure a device inode is real. Returns 1 if the device
2932 * checks out, 0 if not.
2934 * Note: this routine is now also used to check FIFO's and Sockets,
2935 * since they have the same requirement; the i_block fields should be
2939 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2944 * If i_blocks is non-zero, or the index flag is set, then
2945 * this is a bogus device/fifo/socket
2947 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2948 (inode->i_flags & EXT2_INDEX_FL))
2952 * We should be able to do the test below all the time, but
2953 * because the kernel doesn't forcibly clear the device
2954 * inode's additional i_block fields, there are some rare
2955 * occasions when a legitimate device inode will have non-zero
2956 * additional i_block fields. So for now, we only complain
2957 * when the immutable flag is set, which should never happen
2958 * for devices. (And that's when the problem is caused, since
2959 * you can't set or clear immutable flags for devices.) Once
2960 * the kernel has been fixed we can change this...
2962 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2963 for (i=4; i < EXT2_N_BLOCKS; i++)
2964 if (inode->i_block[i])
2971 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2972 * checks out, 0 if not.
2975 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
2981 if ((inode->i_size_high || inode->i_size == 0) ||
2982 (inode->i_flags & EXT2_INDEX_FL))
2985 blocks = ext2fs_inode_data_blocks(fs, inode);
2987 if ((inode->i_size >= fs->blocksize) ||
2988 (blocks != fs->blocksize >> 9) ||
2989 (inode->i_block[0] < fs->super->s_first_data_block) ||
2990 (inode->i_block[0] >= fs->super->s_blocks_count))
2993 for (i = 1; i < EXT2_N_BLOCKS; i++)
2994 if (inode->i_block[i])
2997 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
3000 len = strnlen(buf, fs->blocksize);
3001 if (len == fs->blocksize)
3004 if (inode->i_size >= sizeof(inode->i_block))
3007 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3008 if (len == sizeof(inode->i_block))
3011 if (len != inode->i_size)
3017 * If the immutable (or append-only) flag is set on the inode, offer
3020 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3021 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3023 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3026 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3029 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3030 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3034 * If device, fifo or socket, check size is zero -- if not offer to
3037 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3039 struct ext2_inode *inode = pctx->inode;
3041 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3044 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3048 inode->i_size_high = 0;
3049 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3052 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3054 struct ext2_super_block *sb = ctx->fs->super;
3055 struct ext2_inode_large *inode;
3056 struct ext2_ext_attr_entry *entry;
3058 int storage_size, remain, offs;
3061 inode = (struct ext2_inode_large *) pctx->inode;
3062 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3063 inode->i_extra_isize;
3064 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3065 inode->i_extra_isize + sizeof(__u32);
3066 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3067 entry = (struct ext2_ext_attr_entry *) start;
3069 /* scan all entry's headers first */
3071 /* take finish entry 0UL into account */
3072 remain = storage_size - sizeof(__u32);
3075 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3077 /* header eats this space */
3078 remain -= sizeof(struct ext2_ext_attr_entry);
3080 /* is attribute name valid? */
3081 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3082 pctx->num = entry->e_name_len;
3083 problem = PR_1_ATTR_NAME_LEN;
3087 /* attribute len eats this space */
3088 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3090 /* check value size */
3091 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3092 pctx->num = entry->e_value_size;
3093 problem = PR_1_ATTR_VALUE_SIZE;
3097 /* check value placement */
3098 if (entry->e_value_offs +
3099 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3100 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3101 pctx->num = entry->e_value_offs;
3102 problem = PR_1_ATTR_VALUE_OFFSET;
3106 /* e_value_block must be 0 in inode's ea */
3107 if (entry->e_value_block != 0) {
3108 pctx->num = entry->e_value_block;
3109 problem = PR_1_ATTR_VALUE_BLOCK;
3113 /* e_hash must be 0 in inode's ea */
3114 if (entry->e_hash != 0) {
3115 pctx->num = entry->e_hash;
3116 problem = PR_1_ATTR_HASH;
3120 remain -= entry->e_value_size;
3121 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3123 entry = EXT2_EXT_ATTR_NEXT(entry);
3127 * it seems like a corruption. it's very unlikely we could repair
3128 * EA(s) in automatic fashion -bzzz
3130 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3133 /* simple remove all possible EA(s) */
3134 *((__u32 *)start) = 0UL;
3135 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3136 EXT2_INODE_SIZE(sb), "pass1");
3139 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3141 struct ext2_super_block *sb = ctx->fs->super;
3142 struct ext2_inode_large *inode;
3146 inode = (struct ext2_inode_large *) pctx->inode;
3147 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3148 /* this isn't large inode. so, nothing to check */
3152 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3153 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3154 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3156 * For now we will allow i_extra_isize to be 0, but really
3157 * implementations should never allow i_extra_isize to be 0
3159 if (inode->i_extra_isize &&
3160 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3161 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3163 inode->i_extra_isize = min;
3164 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3165 EXT2_INODE_SIZE(sb), "pass1");
3169 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3170 inode->i_extra_isize);
3171 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3172 /* it seems inode has an extended attribute(s) in body */
3173 check_ea_in_inode(ctx, pctx);
3177 static void e2fsck_pass1(e2fsck_t ctx)
3181 ext2_filsys fs = ctx->fs;
3183 struct ext2_inode *inode;
3184 ext2_inode_scan scan;
3186 unsigned char frag, fsize;
3187 struct problem_context pctx;
3188 struct scan_callback_struct scan_struct;
3189 struct ext2_super_block *sb = ctx->fs->super;
3191 int busted_fs_time = 0;
3194 clear_problem_context(&pctx);
3196 if (!(ctx->options & E2F_OPT_PREEN))
3197 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3199 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3200 !(ctx->options & E2F_OPT_NO)) {
3201 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3202 ctx->dirs_to_hash = 0;
3207 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3209 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3210 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3211 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3212 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3213 max_sizes = (max_sizes * (1UL << i)) - 1;
3214 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3218 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3221 * Allocate bitmaps structures
3223 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3224 &ctx->inode_used_map);
3227 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3228 ctx->flags |= E2F_FLAG_ABORT;
3231 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3232 _("directory inode map"), &ctx->inode_dir_map);
3235 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3236 ctx->flags |= E2F_FLAG_ABORT;
3239 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3240 _("regular file inode map"), &ctx->inode_reg_map);
3243 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3244 ctx->flags |= E2F_FLAG_ABORT;
3247 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3248 &ctx->block_found_map);
3251 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3252 ctx->flags |= E2F_FLAG_ABORT;
3255 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3256 &ctx->inode_link_info);
3258 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3259 ctx->flags |= E2F_FLAG_ABORT;
3262 inode_size = EXT2_INODE_SIZE(fs->super);
3263 inode = (struct ext2_inode *)
3264 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3266 inodes_to_process = (struct process_inode_block *)
3267 e2fsck_allocate_memory(ctx,
3268 (ctx->process_inode_size *
3269 sizeof(struct process_inode_block)),
3270 "array of inodes to process");
3271 process_inode_count = 0;
3273 pctx.errcode = ext2fs_init_dblist(fs, 0);
3275 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3276 ctx->flags |= E2F_FLAG_ABORT;
3281 * If the last orphan field is set, clear it, since the pass1
3282 * processing will automatically find and clear the orphans.
3283 * In the future, we may want to try using the last_orphan
3284 * linked list ourselves, but for now, we clear it so that the
3285 * ext3 mount code won't get confused.
3287 if (!(ctx->options & E2F_OPT_READONLY)) {
3288 if (fs->super->s_last_orphan) {
3289 fs->super->s_last_orphan = 0;
3290 ext2fs_mark_super_dirty(fs);
3294 mark_table_blocks(ctx);
3295 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3296 "block interate buffer");
3297 e2fsck_use_inode_shortcuts(ctx, 1);
3298 ehandler_operation(_("doing inode scan"));
3299 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3302 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3303 ctx->flags |= E2F_FLAG_ABORT;
3306 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3307 ctx->stashed_inode = inode;
3308 scan_struct.ctx = ctx;
3309 scan_struct.block_buf = block_buf;
3310 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3312 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3314 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3315 (fs->super->s_mtime < fs->super->s_inodes_count))
3319 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3321 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3323 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3327 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3328 ctx->flags |= E2F_FLAG_ABORT;
3335 ctx->stashed_ino = ino;
3336 if (inode->i_links_count) {
3337 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3338 ino, inode->i_links_count);
3340 pctx.num = inode->i_links_count;
3341 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3342 ctx->flags |= E2F_FLAG_ABORT;
3346 if (ino == EXT2_BAD_INO) {
3347 struct process_block_struct_1 pb;
3349 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3350 &pb.fs_meta_blocks);
3353 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3354 ctx->flags |= E2F_FLAG_ABORT;
3357 pb.ino = EXT2_BAD_INO;
3358 pb.num_blocks = pb.last_block = 0;
3359 pb.num_illegal_blocks = 0;
3360 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3361 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3365 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3366 block_buf, process_bad_block, &pb);
3367 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3369 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3370 ctx->flags |= E2F_FLAG_ABORT;
3374 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3375 ctx->flags |= E2F_FLAG_ABORT;
3378 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3379 clear_problem_context(&pctx);
3381 } else if (ino == EXT2_ROOT_INO) {
3383 * Make sure the root inode is a directory; if
3384 * not, offer to clear it. It will be
3385 * regnerated in pass #3.
3387 if (!LINUX_S_ISDIR(inode->i_mode)) {
3388 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3389 inode->i_dtime = time(NULL);
3390 inode->i_links_count = 0;
3391 ext2fs_icount_store(ctx->inode_link_info,
3393 e2fsck_write_inode(ctx, ino, inode,
3398 * If dtime is set, offer to clear it. mke2fs
3399 * version 0.2b created filesystems with the
3400 * dtime field set for the root and lost+found
3401 * directories. We won't worry about
3402 * /lost+found, since that can be regenerated
3403 * easily. But we will fix the root directory
3404 * as a special case.
3406 if (inode->i_dtime && inode->i_links_count) {
3407 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3409 e2fsck_write_inode(ctx, ino, inode,
3413 } else if (ino == EXT2_JOURNAL_INO) {
3414 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3415 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3416 if (!LINUX_S_ISREG(inode->i_mode) &&
3417 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3419 inode->i_mode = LINUX_S_IFREG;
3420 e2fsck_write_inode(ctx, ino, inode,
3423 check_blocks(ctx, &pctx, block_buf);
3426 if ((inode->i_links_count || inode->i_blocks ||
3427 inode->i_blocks || inode->i_block[0]) &&
3428 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3430 memset(inode, 0, inode_size);
3431 ext2fs_icount_store(ctx->inode_link_info,
3433 e2fsck_write_inode_full(ctx, ino, inode,
3434 inode_size, "pass1");
3436 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3439 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3440 if (ino == EXT2_BOOT_LOADER_INO) {
3441 if (LINUX_S_ISDIR(inode->i_mode))
3442 problem = PR_1_RESERVED_BAD_MODE;
3443 } else if (ino == EXT2_RESIZE_INO) {
3444 if (inode->i_mode &&
3445 !LINUX_S_ISREG(inode->i_mode))
3446 problem = PR_1_RESERVED_BAD_MODE;
3448 if (inode->i_mode != 0)
3449 problem = PR_1_RESERVED_BAD_MODE;
3452 if (fix_problem(ctx, problem, &pctx)) {
3454 e2fsck_write_inode(ctx, ino, inode,
3458 check_blocks(ctx, &pctx, block_buf);
3462 * Check for inodes who might have been part of the
3463 * orphaned list linked list. They should have gotten
3464 * dealt with by now, unless the list had somehow been
3467 * FIXME: In the future, inodes which are still in use
3468 * (and which are therefore) pending truncation should
3469 * be handled specially. Right now we just clear the
3470 * dtime field, and the normal e2fsck handling of
3471 * inodes where i_size and the inode blocks are
3472 * inconsistent is to fix i_size, instead of releasing
3473 * the extra blocks. This won't catch the inodes that
3474 * was at the end of the orphan list, but it's better
3475 * than nothing. The right answer is that there
3476 * shouldn't be any bugs in the orphan list handling. :-)
3478 if (inode->i_dtime && !busted_fs_time &&
3479 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3480 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3481 inode->i_dtime = inode->i_links_count ?
3483 e2fsck_write_inode(ctx, ino, inode,
3489 * This code assumes that deleted inodes have
3490 * i_links_count set to 0.
3492 if (!inode->i_links_count) {
3493 if (!inode->i_dtime && inode->i_mode) {
3494 if (fix_problem(ctx,
3495 PR_1_ZERO_DTIME, &pctx)) {
3496 inode->i_dtime = time(NULL);
3497 e2fsck_write_inode(ctx, ino, inode,
3504 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3505 * deleted files. Oops.
3507 * Since all new ext2 implementations get this right,
3508 * we now assume that the case of non-zero
3509 * i_links_count and non-zero dtime means that we
3510 * should keep the file, not delete it.
3513 if (inode->i_dtime) {
3514 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3516 e2fsck_write_inode(ctx, ino, inode, "pass1");
3520 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3521 switch (fs->super->s_creator_os) {
3523 frag = inode->osd2.linux2.l_i_frag;
3524 fsize = inode->osd2.linux2.l_i_fsize;
3527 frag = inode->osd2.hurd2.h_i_frag;
3528 fsize = inode->osd2.hurd2.h_i_fsize;
3531 frag = inode->osd2.masix2.m_i_frag;
3532 fsize = inode->osd2.masix2.m_i_fsize;
3538 if (inode->i_faddr || frag || fsize ||
3539 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3540 mark_inode_bad(ctx, ino);
3541 if (inode->i_flags & EXT2_IMAGIC_FL) {
3543 if (!ctx->inode_imagic_map)
3544 alloc_imagic_map(ctx);
3545 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3548 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3549 inode->i_flags &= ~EXT2_IMAGIC_FL;
3550 e2fsck_write_inode(ctx, ino,
3556 check_inode_extra_space(ctx, &pctx);
3558 if (LINUX_S_ISDIR(inode->i_mode)) {
3559 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3560 e2fsck_add_dir_info(ctx, ino, 0);
3561 ctx->fs_directory_count++;
3562 } else if (LINUX_S_ISREG (inode->i_mode)) {
3563 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3564 ctx->fs_regular_count++;
3565 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3566 e2fsck_pass1_check_device_inode(fs, inode)) {
3567 check_immutable(ctx, &pctx);
3568 check_size(ctx, &pctx);
3569 ctx->fs_chardev_count++;
3570 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3571 e2fsck_pass1_check_device_inode(fs, inode)) {
3572 check_immutable(ctx, &pctx);
3573 check_size(ctx, &pctx);
3574 ctx->fs_blockdev_count++;
3575 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3576 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3577 check_immutable(ctx, &pctx);
3578 ctx->fs_symlinks_count++;
3579 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3580 ctx->fs_fast_symlinks_count++;
3581 check_blocks(ctx, &pctx, block_buf);
3585 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3586 e2fsck_pass1_check_device_inode(fs, inode)) {
3587 check_immutable(ctx, &pctx);
3588 check_size(ctx, &pctx);
3589 ctx->fs_fifo_count++;
3590 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3591 e2fsck_pass1_check_device_inode(fs, inode)) {
3592 check_immutable(ctx, &pctx);
3593 check_size(ctx, &pctx);
3594 ctx->fs_sockets_count++;
3596 mark_inode_bad(ctx, ino);
3597 if (inode->i_block[EXT2_IND_BLOCK])
3598 ctx->fs_ind_count++;
3599 if (inode->i_block[EXT2_DIND_BLOCK])
3600 ctx->fs_dind_count++;
3601 if (inode->i_block[EXT2_TIND_BLOCK])
3602 ctx->fs_tind_count++;
3603 if (inode->i_block[EXT2_IND_BLOCK] ||
3604 inode->i_block[EXT2_DIND_BLOCK] ||
3605 inode->i_block[EXT2_TIND_BLOCK] ||
3606 inode->i_file_acl) {
3607 inodes_to_process[process_inode_count].ino = ino;
3608 inodes_to_process[process_inode_count].inode = *inode;
3609 process_inode_count++;
3611 check_blocks(ctx, &pctx, block_buf);
3613 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3616 if (process_inode_count >= ctx->process_inode_size) {
3617 process_inodes(ctx, block_buf);
3619 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3623 process_inodes(ctx, block_buf);
3624 ext2fs_close_inode_scan(scan);
3625 ehandler_operation(0);
3628 * If any extended attribute blocks' reference counts need to
3629 * be adjusted, either up (ctx->refcount_extra), or down
3630 * (ctx->refcount), then fix them.
3632 if (ctx->refcount) {
3633 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3634 ea_refcount_free(ctx->refcount);
3637 if (ctx->refcount_extra) {
3638 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3640 ea_refcount_free(ctx->refcount_extra);
3641 ctx->refcount_extra = 0;
3644 if (ctx->invalid_bitmaps)
3645 handle_fs_bad_blocks(ctx);
3647 /* We don't need the block_ea_map any more */
3648 ext2fs_free_block_bitmap(ctx->block_ea_map);
3649 ctx->block_ea_map = 0;
3651 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3652 ext2fs_block_bitmap save_bmap;
3654 save_bmap = fs->block_map;
3655 fs->block_map = ctx->block_found_map;
3656 clear_problem_context(&pctx);
3657 pctx.errcode = ext2fs_create_resize_inode(fs);
3659 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3660 /* Should never get here */
3661 ctx->flags |= E2F_FLAG_ABORT;
3664 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3666 inode->i_mtime = time(NULL);
3667 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3669 fs->block_map = save_bmap;
3670 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3673 if (ctx->flags & E2F_FLAG_RESTART) {
3675 * Only the master copy of the superblock and block
3676 * group descriptors are going to be written during a
3677 * restart, so set the superblock to be used to be the
3678 * master superblock.
3680 ctx->use_superblock = 0;
3685 if (ctx->block_dup_map) {
3686 if (ctx->options & E2F_OPT_PREEN) {
3687 clear_problem_context(&pctx);
3688 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3690 e2fsck_pass1_dupblocks(ctx, block_buf);
3692 ext2fs_free_mem(&inodes_to_process);
3694 e2fsck_use_inode_shortcuts(ctx, 0);
3696 ext2fs_free_mem(&block_buf);
3697 ext2fs_free_mem(&inode);
3701 * When the inode_scan routines call this callback at the end of the
3702 * glock group, call process_inodes.
3704 static errcode_t scan_callback(ext2_filsys fs,
3705 dgrp_t group, void * priv_data)
3707 struct scan_callback_struct *scan_struct;
3710 scan_struct = (struct scan_callback_struct *) priv_data;
3711 ctx = scan_struct->ctx;
3713 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3716 if ((ctx->progress)(ctx, 1, group+1,
3717 ctx->fs->group_desc_count))
3718 return EXT2_ET_CANCEL_REQUESTED;
3724 * Process the inodes in the "inodes to process" list.
3726 static void process_inodes(e2fsck_t ctx, char *block_buf)
3729 struct ext2_inode *old_stashed_inode;
3730 ext2_ino_t old_stashed_ino;
3731 const char *old_operation;
3733 struct problem_context pctx;
3735 /* begin process_inodes */
3736 if (process_inode_count == 0)
3738 old_operation = ehandler_operation(0);
3739 old_stashed_inode = ctx->stashed_inode;
3740 old_stashed_ino = ctx->stashed_ino;
3741 qsort(inodes_to_process, process_inode_count,
3742 sizeof(struct process_inode_block), process_inode_cmp);
3743 clear_problem_context(&pctx);
3744 for (i=0; i < process_inode_count; i++) {
3745 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3746 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3747 sprintf(buf, _("reading indirect blocks of inode %u"),
3749 ehandler_operation(buf);
3750 check_blocks(ctx, &pctx, block_buf);
3751 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3754 ctx->stashed_inode = old_stashed_inode;
3755 ctx->stashed_ino = old_stashed_ino;
3756 process_inode_count = 0;
3757 /* end process inodes */
3759 ehandler_operation(old_operation);
3762 static int process_inode_cmp(const void *a, const void *b)
3764 const struct process_inode_block *ib_a =
3765 (const struct process_inode_block *) a;
3766 const struct process_inode_block *ib_b =
3767 (const struct process_inode_block *) b;
3770 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3771 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3773 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3778 * Mark an inode as being bad in some what
3780 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3782 struct problem_context pctx;
3784 if (!ctx->inode_bad_map) {
3785 clear_problem_context(&pctx);
3787 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3788 _("bad inode map"), &ctx->inode_bad_map);
3791 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3792 /* Should never get here */
3793 ctx->flags |= E2F_FLAG_ABORT;
3797 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3802 * This procedure will allocate the inode imagic table
3804 static void alloc_imagic_map(e2fsck_t ctx)
3806 struct problem_context pctx;
3808 clear_problem_context(&pctx);
3809 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3810 _("imagic inode map"),
3811 &ctx->inode_imagic_map);
3814 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3815 /* Should never get here */
3816 ctx->flags |= E2F_FLAG_ABORT;
3822 * Marks a block as in use, setting the dup_map if it's been set
3823 * already. Called by process_block and process_bad_block.
3825 * WARNING: Assumes checks have already been done to make sure block
3826 * is valid. This is true in both process_block and process_bad_block.
3828 static void mark_block_used(e2fsck_t ctx, blk_t block)
3830 struct problem_context pctx;
3832 clear_problem_context(&pctx);
3834 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3835 if (!ctx->block_dup_map) {
3836 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3837 _("multiply claimed block map"),
3838 &ctx->block_dup_map);
3841 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3843 /* Should never get here */
3844 ctx->flags |= E2F_FLAG_ABORT;
3848 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3850 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3855 * Adjust the extended attribute block's reference counts at the end
3856 * of pass 1, either by subtracting out references for EA blocks that
3857 * are still referenced in ctx->refcount, or by adding references for
3858 * EA blocks that had extra references as accounted for in
3859 * ctx->refcount_extra.
3861 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3862 char *block_buf, int adjust_sign)
3864 struct ext2_ext_attr_header *header;
3865 struct problem_context pctx;
3866 ext2_filsys fs = ctx->fs;
3871 clear_problem_context(&pctx);
3873 ea_refcount_intr_begin(refcount);
3875 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3878 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3880 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3883 header = (struct ext2_ext_attr_header *) block_buf;
3884 pctx.blkcount = header->h_refcount;
3885 should_be = header->h_refcount + adjust_sign * count;
3886 pctx.num = should_be;
3887 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3888 header->h_refcount = should_be;
3889 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3892 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3900 * Handle processing the extended attribute blocks
3902 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3905 ext2_filsys fs = ctx->fs;
3906 ext2_ino_t ino = pctx->ino;
3907 struct ext2_inode *inode = pctx->inode;
3910 struct ext2_ext_attr_header *header;
3911 struct ext2_ext_attr_entry *entry;
3915 blk = inode->i_file_acl;
3920 * If the Extended attribute flag isn't set, then a non-zero
3921 * file acl means that the inode is corrupted.
3923 * Or if the extended attribute block is an invalid block,
3924 * then the inode is also corrupted.
3926 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3927 (blk < fs->super->s_first_data_block) ||
3928 (blk >= fs->super->s_blocks_count)) {
3929 mark_inode_bad(ctx, ino);
3933 /* If ea bitmap hasn't been allocated, create it */
3934 if (!ctx->block_ea_map) {
3935 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3936 _("ext attr block map"),
3937 &ctx->block_ea_map);
3938 if (pctx->errcode) {
3940 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3941 ctx->flags |= E2F_FLAG_ABORT;
3946 /* Create the EA refcount structure if necessary */
3947 if (!ctx->refcount) {
3948 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3949 if (pctx->errcode) {
3951 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3952 ctx->flags |= E2F_FLAG_ABORT;
3957 /* Have we seen this EA block before? */
3958 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3959 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3961 /* Ooops, this EA was referenced more than it stated */
3962 if (!ctx->refcount_extra) {
3963 pctx->errcode = ea_refcount_create(0,
3964 &ctx->refcount_extra);
3965 if (pctx->errcode) {
3967 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3968 ctx->flags |= E2F_FLAG_ABORT;
3972 ea_refcount_increment(ctx->refcount_extra, blk, 0);
3977 * OK, we haven't seen this EA block yet. So we need to
3981 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3982 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
3984 header = (struct ext2_ext_attr_header *) block_buf;
3985 pctx->blk = inode->i_file_acl;
3986 if (((ctx->ext_attr_ver == 1) &&
3987 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
3988 ((ctx->ext_attr_ver == 2) &&
3989 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
3990 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
3994 if (header->h_blocks != 1) {
3995 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
3999 region = region_create(0, fs->blocksize);
4001 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
4002 ctx->flags |= E2F_FLAG_ABORT;
4005 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4006 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4010 entry = (struct ext2_ext_attr_entry *)(header+1);
4011 end = block_buf + fs->blocksize;
4012 while ((char *)entry < end && *(__u32 *)entry) {
4013 if (region_allocate(region, (char *)entry - (char *)header,
4014 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4015 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4018 if ((ctx->ext_attr_ver == 1 &&
4019 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4020 (ctx->ext_attr_ver == 2 &&
4021 entry->e_name_index == 0)) {
4022 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4025 if (entry->e_value_block != 0) {
4026 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4029 if (entry->e_value_size &&
4030 region_allocate(region, entry->e_value_offs,
4031 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4032 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4035 entry = EXT2_EXT_ATTR_NEXT(entry);
4037 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4038 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4041 region_free(region);
4043 count = header->h_refcount - 1;
4045 ea_refcount_store(ctx->refcount, blk, count);
4046 mark_block_used(ctx, blk);
4047 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4052 inode->i_file_acl = 0;
4053 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4057 /* Returns 1 if bad htree, 0 if OK */
4058 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4059 ext2_ino_t ino FSCK_ATTR((unused)),
4060 struct ext2_inode *inode,
4063 struct ext2_dx_root_info *root;
4064 ext2_filsys fs = ctx->fs;
4068 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4069 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4070 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4071 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4074 blk = inode->i_block[0];
4076 (blk < fs->super->s_first_data_block) ||
4077 (blk >= fs->super->s_blocks_count)) &&
4078 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4081 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4082 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4085 /* XXX should check that beginning matches a directory */
4086 root = (struct ext2_dx_root_info *) (block_buf + 24);
4088 if ((root->reserved_zero || root->info_length < 8) &&
4089 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4092 pctx->num = root->hash_version;
4093 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4094 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4095 (root->hash_version != EXT2_HASH_TEA) &&
4096 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4099 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4100 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4103 pctx->num = root->indirect_levels;
4104 if ((root->indirect_levels > 1) &&
4105 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4112 * This subroutine is called on each inode to account for all of the
4113 * blocks used by that inode.
4115 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4118 ext2_filsys fs = ctx->fs;
4119 struct process_block_struct_1 pb;
4120 ext2_ino_t ino = pctx->ino;
4121 struct ext2_inode *inode = pctx->inode;
4123 int dirty_inode = 0;
4129 pb.num_illegal_blocks = 0;
4130 pb.suppress = 0; pb.clear = 0;
4133 pb.previous_block = 0;
4134 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4135 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4136 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4143 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4144 if (fs->super->s_feature_incompat &
4145 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4148 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4149 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4155 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4158 if (ext2fs_inode_has_valid_blocks(inode))
4159 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4160 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4161 block_buf, process_block, &pb);
4162 end_problem_latch(ctx, PR_LATCH_BLOCK);
4163 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4164 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4167 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4169 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4170 ctx->fs_fragmented++;
4173 inode->i_links_count = 0;
4174 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4175 inode->i_dtime = time(NULL);
4177 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4178 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4179 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4181 * The inode was probably partially accounted for
4182 * before processing was aborted, so we need to
4183 * restart the pass 1 scan.
4185 ctx->flags |= E2F_FLAG_RESTART;
4189 if (inode->i_flags & EXT2_INDEX_FL) {
4190 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4191 inode->i_flags &= ~EXT2_INDEX_FL;
4195 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4199 if (ctx->dirs_to_hash && pb.is_dir &&
4200 !(inode->i_flags & EXT2_INDEX_FL) &&
4201 ((inode->i_size / fs->blocksize) >= 3))
4202 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4204 if (!pb.num_blocks && pb.is_dir) {
4205 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4206 inode->i_links_count = 0;
4207 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4208 inode->i_dtime = time(NULL);
4210 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4211 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4212 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4213 ctx->fs_directory_count--;
4218 pb.num_blocks *= (fs->blocksize / 512);
4221 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4222 if (nblock > (pb.last_block + 1))
4224 else if (nblock < (pb.last_block + 1)) {
4225 if (((pb.last_block + 1) - nblock) >
4226 fs->super->s_prealloc_dir_blocks)
4230 size = EXT2_I_SIZE(inode);
4231 if ((pb.last_block >= 0) &&
4232 (size < (__u64) pb.last_block * fs->blocksize))
4234 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4237 /* i_size for symlinks is checked elsewhere */
4238 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4239 pctx->num = (pb.last_block+1) * fs->blocksize;
4240 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4241 inode->i_size = pctx->num;
4242 if (!LINUX_S_ISDIR(inode->i_mode))
4243 inode->i_size_high = pctx->num >> 32;
4248 if (LINUX_S_ISREG(inode->i_mode) &&
4249 (inode->i_size_high || inode->i_size & 0x80000000UL))
4251 if (pb.num_blocks != inode->i_blocks) {
4252 pctx->num = pb.num_blocks;
4253 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4254 inode->i_blocks = pb.num_blocks;
4261 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4266 * This is a helper function for check_blocks().
4268 static int process_block(ext2_filsys fs,
4270 e2_blkcnt_t blockcnt,
4271 blk_t ref_block FSCK_ATTR((unused)),
4272 int ref_offset FSCK_ATTR((unused)),
4275 struct process_block_struct_1 *p;
4276 struct problem_context *pctx;
4277 blk_t blk = *block_nr;
4282 p = (struct process_block_struct_1 *) priv_data;
4286 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4287 /* todo: Check that the comprblk_fl is high, that the
4288 blkaddr pattern looks right (all non-holes up to
4289 first EXT2FS_COMPRESSED_BLKADDR, then all
4290 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4291 that the feature_incompat bit is high, and that the
4292 inode is a regular file. If we're doing a "full
4293 check" (a concept introduced to e2fsck by e2compr,
4294 meaning that we look at data blocks as well as
4295 metadata) then call some library routine that
4296 checks the compressed data. I'll have to think
4297 about this, because one particularly important
4298 problem to be able to fix is to recalculate the
4299 cluster size if necessary. I think that perhaps
4300 we'd better do most/all e2compr-specific checks
4301 separately, after the non-e2compr checks. If not
4302 doing a full check, it may be useful to test that
4303 the personality is linux; e.g. if it isn't then
4304 perhaps this really is just an illegal block. */
4309 if (p->is_dir == 0) {
4311 * Should never happen, since only directories
4312 * get called with BLOCK_FLAG_HOLE
4315 printf("process_block() called with blk == 0, "
4316 "blockcnt=%d, inode %lu???\n",
4323 if (blockcnt * fs->blocksize < p->inode->i_size) {
4330 * Simplistic fragmentation check. We merely require that the
4331 * file be contiguous. (Which can never be true for really
4332 * big files that are greater than a block group.)
4334 if (!HOLE_BLKADDR(p->previous_block)) {
4335 if (p->previous_block+1 != blk)
4338 p->previous_block = blk;
4340 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4341 problem = PR_1_TOOBIG_DIR;
4342 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4343 problem = PR_1_TOOBIG_REG;
4344 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4345 problem = PR_1_TOOBIG_SYMLINK;
4347 if (blk < fs->super->s_first_data_block ||
4348 blk >= fs->super->s_blocks_count)
4349 problem = PR_1_ILLEGAL_BLOCK_NUM;
4352 p->num_illegal_blocks++;
4353 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4354 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4358 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4360 set_latch_flags(PR_LATCH_BLOCK,
4365 pctx->blkcount = blockcnt;
4366 if (fix_problem(ctx, problem, pctx)) {
4367 blk = *block_nr = 0;
4368 ret_code = BLOCK_CHANGED;
4374 if (p->ino == EXT2_RESIZE_INO) {
4376 * The resize inode has already be sanity checked
4377 * during pass #0 (the superblock checks). All we
4378 * have to do is mark the double indirect block as
4379 * being in use; all of the other blocks are handled
4380 * by mark_table_blocks()).
4382 if (blockcnt == BLOCK_COUNT_DIND)
4383 mark_block_used(ctx, blk);
4385 mark_block_used(ctx, blk);
4388 p->last_block = blockcnt;
4390 if (p->is_dir && (blockcnt >= 0)) {
4391 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4393 if (pctx->errcode) {
4395 pctx->num = blockcnt;
4396 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4397 /* Should never get here */
4398 ctx->flags |= E2F_FLAG_ABORT;
4405 static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4407 e2_blkcnt_t blockcnt,
4408 blk_t ref_block FSCK_ATTR((unused)),
4409 int ref_offset FSCK_ATTR((unused)),
4410 void *priv_data EXT2FS_ATTR((unused)))
4413 * Note: This function processes blocks for the bad blocks
4414 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4417 printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4422 * This routine gets called at the end of pass 1 if bad blocks are
4423 * detected in the superblock, group descriptors, inode_bitmaps, or
4424 * block bitmaps. At this point, all of the blocks have been mapped
4425 * out, so we can try to allocate new block(s) to replace the bad
4428 static void handle_fs_bad_blocks(e2fsck_t ctx)
4430 printf("Bad blocks detected on your filesystem\n"
4431 "You should get your data off as the device will soon die\n");
4435 * This routine marks all blocks which are used by the superblock,
4436 * group descriptors, inode bitmaps, and block bitmaps.
4438 static void mark_table_blocks(e2fsck_t ctx)
4440 ext2_filsys fs = ctx->fs;
4444 struct problem_context pctx;
4446 clear_problem_context(&pctx);
4448 block = fs->super->s_first_data_block;
4449 for (i = 0; i < fs->group_desc_count; i++) {
4452 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4455 * Mark the blocks used for the inode table
4457 if (fs->group_desc[i].bg_inode_table) {
4458 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4459 j < fs->inode_blocks_per_group;
4461 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4464 if (fix_problem(ctx,
4465 PR_1_ITABLE_CONFLICT, &pctx)) {
4466 ctx->invalid_inode_table_flag[i]++;
4467 ctx->invalid_bitmaps++;
4470 ext2fs_mark_block_bitmap(ctx->block_found_map, b);
4476 * Mark block used for the block bitmap
4478 if (fs->group_desc[i].bg_block_bitmap) {
4479 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4480 fs->group_desc[i].bg_block_bitmap)) {
4481 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4482 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4483 ctx->invalid_block_bitmap_flag[i]++;
4484 ctx->invalid_bitmaps++;
4487 ext2fs_mark_block_bitmap(ctx->block_found_map,
4488 fs->group_desc[i].bg_block_bitmap);
4492 * Mark block used for the inode bitmap
4494 if (fs->group_desc[i].bg_inode_bitmap) {
4495 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4496 fs->group_desc[i].bg_inode_bitmap)) {
4497 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4498 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4499 ctx->invalid_inode_bitmap_flag[i]++;
4500 ctx->invalid_bitmaps++;
4503 ext2fs_mark_block_bitmap(ctx->block_found_map,
4504 fs->group_desc[i].bg_inode_bitmap);
4507 block += fs->super->s_blocks_per_group;
4512 * Thes subroutines short circuits ext2fs_get_blocks and
4513 * ext2fs_check_directory; we use them since we already have the inode
4514 * structure, so there's no point in letting the ext2fs library read
4517 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4520 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4523 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4524 return EXT2_ET_CALLBACK_NOTHANDLED;
4526 for (i=0; i < EXT2_N_BLOCKS; i++)
4527 blocks[i] = ctx->stashed_inode->i_block[i];
4531 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4532 struct ext2_inode *inode)
4534 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4536 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4537 return EXT2_ET_CALLBACK_NOTHANDLED;
4538 *inode = *ctx->stashed_inode;
4542 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4543 struct ext2_inode *inode)
4545 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4547 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4548 *ctx->stashed_inode = *inode;
4549 return EXT2_ET_CALLBACK_NOTHANDLED;
4552 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4554 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4556 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4557 return EXT2_ET_CALLBACK_NOTHANDLED;
4559 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4560 return EXT2_ET_NO_DIRECTORY;
4564 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4566 ext2_filsys fs = ctx->fs;
4569 fs->get_blocks = pass1_get_blocks;
4570 fs->check_directory = pass1_check_directory;
4571 fs->read_inode = pass1_read_inode;
4572 fs->write_inode = pass1_write_inode;
4573 ctx->stashed_ino = 0;
4576 fs->check_directory = 0;
4578 fs->write_inode = 0;
4583 * pass1b.c --- Pass #1b of e2fsck
4585 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4586 * only invoked if pass 1 discovered blocks which are in use by more
4589 * Pass1B scans the data blocks of all the inodes again, generating a
4590 * complete list of duplicate blocks and which inodes have claimed
4593 * Pass1C does a tree-traversal of the filesystem, to determine the
4594 * parent directories of these inodes. This step is necessary so that
4595 * e2fsck can print out the pathnames of affected inodes.
4597 * Pass1D is a reconciliation pass. For each inode with duplicate
4598 * blocks, the user is prompted if s/he would like to clone the file
4599 * (so that the file gets a fresh copy of the duplicated blocks) or
4600 * simply to delete the file.
4605 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4606 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4607 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4609 /* Define an extension to the ext2 library's block count information */
4610 #define BLOCK_COUNT_EXTATTR (-5)
4614 struct block_el *next;
4619 struct inode_el *next;
4624 struct inode_el *inode_list;
4628 * This structure stores information about a particular inode which
4629 * is sharing blocks with other inodes. This information is collected
4630 * to display to the user, so that the user knows what files he or she
4631 * is dealing with, when trying to decide how to resolve the conflict
4632 * of multiply-claimed blocks.
4637 struct ext2_inode inode;
4638 struct block_el *block_list;
4641 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
4642 e2_blkcnt_t blockcnt, blk_t ref_blk,
4643 int ref_offset, void *priv_data);
4644 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4645 struct dup_inode *dp, char *block_buf);
4646 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4647 struct dup_inode *dp, char* block_buf);
4648 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4650 static void pass1b(e2fsck_t ctx, char *block_buf);
4651 static void pass1c(e2fsck_t ctx, char *block_buf);
4652 static void pass1d(e2fsck_t ctx, char *block_buf);
4654 static int dup_inode_count = 0;
4656 static dict_t blk_dict, ino_dict;
4658 static ext2fs_inode_bitmap inode_dup_map;
4660 static int dict_int_cmp(const void *a, const void *b)
4671 * Add a duplicate block record
4673 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4674 struct ext2_inode *inode)
4677 struct dup_block *db;
4678 struct dup_inode *di;
4679 struct block_el *blk_el;
4680 struct inode_el *ino_el;
4682 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4684 db = (struct dup_block *) dnode_get(n);
4686 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4687 sizeof(struct dup_block), "duplicate block header");
4690 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4692 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4693 sizeof(struct inode_el), "inode element");
4694 ino_el->inode = ino;
4695 ino_el->next = db->inode_list;
4696 db->inode_list = ino_el;
4699 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4701 di = (struct dup_inode *) dnode_get(n);
4703 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4704 sizeof(struct dup_inode), "duplicate inode header");
4705 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0;
4706 di->num_dupblocks = 0;
4709 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4711 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4712 sizeof(struct block_el), "block element");
4713 blk_el->block = blk;
4714 blk_el->next = di->block_list;
4715 di->block_list = blk_el;
4716 di->num_dupblocks++;
4720 * Free a duplicate inode record
4722 static void inode_dnode_free(dnode_t *node)
4724 struct dup_inode *di;
4725 struct block_el *p, *next;
4727 di = (struct dup_inode *) dnode_get(node);
4728 for (p = di->block_list; p; p = next) {
4736 * Free a duplicate block record
4738 static void block_dnode_free(dnode_t *node)
4740 struct dup_block *db;
4741 struct inode_el *p, *next;
4743 db = (struct dup_block *) dnode_get(node);
4744 for (p = db->inode_list; p; p = next) {
4753 * Main procedure for handling duplicate blocks
4755 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4757 ext2_filsys fs = ctx->fs;
4758 struct problem_context pctx;
4760 clear_problem_context(&pctx);
4762 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4763 _("multiply claimed inode map"), &inode_dup_map);
4765 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4766 ctx->flags |= E2F_FLAG_ABORT;
4770 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4771 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4772 dict_set_allocator(&ino_dict, inode_dnode_free);
4773 dict_set_allocator(&blk_dict, block_dnode_free);
4775 pass1b(ctx, block_buf);
4776 pass1c(ctx, block_buf);
4777 pass1d(ctx, block_buf);
4780 * Time to free all of the accumulated data structures that we
4781 * don't need anymore.
4783 dict_free_nodes(&ino_dict);
4784 dict_free_nodes(&blk_dict);
4788 * Scan the inodes looking for inodes that contain duplicate blocks.
4790 struct process_block_struct_1b {
4794 struct ext2_inode *inode;
4795 struct problem_context *pctx;
4798 static void pass1b(e2fsck_t ctx, char *block_buf)
4800 ext2_filsys fs = ctx->fs;
4802 struct ext2_inode inode;
4803 ext2_inode_scan scan;
4804 struct process_block_struct_1b pb;
4805 struct problem_context pctx;
4807 clear_problem_context(&pctx);
4809 if (!(ctx->options & E2F_OPT_PREEN))
4810 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4811 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4814 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4815 ctx->flags |= E2F_FLAG_ABORT;
4818 ctx->stashed_inode = &inode;
4821 pctx.str = "pass1b";
4823 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4824 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4827 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4828 ctx->flags |= E2F_FLAG_ABORT;
4833 pctx.ino = ctx->stashed_ino = ino;
4834 if ((ino != EXT2_BAD_INO) &&
4835 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4842 if (ext2fs_inode_has_valid_blocks(&inode) ||
4843 (ino == EXT2_BAD_INO))
4844 pctx.errcode = ext2fs_block_iterate2(fs, ino,
4845 0, block_buf, process_pass1b_block, &pb);
4846 if (inode.i_file_acl)
4847 process_pass1b_block(fs, &inode.i_file_acl,
4848 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4849 if (pb.dup_blocks) {
4850 end_problem_latch(ctx, PR_LATCH_DBLOCK);
4851 if (ino >= EXT2_FIRST_INODE(fs->super) ||
4852 ino == EXT2_ROOT_INO)
4856 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4858 ext2fs_close_inode_scan(scan);
4859 e2fsck_use_inode_shortcuts(ctx, 0);
4862 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4864 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4865 blk_t ref_blk FSCK_ATTR((unused)),
4866 int ref_offset FSCK_ATTR((unused)),
4869 struct process_block_struct_1b *p;
4872 if (HOLE_BLKADDR(*block_nr))
4874 p = (struct process_block_struct_1b *) priv_data;
4877 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4880 /* OK, this is a duplicate block */
4881 if (p->ino != EXT2_BAD_INO) {
4882 p->pctx->blk = *block_nr;
4883 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4886 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4888 add_dupe(ctx, p->ino, *block_nr, p->inode);
4894 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4895 * is used so that we can print pathnames when prompting the user for
4898 struct search_dir_struct {
4900 ext2_ino_t first_inode;
4901 ext2_ino_t max_inode;
4904 static int search_dirent_proc(ext2_ino_t dir, int entry,
4905 struct ext2_dir_entry *dirent,
4906 int offset FSCK_ATTR((unused)),
4907 int blocksize FSCK_ATTR((unused)),
4908 char *buf FSCK_ATTR((unused)),
4911 struct search_dir_struct *sd;
4912 struct dup_inode *p;
4915 sd = (struct search_dir_struct *) priv_data;
4917 if (dirent->inode > sd->max_inode)
4918 /* Should abort this inode, but not everything */
4921 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4922 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4925 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4928 p = (struct dup_inode *) dnode_get(n);
4932 return sd->count ? 0 : DIRENT_ABORT;
4936 static void pass1c(e2fsck_t ctx, char *block_buf)
4938 ext2_filsys fs = ctx->fs;
4939 struct search_dir_struct sd;
4940 struct problem_context pctx;
4942 clear_problem_context(&pctx);
4944 if (!(ctx->options & E2F_OPT_PREEN))
4945 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4948 * Search through all directories to translate inodes to names
4949 * (by searching for the containing directory for that inode.)
4951 sd.count = dup_inode_count;
4952 sd.first_inode = EXT2_FIRST_INODE(fs->super);
4953 sd.max_inode = fs->super->s_inodes_count;
4954 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4955 search_dirent_proc, &sd);
4958 static void pass1d(e2fsck_t ctx, char *block_buf)
4960 ext2_filsys fs = ctx->fs;
4961 struct dup_inode *p, *t;
4962 struct dup_block *q;
4963 ext2_ino_t *shared, ino;
4968 struct problem_context pctx;
4973 clear_problem_context(&pctx);
4975 if (!(ctx->options & E2F_OPT_PREEN))
4976 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
4977 e2fsck_read_bitmaps(ctx);
4979 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
4980 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
4981 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
4982 sizeof(ext2_ino_t) * dict_count(&ino_dict),
4983 "Shared inode list");
4984 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
4985 p = (struct dup_inode *) dnode_get(n);
4988 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
4989 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
4993 * Find all of the inodes which share blocks with this
4994 * one. First we find all of the duplicate blocks
4995 * belonging to this inode, and then search each block
4996 * get the list of inodes, and merge them together.
4998 for (s = p->block_list; s; s = s->next) {
4999 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5001 continue; /* Should never happen... */
5002 q = (struct dup_block *) dnode_get(m);
5005 if (check_if_fs_block(ctx, s->block)) {
5011 * Add all inodes used by this block to the
5012 * shared[] --- which is a unique list, so
5013 * if an inode is already in shared[], don't
5016 for (r = q->inode_list; r; r = r->next) {
5017 if (r->inode == ino)
5019 for (i = 0; i < shared_len; i++)
5020 if (shared[i] == r->inode)
5022 if (i == shared_len) {
5023 shared[shared_len++] = r->inode;
5029 * Report the inode that we are working on
5031 pctx.inode = &p->inode;
5034 pctx.blkcount = p->num_dupblocks;
5035 pctx.num = meta_data ? shared_len+1 : shared_len;
5036 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5041 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5043 for (i = 0; i < shared_len; i++) {
5044 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5046 continue; /* should never happen */
5047 t = (struct dup_inode *) dnode_get(m);
5049 * Report the inode that we are sharing with
5051 pctx.inode = &t->inode;
5052 pctx.ino = shared[i];
5054 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5057 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5060 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5061 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5063 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5067 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5068 delete_file(ctx, ino, p, block_buf);
5070 ext2fs_unmark_valid(fs);
5072 ext2fs_free_mem(&shared);
5076 * Drop the refcount on the dup_block structure, and clear the entry
5077 * in the block_dup_map if appropriate.
5079 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5082 if (p->num_bad <= 0 ||
5083 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5084 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5087 static int delete_file_block(ext2_filsys fs,
5089 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5090 blk_t ref_block FSCK_ATTR((unused)),
5091 int ref_offset FSCK_ATTR((unused)),
5094 struct process_block_struct_1b *pb;
5095 struct dup_block *p;
5099 pb = (struct process_block_struct_1b *) priv_data;
5102 if (HOLE_BLKADDR(*block_nr))
5105 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5106 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5108 p = (struct dup_block *) dnode_get(n);
5109 decrement_badcount(ctx, *block_nr, p);
5111 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5114 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5115 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5121 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5122 struct dup_inode *dp, char* block_buf)
5124 ext2_filsys fs = ctx->fs;
5125 struct process_block_struct_1b pb;
5126 struct ext2_inode inode;
5127 struct problem_context pctx;
5130 clear_problem_context(&pctx);
5131 pctx.ino = pb.ino = ino;
5132 pb.dup_blocks = dp->num_dupblocks;
5134 pctx.str = "delete_file";
5136 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5137 if (ext2fs_inode_has_valid_blocks(&inode))
5138 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5139 delete_file_block, &pb);
5141 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5142 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5143 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5144 if (ctx->inode_bad_map)
5145 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5146 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5148 /* Inode may have changed by block_iterate, so reread it */
5149 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5150 inode.i_links_count = 0;
5151 inode.i_dtime = time(NULL);
5152 if (inode.i_file_acl &&
5153 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5155 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5156 block_buf, -1, &count);
5157 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5162 pctx.blk = inode.i_file_acl;
5163 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5166 * If the count is zero, then arrange to have the
5167 * block deleted. If the block is in the block_dup_map,
5168 * also call delete_file_block since it will take care
5169 * of keeping the accounting straight.
5172 ext2fs_test_block_bitmap(ctx->block_dup_map,
5174 delete_file_block(fs, &inode.i_file_acl,
5175 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5177 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5180 struct clone_struct {
5187 static int clone_file_block(ext2_filsys fs,
5189 e2_blkcnt_t blockcnt,
5190 blk_t ref_block FSCK_ATTR((unused)),
5191 int ref_offset FSCK_ATTR((unused)),
5194 struct dup_block *p;
5197 struct clone_struct *cs = (struct clone_struct *) priv_data;
5203 if (HOLE_BLKADDR(*block_nr))
5206 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5207 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5209 p = (struct dup_block *) dnode_get(n);
5210 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5213 cs->errcode = retval;
5216 if (cs->dir && (blockcnt >= 0)) {
5217 retval = ext2fs_set_dir_block(fs->dblist,
5218 cs->dir, new_block, blockcnt);
5220 cs->errcode = retval;
5225 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5228 cs->errcode = retval;
5231 retval = io_channel_write_blk(fs->io, new_block, 1,
5234 cs->errcode = retval;
5237 decrement_badcount(ctx, *block_nr, p);
5238 *block_nr = new_block;
5239 ext2fs_mark_block_bitmap(ctx->block_found_map,
5241 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5242 return BLOCK_CHANGED;
5244 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5250 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5251 struct dup_inode *dp, char* block_buf)
5253 ext2_filsys fs = ctx->fs;
5255 struct clone_struct cs;
5256 struct problem_context pctx;
5259 struct inode_el *ino_el;
5260 struct dup_block *db;
5261 struct dup_inode *di;
5263 clear_problem_context(&pctx);
5267 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5271 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5275 pctx.str = "clone_file";
5276 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5277 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5278 clone_file_block, &cs);
5279 ext2fs_mark_bb_dirty(fs);
5281 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5282 retval = pctx.errcode;
5286 bb_error_msg(_("returned from clone_file_block"));
5287 retval = cs.errcode;
5290 /* The inode may have changed on disk, so we have to re-read it */
5291 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5292 blk = dp->inode.i_file_acl;
5293 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5294 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5296 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5298 * If we cloned the EA block, find all other inodes
5299 * which refered to that EA block, and modify
5300 * them to point to the new EA block.
5302 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5303 db = (struct dup_block *) dnode_get(n);
5304 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5305 if (ino_el->inode == ino)
5307 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5308 di = (struct dup_inode *) dnode_get(n);
5309 if (di->inode.i_file_acl == blk) {
5310 di->inode.i_file_acl = dp->inode.i_file_acl;
5311 e2fsck_write_inode(ctx, ino_el->inode,
5312 &di->inode, "clone file EA");
5313 decrement_badcount(ctx, blk, db);
5319 ext2fs_free_mem(&cs.buf);
5324 * This routine returns 1 if a block overlaps with one of the superblocks,
5325 * group descriptors, inode bitmaps, or block bitmaps.
5327 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5329 ext2_filsys fs = ctx->fs;
5333 block = fs->super->s_first_data_block;
5334 for (i = 0; i < fs->group_desc_count; i++) {
5336 /* Check superblocks/block group descriptros */
5337 if (ext2fs_bg_has_super(fs, i)) {
5338 if (test_block >= block &&
5339 (test_block <= block + fs->desc_blocks))
5343 /* Check the inode table */
5344 if ((fs->group_desc[i].bg_inode_table) &&
5345 (test_block >= fs->group_desc[i].bg_inode_table) &&
5346 (test_block < (fs->group_desc[i].bg_inode_table +
5347 fs->inode_blocks_per_group)))
5350 /* Check the bitmap blocks */
5351 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5352 (test_block == fs->group_desc[i].bg_inode_bitmap))
5355 block += fs->super->s_blocks_per_group;
5360 * pass2.c --- check directory structure
5362 * Pass 2 of e2fsck iterates through all active directory inodes, and
5363 * applies to following tests to each directory entry in the directory
5364 * blocks in the inodes:
5366 * - The length of the directory entry (rec_len) should be at
5367 * least 8 bytes, and no more than the remaining space
5368 * left in the directory block.
5369 * - The length of the name in the directory entry (name_len)
5370 * should be less than (rec_len - 8).
5371 * - The inode number in the directory entry should be within
5373 * - The inode number should refer to a in-use inode.
5374 * - The first entry should be '.', and its inode should be
5375 * the inode of the directory.
5376 * - The second entry should be '..'.
5378 * To minimize disk seek time, the directory blocks are processed in
5379 * sorted order of block numbers.
5381 * Pass 2 also collects the following information:
5382 * - The inode numbers of the subdirectories for each directory.
5384 * Pass 2 relies on the following information from previous passes:
5385 * - The directory information collected in pass 1.
5386 * - The inode_used_map bitmap
5387 * - The inode_bad_map bitmap
5388 * - The inode_dir_map bitmap
5390 * Pass 2 frees the following data structures
5391 * - The inode_bad_map bitmap
5392 * - The inode_reg_map bitmap
5396 * Keeps track of how many times an inode is referenced.
5398 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5399 static int check_dir_block(ext2_filsys fs,
5400 struct ext2_db_entry *dir_blocks_info,
5402 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5403 struct problem_context *pctx);
5404 static int update_dir_block(ext2_filsys fs,
5406 e2_blkcnt_t blockcnt,
5410 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5411 static int htree_depth(struct dx_dir_info *dx_dir,
5412 struct dx_dirblock_info *dx_db);
5413 static int special_dir_block_cmp(const void *a, const void *b);
5415 struct check_dir_struct {
5417 struct problem_context pctx;
5422 static void e2fsck_pass2(e2fsck_t ctx)
5424 struct ext2_super_block *sb = ctx->fs->super;
5425 struct problem_context pctx;
5426 ext2_filsys fs = ctx->fs;
5428 struct dir_info *dir;
5429 struct check_dir_struct cd;
5430 struct dx_dir_info *dx_dir;
5431 struct dx_dirblock_info *dx_db, *dx_parent;
5437 clear_problem_context(&cd.pctx);
5441 if (!(ctx->options & E2F_OPT_PREEN))
5442 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5444 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5445 0, ctx->inode_link_info,
5447 if (cd.pctx.errcode) {
5448 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5449 ctx->flags |= E2F_FLAG_ABORT;
5452 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5453 "directory scan buffer");
5456 * Set up the parent pointer for the root directory, if
5457 * present. (If the root directory is not present, we will
5458 * create it in pass 3.)
5460 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5462 dir->parent = EXT2_ROOT_INO;
5467 cd.max = ext2fs_dblist_count(fs->dblist);
5470 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5472 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5473 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5475 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5477 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5479 if (cd.pctx.errcode) {
5480 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5481 ctx->flags |= E2F_FLAG_ABORT;
5486 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5487 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5489 if (dx_dir->numblocks == 0)
5491 clear_problem_context(&pctx);
5493 pctx.dir = dx_dir->ino;
5494 dx_db = dx_dir->dx_block;
5495 if (dx_db->flags & DX_FLAG_REFERENCED)
5496 dx_db->flags |= DX_FLAG_DUP_REF;
5498 dx_db->flags |= DX_FLAG_REFERENCED;
5500 * Find all of the first and last leaf blocks, and
5501 * update their parent's min and max hash values
5503 for (b=0, dx_db = dx_dir->dx_block;
5504 b < dx_dir->numblocks;
5506 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5507 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5509 dx_parent = &dx_dir->dx_block[dx_db->parent];
5511 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5513 if (dx_db->flags & DX_FLAG_FIRST)
5514 dx_parent->min_hash = dx_db->min_hash;
5516 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5518 if (dx_db->flags & DX_FLAG_LAST)
5519 dx_parent->max_hash = dx_db->max_hash;
5522 for (b=0, dx_db = dx_dir->dx_block;
5523 b < dx_dir->numblocks;
5526 pctx.group = dx_db->parent;
5528 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5529 (dx_db->min_hash < dx_db->node_min_hash)) {
5530 pctx.blk = dx_db->min_hash;
5531 pctx.blk2 = dx_db->node_min_hash;
5532 code = PR_2_HTREE_MIN_HASH;
5533 fix_problem(ctx, code, &pctx);
5536 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5537 depth = htree_depth(dx_dir, dx_db);
5538 if (depth != dx_dir->depth) {
5539 code = PR_2_HTREE_BAD_DEPTH;
5540 fix_problem(ctx, code, &pctx);
5545 * This test doesn't apply for the root block
5549 (dx_db->max_hash > dx_db->node_max_hash)) {
5550 pctx.blk = dx_db->max_hash;
5551 pctx.blk2 = dx_db->node_max_hash;
5552 code = PR_2_HTREE_MAX_HASH;
5553 fix_problem(ctx, code, &pctx);
5556 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5557 code = PR_2_HTREE_NOTREF;
5558 fix_problem(ctx, code, &pctx);
5560 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5561 code = PR_2_HTREE_DUPREF;
5562 fix_problem(ctx, code, &pctx);
5568 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5569 clear_htree(ctx, dx_dir->ino);
5570 dx_dir->numblocks = 0;
5574 ext2fs_free_mem(&buf);
5575 ext2fs_free_dblist(fs->dblist);
5577 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5578 ctx->inode_bad_map = 0;
5579 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5580 ctx->inode_reg_map = 0;
5582 clear_problem_context(&pctx);
5583 if (ctx->large_files) {
5584 if (!(sb->s_feature_ro_compat &
5585 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5586 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5587 sb->s_feature_ro_compat |=
5588 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5589 ext2fs_mark_super_dirty(fs);
5591 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5592 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5593 ext2fs_update_dynamic_rev(fs);
5594 ext2fs_mark_super_dirty(fs);
5596 } else if (!ctx->large_files &&
5597 (sb->s_feature_ro_compat &
5598 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5599 if (fs->flags & EXT2_FLAG_RW) {
5600 sb->s_feature_ro_compat &=
5601 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5602 ext2fs_mark_super_dirty(fs);
5607 #define MAX_DEPTH 32000
5608 static int htree_depth(struct dx_dir_info *dx_dir,
5609 struct dx_dirblock_info *dx_db)
5613 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5614 dx_db = &dx_dir->dx_block[dx_db->parent];
5620 static int dict_de_cmp(const void *a, const void *b)
5622 const struct ext2_dir_entry *de_a, *de_b;
5625 de_a = (const struct ext2_dir_entry *) a;
5626 a_len = de_a->name_len & 0xFF;
5627 de_b = (const struct ext2_dir_entry *) b;
5628 b_len = de_b->name_len & 0xFF;
5631 return (a_len - b_len);
5633 return strncmp(de_a->name, de_b->name, a_len);
5637 * This is special sort function that makes sure that directory blocks
5638 * with a dirblock of zero are sorted to the beginning of the list.
5639 * This guarantees that the root node of the htree directories are
5640 * processed first, so we know what hash version to use.
5642 static int special_dir_block_cmp(const void *a, const void *b)
5644 const struct ext2_db_entry *db_a =
5645 (const struct ext2_db_entry *) a;
5646 const struct ext2_db_entry *db_b =
5647 (const struct ext2_db_entry *) b;
5649 if (db_a->blockcnt && !db_b->blockcnt)
5652 if (!db_a->blockcnt && db_b->blockcnt)
5655 if (db_a->blk != db_b->blk)
5656 return (int) (db_a->blk - db_b->blk);
5658 if (db_a->ino != db_b->ino)
5659 return (int) (db_a->ino - db_b->ino);
5661 return (int) (db_a->blockcnt - db_b->blockcnt);
5666 * Make sure the first entry in the directory is '.', and that the
5667 * directory entry is sane.
5669 static int check_dot(e2fsck_t ctx,
5670 struct ext2_dir_entry *dirent,
5671 ext2_ino_t ino, struct problem_context *pctx)
5673 struct ext2_dir_entry *nextdir;
5680 problem = PR_2_MISSING_DOT;
5681 else if (((dirent->name_len & 0xFF) != 1) ||
5682 (dirent->name[0] != '.'))
5683 problem = PR_2_1ST_NOT_DOT;
5684 else if (dirent->name[1] != '\0')
5685 problem = PR_2_DOT_NULL_TERM;
5688 if (fix_problem(ctx, problem, pctx)) {
5689 if (dirent->rec_len < 12)
5690 dirent->rec_len = 12;
5691 dirent->inode = ino;
5692 dirent->name_len = 1;
5693 dirent->name[0] = '.';
5694 dirent->name[1] = '\0';
5699 if (dirent->inode != ino) {
5700 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5701 dirent->inode = ino;
5705 if (dirent->rec_len > 12) {
5706 new_len = dirent->rec_len - 12;
5709 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5710 nextdir = (struct ext2_dir_entry *)
5711 ((char *) dirent + 12);
5712 dirent->rec_len = 12;
5713 nextdir->rec_len = new_len;
5715 nextdir->name_len = 0;
5724 * Make sure the second entry in the directory is '..', and that the
5725 * directory entry is sane. We do not check the inode number of '..'
5726 * here; this gets done in pass 3.
5728 static int check_dotdot(e2fsck_t ctx,
5729 struct ext2_dir_entry *dirent,
5730 struct dir_info *dir, struct problem_context *pctx)
5735 problem = PR_2_MISSING_DOT_DOT;
5736 else if (((dirent->name_len & 0xFF) != 2) ||
5737 (dirent->name[0] != '.') ||
5738 (dirent->name[1] != '.'))
5739 problem = PR_2_2ND_NOT_DOT_DOT;
5740 else if (dirent->name[2] != '\0')
5741 problem = PR_2_DOT_DOT_NULL_TERM;
5744 if (fix_problem(ctx, problem, pctx)) {
5745 if (dirent->rec_len < 12)
5746 dirent->rec_len = 12;
5748 * Note: we don't have the parent inode just
5749 * yet, so we will fill it in with the root
5750 * inode. This will get fixed in pass 3.
5752 dirent->inode = EXT2_ROOT_INO;
5753 dirent->name_len = 2;
5754 dirent->name[0] = '.';
5755 dirent->name[1] = '.';
5756 dirent->name[2] = '\0';
5761 dir->dotdot = dirent->inode;
5766 * Check to make sure a directory entry doesn't contain any illegal
5769 static int check_name(e2fsck_t ctx,
5770 struct ext2_dir_entry *dirent,
5771 struct problem_context *pctx)
5777 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5778 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5780 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5783 dirent->name[i] = '.';
5792 * Check the directory filetype (if present)
5796 * Given a mode, return the ext2 file type
5798 static int ext2_file_type(unsigned int mode)
5800 if (LINUX_S_ISREG(mode))
5801 return EXT2_FT_REG_FILE;
5803 if (LINUX_S_ISDIR(mode))
5806 if (LINUX_S_ISCHR(mode))
5807 return EXT2_FT_CHRDEV;
5809 if (LINUX_S_ISBLK(mode))
5810 return EXT2_FT_BLKDEV;
5812 if (LINUX_S_ISLNK(mode))
5813 return EXT2_FT_SYMLINK;
5815 if (LINUX_S_ISFIFO(mode))
5816 return EXT2_FT_FIFO;
5818 if (LINUX_S_ISSOCK(mode))
5819 return EXT2_FT_SOCK;
5824 static int check_filetype(e2fsck_t ctx,
5825 struct ext2_dir_entry *dirent,
5826 struct problem_context *pctx)
5828 int filetype = dirent->name_len >> 8;
5829 int should_be = EXT2_FT_UNKNOWN;
5830 struct ext2_inode inode;
5832 if (!(ctx->fs->super->s_feature_incompat &
5833 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5834 if (filetype == 0 ||
5835 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5837 dirent->name_len = dirent->name_len & 0xFF;
5841 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5842 should_be = EXT2_FT_DIR;
5843 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5845 should_be = EXT2_FT_REG_FILE;
5846 } else if (ctx->inode_bad_map &&
5847 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5851 e2fsck_read_inode(ctx, dirent->inode, &inode,
5853 should_be = ext2_file_type(inode.i_mode);
5855 if (filetype == should_be)
5857 pctx->num = should_be;
5859 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5863 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5868 static void parse_int_node(ext2_filsys fs,
5869 struct ext2_db_entry *db,
5870 struct check_dir_struct *cd,
5871 struct dx_dir_info *dx_dir,
5874 struct ext2_dx_root_info *root;
5875 struct ext2_dx_entry *ent;
5876 struct ext2_dx_countlimit *limit;
5877 struct dx_dirblock_info *dx_db;
5878 int i, expect_limit, count;
5880 ext2_dirhash_t min_hash = 0xffffffff;
5881 ext2_dirhash_t max_hash = 0;
5882 ext2_dirhash_t hash = 0, prev_hash;
5884 if (db->blockcnt == 0) {
5885 root = (struct ext2_dx_root_info *) (block_buf + 24);
5886 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5888 ent = (struct ext2_dx_entry *) (block_buf+8);
5890 limit = (struct ext2_dx_countlimit *) ent;
5892 count = ext2fs_le16_to_cpu(limit->count);
5893 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5894 sizeof(struct ext2_dx_entry);
5895 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5896 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5897 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5898 goto clear_and_exit;
5900 if (count > expect_limit) {
5901 cd->pctx.num = count;
5902 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5903 goto clear_and_exit;
5904 count = expect_limit;
5907 for (i=0; i < count; i++) {
5909 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5910 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5911 /* Check to make sure the block is valid */
5912 if (blk > (blk_t) dx_dir->numblocks) {
5914 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5916 goto clear_and_exit;
5918 if (hash < prev_hash &&
5919 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5920 goto clear_and_exit;
5921 dx_db = &dx_dir->dx_block[blk];
5922 if (dx_db->flags & DX_FLAG_REFERENCED) {
5923 dx_db->flags |= DX_FLAG_DUP_REF;
5925 dx_db->flags |= DX_FLAG_REFERENCED;
5926 dx_db->parent = db->blockcnt;
5928 if (hash < min_hash)
5930 if (hash > max_hash)
5932 dx_db->node_min_hash = hash;
5934 dx_db->node_max_hash =
5935 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5937 dx_db->node_max_hash = 0xfffffffe;
5938 dx_db->flags |= DX_FLAG_LAST;
5941 dx_db->flags |= DX_FLAG_FIRST;
5943 dx_db = &dx_dir->dx_block[db->blockcnt];
5944 dx_db->min_hash = min_hash;
5945 dx_db->max_hash = max_hash;
5949 clear_htree(cd->ctx, cd->pctx.ino);
5950 dx_dir->numblocks = 0;
5952 #endif /* ENABLE_HTREE */
5955 * Given a busted directory, try to salvage it somehow.
5958 static void salvage_directory(ext2_filsys fs,
5959 struct ext2_dir_entry *dirent,
5960 struct ext2_dir_entry *prev,
5961 unsigned int *offset)
5963 char *cp = (char *) dirent;
5964 int left = fs->blocksize - *offset - dirent->rec_len;
5965 int name_len = dirent->name_len & 0xFF;
5968 * Special case of directory entry of size 8: copy what's left
5969 * of the directory block up to cover up the invalid hole.
5971 if ((left >= 12) && (dirent->rec_len == 8)) {
5972 memmove(cp, cp+8, left);
5973 memset(cp + left, 0, 8);
5977 * If the directory entry overruns the end of the directory
5978 * block, and the name is small enough to fit, then adjust the
5982 (name_len + 8 <= dirent->rec_len + left) &&
5983 dirent->inode <= fs->super->s_inodes_count &&
5984 strnlen(dirent->name, name_len) == name_len) {
5985 dirent->rec_len += left;
5989 * If the directory entry is a multiple of four, so it is
5990 * valid, let the previous directory entry absorb the invalid
5993 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
5994 prev->rec_len += dirent->rec_len;
5995 *offset += dirent->rec_len;
5999 * Default salvage method --- kill all of the directory
6000 * entries for the rest of the block. We will either try to
6001 * absorb it into the previous directory entry, or create a
6002 * new empty directory entry the rest of the directory block.
6005 prev->rec_len += fs->blocksize - *offset;
6006 *offset = fs->blocksize;
6008 dirent->rec_len = fs->blocksize - *offset;
6009 dirent->name_len = 0;
6014 static int check_dir_block(ext2_filsys fs,
6015 struct ext2_db_entry *db,
6018 struct dir_info *subdir, *dir;
6019 struct dx_dir_info *dx_dir;
6021 struct dx_dirblock_info *dx_db = NULL;
6022 #endif /* ENABLE_HTREE */
6023 struct ext2_dir_entry *dirent, *prev;
6024 ext2_dirhash_t hash;
6025 unsigned int offset = 0;
6026 int dir_modified = 0;
6028 blk_t block_nr = db->blk;
6029 ext2_ino_t ino = db->ino;
6031 struct check_dir_struct *cd;
6035 struct ext2_dx_root_info *root;
6036 struct ext2_dx_countlimit *limit;
6037 static dict_t de_dict;
6038 struct problem_context pctx;
6041 cd = (struct check_dir_struct *) priv_data;
6045 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6046 return DIRENT_ABORT;
6048 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6049 return DIRENT_ABORT;
6052 * Make sure the inode is still in use (could have been
6053 * deleted in the duplicate/bad blocks pass.
6055 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6059 cd->pctx.blk = block_nr;
6060 cd->pctx.blkcount = db->blockcnt;
6062 cd->pctx.dirent = 0;
6066 if (allocate_dir_block(ctx, db, &cd->pctx))
6076 if (ctx->dirs_to_hash &&
6077 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6080 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6081 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6082 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6083 if (cd->pctx.errcode) {
6084 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6085 ctx->flags |= E2F_FLAG_ABORT;
6086 return DIRENT_ABORT;
6088 memset(buf, 0, fs->blocksize);
6091 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6092 if (dx_dir && dx_dir->numblocks) {
6093 if (db->blockcnt >= dx_dir->numblocks) {
6094 printf("XXX should never happen!!!\n");
6097 dx_db = &dx_dir->dx_block[db->blockcnt];
6098 dx_db->type = DX_DIRBLOCK_LEAF;
6099 dx_db->phys = block_nr;
6100 dx_db->min_hash = ~0;
6101 dx_db->max_hash = 0;
6103 dirent = (struct ext2_dir_entry *) buf;
6104 limit = (struct ext2_dx_countlimit *) (buf+8);
6105 if (db->blockcnt == 0) {
6106 root = (struct ext2_dx_root_info *) (buf + 24);
6107 dx_db->type = DX_DIRBLOCK_ROOT;
6108 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6109 if ((root->reserved_zero ||
6110 root->info_length < 8 ||
6111 root->indirect_levels > 1) &&
6112 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6113 clear_htree(ctx, ino);
6114 dx_dir->numblocks = 0;
6117 dx_dir->hashversion = root->hash_version;
6118 dx_dir->depth = root->indirect_levels + 1;
6119 } else if ((dirent->inode == 0) &&
6120 (dirent->rec_len == fs->blocksize) &&
6121 (dirent->name_len == 0) &&
6122 (ext2fs_le16_to_cpu(limit->limit) ==
6123 ((fs->blocksize-8) /
6124 sizeof(struct ext2_dx_entry))))
6125 dx_db->type = DX_DIRBLOCK_NODE;
6127 #endif /* ENABLE_HTREE */
6129 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6133 dirent = (struct ext2_dir_entry *) (buf + offset);
6134 cd->pctx.dirent = dirent;
6135 cd->pctx.num = offset;
6136 if (((offset + dirent->rec_len) > fs->blocksize) ||
6137 (dirent->rec_len < 12) ||
6138 ((dirent->rec_len % 4) != 0) ||
6139 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6140 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6141 salvage_directory(fs, dirent, prev, &offset);
6145 goto abort_free_dict;
6147 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6148 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6149 dirent->name_len = EXT2_NAME_LEN;
6154 if (dot_state == 0) {
6155 if (check_dot(ctx, dirent, ino, &cd->pctx))
6157 } else if (dot_state == 1) {
6158 dir = e2fsck_get_dir_info(ctx, ino);
6160 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6161 goto abort_free_dict;
6163 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6165 } else if (dirent->inode == ino) {
6166 problem = PR_2_LINK_DOT;
6167 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6177 * Make sure the inode listed is a legal one.
6179 if (((dirent->inode != EXT2_ROOT_INO) &&
6180 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6181 (dirent->inode > fs->super->s_inodes_count)) {
6182 problem = PR_2_BAD_INO;
6183 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6186 * If the inode is unused, offer to clear it.
6188 problem = PR_2_UNUSED_INODE;
6189 } else if ((dot_state > 1) &&
6190 ((dirent->name_len & 0xFF) == 1) &&
6191 (dirent->name[0] == '.')) {
6193 * If there's a '.' entry in anything other
6194 * than the first directory entry, it's a
6195 * duplicate entry that should be removed.
6197 problem = PR_2_DUP_DOT;
6198 } else if ((dot_state > 1) &&
6199 ((dirent->name_len & 0xFF) == 2) &&
6200 (dirent->name[0] == '.') &&
6201 (dirent->name[1] == '.')) {
6203 * If there's a '..' entry in anything other
6204 * than the second directory entry, it's a
6205 * duplicate entry that should be removed.
6207 problem = PR_2_DUP_DOT_DOT;
6208 } else if ((dot_state > 1) &&
6209 (dirent->inode == EXT2_ROOT_INO)) {
6211 * Don't allow links to the root directory.
6212 * We check this specially to make sure we
6213 * catch this error case even if the root
6214 * directory hasn't been created yet.
6216 problem = PR_2_LINK_ROOT;
6217 } else if ((dot_state > 1) &&
6218 (dirent->name_len & 0xFF) == 0) {
6220 * Don't allow zero-length directory names.
6222 problem = PR_2_NULL_NAME;
6226 if (fix_problem(ctx, problem, &cd->pctx)) {
6231 ext2fs_unmark_valid(fs);
6232 if (problem == PR_2_BAD_INO)
6238 * If the inode was marked as having bad fields in
6239 * pass1, process it and offer to fix/clear it.
6240 * (We wait until now so that we can display the
6241 * pathname to the user.)
6243 if (ctx->inode_bad_map &&
6244 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6246 if (e2fsck_process_bad_inode(ctx, ino,
6248 buf + fs->blocksize)) {
6253 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6254 return DIRENT_ABORT;
6257 if (check_name(ctx, dirent, &cd->pctx))
6260 if (check_filetype(ctx, dirent, &cd->pctx))
6265 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6266 (dirent->name_len & 0xFF),
6267 fs->super->s_hash_seed, &hash, 0);
6268 if (hash < dx_db->min_hash)
6269 dx_db->min_hash = hash;
6270 if (hash > dx_db->max_hash)
6271 dx_db->max_hash = hash;
6276 * If this is a directory, then mark its parent in its
6277 * dir_info structure. If the parent field is already
6278 * filled in, then this directory has more than one
6279 * hard link. We assume the first link is correct,
6280 * and ask the user if he/she wants to clear this one.
6282 if ((dot_state > 1) &&
6283 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6285 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6287 cd->pctx.ino = dirent->inode;
6288 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6289 goto abort_free_dict;
6291 if (subdir->parent) {
6292 cd->pctx.ino2 = subdir->parent;
6293 if (fix_problem(ctx, PR_2_LINK_DIR,
6301 subdir->parent = ino;
6306 } else if (dict_lookup(&de_dict, dirent)) {
6307 clear_problem_context(&pctx);
6309 pctx.dirent = dirent;
6310 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6311 if (!ctx->dirs_to_hash)
6312 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6313 if (ctx->dirs_to_hash)
6314 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6317 dict_alloc_insert(&de_dict, dirent, dirent);
6319 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6322 ctx->fs_links_count++;
6323 ctx->fs_total_count++;
6326 offset += dirent->rec_len;
6328 } while (offset < fs->blocksize);
6331 cd->pctx.dir = cd->pctx.ino;
6332 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6333 (dx_db->type == DX_DIRBLOCK_NODE))
6334 parse_int_node(fs, db, cd, dx_dir, buf);
6336 #endif /* ENABLE_HTREE */
6337 if (offset != fs->blocksize) {
6338 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6339 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6340 dirent->rec_len = cd->pctx.num;
6345 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6346 if (cd->pctx.errcode) {
6347 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6349 goto abort_free_dict;
6351 ext2fs_mark_changed(fs);
6353 dict_free_nodes(&de_dict);
6356 dict_free_nodes(&de_dict);
6357 ctx->flags |= E2F_FLAG_ABORT;
6358 return DIRENT_ABORT;
6362 * This function is called to deallocate a block, and is an interator
6363 * functioned called by deallocate inode via ext2fs_iterate_block().
6365 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6366 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6367 blk_t ref_block FSCK_ATTR((unused)),
6368 int ref_offset FSCK_ATTR((unused)),
6371 e2fsck_t ctx = (e2fsck_t) priv_data;
6373 if (HOLE_BLKADDR(*block_nr))
6375 if ((*block_nr < fs->super->s_first_data_block) ||
6376 (*block_nr >= fs->super->s_blocks_count))
6378 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6379 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6384 * This fuction deallocates an inode
6386 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6388 ext2_filsys fs = ctx->fs;
6389 struct ext2_inode inode;
6390 struct problem_context pctx;
6393 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6394 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6395 inode.i_links_count = 0;
6396 inode.i_dtime = time(NULL);
6397 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6398 clear_problem_context(&pctx);
6402 * Fix up the bitmaps...
6404 e2fsck_read_bitmaps(ctx);
6405 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6406 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6407 if (ctx->inode_bad_map)
6408 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6409 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6411 if (inode.i_file_acl &&
6412 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6413 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6414 block_buf, -1, &count);
6415 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6420 pctx.blk = inode.i_file_acl;
6421 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6422 ctx->flags |= E2F_FLAG_ABORT;
6426 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6428 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6430 inode.i_file_acl = 0;
6433 if (!ext2fs_inode_has_valid_blocks(&inode))
6436 if (LINUX_S_ISREG(inode.i_mode) &&
6437 (inode.i_size_high || inode.i_size & 0x80000000UL))
6440 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6441 deallocate_inode_block, ctx);
6443 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6444 ctx->flags |= E2F_FLAG_ABORT;
6450 * This fuction clears the htree flag on an inode
6452 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6454 struct ext2_inode inode;
6456 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6457 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6458 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6459 if (ctx->dirs_to_hash)
6460 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6464 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6465 ext2_ino_t ino, char *buf)
6467 ext2_filsys fs = ctx->fs;
6468 struct ext2_inode inode;
6469 int inode_modified = 0;
6471 unsigned char *frag, *fsize;
6472 struct problem_context pctx;
6475 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6477 clear_problem_context(&pctx);
6480 pctx.inode = &inode;
6482 if (inode.i_file_acl &&
6483 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6484 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6485 inode.i_file_acl = 0;
6488 * This is a special kludge to deal with long symlinks
6489 * on big endian systems. i_blocks had already been
6490 * decremented earlier in pass 1, but since i_file_acl
6491 * hadn't yet been cleared, ext2fs_read_inode()
6492 * assumed that the file was short symlink and would
6493 * not have byte swapped i_block[0]. Hence, we have
6494 * to byte-swap it here.
6496 if (LINUX_S_ISLNK(inode.i_mode) &&
6497 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6498 (inode.i_blocks == fs->blocksize >> 9))
6499 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6505 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6506 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6507 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6508 !(LINUX_S_ISSOCK(inode.i_mode)))
6509 problem = PR_2_BAD_MODE;
6510 else if (LINUX_S_ISCHR(inode.i_mode)
6511 && !e2fsck_pass1_check_device_inode(fs, &inode))
6512 problem = PR_2_BAD_CHAR_DEV;
6513 else if (LINUX_S_ISBLK(inode.i_mode)
6514 && !e2fsck_pass1_check_device_inode(fs, &inode))
6515 problem = PR_2_BAD_BLOCK_DEV;
6516 else if (LINUX_S_ISFIFO(inode.i_mode)
6517 && !e2fsck_pass1_check_device_inode(fs, &inode))
6518 problem = PR_2_BAD_FIFO;
6519 else if (LINUX_S_ISSOCK(inode.i_mode)
6520 && !e2fsck_pass1_check_device_inode(fs, &inode))
6521 problem = PR_2_BAD_SOCKET;
6522 else if (LINUX_S_ISLNK(inode.i_mode)
6523 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6524 problem = PR_2_INVALID_SYMLINK;
6528 if (fix_problem(ctx, problem, &pctx)) {
6529 deallocate_inode(ctx, ino, 0);
6530 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6538 if (inode.i_faddr) {
6539 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6546 switch (fs->super->s_creator_os) {
6548 frag = &inode.osd2.linux2.l_i_frag;
6549 fsize = &inode.osd2.linux2.l_i_fsize;
6552 frag = &inode.osd2.hurd2.h_i_frag;
6553 fsize = &inode.osd2.hurd2.h_i_fsize;
6556 frag = &inode.osd2.masix2.m_i_frag;
6557 fsize = &inode.osd2.masix2.m_i_fsize;
6562 if (frag && *frag) {
6564 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6571 if (fsize && *fsize) {
6573 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6581 if (inode.i_file_acl &&
6582 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6583 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6584 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6585 inode.i_file_acl = 0;
6590 if (inode.i_dir_acl &&
6591 LINUX_S_ISDIR(inode.i_mode)) {
6592 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6593 inode.i_dir_acl = 0;
6600 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6602 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6608 * allocate_dir_block --- this function allocates a new directory
6609 * block for a particular inode; this is done if a directory has
6610 * a "hole" in it, or if a directory has a illegal block number
6611 * that was zeroed out and now needs to be replaced.
6613 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6614 struct problem_context *pctx)
6616 ext2_filsys fs = ctx->fs;
6619 struct ext2_inode inode;
6621 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6625 * Read the inode and block bitmaps in; we'll be messing with
6628 e2fsck_read_bitmaps(ctx);
6631 * First, find a free block
6633 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6634 if (pctx->errcode) {
6635 pctx->str = "ext2fs_new_block";
6636 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6639 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6640 ext2fs_mark_block_bitmap(fs->block_map, blk);
6641 ext2fs_mark_bb_dirty(fs);
6644 * Now let's create the actual data block for the inode
6647 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6649 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6650 EXT2_ROOT_INO, &block);
6652 if (pctx->errcode) {
6653 pctx->str = "ext2fs_new_dir_block";
6654 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6658 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6659 ext2fs_free_mem(&block);
6660 if (pctx->errcode) {
6661 pctx->str = "ext2fs_write_dir_block";
6662 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6667 * Update the inode block count
6669 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6670 inode.i_blocks += fs->blocksize / 512;
6671 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6672 inode.i_size = (db->blockcnt+1) * fs->blocksize;
6673 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6676 * Finally, update the block pointers for the inode
6679 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6680 0, update_dir_block, db);
6681 if (pctx->errcode) {
6682 pctx->str = "ext2fs_block_iterate";
6683 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6691 * This is a helper function for allocate_dir_block().
6693 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6695 e2_blkcnt_t blockcnt,
6696 blk_t ref_block FSCK_ATTR((unused)),
6697 int ref_offset FSCK_ATTR((unused)),
6700 struct ext2_db_entry *db;
6702 db = (struct ext2_db_entry *) priv_data;
6703 if (db->blockcnt == (int) blockcnt) {
6704 *block_nr = db->blk;
6705 return BLOCK_CHANGED;
6711 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6713 * Pass #3 assures that all directories are connected to the
6714 * filesystem tree, using the following algorithm:
6716 * First, the root directory is checked to make sure it exists; if
6717 * not, e2fsck will offer to create a new one. It is then marked as
6720 * Then, pass3 interates over all directory inodes; for each directory
6721 * it attempts to trace up the filesystem tree, using dirinfo.parent
6722 * until it reaches a directory which has been marked "done". If it
6723 * cannot do so, then the directory must be disconnected, and e2fsck
6724 * will offer to reconnect it to /lost+found. While it is chasing
6725 * parent pointers up the filesystem tree, if pass3 sees a directory
6726 * twice, then it has detected a filesystem loop, and it will again
6727 * offer to reconnect the directory to /lost+found in to break the
6730 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6731 * reconnect inodes to /lost+found; this subroutine is also used by
6732 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6733 * is responsible for creating /lost+found if it does not exist.
6735 * Pass 3 frees the following data structures:
6736 * - The dirinfo directory information cache.
6739 static void check_root(e2fsck_t ctx);
6740 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6741 struct problem_context *pctx);
6742 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6744 static ext2fs_inode_bitmap inode_loop_detect;
6745 static ext2fs_inode_bitmap inode_done_map;
6747 static void e2fsck_pass3(e2fsck_t ctx)
6749 ext2_filsys fs = ctx->fs;
6751 struct problem_context pctx;
6752 struct dir_info *dir;
6753 unsigned long maxdirs, count;
6755 clear_problem_context(&pctx);
6759 if (!(ctx->options & E2F_OPT_PREEN))
6760 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6763 * Allocate some bitmaps to do loop detection.
6765 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6769 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6770 ctx->flags |= E2F_FLAG_ABORT;
6774 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6777 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6779 maxdirs = e2fsck_get_num_dirinfo(ctx);
6783 if ((ctx->progress)(ctx, 3, 0, maxdirs))
6786 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6787 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6789 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6791 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6792 if (check_directory(ctx, dir, &pctx))
6797 * Force the creation of /lost+found if not present
6799 if ((ctx->flags & E2F_OPT_READONLY) == 0)
6800 e2fsck_get_lost_and_found(ctx, 1);
6803 * If there are any directories that need to be indexed or
6804 * optimized, do it here.
6806 e2fsck_rehash_directories(ctx);
6809 e2fsck_free_dir_info(ctx);
6810 ext2fs_free_inode_bitmap(inode_loop_detect);
6811 inode_loop_detect = 0;
6812 ext2fs_free_inode_bitmap(inode_done_map);
6817 * This makes sure the root inode is present; if not, we ask if the
6818 * user wants us to create it. Not creating it is a fatal error.
6820 static void check_root(e2fsck_t ctx)
6822 ext2_filsys fs = ctx->fs;
6824 struct ext2_inode inode;
6826 struct problem_context pctx;
6828 clear_problem_context(&pctx);
6830 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6832 * If the root inode is not a directory, die here. The
6833 * user must have answered 'no' in pass1 when we
6834 * offered to clear it.
6836 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6838 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6839 ctx->flags |= E2F_FLAG_ABORT;
6844 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6845 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6846 ctx->flags |= E2F_FLAG_ABORT;
6850 e2fsck_read_bitmaps(ctx);
6853 * First, find a free block
6855 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6857 pctx.str = "ext2fs_new_block";
6858 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6859 ctx->flags |= E2F_FLAG_ABORT;
6862 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6863 ext2fs_mark_block_bitmap(fs->block_map, blk);
6864 ext2fs_mark_bb_dirty(fs);
6867 * Now let's create the actual data block for the inode
6869 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6872 pctx.str = "ext2fs_new_dir_block";
6873 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6874 ctx->flags |= E2F_FLAG_ABORT;
6878 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6880 pctx.str = "ext2fs_write_dir_block";
6881 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6882 ctx->flags |= E2F_FLAG_ABORT;
6885 ext2fs_free_mem(&block);
6888 * Set up the inode structure
6890 memset(&inode, 0, sizeof(inode));
6891 inode.i_mode = 040755;
6892 inode.i_size = fs->blocksize;
6893 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
6894 inode.i_links_count = 2;
6895 inode.i_blocks = fs->blocksize / 512;
6896 inode.i_block[0] = blk;
6899 * Write out the inode.
6901 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6903 pctx.str = "ext2fs_write_inode";
6904 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6905 ctx->flags |= E2F_FLAG_ABORT;
6910 * Miscellaneous bookkeeping...
6912 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6913 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6914 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6916 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6917 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6918 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6919 ext2fs_mark_ib_dirty(fs);
6923 * This subroutine is responsible for making sure that a particular
6924 * directory is connected to the root; if it isn't we trace it up as
6925 * far as we can go, and then offer to connect the resulting parent to
6926 * the lost+found. We have to do loop detection; if we ever discover
6927 * a loop, we treat that as a disconnected directory and offer to
6928 * reparent it to lost+found.
6930 * However, loop detection is expensive, because for very large
6931 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6932 * is non-trivial. Loops in filesystems are also a rare error case,
6933 * and we shouldn't optimize for error cases. So we try two passes of
6934 * the algorithm. The first time, we ignore loop detection and merely
6935 * increment a counter; if the counter exceeds some extreme threshold,
6936 * then we try again with the loop detection bitmap enabled.
6938 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6939 struct problem_context *pctx)
6941 ext2_filsys fs = ctx->fs;
6942 struct dir_info *p = dir;
6943 int loop_pass = 0, parent_count = 0;
6950 * Mark this inode as being "done"; by the time we
6951 * return from this function, the inode we either be
6952 * verified as being connected to the directory tree,
6953 * or we will have offered to reconnect this to
6956 * If it was marked done already, then we've reached a
6957 * parent we've already checked.
6959 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6963 * If this directory doesn't have a parent, or we've
6964 * seen the parent once already, then offer to
6965 * reparent it to lost+found
6969 (ext2fs_test_inode_bitmap(inode_loop_detect,
6972 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6973 if (e2fsck_reconnect_file(ctx, pctx->ino))
6974 ext2fs_unmark_valid(fs);
6976 p = e2fsck_get_dir_info(ctx, pctx->ino);
6977 p->parent = ctx->lost_and_found;
6978 fix_dotdot(ctx, p, ctx->lost_and_found);
6983 p = e2fsck_get_dir_info(ctx, p->parent);
6985 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
6989 ext2fs_mark_inode_bitmap(inode_loop_detect,
6991 } else if (parent_count++ > 2048) {
6993 * If we've run into a path depth that's
6994 * greater than 2048, try again with the inode
6995 * loop bitmap turned on and start from the
6999 if (inode_loop_detect)
7000 ext2fs_clear_inode_bitmap(inode_loop_detect);
7002 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7003 if (pctx->errcode) {
7006 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7007 ctx->flags |= E2F_FLAG_ABORT;
7016 * Make sure that .. and the parent directory are the same;
7017 * offer to fix it if not.
7019 if (dir->parent != dir->dotdot) {
7020 pctx->ino = dir->ino;
7021 pctx->ino2 = dir->dotdot;
7022 pctx->dir = dir->parent;
7023 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7024 fix_dotdot(ctx, dir, dir->parent);
7030 * This routine gets the lost_and_found inode, making it a directory
7033 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7035 ext2_filsys fs = ctx->fs;
7039 struct ext2_inode inode;
7041 static const char name[] = "lost+found";
7042 struct problem_context pctx;
7043 struct dir_info *dirinfo;
7045 if (ctx->lost_and_found)
7046 return ctx->lost_and_found;
7048 clear_problem_context(&pctx);
7050 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7051 sizeof(name)-1, 0, &ino);
7055 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7056 ctx->lost_and_found = ino;
7060 /* Lost+found isn't a directory! */
7064 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7067 /* OK, unlink the old /lost+found file. */
7068 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7070 pctx.str = "ext2fs_unlink";
7071 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7074 dirinfo = e2fsck_get_dir_info(ctx, ino);
7076 dirinfo->parent = 0;
7077 e2fsck_adjust_inode_count(ctx, ino, -1);
7078 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7079 pctx.errcode = retval;
7080 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7082 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7086 * Read the inode and block bitmaps in; we'll be messing with
7089 e2fsck_read_bitmaps(ctx);
7092 * First, find a free block
7094 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7096 pctx.errcode = retval;
7097 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7100 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7101 ext2fs_block_alloc_stats(fs, blk, +1);
7104 * Next find a free inode.
7106 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7107 ctx->inode_used_map, &ino);
7109 pctx.errcode = retval;
7110 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7113 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7114 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7115 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7118 * Now let's create the actual data block for the inode
7120 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7122 pctx.errcode = retval;
7123 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7127 retval = ext2fs_write_dir_block(fs, blk, block);
7128 ext2fs_free_mem(&block);
7130 pctx.errcode = retval;
7131 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7136 * Set up the inode structure
7138 memset(&inode, 0, sizeof(inode));
7139 inode.i_mode = 040700;
7140 inode.i_size = fs->blocksize;
7141 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
7142 inode.i_links_count = 2;
7143 inode.i_blocks = fs->blocksize / 512;
7144 inode.i_block[0] = blk;
7147 * Next, write out the inode.
7149 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7151 pctx.str = "ext2fs_write_inode";
7152 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7156 * Finally, create the directory link
7158 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7160 pctx.str = "ext2fs_link";
7161 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7166 * Miscellaneous bookkeeping that needs to be kept straight.
7168 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7169 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7170 ext2fs_icount_store(ctx->inode_count, ino, 2);
7171 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7172 ctx->lost_and_found = ino;
7177 * This routine will connect a file to lost+found
7179 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7181 ext2_filsys fs = ctx->fs;
7184 struct problem_context pctx;
7185 struct ext2_inode inode;
7188 clear_problem_context(&pctx);
7191 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7192 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7193 ctx->bad_lost_and_found++;
7195 if (ctx->bad_lost_and_found) {
7196 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7200 sprintf(name, "#%u", ino);
7201 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7202 file_type = ext2_file_type(inode.i_mode);
7203 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7204 if (retval == EXT2_ET_DIR_NO_SPACE) {
7205 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7207 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7210 pctx.errcode = retval;
7211 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7214 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7218 pctx.errcode = retval;
7219 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7222 e2fsck_adjust_inode_count(ctx, ino, 1);
7228 * Utility routine to adjust the inode counts on an inode.
7230 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7232 ext2_filsys fs = ctx->fs;
7234 struct ext2_inode inode;
7239 retval = ext2fs_read_inode(fs, ino, &inode);
7244 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7245 if (inode.i_links_count == (__u16) ~0)
7247 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7248 inode.i_links_count++;
7249 } else if (adj == -1) {
7250 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7251 if (inode.i_links_count == 0)
7253 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7254 inode.i_links_count--;
7257 retval = ext2fs_write_inode(fs, ino, &inode);
7265 * Fix parent --- this routine fixes up the parent of a directory.
7267 struct fix_dotdot_struct {
7274 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7275 int offset FSCK_ATTR((unused)),
7276 int blocksize FSCK_ATTR((unused)),
7277 char *buf FSCK_ATTR((unused)),
7280 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7282 struct problem_context pctx;
7284 if ((dirent->name_len & 0xFF) != 2)
7286 if (strncmp(dirent->name, "..", 2))
7289 clear_problem_context(&pctx);
7291 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7293 pctx.errcode = retval;
7294 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7296 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7298 pctx.errcode = retval;
7299 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7301 dirent->inode = fp->parent;
7304 return DIRENT_ABORT | DIRENT_CHANGED;
7307 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7309 ext2_filsys fs = ctx->fs;
7311 struct fix_dotdot_struct fp;
7312 struct problem_context pctx;
7319 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7320 0, fix_dotdot_proc, &fp);
7321 if (retval || !fp.done) {
7322 clear_problem_context(&pctx);
7323 pctx.ino = dir->ino;
7324 pctx.errcode = retval;
7325 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7326 PR_3_FIX_PARENT_NOFIND, &pctx);
7327 ext2fs_unmark_valid(fs);
7329 dir->dotdot = parent;
7333 * These routines are responsible for expanding a /lost+found if it is
7337 struct expand_dir_struct {
7339 int guaranteed_size;
7346 static int expand_dir_proc(ext2_filsys fs,
7348 e2_blkcnt_t blockcnt,
7349 blk_t ref_block FSCK_ATTR((unused)),
7350 int ref_offset FSCK_ATTR((unused)),
7353 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7355 static blk_t last_blk = 0;
7362 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7366 es->last_block = blockcnt;
7368 last_blk = *blocknr;
7371 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7378 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7384 retval = ext2fs_write_dir_block(fs, new_blk, block);
7386 retval = ext2fs_get_mem(fs->blocksize, &block);
7391 memset(block, 0, fs->blocksize);
7392 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7398 ext2fs_free_mem(&block);
7400 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7401 ext2fs_block_alloc_stats(fs, new_blk, +1);
7405 return (BLOCK_CHANGED | BLOCK_ABORT);
7407 return BLOCK_CHANGED;
7410 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7411 int num, int guaranteed_size)
7413 ext2_filsys fs = ctx->fs;
7415 struct expand_dir_struct es;
7416 struct ext2_inode inode;
7418 if (!(fs->flags & EXT2_FLAG_RW))
7419 return EXT2_ET_RO_FILSYS;
7422 * Read the inode and block bitmaps in; we'll be messing with
7425 e2fsck_read_bitmaps(ctx);
7427 retval = ext2fs_check_directory(fs, dir);
7432 es.guaranteed_size = guaranteed_size;
7438 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7439 0, expand_dir_proc, &es);
7445 * Update the size and block count fields in the inode.
7447 retval = ext2fs_read_inode(fs, dir, &inode);
7451 inode.i_size = (es.last_block + 1) * fs->blocksize;
7452 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7454 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7460 * pass4.c -- pass #4 of e2fsck: Check reference counts
7462 * Pass 4 frees the following data structures:
7463 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7467 * This routine is called when an inode is not connected to the
7470 * This subroutine returns 1 then the caller shouldn't bother with the
7471 * rest of the pass 4 tests.
7473 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7475 ext2_filsys fs = ctx->fs;
7476 struct ext2_inode inode;
7477 struct problem_context pctx;
7479 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7480 clear_problem_context(&pctx);
7482 pctx.inode = &inode;
7485 * Offer to delete any zero-length files that does not have
7486 * blocks. If there is an EA block, it might have useful
7487 * information, so we won't prompt to delete it, but let it be
7488 * reconnected to lost+found.
7490 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7491 LINUX_S_ISDIR(inode.i_mode))) {
7492 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7493 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7494 inode.i_links_count = 0;
7495 inode.i_dtime = time(NULL);
7496 e2fsck_write_inode(ctx, i, &inode,
7497 "disconnect_inode");
7499 * Fix up the bitmaps...
7501 e2fsck_read_bitmaps(ctx);
7502 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7503 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7504 ext2fs_inode_alloc_stats2(fs, i, -1,
7505 LINUX_S_ISDIR(inode.i_mode));
7511 * Prompt to reconnect.
7513 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7514 if (e2fsck_reconnect_file(ctx, i))
7515 ext2fs_unmark_valid(fs);
7518 * If we don't attach the inode, then skip the
7519 * i_links_test since there's no point in trying to
7520 * force i_links_count to zero.
7522 ext2fs_unmark_valid(fs);
7529 static void e2fsck_pass4(e2fsck_t ctx)
7531 ext2_filsys fs = ctx->fs;
7533 struct ext2_inode inode;
7534 struct problem_context pctx;
7535 __u16 link_count, link_counted;
7537 int group, maxgroup;
7541 clear_problem_context(&pctx);
7543 if (!(ctx->options & E2F_OPT_PREEN))
7544 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7547 maxgroup = fs->group_desc_count;
7549 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7552 for (i=1; i <= fs->super->s_inodes_count; i++) {
7553 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7555 if ((i % fs->super->s_inodes_per_group) == 0) {
7558 if ((ctx->progress)(ctx, 4, group, maxgroup))
7561 if (i == EXT2_BAD_INO ||
7562 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7564 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7565 (ctx->inode_imagic_map &&
7566 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7568 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7569 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7570 if (link_counted == 0) {
7572 buf = e2fsck_allocate_memory(ctx,
7573 fs->blocksize, "bad_inode buffer");
7574 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7576 if (disconnect_inode(ctx, i))
7578 ext2fs_icount_fetch(ctx->inode_link_info, i,
7580 ext2fs_icount_fetch(ctx->inode_count, i,
7583 if (link_counted != link_count) {
7584 e2fsck_read_inode(ctx, i, &inode, "pass4");
7586 pctx.inode = &inode;
7587 if (link_count != inode.i_links_count) {
7588 pctx.num = link_count;
7590 PR_4_INCONSISTENT_COUNT, &pctx);
7592 pctx.num = link_counted;
7593 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7594 inode.i_links_count = link_counted;
7595 e2fsck_write_inode(ctx, i, &inode, "pass4");
7599 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7600 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7601 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7602 ctx->inode_imagic_map = 0;
7603 ext2fs_free_mem(&buf);
7607 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7610 #define NO_BLK ((blk_t) -1)
7612 static void print_bitmap_problem(e2fsck_t ctx, int problem,
7613 struct problem_context *pctx)
7616 case PR_5_BLOCK_UNUSED:
7617 if (pctx->blk == pctx->blk2)
7620 problem = PR_5_BLOCK_RANGE_UNUSED;
7622 case PR_5_BLOCK_USED:
7623 if (pctx->blk == pctx->blk2)
7626 problem = PR_5_BLOCK_RANGE_USED;
7628 case PR_5_INODE_UNUSED:
7629 if (pctx->ino == pctx->ino2)
7632 problem = PR_5_INODE_RANGE_UNUSED;
7634 case PR_5_INODE_USED:
7635 if (pctx->ino == pctx->ino2)
7638 problem = PR_5_INODE_RANGE_USED;
7641 fix_problem(ctx, problem, pctx);
7642 pctx->blk = pctx->blk2 = NO_BLK;
7643 pctx->ino = pctx->ino2 = 0;
7646 static void check_block_bitmaps(e2fsck_t ctx)
7648 ext2_filsys fs = ctx->fs;
7652 unsigned int blocks = 0;
7653 unsigned int free_blocks = 0;
7656 struct problem_context pctx;
7657 int problem, save_problem, fixit, had_problem;
7660 clear_problem_context(&pctx);
7661 free_array = (int *) e2fsck_allocate_memory(ctx,
7662 fs->group_desc_count * sizeof(int), "free block count array");
7664 if ((fs->super->s_first_data_block <
7665 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7666 (fs->super->s_blocks_count-1 >
7667 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7669 pctx.blk = fs->super->s_first_data_block;
7670 pctx.blk2 = fs->super->s_blocks_count -1;
7671 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7672 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7673 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7675 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7679 if ((fs->super->s_first_data_block <
7680 ext2fs_get_block_bitmap_start(fs->block_map)) ||
7681 (fs->super->s_blocks_count-1 >
7682 ext2fs_get_block_bitmap_end(fs->block_map))) {
7684 pctx.blk = fs->super->s_first_data_block;
7685 pctx.blk2 = fs->super->s_blocks_count -1;
7686 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7687 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7688 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7690 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7697 pctx.blk = pctx.blk2 = NO_BLK;
7698 for (i = fs->super->s_first_data_block;
7699 i < fs->super->s_blocks_count;
7701 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7702 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7704 if (actual == bitmap)
7707 if (!actual && bitmap) {
7709 * Block not used, but marked in use in the bitmap.
7711 problem = PR_5_BLOCK_UNUSED;
7714 * Block used, but not marked in use in the bitmap.
7716 problem = PR_5_BLOCK_USED;
7718 if (pctx.blk == NO_BLK) {
7719 pctx.blk = pctx.blk2 = i;
7720 save_problem = problem;
7722 if ((problem == save_problem) &&
7726 print_bitmap_problem(ctx, save_problem, &pctx);
7727 pctx.blk = pctx.blk2 = i;
7728 save_problem = problem;
7731 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7740 if ((blocks == fs->super->s_blocks_per_group) ||
7741 (i == fs->super->s_blocks_count-1)) {
7742 free_array[group] = group_free;
7747 if ((ctx->progress)(ctx, 5, group,
7748 fs->group_desc_count*2))
7752 if (pctx.blk != NO_BLK)
7753 print_bitmap_problem(ctx, save_problem, &pctx);
7755 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7758 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7761 ext2fs_free_block_bitmap(fs->block_map);
7762 retval = ext2fs_copy_bitmap(ctx->block_found_map,
7765 clear_problem_context(&pctx);
7766 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7767 ctx->flags |= E2F_FLAG_ABORT;
7770 ext2fs_set_bitmap_padding(fs->block_map);
7771 ext2fs_mark_bb_dirty(fs);
7773 /* Redo the counts */
7774 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7775 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7777 } else if (fixit == 0)
7778 ext2fs_unmark_valid(fs);
7780 for (i = 0; i < fs->group_desc_count; i++) {
7781 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7783 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7784 pctx.blk2 = free_array[i];
7786 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7788 fs->group_desc[i].bg_free_blocks_count =
7790 ext2fs_mark_super_dirty(fs);
7792 ext2fs_unmark_valid(fs);
7795 if (free_blocks != fs->super->s_free_blocks_count) {
7797 pctx.blk = fs->super->s_free_blocks_count;
7798 pctx.blk2 = free_blocks;
7800 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7801 fs->super->s_free_blocks_count = free_blocks;
7802 ext2fs_mark_super_dirty(fs);
7804 ext2fs_unmark_valid(fs);
7806 ext2fs_free_mem(&free_array);
7809 static void check_inode_bitmaps(e2fsck_t ctx)
7811 ext2_filsys fs = ctx->fs;
7813 unsigned int free_inodes = 0;
7817 unsigned int inodes = 0;
7822 struct problem_context pctx;
7823 int problem, save_problem, fixit, had_problem;
7825 clear_problem_context(&pctx);
7826 free_array = (int *) e2fsck_allocate_memory(ctx,
7827 fs->group_desc_count * sizeof(int), "free inode count array");
7829 dir_array = (int *) e2fsck_allocate_memory(ctx,
7830 fs->group_desc_count * sizeof(int), "directory count array");
7832 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7833 (fs->super->s_inodes_count >
7834 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7837 pctx.blk2 = fs->super->s_inodes_count;
7838 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7839 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7840 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7842 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7845 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7846 (fs->super->s_inodes_count >
7847 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7850 pctx.blk2 = fs->super->s_inodes_count;
7851 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7852 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7853 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7855 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7862 pctx.ino = pctx.ino2 = 0;
7863 for (i = 1; i <= fs->super->s_inodes_count; i++) {
7864 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7865 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7867 if (actual == bitmap)
7870 if (!actual && bitmap) {
7872 * Inode wasn't used, but marked in bitmap
7874 problem = PR_5_INODE_UNUSED;
7875 } else /* if (actual && !bitmap) */ {
7877 * Inode used, but not in bitmap
7879 problem = PR_5_INODE_USED;
7881 if (pctx.ino == 0) {
7882 pctx.ino = pctx.ino2 = i;
7883 save_problem = problem;
7885 if ((problem == save_problem) &&
7889 print_bitmap_problem(ctx, save_problem, &pctx);
7890 pctx.ino = pctx.ino2 = i;
7891 save_problem = problem;
7894 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7902 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7906 if ((inodes == fs->super->s_inodes_per_group) ||
7907 (i == fs->super->s_inodes_count)) {
7908 free_array[group] = group_free;
7909 dir_array[group] = dirs_count;
7915 if ((ctx->progress)(ctx, 5,
7916 group + fs->group_desc_count,
7917 fs->group_desc_count*2))
7922 print_bitmap_problem(ctx, save_problem, &pctx);
7925 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7928 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7931 ext2fs_free_inode_bitmap(fs->inode_map);
7932 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7935 clear_problem_context(&pctx);
7936 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7937 ctx->flags |= E2F_FLAG_ABORT;
7940 ext2fs_set_bitmap_padding(fs->inode_map);
7941 ext2fs_mark_ib_dirty(fs);
7944 inodes = 0; free_inodes = 0; group_free = 0;
7945 dirs_count = 0; group = 0;
7946 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7947 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7949 } else if (fixit == 0)
7950 ext2fs_unmark_valid(fs);
7952 for (i = 0; i < fs->group_desc_count; i++) {
7953 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7955 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7956 pctx.ino2 = free_array[i];
7957 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7959 fs->group_desc[i].bg_free_inodes_count =
7961 ext2fs_mark_super_dirty(fs);
7963 ext2fs_unmark_valid(fs);
7965 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7967 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7968 pctx.ino2 = dir_array[i];
7970 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7972 fs->group_desc[i].bg_used_dirs_count =
7974 ext2fs_mark_super_dirty(fs);
7976 ext2fs_unmark_valid(fs);
7979 if (free_inodes != fs->super->s_free_inodes_count) {
7981 pctx.ino = fs->super->s_free_inodes_count;
7982 pctx.ino2 = free_inodes;
7984 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
7985 fs->super->s_free_inodes_count = free_inodes;
7986 ext2fs_mark_super_dirty(fs);
7988 ext2fs_unmark_valid(fs);
7990 ext2fs_free_mem(&free_array);
7991 ext2fs_free_mem(&dir_array);
7994 static void check_inode_end(e2fsck_t ctx)
7996 ext2_filsys fs = ctx->fs;
7997 ext2_ino_t end, save_inodes_count, i;
7998 struct problem_context pctx;
8000 clear_problem_context(&pctx);
8002 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8003 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8004 &save_inodes_count);
8007 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8008 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8011 if (save_inodes_count == end)
8014 for (i = save_inodes_count + 1; i <= end; i++) {
8015 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8016 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8017 for (i = save_inodes_count + 1; i <= end; i++)
8018 ext2fs_mark_inode_bitmap(fs->inode_map,
8020 ext2fs_mark_ib_dirty(fs);
8022 ext2fs_unmark_valid(fs);
8027 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8028 save_inodes_count, 0);
8031 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8032 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8037 static void check_block_end(e2fsck_t ctx)
8039 ext2_filsys fs = ctx->fs;
8040 blk_t end, save_blocks_count, i;
8041 struct problem_context pctx;
8043 clear_problem_context(&pctx);
8045 end = fs->block_map->start +
8046 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8047 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8048 &save_blocks_count);
8051 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8052 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8055 if (save_blocks_count == end)
8058 for (i = save_blocks_count + 1; i <= end; i++) {
8059 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8060 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8061 for (i = save_blocks_count + 1; i <= end; i++)
8062 ext2fs_mark_block_bitmap(fs->block_map,
8064 ext2fs_mark_bb_dirty(fs);
8066 ext2fs_unmark_valid(fs);
8071 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8072 save_blocks_count, 0);
8075 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8076 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8081 static void e2fsck_pass5(e2fsck_t ctx)
8083 struct problem_context pctx;
8087 clear_problem_context(&pctx);
8089 if (!(ctx->options & E2F_OPT_PREEN))
8090 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8093 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8096 e2fsck_read_bitmaps(ctx);
8098 check_block_bitmaps(ctx);
8099 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8101 check_inode_bitmaps(ctx);
8102 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8104 check_inode_end(ctx);
8105 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8107 check_block_end(ctx);
8108 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8111 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8112 ctx->inode_used_map = 0;
8113 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8114 ctx->inode_dir_map = 0;
8115 ext2fs_free_block_bitmap(ctx->block_found_map);
8116 ctx->block_found_map = 0;
8120 * problem.c --- report filesystem problems to the user
8123 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8124 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8125 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8126 #define PR_MSG_ONLY 0x000008 /* Print message only */
8128 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8130 #define PR_FATAL 0x001000 /* Fatal error */
8131 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8133 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8134 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8135 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8136 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8137 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8140 #define PROMPT_NONE 0
8141 #define PROMPT_FIX 1
8142 #define PROMPT_CLEAR 2
8143 #define PROMPT_RELOCATE 3
8144 #define PROMPT_ALLOCATE 4
8145 #define PROMPT_EXPAND 5
8146 #define PROMPT_CONNECT 6
8147 #define PROMPT_CREATE 7
8148 #define PROMPT_SALVAGE 8
8149 #define PROMPT_TRUNCATE 9
8150 #define PROMPT_CLEAR_INODE 10
8151 #define PROMPT_ABORT 11
8152 #define PROMPT_SPLIT 12
8153 #define PROMPT_CONTINUE 13
8154 #define PROMPT_CLONE 14
8155 #define PROMPT_DELETE 15
8156 #define PROMPT_SUPPRESS 16
8157 #define PROMPT_UNLINK 17
8158 #define PROMPT_CLEAR_HTREE 18
8159 #define PROMPT_RECREATE 19
8160 #define PROMPT_NULL 20
8162 struct e2fsck_problem {
8164 const char * e2p_description;
8167 problem_t second_code;
8170 struct latch_descr {
8173 problem_t end_message;
8178 * These are the prompts which are used to ask the user if they want
8181 static const char *const prompt[] = {
8182 N_("(no prompt)"), /* 0 */
8184 N_("Clear"), /* 2 */
8185 N_("Relocate"), /* 3 */
8186 N_("Allocate"), /* 4 */
8187 N_("Expand"), /* 5 */
8188 N_("Connect to /lost+found"), /* 6 */
8189 N_("Create"), /* 7 */
8190 N_("Salvage"), /* 8 */
8191 N_("Truncate"), /* 9 */
8192 N_("Clear inode"), /* 10 */
8193 N_("Abort"), /* 11 */
8194 N_("Split"), /* 12 */
8195 N_("Continue"), /* 13 */
8196 N_("Clone multiply-claimed blocks"), /* 14 */
8197 N_("Delete file"), /* 15 */
8198 N_("Suppress messages"),/* 16 */
8199 N_("Unlink"), /* 17 */
8200 N_("Clear HTree index"),/* 18 */
8201 N_("Recreate"), /* 19 */
8206 * These messages are printed when we are preen mode and we will be
8207 * automatically fixing the problem.
8209 static const char *const preen_msg[] = {
8210 N_("(NONE)"), /* 0 */
8211 N_("FIXED"), /* 1 */
8212 N_("CLEARED"), /* 2 */
8213 N_("RELOCATED"), /* 3 */
8214 N_("ALLOCATED"), /* 4 */
8215 N_("EXPANDED"), /* 5 */
8216 N_("RECONNECTED"), /* 6 */
8217 N_("CREATED"), /* 7 */
8218 N_("SALVAGED"), /* 8 */
8219 N_("TRUNCATED"), /* 9 */
8220 N_("INODE CLEARED"), /* 10 */
8221 N_("ABORTED"), /* 11 */
8222 N_("SPLIT"), /* 12 */
8223 N_("CONTINUING"), /* 13 */
8224 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8225 N_("FILE DELETED"), /* 15 */
8226 N_("SUPPRESSED"), /* 16 */
8227 N_("UNLINKED"), /* 17 */
8228 N_("HTREE INDEX CLEARED"),/* 18 */
8229 N_("WILL RECREATE"), /* 19 */
8233 static const struct e2fsck_problem problem_table[] = {
8235 /* Pre-Pass 1 errors */
8237 /* Block bitmap not in group */
8238 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8239 PROMPT_RELOCATE, PR_LATCH_RELOC },
8241 /* Inode bitmap not in group */
8242 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8243 PROMPT_RELOCATE, PR_LATCH_RELOC },
8245 /* Inode table not in group */
8246 { PR_0_ITABLE_NOT_GROUP,
8247 N_("@i table for @g %g is not in @g. (@b %b)\n"
8248 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8249 PROMPT_RELOCATE, PR_LATCH_RELOC },
8251 /* Superblock corrupt */
8253 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8254 "@f. If the @v is valid and it really contains an ext2\n"
8255 "@f (and not swap or ufs or something else), then the @S\n"
8256 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8257 " e2fsck -b %S <@v>\n\n"),
8258 PROMPT_NONE, PR_FATAL },
8260 /* Filesystem size is wrong */
8261 { PR_0_FS_SIZE_WRONG,
8262 N_("The @f size (according to the @S) is %b @bs\n"
8263 "The physical size of the @v is %c @bs\n"
8264 "Either the @S or the partition table is likely to be corrupt!\n"),
8267 /* Fragments not supported */
8268 { PR_0_NO_FRAGMENTS,
8269 N_("@S @b_size = %b, fragsize = %c.\n"
8270 "This version of e2fsck does not support fragment sizes different\n"
8271 "from the @b size.\n"),
8272 PROMPT_NONE, PR_FATAL },
8274 /* Bad blocks_per_group */
8275 { PR_0_BLOCKS_PER_GROUP,
8276 N_("@S @bs_per_group = %b, should have been %c\n"),
8277 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8279 /* Bad first_data_block */
8280 { PR_0_FIRST_DATA_BLOCK,
8281 N_("@S first_data_@b = %b, should have been %c\n"),
8282 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8284 /* Adding UUID to filesystem */
8286 N_("@f did not have a UUID; generating one.\n\n"),
8290 { PR_0_RELOCATE_HINT,
8291 N_("Note: if several inode or block bitmap blocks or part\n"
8292 "of the inode table require relocation, you may wish to try\n"
8293 "running e2fsck with the '-b %S' option first. The problem\n"
8294 "may lie only with the primary block group descriptors, and\n"
8295 "the backup block group descriptors may be OK.\n\n"),
8296 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8298 /* Miscellaneous superblock corruption */
8299 { PR_0_MISC_CORRUPT_SUPER,
8300 N_("Corruption found in @S. (%s = %N).\n"),
8301 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8303 /* Error determing physical device size of filesystem */
8304 { PR_0_GETSIZE_ERROR,
8305 N_("Error determining size of the physical @v: %m\n"),
8306 PROMPT_NONE, PR_FATAL },
8308 /* Inode count in superblock is incorrect */
8309 { PR_0_INODE_COUNT_WRONG,
8310 N_("@i count in @S is %i, @s %j.\n"),
8313 { PR_0_HURD_CLEAR_FILETYPE,
8314 N_("The Hurd does not support the filetype feature.\n"),
8317 /* Journal inode is invalid */
8318 { PR_0_JOURNAL_BAD_INODE,
8319 N_("@S has an @n ext3 @j (@i %i).\n"),
8320 PROMPT_CLEAR, PR_PREEN_OK },
8322 /* The external journal has (unsupported) multiple filesystems */
8323 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8324 N_("External @j has multiple @f users (unsupported).\n"),
8325 PROMPT_NONE, PR_FATAL },
8327 /* Can't find external journal */
8328 { PR_0_CANT_FIND_JOURNAL,
8329 N_("Can't find external @j\n"),
8330 PROMPT_NONE, PR_FATAL },
8332 /* External journal has bad superblock */
8333 { PR_0_EXT_JOURNAL_BAD_SUPER,
8334 N_("External @j has bad @S\n"),
8335 PROMPT_NONE, PR_FATAL },
8337 /* Superblock has a bad journal UUID */
8338 { PR_0_JOURNAL_BAD_UUID,
8339 N_("External @j does not support this @f\n"),
8340 PROMPT_NONE, PR_FATAL },
8342 /* Journal has an unknown superblock type */
8343 { PR_0_JOURNAL_UNSUPP_SUPER,
8344 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8345 "It is likely that your copy of e2fsck is old and/or doesn't "
8346 "support this @j format.\n"
8347 "It is also possible the @j @S is corrupt.\n"),
8348 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8350 /* Journal superblock is corrupt */
8351 { PR_0_JOURNAL_BAD_SUPER,
8352 N_("Ext3 @j @S is corrupt.\n"),
8353 PROMPT_FIX, PR_PREEN_OK },
8355 /* Superblock flag should be cleared */
8356 { PR_0_JOURNAL_HAS_JOURNAL,
8357 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8358 PROMPT_CLEAR, PR_PREEN_OK },
8360 /* Superblock flag is incorrect */
8361 { PR_0_JOURNAL_RECOVER_SET,
8362 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8363 PROMPT_CLEAR, PR_PREEN_OK },
8365 /* Journal has data, but recovery flag is clear */
8366 { PR_0_JOURNAL_RECOVERY_CLEAR,
8367 N_("ext3 recovery flag is clear, but @j has data.\n"),
8370 /* Ask if we should clear the journal */
8371 { PR_0_JOURNAL_RESET_JOURNAL,
8373 PROMPT_NULL, PR_PREEN_NOMSG },
8375 /* Ask if we should run the journal anyway */
8377 N_("Run @j anyway"),
8380 /* Run the journal by default */
8381 { PR_0_JOURNAL_RUN_DEFAULT,
8382 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8385 /* Clearing orphan inode */
8386 { PR_0_ORPHAN_CLEAR_INODE,
8387 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8390 /* Illegal block found in orphaned inode */
8391 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8392 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8395 /* Already cleared block found in orphaned inode */
8396 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8397 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8400 /* Illegal orphan inode in superblock */
8401 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8402 N_("@I @o @i %i in @S.\n"),
8405 /* Illegal inode in orphaned inode list */
8406 { PR_0_ORPHAN_ILLEGAL_INODE,
8407 N_("@I @i %i in @o @i list.\n"),
8410 /* Filesystem revision is 0, but feature flags are set */
8411 { PR_0_FS_REV_LEVEL,
8412 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8413 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8415 /* Journal superblock has an unknown read-only feature flag set */
8416 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8417 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8420 /* Journal superblock has an unknown incompatible feature flag set */
8421 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8422 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8425 /* Journal has unsupported version number */
8426 { PR_0_JOURNAL_UNSUPP_VERSION,
8427 N_("@j version not supported by this e2fsck.\n"),
8430 /* Moving journal to hidden file */
8431 { PR_0_MOVE_JOURNAL,
8432 N_("Moving @j from /%s to hidden @i.\n\n"),
8435 /* Error moving journal to hidden file */
8436 { PR_0_ERR_MOVE_JOURNAL,
8437 N_("Error moving @j: %m\n\n"),
8440 /* Clearing V2 journal superblock */
8441 { PR_0_CLEAR_V2_JOURNAL,
8442 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8443 "Clearing fields beyond the V1 @j @S...\n\n"),
8446 /* Backup journal inode blocks */
8448 N_("Backing up @j @i @b information.\n\n"),
8451 /* Reserved blocks w/o resize_inode */
8452 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8453 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8454 "is %N; @s zero. "),
8457 /* Resize_inode not enabled, but resize inode is non-zero */
8458 { PR_0_CLEAR_RESIZE_INODE,
8459 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8462 /* Resize inode invalid */
8463 { PR_0_RESIZE_INODE_INVALID,
8464 N_("Resize @i not valid. "),
8465 PROMPT_RECREATE, 0 },
8469 /* Pass 1: Checking inodes, blocks, and sizes */
8471 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8474 /* Root directory is not an inode */
8475 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8478 /* Root directory has dtime set */
8480 N_("@r has dtime set (probably due to old mke2fs). "),
8481 PROMPT_FIX, PR_PREEN_OK },
8483 /* Reserved inode has bad mode */
8484 { PR_1_RESERVED_BAD_MODE,
8485 N_("Reserved @i %i (%Q) has @n mode. "),
8486 PROMPT_CLEAR, PR_PREEN_OK },
8488 /* Deleted inode has zero dtime */
8490 N_("@D @i %i has zero dtime. "),
8491 PROMPT_FIX, PR_PREEN_OK },
8493 /* Inode in use, but dtime set */
8495 N_("@i %i is in use, but has dtime set. "),
8496 PROMPT_FIX, PR_PREEN_OK },
8498 /* Zero-length directory */
8499 { PR_1_ZERO_LENGTH_DIR,
8500 N_("@i %i is a @z @d. "),
8501 PROMPT_CLEAR, PR_PREEN_OK },
8503 /* Block bitmap conflicts with some other fs block */
8505 N_("@g %g's @b @B at %b @C.\n"),
8506 PROMPT_RELOCATE, 0 },
8508 /* Inode bitmap conflicts with some other fs block */
8510 N_("@g %g's @i @B at %b @C.\n"),
8511 PROMPT_RELOCATE, 0 },
8513 /* Inode table conflicts with some other fs block */
8514 { PR_1_ITABLE_CONFLICT,
8515 N_("@g %g's @i table at %b @C.\n"),
8516 PROMPT_RELOCATE, 0 },
8518 /* Block bitmap is on a bad block */
8519 { PR_1_BB_BAD_BLOCK,
8520 N_("@g %g's @b @B (%b) is bad. "),
8521 PROMPT_RELOCATE, 0 },
8523 /* Inode bitmap is on a bad block */
8524 { PR_1_IB_BAD_BLOCK,
8525 N_("@g %g's @i @B (%b) is bad. "),
8526 PROMPT_RELOCATE, 0 },
8528 /* Inode has incorrect i_size */
8530 N_("@i %i, i_size is %Is, @s %N. "),
8531 PROMPT_FIX, PR_PREEN_OK },
8533 /* Inode has incorrect i_blocks */
8534 { PR_1_BAD_I_BLOCKS,
8535 N_("@i %i, i_@bs is %Ib, @s %N. "),
8536 PROMPT_FIX, PR_PREEN_OK },
8538 /* Illegal blocknumber in inode */
8539 { PR_1_ILLEGAL_BLOCK_NUM,
8540 N_("@I @b #%B (%b) in @i %i. "),
8541 PROMPT_CLEAR, PR_LATCH_BLOCK },
8543 /* Block number overlaps fs metadata */
8544 { PR_1_BLOCK_OVERLAPS_METADATA,
8545 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8546 PROMPT_CLEAR, PR_LATCH_BLOCK },
8548 /* Inode has illegal blocks (latch question) */
8549 { PR_1_INODE_BLOCK_LATCH,
8550 N_("@i %i has illegal @b(s). "),
8553 /* Too many bad blocks in inode */
8554 { PR_1_TOO_MANY_BAD_BLOCKS,
8555 N_("Too many illegal @bs in @i %i.\n"),
8556 PROMPT_CLEAR_INODE, PR_NO_OK },
8558 /* Illegal block number in bad block inode */
8559 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8560 N_("@I @b #%B (%b) in bad @b @i. "),
8561 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8563 /* Bad block inode has illegal blocks (latch question) */
8564 { PR_1_INODE_BBLOCK_LATCH,
8565 N_("Bad @b @i has illegal @b(s). "),
8568 /* Duplicate or bad blocks in use! */
8569 { PR_1_DUP_BLOCKS_PREENSTOP,
8570 N_("Duplicate or bad @b in use!\n"),
8573 /* Bad block used as bad block indirect block */
8574 { PR_1_BBINODE_BAD_METABLOCK,
8575 N_("Bad @b %b used as bad @b @i indirect @b. "),
8576 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8578 /* Inconsistency can't be fixed prompt */
8579 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8580 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8581 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8583 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8585 /* Bad primary block */
8586 { PR_1_BAD_PRIMARY_BLOCK,
8587 N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
8588 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8590 /* Bad primary block prompt */
8591 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8592 N_("You can remove this @b from the bad @b list and hope\n"
8593 "that the @b is really OK. But there are no guarantees.\n\n"),
8594 PROMPT_CLEAR, PR_PREEN_NOMSG },
8596 /* Bad primary superblock */
8597 { PR_1_BAD_PRIMARY_SUPERBLOCK,
8598 N_("The primary @S (%b) is on the bad @b list.\n"),
8599 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8601 /* Bad primary block group descriptors */
8602 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8603 N_("Block %b in the primary @g descriptors "
8604 "is on the bad @b list\n"),
8605 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8607 /* Bad superblock in group */
8608 { PR_1_BAD_SUPERBLOCK,
8609 N_("Warning: Group %g's @S (%b) is bad.\n"),
8610 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8612 /* Bad block group descriptors in group */
8613 { PR_1_BAD_GROUP_DESCRIPTORS,
8614 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8616 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8618 /* Block claimed for no reason */
8619 { PR_1_PROGERR_CLAIMED_BLOCK,
8620 N_("Programming error? @b #%b claimed for no reason in "
8621 "process_bad_@b.\n"),
8622 PROMPT_NONE, PR_PREEN_OK },
8624 /* Error allocating blocks for relocating metadata */
8625 { PR_1_RELOC_BLOCK_ALLOCATE,
8626 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8627 PROMPT_NONE, PR_PREEN_OK },
8629 /* Error allocating block buffer during relocation process */
8630 { PR_1_RELOC_MEMORY_ALLOCATE,
8631 N_("@A @b buffer for relocating %s\n"),
8632 PROMPT_NONE, PR_PREEN_OK },
8634 /* Relocating metadata group information from X to Y */
8635 { PR_1_RELOC_FROM_TO,
8636 N_("Relocating @g %g's %s from %b to %c...\n"),
8637 PROMPT_NONE, PR_PREEN_OK },
8639 /* Relocating metatdata group information to X */
8641 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8642 PROMPT_NONE, PR_PREEN_OK },
8644 /* Block read error during relocation process */
8645 { PR_1_RELOC_READ_ERR,
8646 N_("Warning: could not read @b %b of %s: %m\n"),
8647 PROMPT_NONE, PR_PREEN_OK },
8649 /* Block write error during relocation process */
8650 { PR_1_RELOC_WRITE_ERR,
8651 N_("Warning: could not write @b %b for %s: %m\n"),
8652 PROMPT_NONE, PR_PREEN_OK },
8654 /* Error allocating inode bitmap */
8655 { PR_1_ALLOCATE_IBITMAP_ERROR,
8656 N_("@A @i @B (%N): %m\n"),
8657 PROMPT_NONE, PR_FATAL },
8659 /* Error allocating block bitmap */
8660 { PR_1_ALLOCATE_BBITMAP_ERROR,
8661 N_("@A @b @B (%N): %m\n"),
8662 PROMPT_NONE, PR_FATAL },
8664 /* Error allocating icount structure */
8665 { PR_1_ALLOCATE_ICOUNT,
8666 N_("@A icount link information: %m\n"),
8667 PROMPT_NONE, PR_FATAL },
8669 /* Error allocating dbcount */
8670 { PR_1_ALLOCATE_DBCOUNT,
8671 N_("@A @d @b array: %m\n"),
8672 PROMPT_NONE, PR_FATAL },
8674 /* Error while scanning inodes */
8676 N_("Error while scanning @is (%i): %m\n"),
8677 PROMPT_NONE, PR_FATAL },
8679 /* Error while iterating over blocks */
8680 { PR_1_BLOCK_ITERATE,
8681 N_("Error while iterating over @bs in @i %i: %m\n"),
8682 PROMPT_NONE, PR_FATAL },
8684 /* Error while storing inode count information */
8685 { PR_1_ICOUNT_STORE,
8686 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8687 PROMPT_NONE, PR_FATAL },
8689 /* Error while storing directory block information */
8691 N_("Error storing @d @b information "
8692 "(@i=%i, @b=%b, num=%N): %m\n"),
8693 PROMPT_NONE, PR_FATAL },
8695 /* Error while reading inode (for clearing) */
8697 N_("Error reading @i %i: %m\n"),
8698 PROMPT_NONE, PR_FATAL },
8700 /* Suppress messages prompt */
8701 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8703 /* Imagic flag set on an inode when filesystem doesn't support it */
8705 N_("@i %i has imagic flag set. "),
8708 /* Immutable flag set on a device or socket inode */
8709 { PR_1_SET_IMMUTABLE,
8710 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8711 "or append-only flag set. "),
8712 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8714 /* Compression flag set on an inode when filesystem doesn't support it */
8716 N_("@i %i has @cion flag set on @f without @cion support. "),
8719 /* Non-zero size for device, fifo or socket inode */
8720 { PR_1_SET_NONZSIZE,
8721 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8722 PROMPT_FIX, PR_PREEN_OK },
8724 /* Filesystem revision is 0, but feature flags are set */
8725 { PR_1_FS_REV_LEVEL,
8726 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8727 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8729 /* Journal inode is not in use, but contains data */
8730 { PR_1_JOURNAL_INODE_NOT_CLEAR,
8731 N_("@j @i is not in use, but contains data. "),
8732 PROMPT_CLEAR, PR_PREEN_OK },
8734 /* Journal has bad mode */
8735 { PR_1_JOURNAL_BAD_MODE,
8736 N_("@j is not regular file. "),
8737 PROMPT_FIX, PR_PREEN_OK },
8739 /* Deal with inodes that were part of orphan linked list */
8741 N_("@i %i was part of the @o @i list. "),
8742 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8744 /* Deal with inodes that were part of corrupted orphan linked
8745 list (latch question) */
8746 { PR_1_ORPHAN_LIST_REFUGEES,
8747 N_("@is that were part of a corrupted orphan linked list found. "),
8750 /* Error allocating refcount structure */
8751 { PR_1_ALLOCATE_REFCOUNT,
8752 N_("@A refcount structure (%N): %m\n"),
8753 PROMPT_NONE, PR_FATAL },
8755 /* Error reading extended attribute block */
8756 { PR_1_READ_EA_BLOCK,
8757 N_("Error reading @a @b %b for @i %i. "),
8760 /* Invalid extended attribute block */
8761 { PR_1_BAD_EA_BLOCK,
8762 N_("@i %i has a bad @a @b %b. "),
8765 /* Error reading Extended Attribute block while fixing refcount */
8766 { PR_1_EXTATTR_READ_ABORT,
8767 N_("Error reading @a @b %b (%m). "),
8770 /* Extended attribute reference count incorrect */
8771 { PR_1_EXTATTR_REFCOUNT,
8772 N_("@a @b %b has reference count %B, @s %N. "),
8775 /* Error writing Extended Attribute block while fixing refcount */
8776 { PR_1_EXTATTR_WRITE,
8777 N_("Error writing @a @b %b (%m). "),
8780 /* Multiple EA blocks not supported */
8781 { PR_1_EA_MULTI_BLOCK,
8782 N_("@a @b %b has h_@bs > 1. "),
8785 /* Error allocating EA region allocation structure */
8786 { PR_1_EA_ALLOC_REGION,
8787 N_("@A @a @b %b. "),
8790 /* Error EA allocation collision */
8791 { PR_1_EA_ALLOC_COLLISION,
8792 N_("@a @b %b is corrupt (allocation collision). "),
8795 /* Bad extended attribute name */
8797 N_("@a @b %b is corrupt (@n name). "),
8800 /* Bad extended attribute value */
8801 { PR_1_EA_BAD_VALUE,
8802 N_("@a @b %b is corrupt (@n value). "),
8805 /* Inode too big (latch question) */
8806 { PR_1_INODE_TOOBIG,
8807 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
8809 /* Directory too big */
8811 N_("@b #%B (%b) causes @d to be too big. "),
8812 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8814 /* Regular file too big */
8816 N_("@b #%B (%b) causes file to be too big. "),
8817 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8819 /* Symlink too big */
8820 { PR_1_TOOBIG_SYMLINK,
8821 N_("@b #%B (%b) causes symlink to be too big. "),
8822 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8824 /* INDEX_FL flag set on a non-HTREE filesystem */
8826 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8827 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8829 /* INDEX_FL flag set on a non-directory */
8831 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8832 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8834 /* Invalid root node in HTREE directory */
8835 { PR_1_HTREE_BADROOT,
8836 N_("@h %i has an @n root node.\n"),
8837 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8839 /* Unsupported hash version in HTREE directory */
8841 N_("@h %i has an unsupported hash version (%N)\n"),
8842 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8844 /* Incompatible flag in HTREE root node */
8845 { PR_1_HTREE_INCOMPAT,
8846 N_("@h %i uses an incompatible htree root node flag.\n"),
8847 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8849 /* HTREE too deep */
8851 N_("@h %i has a tree depth (%N) which is too big\n"),
8852 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8854 /* Bad block has indirect block that conflicts with filesystem block */
8856 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8858 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8860 /* Resize inode failed */
8861 { PR_1_RESIZE_INODE_CREATE,
8862 N_("Resize @i (re)creation failed: %m."),
8865 /* invalid inode->i_extra_isize */
8867 N_("@i %i has a extra size (%IS) which is @n\n"),
8868 PROMPT_FIX, PR_PREEN_OK },
8870 /* invalid ea entry->e_name_len */
8871 { PR_1_ATTR_NAME_LEN,
8872 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8873 PROMPT_CLEAR, PR_PREEN_OK },
8875 /* invalid ea entry->e_value_size */
8876 { PR_1_ATTR_VALUE_SIZE,
8877 N_("@a in @i %i has a value size (%N) which is @n\n"),
8878 PROMPT_CLEAR, PR_PREEN_OK },
8880 /* invalid ea entry->e_value_offs */
8881 { PR_1_ATTR_VALUE_OFFSET,
8882 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8883 PROMPT_CLEAR, PR_PREEN_OK },
8885 /* invalid ea entry->e_value_block */
8886 { PR_1_ATTR_VALUE_BLOCK,
8887 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8888 PROMPT_CLEAR, PR_PREEN_OK },
8890 /* invalid ea entry->e_hash */
8892 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8893 PROMPT_CLEAR, PR_PREEN_OK },
8895 /* Pass 1b errors */
8897 /* Pass 1B: Rescan for duplicate/bad blocks */
8898 { PR_1B_PASS_HEADER,
8899 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8900 "Pass 1B: Rescanning for @m @bs\n"),
8903 /* Duplicate/bad block(s) header */
8904 { PR_1B_DUP_BLOCK_HEADER,
8905 N_("@m @b(s) in @i %i:"),
8908 /* Duplicate/bad block(s) in inode */
8911 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8913 /* Duplicate/bad block(s) end */
8914 { PR_1B_DUP_BLOCK_END,
8916 PROMPT_NONE, PR_PREEN_NOHDR },
8918 /* Error while scanning inodes */
8919 { PR_1B_ISCAN_ERROR,
8920 N_("Error while scanning inodes (%i): %m\n"),
8921 PROMPT_NONE, PR_FATAL },
8923 /* Error allocating inode bitmap */
8924 { PR_1B_ALLOCATE_IBITMAP_ERROR,
8925 N_("@A @i @B (@i_dup_map): %m\n"),
8926 PROMPT_NONE, PR_FATAL },
8928 /* Error while iterating over blocks */
8929 { PR_1B_BLOCK_ITERATE,
8930 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8933 /* Error adjusting EA refcount */
8934 { PR_1B_ADJ_EA_REFCOUNT,
8935 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8939 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8940 { PR_1C_PASS_HEADER,
8941 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8945 /* Pass 1D: Reconciling multiply-claimed blocks */
8946 { PR_1D_PASS_HEADER,
8947 N_("Pass 1D: Reconciling @m @bs\n"),
8950 /* File has duplicate blocks */
8952 N_("File %Q (@i #%i, mod time %IM)\n"
8953 " has %B @m @b(s), shared with %N file(s):\n"),
8956 /* List of files sharing duplicate blocks */
8957 { PR_1D_DUP_FILE_LIST,
8958 N_("\t%Q (@i #%i, mod time %IM)\n"),
8961 /* File sharing blocks with filesystem metadata */
8962 { PR_1D_SHARE_METADATA,
8963 N_("\t<@f metadata>\n"),
8966 /* Report of how many duplicate/bad inodes */
8967 { PR_1D_NUM_DUP_INODES,
8968 N_("(There are %N @is containing @m @bs.)\n\n"),
8971 /* Duplicated blocks already reassigned or cloned. */
8972 { PR_1D_DUP_BLOCKS_DEALT,
8973 N_("@m @bs already reassigned or cloned.\n\n"),
8976 /* Clone duplicate/bad blocks? */
8977 { PR_1D_CLONE_QUESTION,
8978 "", PROMPT_CLONE, PR_NO_OK },
8981 { PR_1D_DELETE_QUESTION,
8982 "", PROMPT_DELETE, 0 },
8984 /* Couldn't clone file (error) */
8985 { PR_1D_CLONE_ERROR,
8986 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
8990 /* Pass 2: Checking directory structure */
8992 N_("Pass 2: Checking @d structure\n"),
8995 /* Bad inode number for '.' */
8996 { PR_2_BAD_INODE_DOT,
8997 N_("@n @i number for '.' in @d @i %i.\n"),
9000 /* Directory entry has bad inode number */
9002 N_("@E has @n @i #: %Di.\n"),
9005 /* Directory entry has deleted or unused inode */
9006 { PR_2_UNUSED_INODE,
9007 N_("@E has @D/unused @i %Di. "),
9008 PROMPT_CLEAR, PR_PREEN_OK },
9010 /* Directry entry is link to '.' */
9012 N_("@E @L to '.' "),
9015 /* Directory entry points to inode now located in a bad block */
9017 N_("@E points to @i (%Di) located in a bad @b.\n"),
9020 /* Directory entry contains a link to a directory */
9022 N_("@E @L to @d %P (%Di).\n"),
9025 /* Directory entry contains a link to the root directry */
9027 N_("@E @L to the @r.\n"),
9030 /* Directory entry has illegal characters in its name */
9032 N_("@E has illegal characters in its name.\n"),
9035 /* Missing '.' in directory inode */
9037 N_("Missing '.' in @d @i %i.\n"),
9040 /* Missing '..' in directory inode */
9041 { PR_2_MISSING_DOT_DOT,
9042 N_("Missing '..' in @d @i %i.\n"),
9045 /* First entry in directory inode doesn't contain '.' */
9047 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9050 /* Second entry in directory inode doesn't contain '..' */
9051 { PR_2_2ND_NOT_DOT_DOT,
9052 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9055 /* i_faddr should be zero */
9057 N_("i_faddr @F %IF, @s zero.\n"),
9060 /* i_file_acl should be zero */
9061 { PR_2_FILE_ACL_ZERO,
9062 N_("i_file_acl @F %If, @s zero.\n"),
9065 /* i_dir_acl should be zero */
9066 { PR_2_DIR_ACL_ZERO,
9067 N_("i_dir_acl @F %Id, @s zero.\n"),
9070 /* i_frag should be zero */
9072 N_("i_frag @F %N, @s zero.\n"),
9075 /* i_fsize should be zero */
9077 N_("i_fsize @F %N, @s zero.\n"),
9080 /* inode has bad mode */
9082 N_("@i %i (%Q) has @n mode (%Im).\n"),
9085 /* directory corrupted */
9086 { PR_2_DIR_CORRUPTED,
9087 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9088 PROMPT_SALVAGE, 0 },
9090 /* filename too long */
9091 { PR_2_FILENAME_LONG,
9092 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9093 PROMPT_TRUNCATE, 0 },
9095 /* Directory inode has a missing block (hole) */
9096 { PR_2_DIRECTORY_HOLE,
9097 N_("@d @i %i has an unallocated @b #%B. "),
9098 PROMPT_ALLOCATE, 0 },
9100 /* '.' is not NULL terminated */
9101 { PR_2_DOT_NULL_TERM,
9102 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9105 /* '..' is not NULL terminated */
9106 { PR_2_DOT_DOT_NULL_TERM,
9107 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9110 /* Illegal character device inode */
9111 { PR_2_BAD_CHAR_DEV,
9112 N_("@i %i (%Q) is an @I character @v.\n"),
9115 /* Illegal block device inode */
9116 { PR_2_BAD_BLOCK_DEV,
9117 N_("@i %i (%Q) is an @I @b @v.\n"),
9120 /* Duplicate '.' entry */
9122 N_("@E is duplicate '.' @e.\n"),
9125 /* Duplicate '..' entry */
9127 N_("@E is duplicate '..' @e.\n"),
9130 /* Internal error: couldn't find dir_info */
9132 N_("Internal error: cannot find dir_info for %i.\n"),
9133 PROMPT_NONE, PR_FATAL },
9135 /* Final rec_len is wrong */
9136 { PR_2_FINAL_RECLEN,
9137 N_("@E has rec_len of %Dr, @s %N.\n"),
9140 /* Error allocating icount structure */
9141 { PR_2_ALLOCATE_ICOUNT,
9142 N_("@A icount structure: %m\n"),
9143 PROMPT_NONE, PR_FATAL },
9145 /* Error iterating over directory blocks */
9146 { PR_2_DBLIST_ITERATE,
9147 N_("Error iterating over @d @bs: %m\n"),
9148 PROMPT_NONE, PR_FATAL },
9150 /* Error reading directory block */
9151 { PR_2_READ_DIRBLOCK,
9152 N_("Error reading @d @b %b (@i %i): %m\n"),
9153 PROMPT_CONTINUE, 0 },
9155 /* Error writing directory block */
9156 { PR_2_WRITE_DIRBLOCK,
9157 N_("Error writing @d @b %b (@i %i): %m\n"),
9158 PROMPT_CONTINUE, 0 },
9160 /* Error allocating new directory block */
9161 { PR_2_ALLOC_DIRBOCK,
9162 N_("@A new @d @b for @i %i (%s): %m\n"),
9165 /* Error deallocating inode */
9166 { PR_2_DEALLOC_INODE,
9167 N_("Error deallocating @i %i: %m\n"),
9168 PROMPT_NONE, PR_FATAL },
9170 /* Directory entry for '.' is big. Split? */
9172 N_("@d @e for '.' is big. "),
9173 PROMPT_SPLIT, PR_NO_OK },
9175 /* Illegal FIFO inode */
9177 N_("@i %i (%Q) is an @I FIFO.\n"),
9180 /* Illegal socket inode */
9182 N_("@i %i (%Q) is an @I socket.\n"),
9185 /* Directory filetype not set */
9186 { PR_2_SET_FILETYPE,
9187 N_("Setting filetype for @E to %N.\n"),
9188 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9190 /* Directory filetype incorrect */
9191 { PR_2_BAD_FILETYPE,
9192 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9195 /* Directory filetype set on filesystem */
9196 { PR_2_CLEAR_FILETYPE,
9197 N_("@E has filetype set.\n"),
9198 PROMPT_CLEAR, PR_PREEN_OK },
9200 /* Directory filename is null */
9202 N_("@E has a @z name.\n"),
9205 /* Invalid symlink */
9206 { PR_2_INVALID_SYMLINK,
9207 N_("Symlink %Q (@i #%i) is @n.\n"),
9210 /* i_file_acl (extended attribute block) is bad */
9211 { PR_2_FILE_ACL_BAD,
9212 N_("@a @b @F @n (%If).\n"),
9215 /* Filesystem contains large files, but has no such flag in sb */
9216 { PR_2_FEATURE_LARGE_FILES,
9217 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9220 /* Node in HTREE directory not referenced */
9221 { PR_2_HTREE_NOTREF,
9222 N_("@p @h %d: node (%B) not referenced\n"),
9225 /* Node in HTREE directory referenced twice */
9226 { PR_2_HTREE_DUPREF,
9227 N_("@p @h %d: node (%B) referenced twice\n"),
9230 /* Node in HTREE directory has bad min hash */
9231 { PR_2_HTREE_MIN_HASH,
9232 N_("@p @h %d: node (%B) has bad min hash\n"),
9235 /* Node in HTREE directory has bad max hash */
9236 { PR_2_HTREE_MAX_HASH,
9237 N_("@p @h %d: node (%B) has bad max hash\n"),
9240 /* Clear invalid HTREE directory */
9242 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9244 /* Bad block in htree interior node */
9245 { PR_2_HTREE_BADBLK,
9246 N_("@p @h %d (%q): bad @b number %b.\n"),
9247 PROMPT_CLEAR_HTREE, 0 },
9249 /* Error adjusting EA refcount */
9250 { PR_2_ADJ_EA_REFCOUNT,
9251 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9252 PROMPT_NONE, PR_FATAL },
9254 /* Invalid HTREE root node */
9255 { PR_2_HTREE_BAD_ROOT,
9256 N_("@p @h %d: root node is @n\n"),
9257 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9259 /* Invalid HTREE limit */
9260 { PR_2_HTREE_BAD_LIMIT,
9261 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9262 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9264 /* Invalid HTREE count */
9265 { PR_2_HTREE_BAD_COUNT,
9266 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9267 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9269 /* HTREE interior node has out-of-order hashes in table */
9270 { PR_2_HTREE_HASH_ORDER,
9271 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9272 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9274 /* Node in HTREE directory has invalid depth */
9275 { PR_2_HTREE_BAD_DEPTH,
9276 N_("@p @h %d: node (%B) has @n depth\n"),
9279 /* Duplicate directory entry found */
9280 { PR_2_DUPLICATE_DIRENT,
9281 N_("Duplicate @E found. "),
9284 /* Non-unique filename found */
9285 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9286 N_("@E has a non-unique filename.\nRename to %s"),
9289 /* Duplicate directory entry found */
9290 { PR_2_REPORT_DUP_DIRENT,
9291 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9296 /* Pass 3: Checking directory connectivity */
9298 N_("Pass 3: Checking @d connectivity\n"),
9301 /* Root inode not allocated */
9302 { PR_3_NO_ROOT_INODE,
9303 N_("@r not allocated. "),
9304 PROMPT_ALLOCATE, 0 },
9306 /* No room in lost+found */
9307 { PR_3_EXPAND_LF_DIR,
9308 N_("No room in @l @d. "),
9311 /* Unconnected directory inode */
9312 { PR_3_UNCONNECTED_DIR,
9313 N_("Unconnected @d @i %i (%p)\n"),
9314 PROMPT_CONNECT, 0 },
9316 /* /lost+found not found */
9318 N_("/@l not found. "),
9319 PROMPT_CREATE, PR_PREEN_OK },
9321 /* .. entry is incorrect */
9323 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9326 /* Bad or non-existent /lost+found. Cannot reconnect */
9328 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9331 /* Could not expand /lost+found */
9332 { PR_3_CANT_EXPAND_LPF,
9333 N_("Could not expand /@l: %m\n"),
9336 /* Could not reconnect inode */
9337 { PR_3_CANT_RECONNECT,
9338 N_("Could not reconnect %i: %m\n"),
9341 /* Error while trying to find /lost+found */
9342 { PR_3_ERR_FIND_LPF,
9343 N_("Error while trying to find /@l: %m\n"),
9346 /* Error in ext2fs_new_block while creating /lost+found */
9347 { PR_3_ERR_LPF_NEW_BLOCK,
9348 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9351 /* Error in ext2fs_new_inode while creating /lost+found */
9352 { PR_3_ERR_LPF_NEW_INODE,
9353 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9356 /* Error in ext2fs_new_dir_block while creating /lost+found */
9357 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9358 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9361 /* Error while writing directory block for /lost+found */
9362 { PR_3_ERR_LPF_WRITE_BLOCK,
9363 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9366 /* Error while adjusting inode count */
9367 { PR_3_ADJUST_INODE,
9368 N_("Error while adjusting @i count on @i %i\n"),
9371 /* Couldn't fix parent directory -- error */
9372 { PR_3_FIX_PARENT_ERR,
9373 N_("Couldn't fix parent of @i %i: %m\n\n"),
9376 /* Couldn't fix parent directory -- couldn't find it */
9377 { PR_3_FIX_PARENT_NOFIND,
9378 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9381 /* Error allocating inode bitmap */
9382 { PR_3_ALLOCATE_IBITMAP_ERROR,
9383 N_("@A @i @B (%N): %m\n"),
9384 PROMPT_NONE, PR_FATAL },
9386 /* Error creating root directory */
9387 { PR_3_CREATE_ROOT_ERROR,
9388 N_("Error creating root @d (%s): %m\n"),
9389 PROMPT_NONE, PR_FATAL },
9391 /* Error creating lost and found directory */
9392 { PR_3_CREATE_LPF_ERROR,
9393 N_("Error creating /@l @d (%s): %m\n"),
9394 PROMPT_NONE, PR_FATAL },
9396 /* Root inode is not directory; aborting */
9397 { PR_3_ROOT_NOT_DIR_ABORT,
9398 N_("@r is not a @d; aborting.\n"),
9399 PROMPT_NONE, PR_FATAL },
9401 /* Cannot proceed without a root inode. */
9402 { PR_3_NO_ROOT_INODE_ABORT,
9403 N_("can't proceed without a @r.\n"),
9404 PROMPT_NONE, PR_FATAL },
9406 /* Internal error: couldn't find dir_info */
9408 N_("Internal error: cannot find dir_info for %i.\n"),
9409 PROMPT_NONE, PR_FATAL },
9411 /* Lost+found not a directory */
9413 N_("/@l is not a @d (ino=%i)\n"),
9416 /* Pass 3A Directory Optimization */
9418 /* Pass 3A: Optimizing directories */
9419 { PR_3A_PASS_HEADER,
9420 N_("Pass 3A: Optimizing directories\n"),
9421 PROMPT_NONE, PR_PREEN_NOMSG },
9423 /* Error iterating over directories */
9424 { PR_3A_OPTIMIZE_ITER,
9425 N_("Failed to create dirs_to_hash iterator: %m"),
9428 /* Error rehash directory */
9429 { PR_3A_OPTIMIZE_DIR_ERR,
9430 N_("Failed to optimize directory %q (%d): %m"),
9433 /* Rehashing dir header */
9434 { PR_3A_OPTIMIZE_DIR_HEADER,
9435 N_("Optimizing directories: "),
9436 PROMPT_NONE, PR_MSG_ONLY },
9438 /* Rehashing directory %d */
9439 { PR_3A_OPTIMIZE_DIR,
9441 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9443 /* Rehashing dir end */
9444 { PR_3A_OPTIMIZE_DIR_END,
9446 PROMPT_NONE, PR_PREEN_NOHDR },
9450 /* Pass 4: Checking reference counts */
9452 N_("Pass 4: Checking reference counts\n"),
9455 /* Unattached zero-length inode */
9456 { PR_4_ZERO_LEN_INODE,
9457 N_("@u @z @i %i. "),
9458 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9460 /* Unattached inode */
9461 { PR_4_UNATTACHED_INODE,
9463 PROMPT_CONNECT, 0 },
9465 /* Inode ref count wrong */
9466 { PR_4_BAD_REF_COUNT,
9467 N_("@i %i ref count is %Il, @s %N. "),
9468 PROMPT_FIX, PR_PREEN_OK },
9470 { PR_4_INCONSISTENT_COUNT,
9471 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9472 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9473 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9474 "They @s the same!\n"),
9479 /* Pass 5: Checking group summary information */
9481 N_("Pass 5: Checking @g summary information\n"),
9484 /* Padding at end of inode bitmap is not set. */
9485 { PR_5_INODE_BMAP_PADDING,
9486 N_("Padding at end of @i @B is not set. "),
9487 PROMPT_FIX, PR_PREEN_OK },
9489 /* Padding at end of block bitmap is not set. */
9490 { PR_5_BLOCK_BMAP_PADDING,
9491 N_("Padding at end of @b @B is not set. "),
9492 PROMPT_FIX, PR_PREEN_OK },
9494 /* Block bitmap differences header */
9495 { PR_5_BLOCK_BITMAP_HEADER,
9496 N_("@b @B differences: "),
9497 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9499 /* Block not used, but marked in bitmap */
9500 { PR_5_BLOCK_UNUSED,
9502 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9504 /* Block used, but not marked used in bitmap */
9507 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9509 /* Block bitmap differences end */
9510 { PR_5_BLOCK_BITMAP_END,
9512 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9514 /* Inode bitmap differences header */
9515 { PR_5_INODE_BITMAP_HEADER,
9516 N_("@i @B differences: "),
9517 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9519 /* Inode not used, but marked in bitmap */
9520 { PR_5_INODE_UNUSED,
9522 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9524 /* Inode used, but not marked used in bitmap */
9527 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9529 /* Inode bitmap differences end */
9530 { PR_5_INODE_BITMAP_END,
9532 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9534 /* Free inodes count for group wrong */
9535 { PR_5_FREE_INODE_COUNT_GROUP,
9536 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9537 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9539 /* Directories count for group wrong */
9540 { PR_5_FREE_DIR_COUNT_GROUP,
9541 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9542 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9544 /* Free inodes count wrong */
9545 { PR_5_FREE_INODE_COUNT,
9546 N_("Free @is count wrong (%i, counted=%j).\n"),
9547 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9549 /* Free blocks count for group wrong */
9550 { PR_5_FREE_BLOCK_COUNT_GROUP,
9551 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9552 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9554 /* Free blocks count wrong */
9555 { PR_5_FREE_BLOCK_COUNT,
9556 N_("Free @bs count wrong (%b, counted=%c).\n"),
9557 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9559 /* Programming error: bitmap endpoints don't match */
9560 { PR_5_BMAP_ENDPOINTS,
9561 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9562 "match calculated @B endpoints (%i, %j)\n"),
9563 PROMPT_NONE, PR_FATAL },
9565 /* Internal error: fudging end of bitmap */
9566 { PR_5_FUDGE_BITMAP_ERROR,
9567 N_("Internal error: fudging end of bitmap (%N)\n"),
9568 PROMPT_NONE, PR_FATAL },
9570 /* Error copying in replacement inode bitmap */
9571 { PR_5_COPY_IBITMAP_ERROR,
9572 N_("Error copying in replacement @i @B: %m\n"),
9573 PROMPT_NONE, PR_FATAL },
9575 /* Error copying in replacement block bitmap */
9576 { PR_5_COPY_BBITMAP_ERROR,
9577 N_("Error copying in replacement @b @B: %m\n"),
9578 PROMPT_NONE, PR_FATAL },
9580 /* Block range not used, but marked in bitmap */
9581 { PR_5_BLOCK_RANGE_UNUSED,
9583 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9585 /* Block range used, but not marked used in bitmap */
9586 { PR_5_BLOCK_RANGE_USED,
9588 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9590 /* Inode range not used, but marked in bitmap */
9591 { PR_5_INODE_RANGE_UNUSED,
9593 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9595 /* Inode range used, but not marked used in bitmap */
9596 { PR_5_INODE_RANGE_USED,
9598 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9604 * This is the latch flags register. It allows several problems to be
9605 * "latched" together. This means that the user has to answer but one
9606 * question for the set of problems, and all of the associated
9607 * problems will be either fixed or not fixed.
9609 static struct latch_descr pr_latch_info[] = {
9610 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9611 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9612 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9613 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9614 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9615 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9616 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9617 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9618 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9622 static const struct e2fsck_problem *find_problem(problem_t code)
9626 for (i=0; problem_table[i].e2p_code; i++) {
9627 if (problem_table[i].e2p_code == code)
9628 return &problem_table[i];
9633 static struct latch_descr *find_latch(int code)
9637 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9638 if (pr_latch_info[i].latch_code == code)
9639 return &pr_latch_info[i];
9644 int end_problem_latch(e2fsck_t ctx, int mask)
9646 struct latch_descr *ldesc;
9647 struct problem_context pctx;
9650 ldesc = find_latch(mask);
9651 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9652 clear_problem_context(&pctx);
9653 answer = fix_problem(ctx, ldesc->end_message, &pctx);
9655 ldesc->flags &= ~(PRL_VARIABLE);
9659 int set_latch_flags(int mask, int setflags, int clearflags)
9661 struct latch_descr *ldesc;
9663 ldesc = find_latch(mask);
9666 ldesc->flags |= setflags;
9667 ldesc->flags &= ~clearflags;
9671 void clear_problem_context(struct problem_context *ctx)
9673 memset(ctx, 0, sizeof(struct problem_context));
9678 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9680 ext2_filsys fs = ctx->fs;
9681 const struct e2fsck_problem *ptr;
9682 struct latch_descr *ldesc = NULL;
9683 const char *message;
9684 int def_yn, answer, ans;
9685 int print_answer = 0;
9688 ptr = find_problem(code);
9690 printf(_("Unhandled error code (0x%x)!\n"), code);
9694 if ((ptr->flags & PR_NO_DEFAULT) ||
9695 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9696 (ctx->options & E2F_OPT_NO))
9700 * Do special latch processing. This is where we ask the
9701 * latch question, if it exists
9703 if (ptr->flags & PR_LATCH_MASK) {
9704 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9705 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9706 ans = fix_problem(ctx, ldesc->question, pctx);
9708 ldesc->flags |= PRL_YES;
9710 ldesc->flags |= PRL_NO;
9711 ldesc->flags |= PRL_LATCHED;
9713 if (ldesc->flags & PRL_SUPPRESS)
9716 if ((ptr->flags & PR_PREEN_NOMSG) &&
9717 (ctx->options & E2F_OPT_PREEN))
9719 if ((ptr->flags & PR_NO_NOMSG) &&
9720 (ctx->options & E2F_OPT_NO))
9723 message = ptr->e2p_description;
9724 if ((ctx->options & E2F_OPT_PREEN) &&
9725 !(ptr->flags & PR_PREEN_NOHDR)) {
9726 printf("%s: ", ctx->device_name ?
9727 ctx->device_name : ctx->filesystem_name);
9730 print_e2fsck_message(ctx, _(message), pctx, 1);
9732 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9735 if (ptr->flags & PR_FATAL)
9736 bb_error_msg_and_die(0);
9738 if (ptr->prompt == PROMPT_NONE) {
9739 if (ptr->flags & PR_NOCOLLATE)
9744 if (ctx->options & E2F_OPT_PREEN) {
9746 if (!(ptr->flags & PR_PREEN_NOMSG))
9748 } else if ((ptr->flags & PR_LATCH_MASK) &&
9749 (ldesc->flags & (PRL_YES | PRL_NO))) {
9752 if (ldesc->flags & PRL_YES)
9757 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9758 if (!answer && !(ptr->flags & PR_NO_OK))
9759 ext2fs_unmark_valid(fs);
9762 printf("%s.\n", answer ?
9763 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9766 if ((ptr->prompt == PROMPT_ABORT) && answer)
9767 bb_error_msg_and_die(0);
9769 if (ptr->flags & PR_AFTER_CODE)
9770 answer = fix_problem(ctx, ptr->second_code, pctx);
9776 * linux/fs/recovery.c
9778 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9782 * Maintain information about the progress of the recovery job, so that
9783 * the different passes can carry information between them.
9785 struct recovery_info
9787 tid_t start_transaction;
9788 tid_t end_transaction;
9795 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9796 static int do_one_pass(journal_t *journal,
9797 struct recovery_info *info, enum passtype pass);
9798 static int scan_revoke_records(journal_t *, struct buffer_head *,
9799 tid_t, struct recovery_info *);
9802 * Read a block from the journal
9805 static int jread(struct buffer_head **bhp, journal_t *journal,
9806 unsigned int offset)
9809 unsigned long blocknr;
9810 struct buffer_head *bh;
9814 err = journal_bmap(journal, offset, &blocknr);
9817 printf("JBD: bad block at offset %u\n", offset);
9821 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9825 if (!buffer_uptodate(bh)) {
9826 /* If this is a brand new buffer, start readahead.
9827 Otherwise, we assume we are already reading it. */
9828 if (!buffer_req(bh))
9829 do_readahead(journal, offset);
9833 if (!buffer_uptodate(bh)) {
9834 printf("JBD: Failed to read block at offset %u\n", offset);
9845 * Count the number of in-use tags in a journal descriptor block.
9848 static int count_tags(struct buffer_head *bh, int size)
9851 journal_block_tag_t * tag;
9854 tagp = &bh->b_data[sizeof(journal_header_t)];
9856 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9857 tag = (journal_block_tag_t *) tagp;
9860 tagp += sizeof(journal_block_tag_t);
9861 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9864 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9872 /* Make sure we wrap around the log correctly! */
9873 #define wrap(journal, var) \
9875 if (var >= (journal)->j_last) \
9876 var -= ((journal)->j_last - (journal)->j_first); \
9880 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9881 * @journal: the journal to recover
9883 * The primary function for recovering the log contents when mounting a
9886 * Recovery is done in three passes. In the first pass, we look for the
9887 * end of the log. In the second, we assemble the list of revoke
9888 * blocks. In the third and final pass, we replay any un-revoked blocks
9891 int journal_recover(journal_t *journal)
9894 journal_superblock_t * sb;
9896 struct recovery_info info;
9898 memset(&info, 0, sizeof(info));
9899 sb = journal->j_superblock;
9902 * The journal superblock's s_start field (the current log head)
9903 * is always zero if, and only if, the journal was cleanly
9908 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9912 err = do_one_pass(journal, &info, PASS_SCAN);
9914 err = do_one_pass(journal, &info, PASS_REVOKE);
9916 err = do_one_pass(journal, &info, PASS_REPLAY);
9918 /* Restart the log at the next transaction ID, thus invalidating
9919 * any existing commit records in the log. */
9920 journal->j_transaction_sequence = ++info.end_transaction;
9922 journal_clear_revoke(journal);
9923 sync_blockdev(journal->j_fs_dev);
9927 static int do_one_pass(journal_t *journal,
9928 struct recovery_info *info, enum passtype pass)
9930 unsigned int first_commit_ID, next_commit_ID;
9931 unsigned long next_log_block;
9932 int err, success = 0;
9933 journal_superblock_t * sb;
9934 journal_header_t * tmp;
9935 struct buffer_head * bh;
9936 unsigned int sequence;
9939 /* Precompute the maximum metadata descriptors in a descriptor block */
9940 int MAX_BLOCKS_PER_DESC;
9941 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9942 / sizeof(journal_block_tag_t));
9945 * First thing is to establish what we expect to find in the log
9946 * (in terms of transaction IDs), and where (in terms of log
9947 * block offsets): query the superblock.
9950 sb = journal->j_superblock;
9951 next_commit_ID = ntohl(sb->s_sequence);
9952 next_log_block = ntohl(sb->s_start);
9954 first_commit_ID = next_commit_ID;
9955 if (pass == PASS_SCAN)
9956 info->start_transaction = first_commit_ID;
9959 * Now we walk through the log, transaction by transaction,
9960 * making sure that each transaction has a commit block in the
9961 * expected place. Each complete transaction gets replayed back
9962 * into the main filesystem.
9968 journal_block_tag_t * tag;
9969 struct buffer_head * obh;
9970 struct buffer_head * nbh;
9972 /* If we already know where to stop the log traversal,
9973 * check right now that we haven't gone past the end of
9976 if (pass != PASS_SCAN)
9977 if (tid_geq(next_commit_ID, info->end_transaction))
9980 /* Skip over each chunk of the transaction looking
9981 * either the next descriptor block or the final commit
9984 err = jread(&bh, journal, next_log_block);
9989 wrap(journal, next_log_block);
9991 /* What kind of buffer is it?
9993 * If it is a descriptor block, check that it has the
9994 * expected sequence number. Otherwise, we're all done
9997 tmp = (journal_header_t *)bh->b_data;
9999 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10004 blocktype = ntohl(tmp->h_blocktype);
10005 sequence = ntohl(tmp->h_sequence);
10007 if (sequence != next_commit_ID) {
10012 /* OK, we have a valid descriptor block which matches
10013 * all of the sequence number checks. What are we going
10014 * to do with it? That depends on the pass... */
10016 switch (blocktype) {
10017 case JFS_DESCRIPTOR_BLOCK:
10018 /* If it is a valid descriptor block, replay it
10019 * in pass REPLAY; otherwise, just skip over the
10020 * blocks it describes. */
10021 if (pass != PASS_REPLAY) {
10023 count_tags(bh, journal->j_blocksize);
10024 wrap(journal, next_log_block);
10029 /* A descriptor block: we can now write all of
10030 * the data blocks. Yay, useful work is finally
10031 * getting done here! */
10033 tagp = &bh->b_data[sizeof(journal_header_t)];
10034 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10035 <= journal->j_blocksize) {
10036 unsigned long io_block;
10038 tag = (journal_block_tag_t *) tagp;
10039 flags = ntohl(tag->t_flags);
10041 io_block = next_log_block++;
10042 wrap(journal, next_log_block);
10043 err = jread(&obh, journal, io_block);
10045 /* Recover what we can, but
10046 * report failure at the end. */
10048 printf("JBD: IO error %d recovering "
10049 "block %ld in log\n",
10052 unsigned long blocknr;
10054 blocknr = ntohl(tag->t_blocknr);
10056 /* If the block has been
10057 * revoked, then we're all done
10059 if (journal_test_revoke
10063 ++info->nr_revoke_hits;
10067 /* Find a buffer for the new
10068 * data being restored */
10069 nbh = getblk(journal->j_fs_dev,
10071 journal->j_blocksize);
10073 printf("JBD: Out of memory "
10074 "during recovery.\n");
10082 memcpy(nbh->b_data, obh->b_data,
10083 journal->j_blocksize);
10084 if (flags & JFS_FLAG_ESCAPE) {
10085 *((unsigned int *)bh->b_data) =
10086 htonl(JFS_MAGIC_NUMBER);
10089 mark_buffer_uptodate(nbh, 1);
10090 mark_buffer_dirty(nbh);
10091 ++info->nr_replays;
10092 /* ll_rw_block(WRITE, 1, &nbh); */
10093 unlock_buffer(nbh);
10099 tagp += sizeof(journal_block_tag_t);
10100 if (!(flags & JFS_FLAG_SAME_UUID))
10103 if (flags & JFS_FLAG_LAST_TAG)
10110 case JFS_COMMIT_BLOCK:
10111 /* Found an expected commit block: not much to
10112 * do other than move on to the next sequence
10118 case JFS_REVOKE_BLOCK:
10119 /* If we aren't in the REVOKE pass, then we can
10120 * just skip over this block. */
10121 if (pass != PASS_REVOKE) {
10126 err = scan_revoke_records(journal, bh,
10127 next_commit_ID, info);
10140 * We broke out of the log scan loop: either we came to the
10141 * known end of the log or we found an unexpected block in the
10142 * log. If the latter happened, then we know that the "current"
10143 * transaction marks the end of the valid log.
10146 if (pass == PASS_SCAN)
10147 info->end_transaction = next_commit_ID;
10149 /* It's really bad news if different passes end up at
10150 * different places (but possible due to IO errors). */
10151 if (info->end_transaction != next_commit_ID) {
10152 printf("JBD: recovery pass %d ended at "
10153 "transaction %u, expected %u\n",
10154 pass, next_commit_ID, info->end_transaction);
10167 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10169 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10170 tid_t sequence, struct recovery_info *info)
10172 journal_revoke_header_t *header;
10175 header = (journal_revoke_header_t *) bh->b_data;
10176 offset = sizeof(journal_revoke_header_t);
10177 max = ntohl(header->r_count);
10179 while (offset < max) {
10180 unsigned long blocknr;
10183 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10185 err = journal_set_revoke(journal, blocknr, sequence);
10188 ++info->nr_revokes;
10195 * rehash.c --- rebuild hash tree directories
10197 * This algorithm is designed for simplicity of implementation and to
10198 * pack the directory as much as possible. It however requires twice
10199 * as much memory as the size of the directory. The maximum size
10200 * directory supported using a 4k blocksize is roughly a gigabyte, and
10201 * so there may very well be problems with machines that don't have
10202 * virtual memory, and obscenely large directories.
10204 * An alternate algorithm which is much more disk intensive could be
10205 * written, and probably will need to be written in the future. The
10206 * design goals of such an algorithm are: (a) use (roughly) constant
10207 * amounts of memory, no matter how large the directory, (b) the
10208 * directory must be safe at all times, even if e2fsck is interrupted
10209 * in the middle, (c) we must use minimal amounts of extra disk
10210 * blocks. This pretty much requires an incremental approach, where
10211 * we are reading from one part of the directory, and inserting into
10212 * the front half. So the algorithm will have to keep track of a
10213 * moving block boundary between the new tree and the old tree, and
10214 * files will need to be moved from the old directory and inserted
10215 * into the new tree. If the new directory requires space which isn't
10216 * yet available, blocks from the beginning part of the old directory
10217 * may need to be moved to the end of the directory to make room for
10220 * --------------------------------------------------------
10221 * | new tree | | old tree |
10222 * --------------------------------------------------------
10224 * tail new head old
10226 * This is going to be a pain in the tuckus to implement, and will
10227 * require a lot more disk accesses. So I'm going to skip it for now;
10228 * it's only really going to be an issue for really, really big
10229 * filesystems (when we reach the level of tens of millions of files
10230 * in a single directory). It will probably be easier to simply
10231 * require that e2fsck use VM first.
10234 struct fill_dir_struct {
10236 struct ext2_inode *inode;
10239 struct hash_entry *harray;
10240 int max_array, num_array;
10246 struct hash_entry {
10247 ext2_dirhash_t hash;
10248 ext2_dirhash_t minor_hash;
10249 struct ext2_dir_entry *dir;
10256 ext2_dirhash_t *hashes;
10259 static int fill_dir_block(ext2_filsys fs,
10261 e2_blkcnt_t blockcnt,
10262 blk_t ref_block FSCK_ATTR((unused)),
10263 int ref_offset FSCK_ATTR((unused)),
10266 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10267 struct hash_entry *new_array, *ent;
10268 struct ext2_dir_entry *dirent;
10270 unsigned int offset, dir_offset;
10275 offset = blockcnt * fs->blocksize;
10276 if (offset + fs->blocksize > fd->inode->i_size) {
10277 fd->err = EXT2_ET_DIR_CORRUPTED;
10278 return BLOCK_ABORT;
10280 dir = (fd->buf+offset);
10281 if (HOLE_BLKADDR(*block_nr)) {
10282 memset(dir, 0, fs->blocksize);
10283 dirent = (struct ext2_dir_entry *) dir;
10284 dirent->rec_len = fs->blocksize;
10286 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10288 return BLOCK_ABORT;
10290 /* While the directory block is "hot", index it. */
10292 while (dir_offset < fs->blocksize) {
10293 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10294 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10295 (dirent->rec_len < 8) ||
10296 ((dirent->rec_len % 4) != 0) ||
10297 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10298 fd->err = EXT2_ET_DIR_CORRUPTED;
10299 return BLOCK_ABORT;
10301 dir_offset += dirent->rec_len;
10302 if (dirent->inode == 0)
10304 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10305 (dirent->name[0] == '.'))
10307 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10308 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10309 fd->parent = dirent->inode;
10312 if (fd->num_array >= fd->max_array) {
10313 new_array = xrealloc(fd->harray,
10314 sizeof(struct hash_entry) * (fd->max_array+500));
10315 fd->harray = new_array;
10316 fd->max_array += 500;
10318 ent = fd->harray + fd->num_array++;
10320 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10322 ent->hash = ent->minor_hash = 0;
10324 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10326 dirent->name_len & 0xFF,
10327 fs->super->s_hash_seed,
10328 &ent->hash, &ent->minor_hash);
10330 return BLOCK_ABORT;
10337 /* Used for sorting the hash entry */
10338 static int name_cmp(const void *a, const void *b)
10340 const struct hash_entry *he_a = (const struct hash_entry *) a;
10341 const struct hash_entry *he_b = (const struct hash_entry *) b;
10345 min_len = he_a->dir->name_len;
10346 if (min_len > he_b->dir->name_len)
10347 min_len = he_b->dir->name_len;
10349 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10351 if (he_a->dir->name_len > he_b->dir->name_len)
10353 else if (he_a->dir->name_len < he_b->dir->name_len)
10356 ret = he_b->dir->inode - he_a->dir->inode;
10361 /* Used for sorting the hash entry */
10362 static int hash_cmp(const void *a, const void *b)
10364 const struct hash_entry *he_a = (const struct hash_entry *) a;
10365 const struct hash_entry *he_b = (const struct hash_entry *) b;
10368 if (he_a->hash > he_b->hash)
10370 else if (he_a->hash < he_b->hash)
10373 if (he_a->minor_hash > he_b->minor_hash)
10375 else if (he_a->minor_hash < he_b->minor_hash)
10378 ret = name_cmp(a, b);
10383 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10389 new_mem = xrealloc(outdir->buf, blocks * fs->blocksize);
10390 outdir->buf = new_mem;
10391 new_mem = xrealloc(outdir->hashes,
10392 blocks * sizeof(ext2_dirhash_t));
10393 outdir->hashes = new_mem;
10395 outdir->buf = xmalloc(blocks * fs->blocksize);
10396 outdir->hashes = xmalloc(blocks * sizeof(ext2_dirhash_t));
10399 outdir->max = blocks;
10403 static void free_out_dir(struct out_dir *outdir)
10406 free(outdir->hashes);
10411 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10416 if (outdir->num >= outdir->max) {
10417 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10421 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10422 memset(*ret, 0, fs->blocksize);
10427 * This function is used to make a unique filename. We do this by
10428 * appending ~0, and then incrementing the number. However, we cannot
10429 * expand the length of the filename beyond the padding available in
10430 * the directory entry.
10432 static void mutate_name(char *str, __u16 *len)
10435 __u16 l = *len & 0xFF, h = *len & 0xff00;
10438 * First check to see if it looks the name has been mutated
10441 for (i = l-1; i > 0; i--) {
10442 if (!isdigit(str[i]))
10445 if ((i == l-1) || (str[i] != '~')) {
10446 if (((l-1) & 3) < 2)
10455 for (i = l-1; i >= 0; i--) {
10456 if (isdigit(str[i])) {
10468 else if (str[0] == 'Z') {
10473 } else if (i > 0) {
10486 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10488 struct fill_dir_struct *fd)
10490 struct problem_context pctx;
10491 struct hash_entry *ent, *prev;
10494 char new_name[256];
10497 clear_problem_context(&pctx);
10500 for (i=1; i < fd->num_array; i++) {
10501 ent = fd->harray + i;
10503 if (!ent->dir->inode ||
10504 ((ent->dir->name_len & 0xFF) !=
10505 (prev->dir->name_len & 0xFF)) ||
10506 (strncmp(ent->dir->name, prev->dir->name,
10507 ent->dir->name_len & 0xFF)))
10509 pctx.dirent = ent->dir;
10510 if ((ent->dir->inode == prev->dir->inode) &&
10511 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10512 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10513 ent->dir->inode = 0;
10517 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10518 new_len = ent->dir->name_len;
10519 mutate_name(new_name, &new_len);
10520 for (j=0; j < fd->num_array; j++) {
10522 ((ent->dir->name_len & 0xFF) !=
10523 (fd->harray[j].dir->name_len & 0xFF)) ||
10524 (strncmp(new_name, fd->harray[j].dir->name,
10527 mutate_name(new_name, &new_len);
10531 new_name[new_len & 0xFF] = 0;
10532 pctx.str = new_name;
10533 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10534 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10535 ent->dir->name_len = new_len;
10536 ext2fs_dirhash(fs->super->s_def_hash_version,
10538 ent->dir->name_len & 0xFF,
10539 fs->super->s_hash_seed,
10540 &ent->hash, &ent->minor_hash);
10548 static errcode_t copy_dir_entries(ext2_filsys fs,
10549 struct fill_dir_struct *fd,
10550 struct out_dir *outdir)
10554 struct hash_entry *ent;
10555 struct ext2_dir_entry *dirent;
10556 int i, rec_len, left;
10557 ext2_dirhash_t prev_hash;
10561 retval = alloc_size_dir(fs, outdir,
10562 (fd->dir_size / fs->blocksize) + 2);
10565 outdir->num = fd->compress ? 0 : 1;
10567 outdir->hashes[0] = 0;
10569 if ((retval = get_next_block(fs, outdir, &block_start)))
10571 dirent = (struct ext2_dir_entry *) block_start;
10572 left = fs->blocksize;
10573 for (i=0; i < fd->num_array; i++) {
10574 ent = fd->harray + i;
10575 if (ent->dir->inode == 0)
10577 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10578 if (rec_len > left) {
10580 dirent->rec_len += left;
10581 if ((retval = get_next_block(fs, outdir,
10586 left = fs->blocksize - offset;
10587 dirent = (struct ext2_dir_entry *) (block_start + offset);
10589 if (ent->hash == prev_hash)
10590 outdir->hashes[outdir->num-1] = ent->hash | 1;
10592 outdir->hashes[outdir->num-1] = ent->hash;
10594 dirent->inode = ent->dir->inode;
10595 dirent->name_len = ent->dir->name_len;
10596 dirent->rec_len = rec_len;
10597 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10601 dirent->rec_len += left;
10605 prev_hash = ent->hash;
10608 dirent->rec_len += left;
10614 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10615 ext2_ino_t ino, ext2_ino_t parent)
10617 struct ext2_dir_entry *dir;
10618 struct ext2_dx_root_info *root;
10619 struct ext2_dx_countlimit *limits;
10622 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10623 filetype = EXT2_FT_DIR << 8;
10625 memset(buf, 0, fs->blocksize);
10626 dir = (struct ext2_dir_entry *) buf;
10628 dir->name[0] = '.';
10629 dir->name_len = 1 | filetype;
10631 dir = (struct ext2_dir_entry *) (buf + 12);
10632 dir->inode = parent;
10633 dir->name[0] = '.';
10634 dir->name[1] = '.';
10635 dir->name_len = 2 | filetype;
10636 dir->rec_len = fs->blocksize - 12;
10638 root = (struct ext2_dx_root_info *) (buf+24);
10639 root->reserved_zero = 0;
10640 root->hash_version = fs->super->s_def_hash_version;
10641 root->info_length = 8;
10642 root->indirect_levels = 0;
10643 root->unused_flags = 0;
10645 limits = (struct ext2_dx_countlimit *) (buf+32);
10646 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10653 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10655 struct ext2_dir_entry *dir;
10656 struct ext2_dx_countlimit *limits;
10658 memset(buf, 0, fs->blocksize);
10659 dir = (struct ext2_dir_entry *) buf;
10661 dir->rec_len = fs->blocksize;
10663 limits = (struct ext2_dx_countlimit *) (buf+8);
10664 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10667 return (struct ext2_dx_entry *) limits;
10671 * This function takes the leaf nodes which have been written in
10672 * outdir, and populates the root node and any necessary interior nodes.
10674 static errcode_t calculate_tree(ext2_filsys fs,
10675 struct out_dir *outdir,
10679 struct ext2_dx_root_info *root_info;
10680 struct ext2_dx_entry *root, *dx_ent = NULL;
10681 struct ext2_dx_countlimit *root_limit, *limit;
10683 char * block_start;
10684 int i, c1, c2, nblks;
10685 int limit_offset, root_offset;
10687 root_info = set_root_node(fs, outdir->buf, ino, parent);
10688 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10689 root_info->info_length;
10690 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10691 c1 = root_limit->limit;
10692 nblks = outdir->num;
10694 /* Write out the pointer blocks */
10695 if (nblks-1 <= c1) {
10696 /* Just write out the root block, and we're done */
10697 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10698 for (i=1; i < nblks; i++) {
10699 root->block = ext2fs_cpu_to_le32(i);
10702 ext2fs_cpu_to_le32(outdir->hashes[i]);
10709 root_info->indirect_levels = 1;
10710 for (i=1; i < nblks; i++) {
10715 limit->limit = limit->count =
10716 ext2fs_cpu_to_le16(limit->limit);
10717 root = (struct ext2_dx_entry *)
10718 (outdir->buf + root_offset);
10719 root->block = ext2fs_cpu_to_le32(outdir->num);
10722 ext2fs_cpu_to_le32(outdir->hashes[i]);
10723 if ((retval = get_next_block(fs, outdir,
10726 dx_ent = set_int_node(fs, block_start);
10727 limit = (struct ext2_dx_countlimit *) dx_ent;
10729 root_offset += sizeof(struct ext2_dx_entry);
10732 dx_ent->block = ext2fs_cpu_to_le32(i);
10733 if (c2 != limit->limit)
10735 ext2fs_cpu_to_le32(outdir->hashes[i]);
10739 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10740 limit->limit = ext2fs_cpu_to_le16(limit->limit);
10742 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10743 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10744 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10749 struct write_dir_struct {
10750 struct out_dir *outdir;
10757 * Helper function which writes out a directory block.
10759 static int write_dir_block(ext2_filsys fs,
10761 e2_blkcnt_t blockcnt,
10762 blk_t ref_block FSCK_ATTR((unused)),
10763 int ref_offset FSCK_ATTR((unused)),
10766 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10770 if (*block_nr == 0)
10772 if (blockcnt >= wd->outdir->num) {
10773 e2fsck_read_bitmaps(wd->ctx);
10775 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10776 ext2fs_block_alloc_stats(fs, blk, -1);
10779 return BLOCK_CHANGED;
10784 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10785 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10787 return BLOCK_ABORT;
10791 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10792 struct out_dir *outdir,
10793 ext2_ino_t ino, int compress)
10795 struct write_dir_struct wd;
10797 struct ext2_inode inode;
10799 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10803 wd.outdir = outdir;
10808 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10809 write_dir_block, &wd);
10815 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10817 inode.i_flags &= ~EXT2_INDEX_FL;
10819 inode.i_flags |= EXT2_INDEX_FL;
10820 inode.i_size = outdir->num * fs->blocksize;
10821 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10822 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10827 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10829 ext2_filsys fs = ctx->fs;
10831 struct ext2_inode inode;
10832 char *dir_buf = NULL;
10833 struct fill_dir_struct fd;
10834 struct out_dir outdir;
10836 outdir.max = outdir.num = 0;
10839 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10843 dir_buf = xmalloc(inode.i_size);
10845 fd.max_array = inode.i_size / 32;
10847 fd.harray = xmalloc(fd.max_array * sizeof(struct hash_entry));
10855 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10856 (inode.i_size / fs->blocksize) < 2)
10860 /* Read in the entire directory into memory */
10861 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10862 fill_dir_block, &fd);
10868 /* Sort the list */
10871 qsort(fd.harray+2, fd.num_array-2,
10872 sizeof(struct hash_entry), name_cmp);
10874 qsort(fd.harray, fd.num_array,
10875 sizeof(struct hash_entry), hash_cmp);
10878 * Look for duplicates
10880 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10883 if (ctx->options & E2F_OPT_NO) {
10889 * Copy the directory entries. In a htree directory these
10890 * will become the leaf nodes.
10892 retval = copy_dir_entries(fs, &fd, &outdir);
10896 free(dir_buf); dir_buf = 0;
10898 if (!fd.compress) {
10899 /* Calculate the interior nodes */
10900 retval = calculate_tree(fs, &outdir, ino, fd.parent);
10905 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10911 free_out_dir(&outdir);
10915 void e2fsck_rehash_directories(e2fsck_t ctx)
10917 struct problem_context pctx;
10918 struct dir_info *dir;
10919 ext2_u32_iterate iter;
10922 int i, cur, max, all_dirs, dir_index, first = 1;
10924 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10926 if (!ctx->dirs_to_hash && !all_dirs)
10929 e2fsck_get_lost_and_found(ctx, 0);
10931 clear_problem_context(&pctx);
10933 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10937 max = e2fsck_get_num_dirinfo(ctx);
10939 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10942 pctx.errcode = retval;
10943 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10946 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10950 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10954 if (!ext2fs_u32_list_iterate(iter, &ino))
10957 if (ino == ctx->lost_and_found)
10961 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
10964 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
10965 if (pctx.errcode) {
10966 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10967 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
10969 if (ctx->progress && !ctx->progress_fd)
10970 e2fsck_simple_progress(ctx, "Rebuilding directory",
10971 100.0 * (float) (++cur) / (float) max, ino);
10973 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10975 ext2fs_u32_list_iterate_end(iter);
10977 ext2fs_u32_list_free(ctx->dirs_to_hash);
10978 ctx->dirs_to_hash = 0;
10982 * linux/fs/revoke.c
10984 * Journal revoke routines for the generic filesystem journaling code;
10985 * part of the ext2fs journaling system.
10987 * Revoke is the mechanism used to prevent old log records for deleted
10988 * metadata from being replayed on top of newer data using the same
10989 * blocks. The revoke mechanism is used in two separate places:
10991 * + Commit: during commit we write the entire list of the current
10992 * transaction's revoked blocks to the journal
10994 * + Recovery: during recovery we record the transaction ID of all
10995 * revoked blocks. If there are multiple revoke records in the log
10996 * for a single block, only the last one counts, and if there is a log
10997 * entry for a block beyond the last revoke, then that log entry still
11000 * We can get interactions between revokes and new log data within a
11001 * single transaction:
11003 * Block is revoked and then journaled:
11004 * The desired end result is the journaling of the new block, so we
11005 * cancel the revoke before the transaction commits.
11007 * Block is journaled and then revoked:
11008 * The revoke must take precedence over the write of the block, so we
11009 * need either to cancel the journal entry or to write the revoke
11010 * later in the log than the log block. In this case, we choose the
11011 * latter: journaling a block cancels any revoke record for that block
11012 * in the current transaction, so any revoke for that block in the
11013 * transaction must have happened after the block was journaled and so
11014 * the revoke must take precedence.
11016 * Block is revoked and then written as data:
11017 * The data write is allowed to succeed, but the revoke is _not_
11018 * cancelled. We still need to prevent old log records from
11019 * overwriting the new data. We don't even need to clear the revoke
11022 * Revoke information on buffers is a tri-state value:
11024 * RevokeValid clear: no cached revoke status, need to look it up
11025 * RevokeValid set, Revoked clear:
11026 * buffer has not been revoked, and cancel_revoke
11028 * RevokeValid set, Revoked set:
11029 * buffer has been revoked.
11032 static kmem_cache_t *revoke_record_cache;
11033 static kmem_cache_t *revoke_table_cache;
11035 /* Each revoke record represents one single revoked block. During
11036 journal replay, this involves recording the transaction ID of the
11037 last transaction to revoke this block. */
11039 struct jbd_revoke_record_s
11041 struct list_head hash;
11042 tid_t sequence; /* Used for recovery only */
11043 unsigned long blocknr;
11047 /* The revoke table is just a simple hash table of revoke records. */
11048 struct jbd_revoke_table_s
11050 /* It is conceivable that we might want a larger hash table
11051 * for recovery. Must be a power of two. */
11054 struct list_head *hash_table;
11058 /* Utility functions to maintain the revoke table */
11060 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11061 static int hash(journal_t *journal, unsigned long block)
11063 struct jbd_revoke_table_s *table = journal->j_revoke;
11064 int hash_shift = table->hash_shift;
11066 return ((block << (hash_shift - 6)) ^
11068 (block << (hash_shift - 12))) & (table->hash_size - 1);
11071 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11074 struct list_head *hash_list;
11075 struct jbd_revoke_record_s *record;
11077 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11081 record->sequence = seq;
11082 record->blocknr = blocknr;
11083 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11084 list_add(&record->hash, hash_list);
11091 /* Find a revoke record in the journal's hash table. */
11093 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11094 unsigned long blocknr)
11096 struct list_head *hash_list;
11097 struct jbd_revoke_record_s *record;
11099 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11101 record = (struct jbd_revoke_record_s *) hash_list->next;
11102 while (&(record->hash) != hash_list) {
11103 if (record->blocknr == blocknr)
11105 record = (struct jbd_revoke_record_s *) record->hash.next;
11110 int journal_init_revoke_caches(void)
11112 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11113 if (revoke_record_cache == 0)
11116 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11117 if (revoke_table_cache == 0) {
11118 do_cache_destroy(revoke_record_cache);
11119 revoke_record_cache = NULL;
11125 void journal_destroy_revoke_caches(void)
11127 do_cache_destroy(revoke_record_cache);
11128 revoke_record_cache = 0;
11129 do_cache_destroy(revoke_table_cache);
11130 revoke_table_cache = 0;
11133 /* Initialise the revoke table for a given journal to a given size. */
11135 int journal_init_revoke(journal_t *journal, int hash_size)
11139 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11140 if (!journal->j_revoke)
11143 /* Check that the hash_size is a power of two */
11144 journal->j_revoke->hash_size = hash_size;
11148 while ((tmp >>= 1UL) != 0UL)
11150 journal->j_revoke->hash_shift = shift;
11152 journal->j_revoke->hash_table = xmalloc(hash_size * sizeof(struct list_head));
11154 for (tmp = 0; tmp < hash_size; tmp++)
11155 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11160 /* Destoy a journal's revoke table. The table must already be empty! */
11162 void journal_destroy_revoke(journal_t *journal)
11164 struct jbd_revoke_table_s *table;
11165 struct list_head *hash_list;
11168 table = journal->j_revoke;
11172 for (i=0; i<table->hash_size; i++) {
11173 hash_list = &table->hash_table[i];
11176 free(table->hash_table);
11178 journal->j_revoke = NULL;
11182 * Revoke support for recovery.
11184 * Recovery needs to be able to:
11186 * record all revoke records, including the tid of the latest instance
11187 * of each revoke in the journal
11189 * check whether a given block in a given transaction should be replayed
11190 * (ie. has not been revoked by a revoke record in that or a subsequent
11193 * empty the revoke table after recovery.
11197 * First, setting revoke records. We create a new revoke record for
11198 * every block ever revoked in the log as we scan it for recovery, and
11199 * we update the existing records if we find multiple revokes for a
11203 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11206 struct jbd_revoke_record_s *record;
11208 record = find_revoke_record(journal, blocknr);
11210 /* If we have multiple occurences, only record the
11211 * latest sequence number in the hashed record */
11212 if (tid_gt(sequence, record->sequence))
11213 record->sequence = sequence;
11216 return insert_revoke_hash(journal, blocknr, sequence);
11220 * Test revoke records. For a given block referenced in the log, has
11221 * that block been revoked? A revoke record with a given transaction
11222 * sequence number revokes all blocks in that transaction and earlier
11223 * ones, but later transactions still need replayed.
11226 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11229 struct jbd_revoke_record_s *record;
11231 record = find_revoke_record(journal, blocknr);
11234 if (tid_gt(sequence, record->sequence))
11240 * Finally, once recovery is over, we need to clear the revoke table so
11241 * that it can be reused by the running filesystem.
11244 void journal_clear_revoke(journal_t *journal)
11247 struct list_head *hash_list;
11248 struct jbd_revoke_record_s *record;
11249 struct jbd_revoke_table_s *revoke_var;
11251 revoke_var = journal->j_revoke;
11253 for (i = 0; i < revoke_var->hash_size; i++) {
11254 hash_list = &revoke_var->hash_table[i];
11255 while (!list_empty(hash_list)) {
11256 record = (struct jbd_revoke_record_s*) hash_list->next;
11257 list_del(&record->hash);
11264 * e2fsck.c - superblock checks
11267 #define MIN_CHECK 1
11268 #define MAX_CHECK 2
11270 static void check_super_value(e2fsck_t ctx, const char *descr,
11271 unsigned long value, int flags,
11272 unsigned long min_val, unsigned long max_val)
11274 struct problem_context pctx;
11276 if (((flags & MIN_CHECK) && (value < min_val)) ||
11277 ((flags & MAX_CHECK) && (value > max_val))) {
11278 clear_problem_context(&pctx);
11281 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11282 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11287 * This routine may get stubbed out in special compilations of the
11290 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11291 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11293 return (ext2fs_get_device_size(ctx->filesystem_name,
11294 EXT2_BLOCK_SIZE(ctx->fs->super),
11295 &ctx->num_blocks));
11300 * helper function to release an inode
11302 struct process_block_struct {
11305 struct problem_context *pctx;
11307 int truncate_offset;
11308 e2_blkcnt_t truncate_block;
11309 int truncated_blocks;
11314 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11315 e2_blkcnt_t blockcnt,
11316 blk_t ref_blk FSCK_ATTR((unused)),
11317 int ref_offset FSCK_ATTR((unused)),
11320 struct process_block_struct *pb;
11322 struct problem_context *pctx;
11323 blk_t blk = *block_nr;
11326 pb = (struct process_block_struct *) priv_data;
11331 pctx->blkcount = blockcnt;
11333 if (HOLE_BLKADDR(blk))
11336 if ((blk < fs->super->s_first_data_block) ||
11337 (blk >= fs->super->s_blocks_count)) {
11338 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11341 return BLOCK_ABORT;
11344 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11345 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11350 * If we are deleting an orphan, then we leave the fields alone.
11351 * If we are truncating an orphan, then update the inode fields
11352 * and clean up any partial block data.
11354 if (pb->truncating) {
11356 * We only remove indirect blocks if they are
11357 * completely empty.
11359 if (blockcnt < 0) {
11363 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11368 limit = fs->blocksize >> 2;
11369 for (i = 0, bp = (blk_t *) pb->buf;
11370 i < limit; i++, bp++)
11375 * We don't remove direct blocks until we've reached
11376 * the truncation block.
11378 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11381 * If part of the last block needs truncating, we do
11384 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11385 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11389 memset(pb->buf + pb->truncate_offset, 0,
11390 fs->blocksize - pb->truncate_offset);
11391 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11396 pb->truncated_blocks++;
11398 retval |= BLOCK_CHANGED;
11401 ext2fs_block_alloc_stats(fs, blk, -1);
11406 * This function releases an inode. Returns 1 if an inconsistency was
11407 * found. If the inode has a link count, then it is being truncated and
11410 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11411 struct ext2_inode *inode, char *block_buf,
11412 struct problem_context *pctx)
11414 struct process_block_struct pb;
11415 ext2_filsys fs = ctx->fs;
11419 if (!ext2fs_inode_has_valid_blocks(inode))
11422 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11427 if (inode->i_links_count) {
11429 pb.truncate_block = (e2_blkcnt_t)
11430 ((((long long)inode->i_size_high << 32) +
11431 inode->i_size + fs->blocksize - 1) /
11433 pb.truncate_offset = inode->i_size % fs->blocksize;
11436 pb.truncate_block = 0;
11437 pb.truncate_offset = 0;
11439 pb.truncated_blocks = 0;
11440 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11441 block_buf, release_inode_block, &pb);
11443 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11450 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11451 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11453 if (pb.truncated_blocks)
11454 inode->i_blocks -= pb.truncated_blocks *
11455 (fs->blocksize / 512);
11457 if (inode->i_file_acl) {
11458 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11459 block_buf, -1, &count);
11460 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11465 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11470 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11471 inode->i_file_acl = 0;
11477 * This function releases all of the orphan inodes. It returns 1 if
11478 * it hit some error, and 0 on success.
11480 static int release_orphan_inodes(e2fsck_t ctx)
11482 ext2_filsys fs = ctx->fs;
11483 ext2_ino_t ino, next_ino;
11484 struct ext2_inode inode;
11485 struct problem_context pctx;
11488 if ((ino = fs->super->s_last_orphan) == 0)
11492 * Win or lose, we won't be using the head of the orphan inode
11495 fs->super->s_last_orphan = 0;
11496 ext2fs_mark_super_dirty(fs);
11499 * If the filesystem contains errors, don't run the orphan
11500 * list, since the orphan list can't be trusted; and we're
11501 * going to be running a full e2fsck run anyway...
11503 if (fs->super->s_state & EXT2_ERROR_FS)
11506 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11507 (ino > fs->super->s_inodes_count)) {
11508 clear_problem_context(&pctx);
11510 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11514 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11515 "block iterate buffer");
11516 e2fsck_read_bitmaps(ctx);
11519 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11520 clear_problem_context(&pctx);
11522 pctx.inode = &inode;
11523 pctx.str = inode.i_links_count ? _("Truncating") :
11526 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11528 next_ino = inode.i_dtime;
11530 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11531 (next_ino > fs->super->s_inodes_count))) {
11532 pctx.ino = next_ino;
11533 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11537 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11540 if (!inode.i_links_count) {
11541 ext2fs_inode_alloc_stats2(fs, ino, -1,
11542 LINUX_S_ISDIR(inode.i_mode));
11543 inode.i_dtime = time(NULL);
11547 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11550 ext2fs_free_mem(&block_buf);
11553 ext2fs_free_mem(&block_buf);
11558 * Check the resize inode to make sure it is sane. We check both for
11559 * the case where on-line resizing is not enabled (in which case the
11560 * resize inode should be cleared) as well as the case where on-line
11561 * resizing is enabled.
11563 static void check_resize_inode(e2fsck_t ctx)
11565 ext2_filsys fs = ctx->fs;
11566 struct ext2_inode inode;
11567 struct problem_context pctx;
11568 int i, j, gdt_off, ind_off;
11569 blk_t blk, pblk, expect;
11570 __u32 *dind_buf = NULL, *ind_buf;
11573 clear_problem_context(&pctx);
11576 * If the resize inode feature isn't set, then
11577 * s_reserved_gdt_blocks must be zero.
11579 if (!(fs->super->s_feature_compat &
11580 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11581 if (fs->super->s_reserved_gdt_blocks) {
11582 pctx.num = fs->super->s_reserved_gdt_blocks;
11583 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11585 fs->super->s_reserved_gdt_blocks = 0;
11586 ext2fs_mark_super_dirty(fs);
11591 /* Read the resize inode */
11592 pctx.ino = EXT2_RESIZE_INO;
11593 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11595 if (fs->super->s_feature_compat &
11596 EXT2_FEATURE_COMPAT_RESIZE_INODE)
11597 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11602 * If the resize inode feature isn't set, check to make sure
11603 * the resize inode is cleared; then we're done.
11605 if (!(fs->super->s_feature_compat &
11606 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11607 for (i=0; i < EXT2_N_BLOCKS; i++) {
11608 if (inode.i_block[i])
11611 if ((i < EXT2_N_BLOCKS) &&
11612 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11613 memset(&inode, 0, sizeof(inode));
11614 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11621 * The resize inode feature is enabled; check to make sure the
11622 * only block in use is the double indirect block
11624 blk = inode.i_block[EXT2_DIND_BLOCK];
11625 for (i=0; i < EXT2_N_BLOCKS; i++) {
11626 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11629 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11630 !(inode.i_mode & LINUX_S_IFREG) ||
11631 (blk < fs->super->s_first_data_block ||
11632 blk >= fs->super->s_blocks_count)) {
11633 resize_inode_invalid:
11634 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11635 memset(&inode, 0, sizeof(inode));
11636 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11638 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11640 if (!(ctx->options & E2F_OPT_READONLY)) {
11641 fs->super->s_state &= ~EXT2_VALID_FS;
11642 ext2fs_mark_super_dirty(fs);
11646 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11647 "resize dind buffer");
11648 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11650 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11652 goto resize_inode_invalid;
11654 gdt_off = fs->desc_blocks;
11655 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11656 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11657 i++, gdt_off++, pblk++) {
11658 gdt_off %= fs->blocksize/4;
11659 if (dind_buf[gdt_off] != pblk)
11660 goto resize_inode_invalid;
11661 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11663 goto resize_inode_invalid;
11665 for (j = 1; j < fs->group_desc_count; j++) {
11666 if (!ext2fs_bg_has_super(fs, j))
11668 expect = pblk + (j * fs->super->s_blocks_per_group);
11669 if (ind_buf[ind_off] != expect)
11670 goto resize_inode_invalid;
11676 ext2fs_free_mem(&dind_buf);
11679 static void check_super_block(e2fsck_t ctx)
11681 ext2_filsys fs = ctx->fs;
11682 blk_t first_block, last_block;
11683 struct ext2_super_block *sb = fs->super;
11684 struct ext2_group_desc *gd;
11685 blk_t blocks_per_group = fs->super->s_blocks_per_group;
11687 int inodes_per_block;
11692 struct problem_context pctx;
11693 __u32 free_blocks = 0, free_inodes = 0;
11695 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11696 ipg_max = inodes_per_block * (blocks_per_group - 4);
11697 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11698 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11699 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11700 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11701 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11703 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11704 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11705 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11706 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11707 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11708 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11710 clear_problem_context(&pctx);
11713 * Verify the super block constants...
11715 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11717 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11719 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11720 MAX_CHECK, 0, sb->s_blocks_count);
11721 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11722 MIN_CHECK | MAX_CHECK, 0,
11723 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11724 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11725 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11726 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11727 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11729 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11730 MIN_CHECK | MAX_CHECK, 8, bpg_max);
11731 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11732 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11733 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11734 MAX_CHECK, 0, sb->s_blocks_count / 2);
11735 check_super_value(ctx, "reserved_gdt_blocks",
11736 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11738 inode_size = EXT2_INODE_SIZE(sb);
11739 check_super_value(ctx, "inode_size",
11740 inode_size, MIN_CHECK | MAX_CHECK,
11741 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11742 if (inode_size & (inode_size - 1)) {
11743 pctx.num = inode_size;
11744 pctx.str = "inode_size";
11745 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11746 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11750 if (!ctx->num_blocks) {
11751 pctx.errcode = e2fsck_get_device_size(ctx);
11752 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11753 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11754 ctx->flags |= E2F_FLAG_ABORT;
11757 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11758 (ctx->num_blocks < sb->s_blocks_count)) {
11759 pctx.blk = sb->s_blocks_count;
11760 pctx.blk2 = ctx->num_blocks;
11761 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11762 ctx->flags |= E2F_FLAG_ABORT;
11768 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11769 pctx.blk = EXT2_BLOCK_SIZE(sb);
11770 pctx.blk2 = EXT2_FRAG_SIZE(sb);
11771 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11772 ctx->flags |= E2F_FLAG_ABORT;
11776 should_be = sb->s_frags_per_group >>
11777 (sb->s_log_block_size - sb->s_log_frag_size);
11778 if (sb->s_blocks_per_group != should_be) {
11779 pctx.blk = sb->s_blocks_per_group;
11780 pctx.blk2 = should_be;
11781 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11782 ctx->flags |= E2F_FLAG_ABORT;
11786 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11787 if (sb->s_first_data_block != should_be) {
11788 pctx.blk = sb->s_first_data_block;
11789 pctx.blk2 = should_be;
11790 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11791 ctx->flags |= E2F_FLAG_ABORT;
11795 should_be = sb->s_inodes_per_group * fs->group_desc_count;
11796 if (sb->s_inodes_count != should_be) {
11797 pctx.ino = sb->s_inodes_count;
11798 pctx.ino2 = should_be;
11799 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11800 sb->s_inodes_count = should_be;
11801 ext2fs_mark_super_dirty(fs);
11806 * Verify the group descriptors....
11808 first_block = sb->s_first_data_block;
11809 last_block = first_block + blocks_per_group;
11811 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11814 if (i == fs->group_desc_count - 1)
11815 last_block = sb->s_blocks_count;
11816 if ((gd->bg_block_bitmap < first_block) ||
11817 (gd->bg_block_bitmap >= last_block)) {
11818 pctx.blk = gd->bg_block_bitmap;
11819 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11820 gd->bg_block_bitmap = 0;
11822 if (gd->bg_block_bitmap == 0) {
11823 ctx->invalid_block_bitmap_flag[i]++;
11824 ctx->invalid_bitmaps++;
11826 if ((gd->bg_inode_bitmap < first_block) ||
11827 (gd->bg_inode_bitmap >= last_block)) {
11828 pctx.blk = gd->bg_inode_bitmap;
11829 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11830 gd->bg_inode_bitmap = 0;
11832 if (gd->bg_inode_bitmap == 0) {
11833 ctx->invalid_inode_bitmap_flag[i]++;
11834 ctx->invalid_bitmaps++;
11836 if ((gd->bg_inode_table < first_block) ||
11837 ((gd->bg_inode_table +
11838 fs->inode_blocks_per_group - 1) >= last_block)) {
11839 pctx.blk = gd->bg_inode_table;
11840 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11841 gd->bg_inode_table = 0;
11843 if (gd->bg_inode_table == 0) {
11844 ctx->invalid_inode_table_flag[i]++;
11845 ctx->invalid_bitmaps++;
11847 free_blocks += gd->bg_free_blocks_count;
11848 free_inodes += gd->bg_free_inodes_count;
11849 first_block += sb->s_blocks_per_group;
11850 last_block += sb->s_blocks_per_group;
11852 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11853 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11854 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11855 ext2fs_unmark_valid(fs);
11859 * Update the global counts from the block group counts. This
11860 * is needed for an experimental patch which eliminates
11861 * locking the entire filesystem when allocating blocks or
11862 * inodes; if the filesystem is not unmounted cleanly, the
11863 * global counts may not be accurate.
11865 if ((free_blocks != sb->s_free_blocks_count) ||
11866 (free_inodes != sb->s_free_inodes_count)) {
11867 if (ctx->options & E2F_OPT_READONLY)
11868 ext2fs_unmark_valid(fs);
11870 sb->s_free_blocks_count = free_blocks;
11871 sb->s_free_inodes_count = free_inodes;
11872 ext2fs_mark_super_dirty(fs);
11876 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11877 (sb->s_free_inodes_count > sb->s_inodes_count))
11878 ext2fs_unmark_valid(fs);
11882 * If we have invalid bitmaps, set the error state of the
11885 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11886 sb->s_state &= ~EXT2_VALID_FS;
11887 ext2fs_mark_super_dirty(fs);
11890 clear_problem_context(&pctx);
11893 * If the UUID field isn't assigned, assign it.
11895 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11896 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11897 uuid_generate(sb->s_uuid);
11898 ext2fs_mark_super_dirty(fs);
11899 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11903 /* FIXME - HURD support?
11904 * For the Hurd, check to see if the filetype option is set,
11905 * since it doesn't support it.
11907 if (!(ctx->options & E2F_OPT_READONLY) &&
11908 fs->super->s_creator_os == EXT2_OS_HURD &&
11909 (fs->super->s_feature_incompat &
11910 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11911 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11912 fs->super->s_feature_incompat &=
11913 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11914 ext2fs_mark_super_dirty(fs);
11919 * If we have any of the compatibility flags set, we need to have a
11920 * revision 1 filesystem. Most kernels will not check the flags on
11921 * a rev 0 filesystem and we may have corruption issues because of
11922 * the incompatible changes to the filesystem.
11924 if (!(ctx->options & E2F_OPT_READONLY) &&
11925 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11926 (fs->super->s_feature_compat ||
11927 fs->super->s_feature_ro_compat ||
11928 fs->super->s_feature_incompat) &&
11929 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11930 ext2fs_update_dynamic_rev(fs);
11931 ext2fs_mark_super_dirty(fs);
11934 check_resize_inode(ctx);
11937 * Clean up any orphan inodes, if present.
11939 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11940 fs->super->s_state &= ~EXT2_VALID_FS;
11941 ext2fs_mark_super_dirty(fs);
11945 * Move the ext3 journal file, if necessary.
11947 e2fsck_move_ext3_journal(ctx);
11951 * swapfs.c --- byte-swap an ext2 filesystem
11954 #ifdef ENABLE_SWAPFS
11956 struct swap_block_struct {
11961 struct ext2_inode *inode;
11965 * This is a helper function for block_iterate. We mark all of the
11966 * indirect and direct blocks as changed, so that block_iterate will
11969 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
11974 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
11976 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
11977 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
11979 sb->errcode = retval;
11980 return BLOCK_ABORT;
11982 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
11984 sb->errcode = retval;
11985 return BLOCK_ABORT;
11988 if (blockcnt >= 0) {
11989 if (blockcnt < EXT2_NDIR_BLOCKS)
11991 return BLOCK_CHANGED;
11993 if (blockcnt == BLOCK_COUNT_IND) {
11994 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
11996 return BLOCK_CHANGED;
11998 if (blockcnt == BLOCK_COUNT_DIND) {
11999 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12001 return BLOCK_CHANGED;
12003 if (blockcnt == BLOCK_COUNT_TIND) {
12004 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12006 return BLOCK_CHANGED;
12008 return BLOCK_CHANGED;
12012 * This function is responsible for byte-swapping all of the indirect,
12013 * block pointers. It is also responsible for byte-swapping directories.
12015 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12016 struct ext2_inode *inode)
12019 struct swap_block_struct sb;
12023 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12026 if (LINUX_S_ISDIR(inode->i_mode))
12029 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12032 bb_error_msg(_("while calling ext2fs_block_iterate"));
12033 ctx->flags |= E2F_FLAG_ABORT;
12037 bb_error_msg(_("while calling iterator function"));
12038 ctx->flags |= E2F_FLAG_ABORT;
12043 static void swap_inodes(e2fsck_t ctx)
12045 ext2_filsys fs = ctx->fs;
12048 ext2_ino_t ino = 1;
12049 char *buf, *block_buf;
12051 struct ext2_inode * inode;
12053 e2fsck_use_inode_shortcuts(ctx, 1);
12055 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12058 bb_error_msg(_("while allocating inode buffer"));
12059 ctx->flags |= E2F_FLAG_ABORT;
12062 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12063 "block interate buffer");
12064 for (group = 0; group < fs->group_desc_count; group++) {
12065 retval = io_channel_read_blk(fs->io,
12066 fs->group_desc[group].bg_inode_table,
12067 fs->inode_blocks_per_group, buf);
12069 bb_error_msg(_("while reading inode table (group %d)"),
12071 ctx->flags |= E2F_FLAG_ABORT;
12074 inode = (struct ext2_inode *) buf;
12075 for (i=0; i < fs->super->s_inodes_per_group;
12076 i++, ino++, inode++) {
12077 ctx->stashed_ino = ino;
12078 ctx->stashed_inode = inode;
12080 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12081 ext2fs_swap_inode(fs, inode, inode, 0);
12084 * Skip deleted files.
12086 if (inode->i_links_count == 0)
12089 if (LINUX_S_ISDIR(inode->i_mode) ||
12090 ((inode->i_block[EXT2_IND_BLOCK] ||
12091 inode->i_block[EXT2_DIND_BLOCK] ||
12092 inode->i_block[EXT2_TIND_BLOCK]) &&
12093 ext2fs_inode_has_valid_blocks(inode)))
12094 swap_inode_blocks(ctx, ino, block_buf, inode);
12096 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12099 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12100 ext2fs_swap_inode(fs, inode, inode, 1);
12102 retval = io_channel_write_blk(fs->io,
12103 fs->group_desc[group].bg_inode_table,
12104 fs->inode_blocks_per_group, buf);
12106 bb_error_msg(_("while writing inode table (group %d)"),
12108 ctx->flags |= E2F_FLAG_ABORT;
12112 ext2fs_free_mem(&buf);
12113 ext2fs_free_mem(&block_buf);
12114 e2fsck_use_inode_shortcuts(ctx, 0);
12115 ext2fs_flush_icache(fs);
12118 #if defined(__powerpc__) && BB_BIG_ENDIAN
12120 * On the PowerPC, the big-endian variant of the ext2 filesystem
12121 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12122 * of each word. Thus a bitmap with only bit 0 set would be, as
12123 * a string of bytes, 00 00 00 01 00 ...
12124 * To cope with this, we byte-reverse each word of a bitmap if
12125 * we have a big-endian filesystem, that is, if we are *not*
12126 * byte-swapping other word-sized numbers.
12128 #define EXT2_BIG_ENDIAN_BITMAPS
12131 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12132 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12134 __u32 *p = (__u32 *) bmap->bitmap;
12135 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12137 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12138 *p = ext2fs_swab32(*p);
12143 #ifdef ENABLE_SWAPFS
12144 static void swap_filesys(e2fsck_t ctx)
12146 ext2_filsys fs = ctx->fs;
12147 if (!(ctx->options & E2F_OPT_PREEN))
12148 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12152 if (fs->super->s_mnt_count) {
12153 fprintf(stderr, _("%s: the filesystem must be freshly "
12154 "checked using fsck\n"
12155 "and not mounted before trying to "
12156 "byte-swap it.\n"), ctx->device_name);
12157 ctx->flags |= E2F_FLAG_ABORT;
12160 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12161 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12162 EXT2_FLAG_SWAP_BYTES_WRITE);
12163 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12165 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12166 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12169 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12171 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12172 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12173 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12174 EXT2_FLAG_SWAP_BYTES_WRITE);
12176 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12177 e2fsck_read_bitmaps(ctx);
12178 ext2fs_swap_bitmap(fs->inode_map);
12179 ext2fs_swap_bitmap(fs->block_map);
12180 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12182 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12184 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12186 #endif /* ENABLE_SWAPFS */
12191 * util.c --- miscellaneous utilities
12195 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12196 const char *description)
12201 ret = xzalloc(size);
12205 static char *string_copy(const char *str, int len)
12213 ret = xmalloc(len+1);
12214 strncpy(ret, str, len);
12219 #ifndef HAVE_CONIO_H
12220 static int read_a_char(void)
12227 if (e2fsck_global_ctx &&
12228 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12231 r = read(0, &c, 1);
12241 static int ask_yn(const char * string, int def)
12244 const char *defstr;
12245 static const char short_yes[] = "yY";
12246 static const char short_no[] = "nN";
12248 #ifdef HAVE_TERMIOS_H
12249 struct termios termios, tmp;
12251 tcgetattr (0, &termios);
12253 tmp.c_lflag &= ~(ICANON | ECHO);
12254 tmp.c_cc[VMIN] = 1;
12255 tmp.c_cc[VTIME] = 0;
12256 tcsetattr_stdin_TCSANOW(&tmp);
12265 printf("%s%s? ", string, defstr);
12268 if ((c = read_a_char()) == EOF)
12271 #ifdef HAVE_TERMIOS_H
12272 tcsetattr_stdin_TCSANOW(&termios);
12274 if (e2fsck_global_ctx &&
12275 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12277 longjmp(e2fsck_global_ctx->abort_loc, 1);
12279 puts(_("cancelled!\n"));
12282 if (strchr(short_yes, (char) c)) {
12286 else if (strchr(short_no, (char) c)) {
12290 else if ((c == ' ' || c == '\n') && (def != -1))
12297 #ifdef HAVE_TERMIOS_H
12298 tcsetattr_stdin_TCSANOW(&termios);
12303 int ask (e2fsck_t ctx, const char * string, int def)
12305 if (ctx->options & E2F_OPT_NO) {
12306 printf(_("%s? no\n\n"), string);
12309 if (ctx->options & E2F_OPT_YES) {
12310 printf(_("%s? yes\n\n"), string);
12313 if (ctx->options & E2F_OPT_PREEN) {
12314 printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
12317 return ask_yn(string, def);
12320 void e2fsck_read_bitmaps(e2fsck_t ctx)
12322 ext2_filsys fs = ctx->fs;
12325 if (ctx->invalid_bitmaps) {
12326 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12328 bb_error_msg_and_die(0);
12331 ehandler_operation(_("reading inode and block bitmaps"));
12332 retval = ext2fs_read_bitmaps(fs);
12333 ehandler_operation(0);
12335 bb_error_msg(_("while retrying to read bitmaps for %s"),
12337 bb_error_msg_and_die(0);
12341 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12343 ext2_filsys fs = ctx->fs;
12346 if (ext2fs_test_bb_dirty(fs)) {
12347 ehandler_operation(_("writing block bitmaps"));
12348 retval = ext2fs_write_block_bitmap(fs);
12349 ehandler_operation(0);
12351 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12353 bb_error_msg_and_die(0);
12357 if (ext2fs_test_ib_dirty(fs)) {
12358 ehandler_operation(_("writing inode bitmaps"));
12359 retval = ext2fs_write_inode_bitmap(fs);
12360 ehandler_operation(0);
12362 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12364 bb_error_msg_and_die(0);
12369 void preenhalt(e2fsck_t ctx)
12371 ext2_filsys fs = ctx->fs;
12373 if (!(ctx->options & E2F_OPT_PREEN))
12375 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12376 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12379 fs->super->s_state |= EXT2_ERROR_FS;
12380 ext2fs_mark_super_dirty(fs);
12383 exit(EXIT_UNCORRECTED);
12386 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12387 struct ext2_inode * inode, const char *proc)
12391 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12393 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12394 bb_error_msg_and_die(0);
12398 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12399 struct ext2_inode * inode, int bufsize,
12404 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12406 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12407 bb_error_msg_and_die(0);
12411 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12412 struct ext2_inode * inode, const char *proc)
12416 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12418 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12419 bb_error_msg_and_die(0);
12423 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12424 io_manager manager)
12426 struct ext2_super_block *sb;
12427 io_channel io = NULL;
12430 blk_t superblock, ret_sb = 8193;
12432 if (fs && fs->super) {
12433 ret_sb = (fs->super->s_blocks_per_group +
12434 fs->super->s_first_data_block);
12436 ctx->superblock = ret_sb;
12437 ctx->blocksize = fs->blocksize;
12443 if (ctx->blocksize) {
12444 ret_sb = ctx->blocksize * 8;
12445 if (ctx->blocksize == 1024)
12447 ctx->superblock = ret_sb;
12450 ctx->superblock = ret_sb;
12451 ctx->blocksize = 1024;
12454 if (!name || !manager)
12457 if (manager->open(name, 0, &io) != 0)
12460 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12462 sb = (struct ext2_super_block *) buf;
12464 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12465 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
12466 superblock = blocksize*8;
12467 if (blocksize == 1024)
12469 io_channel_set_blksize(io, blocksize);
12470 if (io_channel_read_blk(io, superblock,
12471 -SUPERBLOCK_SIZE, buf))
12474 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12475 ext2fs_swap_super(sb);
12477 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12478 ret_sb = superblock;
12480 ctx->superblock = superblock;
12481 ctx->blocksize = blocksize;
12489 io_channel_close(io);
12490 ext2fs_free_mem(&buf);
12496 * This function runs through the e2fsck passes and calls them all,
12497 * returning restart, abort, or cancel as necessary...
12499 typedef void (*pass_t)(e2fsck_t ctx);
12501 static const pass_t e2fsck_passes[] = {
12502 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12505 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12507 static int e2fsck_run(e2fsck_t ctx)
12510 pass_t e2fsck_pass;
12512 if (setjmp(ctx->abort_loc)) {
12513 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12514 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12516 ctx->flags |= E2F_FLAG_SETJMP_OK;
12518 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12519 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12523 (void) (ctx->progress)(ctx, 0, 0, 0);
12525 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12527 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12528 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12534 * unix.c - The unix-specific code for e2fsck
12538 /* Command line options */
12540 #ifdef ENABLE_SWAPFS
12541 static int normalize_swapfs;
12543 static int cflag; /* check disk */
12544 static int show_version_only;
12545 static int verbose;
12547 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12549 static void show_stats(e2fsck_t ctx)
12551 ext2_filsys fs = ctx->fs;
12552 int inodes, inodes_used, blocks, blocks_used;
12554 int num_files, num_links;
12557 dir_links = 2 * ctx->fs_directory_count - 1;
12558 num_files = ctx->fs_total_count - dir_links;
12559 num_links = ctx->fs_links_count - dir_links;
12560 inodes = fs->super->s_inodes_count;
12561 inodes_used = (fs->super->s_inodes_count -
12562 fs->super->s_free_inodes_count);
12563 blocks = fs->super->s_blocks_count;
12564 blocks_used = (fs->super->s_blocks_count -
12565 fs->super->s_free_blocks_count);
12567 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12568 frag_percent = (frag_percent + 5) / 10;
12571 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12572 ctx->device_name, inodes_used, inodes,
12573 frag_percent / 10, frag_percent % 10,
12574 blocks_used, blocks);
12577 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12578 100 * inodes_used / inodes);
12579 printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12580 P_E2("", "s", ctx->fs_fragmented),
12581 frag_percent / 10, frag_percent % 10);
12582 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12583 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12584 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12585 (int) ((long long) 100 * blocks_used / blocks));
12586 printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12587 printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12588 printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12589 printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12590 printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12591 printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12592 printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12593 printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12594 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12595 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12596 printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12599 static void check_mount(e2fsck_t ctx)
12604 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12605 &ctx->mount_flags);
12607 bb_error_msg(_("while determining whether %s is mounted"),
12608 ctx->filesystem_name);
12613 * If the filesystem isn't mounted, or it's the root filesystem
12614 * and it's mounted read-only, then everything's fine.
12616 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12617 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12618 (ctx->mount_flags & EXT2_MF_READONLY)))
12621 if (ctx->options & E2F_OPT_READONLY) {
12622 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
12626 printf(_("%s is mounted. "), ctx->filesystem_name);
12627 if (!ctx->interactive)
12628 bb_error_msg_and_die(_("can't continue, aborting"));
12629 printf(_("\n\n\007\007\007\007WARNING!!! "
12630 "Running e2fsck on a mounted filesystem may cause\n"
12631 "SEVERE filesystem damage.\007\007\007\n\n"));
12632 cont = ask_yn(_("Do you really want to continue"), -1);
12634 printf(_("check aborted.\n"));
12639 static int is_on_batt(void)
12643 char tmp[80], tmp2[80], fname[80];
12644 unsigned int acflag;
12647 f = fopen_for_read("/proc/apm");
12649 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12652 return (acflag != 1);
12654 d = opendir("/proc/acpi/ac_adapter");
12656 while ((de=readdir(d)) != NULL) {
12657 if (!strncmp(".", de->d_name, 1))
12659 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12661 f = fopen_for_read(fname);
12664 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12667 if (strncmp(tmp, "off-line", 8) == 0) {
12678 * This routine checks to see if a filesystem can be skipped; if so,
12679 * it will exit with EXIT_OK. Under some conditions it will print a
12680 * message explaining why a check is being forced.
12682 static void check_if_skip(e2fsck_t ctx)
12684 ext2_filsys fs = ctx->fs;
12685 const char *reason = NULL;
12686 unsigned int reason_arg = 0;
12688 int batt = is_on_batt();
12689 time_t now = time(NULL);
12691 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12694 if ((fs->super->s_state & EXT2_ERROR_FS) ||
12695 !ext2fs_test_valid(fs))
12696 reason = _(" contains a file system with errors");
12697 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12698 reason = _(" was not cleanly unmounted");
12699 else if ((fs->super->s_max_mnt_count > 0) &&
12700 (fs->super->s_mnt_count >=
12701 (unsigned) fs->super->s_max_mnt_count)) {
12702 reason = _(" has been mounted %u times without being checked");
12703 reason_arg = fs->super->s_mnt_count;
12704 if (batt && (fs->super->s_mnt_count <
12705 (unsigned) fs->super->s_max_mnt_count*2))
12707 } else if (fs->super->s_checkinterval &&
12708 ((now - fs->super->s_lastcheck) >=
12709 fs->super->s_checkinterval)) {
12710 reason = _(" has gone %u days without being checked");
12711 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12712 if (batt && ((now - fs->super->s_lastcheck) <
12713 fs->super->s_checkinterval*2))
12717 fputs(ctx->device_name, stdout);
12718 printf(reason, reason_arg);
12719 fputs(_(", check forced.\n"), stdout);
12722 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12723 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12724 fs->super->s_inodes_count,
12725 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12726 fs->super->s_blocks_count);
12727 next_check = 100000;
12728 if (fs->super->s_max_mnt_count > 0) {
12729 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12730 if (next_check <= 0)
12733 if (fs->super->s_checkinterval &&
12734 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12736 if (next_check <= 5) {
12737 if (next_check == 1)
12738 fputs(_(" (check after next mount)"), stdout);
12740 printf(_(" (check in %ld mounts)"), next_check);
12745 e2fsck_free_context(ctx);
12750 * For completion notice
12752 struct percent_tbl {
12756 static const struct percent_tbl e2fsck_tbl = {
12757 5, { 0, 70, 90, 92, 95, 100 }
12760 static char bar[128], spaces[128];
12762 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12769 if (pass > tbl->max_pass || max == 0)
12771 percent = ((float) curr) / ((float) max);
12772 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12773 + tbl->table[pass-1]);
12776 void e2fsck_clear_progbar(e2fsck_t ctx)
12778 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12781 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12784 ctx->flags &= ~E2F_FLAG_PROG_BAR;
12787 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12788 unsigned int dpynum)
12790 static const char spinner[] = "\\|/-";
12797 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12801 * Calculate the new progress position. If the
12802 * percentage hasn't changed, then we skip out right
12805 fixed_percent = (int) ((10 * percent) + 0.5);
12806 if (ctx->progress_last_percent == fixed_percent)
12808 ctx->progress_last_percent = fixed_percent;
12811 * If we've already updated the spinner once within
12812 * the last 1/8th of a second, no point doing it
12815 gettimeofday(&tv, NULL);
12816 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12817 if ((tick == ctx->progress_last_time) &&
12818 (fixed_percent != 0) && (fixed_percent != 1000))
12820 ctx->progress_last_time = tick;
12823 * Advance the spinner, and note that the progress bar
12824 * will be on the screen
12826 ctx->progress_pos = (ctx->progress_pos+1) & 3;
12827 ctx->flags |= E2F_FLAG_PROG_BAR;
12829 dpywidth = 66 - strlen(label);
12830 dpywidth = 8 * (dpywidth / 8);
12834 i = ((percent * dpywidth) + 50) / 100;
12835 printf("%s%s: |%s%s", ctx->start_meta, label,
12836 bar + (sizeof(bar) - (i+1)),
12837 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12838 if (fixed_percent == 1000)
12841 bb_putchar(spinner[ctx->progress_pos & 3]);
12842 printf(" %4.1f%% ", percent);
12844 printf("%u\r", dpynum);
12846 fputs(" \r", stdout);
12847 fputs(ctx->stop_meta, stdout);
12849 if (fixed_percent == 1000)
12850 e2fsck_clear_progbar(ctx);
12856 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12857 unsigned long cur, unsigned long max)
12865 if (ctx->progress_fd) {
12866 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12867 xwrite_str(ctx->progress_fd, buf);
12869 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12870 e2fsck_simple_progress(ctx, ctx->device_name,
12876 static void reserve_stdio_fds(void)
12881 fd = open(bb_dev_null, O_RDWR);
12885 fprintf(stderr, _("ERROR: Cannot open "
12886 "/dev/null (%s)\n"),
12894 static void signal_progress_on(int sig FSCK_ATTR((unused)))
12896 e2fsck_t ctx = e2fsck_global_ctx;
12901 ctx->progress = e2fsck_update_progress;
12902 ctx->progress_fd = 0;
12905 static void signal_progress_off(int sig FSCK_ATTR((unused)))
12907 e2fsck_t ctx = e2fsck_global_ctx;
12912 e2fsck_clear_progbar(ctx);
12916 static void signal_cancel(int sig FSCK_ATTR((unused)))
12918 e2fsck_t ctx = e2fsck_global_ctx;
12921 exit(FSCK_CANCELED);
12923 ctx->flags |= E2F_FLAG_CANCEL;
12926 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12928 char *buf, *token, *next, *p, *arg;
12930 int extended_usage = 0;
12932 buf = string_copy(opts, 0);
12933 for (token = buf; token && *token; token = next) {
12934 p = strchr(token, ',');
12940 arg = strchr(token, '=');
12945 if (strcmp(token, "ea_ver") == 0) {
12950 ea_ver = strtoul(arg, &p, 0);
12952 ((ea_ver != 1) && (ea_ver != 2))) {
12954 _("Invalid EA version.\n"));
12958 ctx->ext_attr_ver = ea_ver;
12960 fprintf(stderr, _("Unknown extended option: %s\n"),
12965 if (extended_usage) {
12966 bb_error_msg_and_die(
12967 "Extended options are separated by commas, "
12968 "and may take an argument which\n"
12969 "is set off by an equals ('=') sign. "
12970 "Valid extended options are:\n"
12971 "\tea_ver=<ea_version (1 or 2)>\n\n");
12976 static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx)
12982 struct sigaction sa;
12983 char *extended_opts = NULL;
12985 retval = e2fsck_allocate_context(&ctx);
12991 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
12992 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
12993 if (isatty(0) && isatty(1)) {
12994 ctx->interactive = 1;
12996 ctx->start_meta[0] = '\001';
12997 ctx->stop_meta[0] = '\002';
12999 memset(bar, '=', sizeof(bar)-1);
13000 memset(spaces, ' ', sizeof(spaces)-1);
13001 blkid_get_cache(&ctx->blkid, NULL);
13004 ctx->program_name = *argv;
13006 ctx->program_name = "e2fsck";
13007 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13010 ctx->progress = e2fsck_update_progress;
13011 ctx->progress_fd = atoi(optarg);
13012 if (!ctx->progress_fd)
13014 /* Validate the file descriptor to avoid disasters */
13015 fd = dup(ctx->progress_fd);
13018 _("Error validating file descriptor %d: %s\n"),
13020 error_message(errno));
13021 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13026 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13029 extended_opts = optarg;
13033 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13035 bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
13037 ctx->options |= E2F_OPT_PREEN;
13040 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13042 ctx->options |= E2F_OPT_NO;
13045 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13047 ctx->options |= E2F_OPT_YES;
13050 /* FIXME - This needs to go away in a future path - will change binary */
13051 fprintf(stderr, _("The -t option is not "
13052 "supported on this version of e2fsck.\n"));
13056 ctx->options |= E2F_OPT_WRITECHECK;
13057 ctx->options |= E2F_OPT_CHECKBLOCKS;
13060 /* What we do by default, anyway! */
13063 ctx->use_superblock = atoi(optarg);
13064 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13067 ctx->blocksize = atoi(optarg);
13070 ctx->inode_buffer_blocks = atoi(optarg);
13073 ctx->journal_name = string_copy(optarg, 0);
13076 ctx->process_inode_size = atoi(optarg);
13079 ctx->options |= E2F_OPT_DEBUG;
13082 ctx->options |= E2F_OPT_FORCE;
13091 show_version_only = 1;
13094 ctx->device_name = optarg;
13096 #ifdef ENABLE_SWAPFS
13098 normalize_swapfs = 1;
13105 fprintf(stderr, _("Byte-swapping filesystems "
13106 "not compiled in this version "
13113 if (show_version_only)
13115 if (optind != argc - 1)
13117 if ((ctx->options & E2F_OPT_NO) &&
13118 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13119 ctx->options |= E2F_OPT_READONLY;
13120 ctx->io_options = strchr(argv[optind], '?');
13121 if (ctx->io_options)
13122 *ctx->io_options++ = 0;
13123 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13124 if (!ctx->filesystem_name) {
13125 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13126 bb_error_msg_and_die(0);
13129 parse_extended_opts(ctx, extended_opts);
13132 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13134 bb_error_msg(_("while opening %s for flushing"),
13135 ctx->filesystem_name);
13136 bb_error_msg_and_die(0);
13138 if ((retval = ext2fs_sync_device(fd, 1))) {
13139 bb_error_msg(_("while trying to flush %s"),
13140 ctx->filesystem_name);
13141 bb_error_msg_and_die(0);
13145 #ifdef ENABLE_SWAPFS
13146 if (swapfs && cflag) {
13147 fprintf(stderr, _("Incompatible options not "
13148 "allowed when byte-swapping.\n"));
13153 * Set up signal action
13155 memset(&sa, 0, sizeof(struct sigaction));
13156 sa.sa_handler = signal_cancel;
13157 sigaction(SIGINT, &sa, 0);
13158 sigaction(SIGTERM, &sa, 0);
13160 sa.sa_flags = SA_RESTART;
13162 e2fsck_global_ctx = ctx;
13163 sa.sa_handler = signal_progress_on;
13164 sigaction(SIGUSR1, &sa, 0);
13165 sa.sa_handler = signal_progress_off;
13166 sigaction(SIGUSR2, &sa, 0);
13168 /* Update our PATH to include /sbin if we need to run badblocks */
13170 e2fs_set_sbin_path();
13174 static const char my_ver_string[] = E2FSPROGS_VERSION;
13175 static const char my_ver_date[] = E2FSPROGS_DATE;
13177 int e2fsck_main (int argc, char **argv);
13178 int e2fsck_main (int argc, char **argv)
13181 int exit_value = EXIT_OK;
13182 ext2_filsys fs = 0;
13184 struct ext2_super_block *sb;
13185 const char *lib_ver_date;
13186 int my_ver, lib_ver;
13188 struct problem_context pctx;
13189 int flags, run_result;
13191 clear_problem_context(&pctx);
13193 my_ver = ext2fs_parse_version_string(my_ver_string);
13194 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13195 if (my_ver > lib_ver) {
13196 fprintf( stderr, _("Error: ext2fs library version "
13197 "out of date!\n"));
13198 show_version_only++;
13201 retval = PRS(argc, argv, &ctx);
13203 bb_error_msg(_("while trying to initialize program"));
13206 reserve_stdio_fds();
13208 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13209 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13212 if (show_version_only) {
13213 fprintf(stderr, _("\tUsing %s, %s\n"),
13214 error_message(EXT2_ET_BASE), lib_ver_date);
13220 if (!(ctx->options & E2F_OPT_PREEN) &&
13221 !(ctx->options & E2F_OPT_NO) &&
13222 !(ctx->options & E2F_OPT_YES)) {
13223 if (!ctx->interactive)
13224 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13226 ctx->superblock = ctx->use_superblock;
13228 #ifdef CONFIG_TESTIO_DEBUG
13229 io_ptr = test_io_manager;
13230 test_io_backing_manager = unix_io_manager;
13232 io_ptr = unix_io_manager;
13235 if ((ctx->options & E2F_OPT_READONLY) == 0)
13236 flags |= EXT2_FLAG_RW;
13238 if (ctx->superblock && ctx->blocksize) {
13239 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13240 flags, ctx->superblock, ctx->blocksize,
13242 } else if (ctx->superblock) {
13244 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13245 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13246 retval = ext2fs_open2(ctx->filesystem_name,
13247 ctx->io_options, flags,
13248 ctx->superblock, blocksize,
13254 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13255 flags, 0, 0, io_ptr, &fs);
13256 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13257 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13258 ((retval == EXT2_ET_BAD_MAGIC) ||
13259 ((retval == 0) && ext2fs_check_desc(fs)))) {
13260 if (!fs || (fs->group_desc_count > 1)) {
13261 printf(_("%s trying backup blocks...\n"),
13262 retval ? _("Couldn't find ext2 superblock,") :
13263 _("Group descriptors look bad..."));
13264 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13271 bb_error_msg(_("while trying to open %s"),
13272 ctx->filesystem_name);
13273 if (retval == EXT2_ET_REV_TOO_HIGH) {
13274 printf(_("The filesystem revision is apparently "
13275 "too high for this version of e2fsck.\n"
13276 "(Or the filesystem superblock "
13277 "is corrupt)\n\n"));
13278 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13279 } else if (retval == EXT2_ET_SHORT_READ)
13280 printf(_("Could this be a zero-length partition?\n"));
13281 else if ((retval == EPERM) || (retval == EACCES))
13282 printf(_("You must have %s access to the "
13283 "filesystem or be root\n"),
13284 (ctx->options & E2F_OPT_READONLY) ?
13286 else if (retval == ENXIO)
13287 printf(_("Possibly non-existent or swap device?\n"));
13289 else if (retval == EROFS)
13290 printf(_("Disk write-protected; use the -n option "
13291 "to do a read-only\n"
13292 "check of the device.\n"));
13295 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13296 bb_error_msg_and_die(0);
13299 fs->priv_data = ctx;
13301 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13302 bb_error_msg(_("while trying to open %s"),
13303 ctx->filesystem_name);
13305 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13309 * Set the device name, which is used whenever we print error
13310 * or informational messages to the user.
13312 if (ctx->device_name == 0 &&
13313 (sb->s_volume_name[0] != 0)) {
13314 ctx->device_name = string_copy(sb->s_volume_name,
13315 sizeof(sb->s_volume_name));
13317 if (ctx->device_name == 0)
13318 ctx->device_name = ctx->filesystem_name;
13321 * Make sure the ext3 superblock fields are consistent.
13323 retval = e2fsck_check_ext3_journal(ctx);
13325 bb_error_msg(_("while checking ext3 journal for %s"),
13327 bb_error_msg_and_die(0);
13331 * Check to see if we need to do ext3-style recovery. If so,
13332 * do it, and then restart the fsck.
13334 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13335 if (ctx->options & E2F_OPT_READONLY) {
13336 printf(_("Warning: skipping journal recovery "
13337 "because doing a read-only filesystem "
13339 io_channel_flush(ctx->fs->io);
13341 if (ctx->flags & E2F_FLAG_RESTARTED) {
13343 * Whoops, we attempted to run the
13344 * journal twice. This should never
13345 * happen, unless the hardware or
13346 * device driver is being bogus.
13348 bb_error_msg(_("can't set superblock flags on %s"), ctx->device_name);
13349 bb_error_msg_and_die(0);
13351 retval = e2fsck_run_ext3_journal(ctx);
13353 bb_error_msg(_("while recovering ext3 journal of %s"),
13355 bb_error_msg_and_die(0);
13357 ext2fs_close(ctx->fs);
13359 ctx->flags |= E2F_FLAG_RESTARTED;
13365 * Check for compatibility with the feature sets. We need to
13366 * be more stringent than ext2fs_open().
13368 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13369 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13370 bb_error_msg("(%s)", ctx->device_name);
13373 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13374 bb_error_msg("(%s)", ctx->device_name);
13377 #ifdef ENABLE_COMPRESSION
13378 /* FIXME - do we support this at all? */
13379 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13380 bb_error_msg(_("warning: compression support is experimental"));
13382 #ifndef ENABLE_HTREE
13383 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13384 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13385 "but filesystem %s has HTREE directories."),
13392 * If the user specified a specific superblock, presumably the
13393 * master superblock has been trashed. So we mark the
13394 * superblock as dirty, so it can be written out.
13396 if (ctx->superblock &&
13397 !(ctx->options & E2F_OPT_READONLY))
13398 ext2fs_mark_super_dirty(fs);
13401 * We only update the master superblock because (a) paranoia;
13402 * we don't want to corrupt the backup superblocks, and (b) we
13403 * don't need to update the mount count and last checked
13404 * fields in the backup superblock (the kernel doesn't
13405 * update the backup superblocks anyway).
13407 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13409 ehandler_init(fs->io);
13411 if (ctx->superblock)
13412 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13413 ext2fs_mark_valid(fs);
13414 check_super_block(ctx);
13415 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13416 bb_error_msg_and_die(0);
13417 check_if_skip(ctx);
13418 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13419 bb_error_msg_and_die(0);
13420 #ifdef ENABLE_SWAPFS
13422 #ifdef WORDS_BIGENDIAN
13423 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13425 #define NATIVE_FLAG 0
13429 if (normalize_swapfs) {
13430 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13431 fprintf(stderr, _("%s: Filesystem byte order "
13432 "already normalized.\n"), ctx->device_name);
13433 bb_error_msg_and_die(0);
13438 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13439 bb_error_msg_and_die(0);
13444 * Mark the system as valid, 'til proven otherwise
13446 ext2fs_mark_valid(fs);
13448 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13450 bb_error_msg(_("while reading bad blocks inode"));
13452 printf(_("This doesn't bode well,"
13453 " but we'll try to go on...\n"));
13456 run_result = e2fsck_run(ctx);
13457 e2fsck_clear_progbar(ctx);
13458 if (run_result == E2F_FLAG_RESTART) {
13459 printf(_("Restarting e2fsck from the beginning...\n"));
13460 retval = e2fsck_reset_context(ctx);
13462 bb_error_msg(_("while resetting context"));
13463 bb_error_msg_and_die(0);
13468 if (run_result & E2F_FLAG_CANCEL) {
13469 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13470 ctx->device_name : ctx->filesystem_name);
13471 exit_value |= FSCK_CANCELED;
13473 if (run_result & E2F_FLAG_ABORT)
13474 bb_error_msg_and_die(_("aborted"));
13477 if (ext2fs_test_changed(fs)) {
13478 exit_value |= EXIT_NONDESTRUCT;
13479 if (!(ctx->options & E2F_OPT_PREEN))
13480 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13482 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13483 printf(_("%s: ***** REBOOT LINUX *****\n"),
13485 exit_value |= EXIT_DESTRUCT;
13488 if (!ext2fs_test_valid(fs)) {
13489 printf(_("\n%s: ********** WARNING: Filesystem still has "
13490 "errors **********\n\n"), ctx->device_name);
13491 exit_value |= EXIT_UNCORRECTED;
13492 exit_value &= ~EXIT_NONDESTRUCT;
13494 if (exit_value & FSCK_CANCELED)
13495 exit_value &= ~EXIT_NONDESTRUCT;
13498 if (!(ctx->options & E2F_OPT_READONLY)) {
13499 if (ext2fs_test_valid(fs)) {
13500 if (!(sb->s_state & EXT2_VALID_FS))
13501 exit_value |= EXIT_NONDESTRUCT;
13502 sb->s_state = EXT2_VALID_FS;
13504 sb->s_state &= ~EXT2_VALID_FS;
13505 sb->s_mnt_count = 0;
13506 sb->s_lastcheck = time(NULL);
13507 ext2fs_mark_super_dirty(fs);
13511 e2fsck_write_bitmaps(ctx);
13515 free(ctx->filesystem_name);
13516 free(ctx->journal_name);
13517 e2fsck_free_context(ctx);