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 tarball for details.
32 #include "e2fsck.h" /*Put all of our defines here to clean things up*/
38 * Procedure declarations
41 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
44 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
47 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
48 ext2_ino_t ino, char *buf);
51 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
52 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
53 int num, int gauranteed_size);
54 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
55 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
59 static void e2fsck_rehash_directories(e2fsck_t ctx);
62 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
63 const char *description);
64 static int ask(e2fsck_t ctx, const char * string, int def);
65 static void e2fsck_read_bitmaps(e2fsck_t ctx);
66 static void preenhalt(e2fsck_t ctx);
67 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
68 struct ext2_inode * inode, const char * proc);
69 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
70 struct ext2_inode * inode, const char * proc);
71 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
72 const char *name, io_manager manager);
75 static void e2fsck_clear_progbar(e2fsck_t ctx);
76 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
77 float percent, unsigned int dpynum);
81 * problem.h --- e2fsck problem error codes
84 typedef __u32 problem_t;
86 struct problem_context {
88 ext2_ino_t ino, ino2, dir;
89 struct ext2_inode *inode;
90 struct ext2_dir_entry *dirent;
100 * Function declarations
102 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
103 static int end_problem_latch(e2fsck_t ctx, int mask);
104 static int set_latch_flags(int mask, int setflags, int clearflags);
105 static void clear_problem_context(struct problem_context *ctx);
108 * Dictionary Abstract Data Type
109 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
111 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
119 * Blurb for inclusion into C++ translation units
122 typedef unsigned long dictcount_t;
123 #define DICTCOUNT_T_MAX ULONG_MAX
126 * The dictionary is implemented as a red-black tree
129 typedef enum { dnode_red, dnode_black } dnode_color_t;
131 typedef struct dnode_t {
132 struct dnode_t *dict_left;
133 struct dnode_t *dict_right;
134 struct dnode_t *dict_parent;
135 dnode_color_t dict_color;
136 const void *dict_key;
140 typedef int (*dict_comp_t)(const void *, const void *);
141 typedef void (*dnode_free_t)(dnode_t *);
143 typedef struct dict_t {
144 dnode_t dict_nilnode;
145 dictcount_t dict_nodecount;
146 dictcount_t dict_maxcount;
147 dict_comp_t dict_compare;
148 dnode_free_t dict_freenode;
152 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
154 typedef struct dict_load_t {
155 dict_t *dict_dictptr;
156 dnode_t dict_nilnode;
159 #define dict_count(D) ((D)->dict_nodecount)
160 #define dnode_get(N) ((N)->dict_data)
161 #define dnode_getkey(N) ((N)->dict_key)
166 * Compatibility header file for e2fsck which should be included
167 * instead of linux/jfs.h
169 * Copyright (C) 2000 Stephen C. Tweedie
173 * Pull in the definition of the e2fsck context structure
189 #define K_DEV_JOURNAL 2
191 #define lock_buffer(bh) do {} while (0)
192 #define unlock_buffer(bh) do {} while (0)
193 #define buffer_req(bh) 1
194 #define do_readahead(journal, start) do {} while (0)
196 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
202 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
205 * We use the standard libext2fs portability tricks for inline
209 static kmem_cache_t * do_cache_create(int len)
211 kmem_cache_t *new_cache;
213 new_cache = xmalloc(sizeof(*new_cache));
214 new_cache->object_length = len;
218 static void do_cache_destroy(kmem_cache_t *cache)
225 * Dictionary Abstract Data Type
230 * These macros provide short convenient names for structure members,
231 * which are embellished with dict_ prefixes so that they are
232 * properly confined to the documented namespace. It's legal for a
233 * program which uses dict to define, for instance, a macro called ``parent''.
234 * Such a macro would interfere with the dnode_t struct definition.
235 * In general, highly portable and reusable C modules which expose their
236 * structures need to confine structure member names to well-defined spaces.
237 * The resulting identifiers aren't necessarily convenient to use, nor
238 * readable, in the implementation, however!
241 #define left dict_left
242 #define right dict_right
243 #define parent dict_parent
244 #define color dict_color
246 #define data dict_data
248 #define nilnode dict_nilnode
249 #define maxcount dict_maxcount
250 #define compare dict_compare
251 #define dupes dict_dupes
253 #define dict_root(D) ((D)->nilnode.left)
254 #define dict_nil(D) (&(D)->nilnode)
256 static void dnode_free(dnode_t *node);
259 * Perform a ``left rotation'' adjustment on the tree. The given node P and
260 * its right child C are rearranged so that the P instead becomes the left
261 * child of C. The left subtree of C is inherited as the new right subtree
262 * for P. The ordering of the keys within the tree is thus preserved.
265 static void rotate_left(dnode_t *upper)
267 dnode_t *lower, *lowleft, *upparent;
269 lower = upper->right;
270 upper->right = lowleft = lower->left;
271 lowleft->parent = upper;
273 lower->parent = upparent = upper->parent;
275 /* don't need to check for root node here because root->parent is
276 the sentinel nil node, and root->parent->left points back to root */
278 if (upper == upparent->left) {
279 upparent->left = lower;
281 assert (upper == upparent->right);
282 upparent->right = lower;
286 upper->parent = lower;
290 * This operation is the ``mirror'' image of rotate_left. It is
291 * the same procedure, but with left and right interchanged.
294 static void rotate_right(dnode_t *upper)
296 dnode_t *lower, *lowright, *upparent;
299 upper->left = lowright = lower->right;
300 lowright->parent = upper;
302 lower->parent = upparent = upper->parent;
304 if (upper == upparent->right) {
305 upparent->right = lower;
307 assert (upper == upparent->left);
308 upparent->left = lower;
311 lower->right = upper;
312 upper->parent = lower;
316 * Do a postorder traversal of the tree rooted at the specified
317 * node and free everything under it. Used by dict_free().
320 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
324 free_nodes(dict, node->left, nil);
325 free_nodes(dict, node->right, nil);
326 dict->dict_freenode(node);
330 * Verify that the tree contains the given node. This is done by
331 * traversing all of the nodes and comparing their pointers to the
332 * given pointer. Returns 1 if the node is found, otherwise
333 * returns zero. It is intended for debugging purposes.
336 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
340 || verify_dict_has_node(nil, root->left, node)
341 || verify_dict_has_node(nil, root->right, node);
348 * Select a different set of node allocator routines.
351 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
353 assert(dict_count(dict) == 0);
354 dict->dict_freenode = fr;
358 * Free all the nodes in the dictionary by using the dictionary's
359 * installed free routine. The dictionary is emptied.
362 static void dict_free_nodes(dict_t *dict)
364 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
365 free_nodes(dict, root, nil);
366 dict->dict_nodecount = 0;
367 dict->nilnode.left = &dict->nilnode;
368 dict->nilnode.right = &dict->nilnode;
372 * Initialize a user-supplied dictionary object.
375 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
377 dict->compare = comp;
378 dict->dict_freenode = dnode_free;
379 dict->dict_nodecount = 0;
380 dict->maxcount = maxcount;
381 dict->nilnode.left = &dict->nilnode;
382 dict->nilnode.right = &dict->nilnode;
383 dict->nilnode.parent = &dict->nilnode;
384 dict->nilnode.color = dnode_black;
390 * Locate a node in the dictionary having the given key.
391 * If the node is not found, a null a pointer is returned (rather than
392 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
393 * located node is returned.
396 static dnode_t *dict_lookup(dict_t *dict, const void *key)
398 dnode_t *root = dict_root(dict);
399 dnode_t *nil = dict_nil(dict);
403 /* simple binary search adapted for trees that contain duplicate keys */
405 while (root != nil) {
406 result = dict->compare(key, root->key);
412 if (!dict->dupes) { /* no duplicates, return match */
414 } else { /* could be dupes, find leftmost one */
418 while (root != nil && dict->compare(key, root->key))
420 } while (root != nil);
430 * Insert a node into the dictionary. The node should have been
431 * initialized with a data field. All other fields are ignored.
432 * The behavior is undefined if the user attempts to insert into
433 * a dictionary that is already full (for which the dict_isfull()
434 * function returns true).
437 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
439 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
440 dnode_t *parent = nil, *uncle, *grandpa;
445 /* basic binary tree insert */
447 while (where != nil) {
449 result = dict->compare(key, where->key);
450 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
451 assert(dict->dupes || result != 0);
455 where = where->right;
458 assert(where == nil);
463 parent->right = node;
465 node->parent = parent;
469 dict->dict_nodecount++;
471 /* red black adjustments */
473 node->color = dnode_red;
475 while (parent->color == dnode_red) {
476 grandpa = parent->parent;
477 if (parent == grandpa->left) {
478 uncle = grandpa->right;
479 if (uncle->color == dnode_red) { /* red parent, red uncle */
480 parent->color = dnode_black;
481 uncle->color = dnode_black;
482 grandpa->color = dnode_red;
484 parent = grandpa->parent;
485 } else { /* red parent, black uncle */
486 if (node == parent->right) {
489 assert (grandpa == parent->parent);
490 /* rotation between parent and child preserves grandpa */
492 parent->color = dnode_black;
493 grandpa->color = dnode_red;
494 rotate_right(grandpa);
497 } else { /* symmetric cases: parent == parent->parent->right */
498 uncle = grandpa->left;
499 if (uncle->color == dnode_red) {
500 parent->color = dnode_black;
501 uncle->color = dnode_black;
502 grandpa->color = dnode_red;
504 parent = grandpa->parent;
506 if (node == parent->left) {
507 rotate_right(parent);
509 assert (grandpa == parent->parent);
511 parent->color = dnode_black;
512 grandpa->color = dnode_red;
513 rotate_left(grandpa);
519 dict_root(dict)->color = dnode_black;
523 * Allocate a node using the dictionary's allocator routine, give it
527 static dnode_t *dnode_init(dnode_t *dnode, void *data)
530 dnode->parent = NULL;
536 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
538 dnode_t *node = xmalloc(sizeof(dnode_t));
540 dnode_init(node, data);
541 dict_insert(dict, node, key);
546 * Return the node with the lowest (leftmost) key. If the dictionary is empty
547 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
550 static dnode_t *dict_first(dict_t *dict)
552 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
555 while ((left = root->left) != nil)
558 return (root == nil) ? NULL : root;
562 * Return the given node's successor node---the node which has the
563 * next key in the the left to right ordering. If the node has
564 * no successor, a null pointer is returned rather than a pointer to
568 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
570 dnode_t *nil = dict_nil(dict), *parent, *left;
572 if (curr->right != nil) {
574 while ((left = curr->left) != nil)
579 parent = curr->parent;
581 while (parent != nil && curr == parent->right) {
583 parent = curr->parent;
586 return (parent == nil) ? NULL : parent;
590 static void dnode_free(dnode_t *node)
610 * dirinfo.c --- maintains the directory information table for e2fsck.
614 * This subroutine is called during pass1 to create a directory info
615 * entry. During pass1, the passed-in parent is 0; it will get filled
618 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
620 struct dir_info *dir;
624 unsigned long old_size;
626 if (!ctx->dir_info) {
627 ctx->dir_info_count = 0;
628 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
630 num_dirs = 1024; /* Guess */
631 ctx->dir_info_size = num_dirs + 10;
632 ctx->dir_info = (struct dir_info *)
633 e2fsck_allocate_memory(ctx, ctx->dir_info_size
634 * sizeof (struct dir_info),
638 if (ctx->dir_info_count >= ctx->dir_info_size) {
639 old_size = ctx->dir_info_size * sizeof(struct dir_info);
640 ctx->dir_info_size += 10;
641 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
642 sizeof(struct dir_info),
645 ctx->dir_info_size -= 10;
651 * Normally, add_dir_info is called with each inode in
652 * sequential order; but once in a while (like when pass 3
653 * needs to recreate the root directory or lost+found
654 * directory) it is called out of order. In those cases, we
655 * need to move the dir_info entries down to make room, since
656 * the dir_info array needs to be sorted by inode number for
657 * get_dir_info()'s sake.
659 if (ctx->dir_info_count &&
660 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
661 for (i = ctx->dir_info_count-1; i > 0; i--)
662 if (ctx->dir_info[i-1].ino < ino)
664 dir = &ctx->dir_info[i];
666 for (j = ctx->dir_info_count++; j > i; j--)
667 ctx->dir_info[j] = ctx->dir_info[j-1];
669 dir = &ctx->dir_info[ctx->dir_info_count++];
672 dir->dotdot = parent;
673 dir->parent = parent;
677 * get_dir_info() --- given an inode number, try to find the directory
678 * information entry for it.
680 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
685 high = ctx->dir_info_count-1;
688 if (ino == ctx->dir_info[low].ino)
689 return &ctx->dir_info[low];
690 if (ino == ctx->dir_info[high].ino)
691 return &ctx->dir_info[high];
695 if (mid == low || mid == high)
697 if (ino == ctx->dir_info[mid].ino)
698 return &ctx->dir_info[mid];
699 if (ino < ctx->dir_info[mid].ino)
708 * Free the dir_info structure when it isn't needed any more.
710 static void e2fsck_free_dir_info(e2fsck_t ctx)
712 ext2fs_free_mem(&ctx->dir_info);
713 ctx->dir_info_size = 0;
714 ctx->dir_info_count = 0;
718 * Return the count of number of directories in the dir_info structure
720 static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
722 return ctx->dir_info_count;
726 * A simple interator function
728 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
730 if (*control >= ctx->dir_info_count)
733 return ctx->dir_info + (*control)++;
737 * dirinfo.c --- maintains the directory information table for e2fsck.
744 * This subroutine is called during pass1 to create a directory info
745 * entry. During pass1, the passed-in parent is 0; it will get filled
748 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
750 struct dx_dir_info *dir;
753 unsigned long old_size;
755 if (!ctx->dx_dir_info) {
756 ctx->dx_dir_info_count = 0;
757 ctx->dx_dir_info_size = 100; /* Guess */
758 ctx->dx_dir_info = (struct dx_dir_info *)
759 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
760 * sizeof (struct dx_dir_info),
764 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
765 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
766 ctx->dx_dir_info_size += 10;
767 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
768 sizeof(struct dx_dir_info),
771 ctx->dx_dir_info_size -= 10;
777 * Normally, add_dx_dir_info is called with each inode in
778 * sequential order; but once in a while (like when pass 3
779 * needs to recreate the root directory or lost+found
780 * directory) it is called out of order. In those cases, we
781 * need to move the dx_dir_info entries down to make room, since
782 * the dx_dir_info array needs to be sorted by inode number for
783 * get_dx_dir_info()'s sake.
785 if (ctx->dx_dir_info_count &&
786 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
787 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
788 if (ctx->dx_dir_info[i-1].ino < ino)
790 dir = &ctx->dx_dir_info[i];
792 for (j = ctx->dx_dir_info_count++; j > i; j--)
793 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
795 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
798 dir->numblocks = num_blocks;
799 dir->hashversion = 0;
800 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
801 * sizeof (struct dx_dirblock_info),
802 "dx_block info array");
806 * get_dx_dir_info() --- given an inode number, try to find the directory
807 * information entry for it.
809 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
814 high = ctx->dx_dir_info_count-1;
815 if (!ctx->dx_dir_info)
817 if (ino == ctx->dx_dir_info[low].ino)
818 return &ctx->dx_dir_info[low];
819 if (ino == ctx->dx_dir_info[high].ino)
820 return &ctx->dx_dir_info[high];
824 if (mid == low || mid == high)
826 if (ino == ctx->dx_dir_info[mid].ino)
827 return &ctx->dx_dir_info[mid];
828 if (ino < ctx->dx_dir_info[mid].ino)
837 * Free the dx_dir_info structure when it isn't needed any more.
839 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
842 struct dx_dir_info *dir;
844 if (ctx->dx_dir_info) {
845 dir = ctx->dx_dir_info;
846 for (i=0; i < ctx->dx_dir_info_count; i++) {
847 ext2fs_free_mem(&dir->dx_block);
849 ext2fs_free_mem(&ctx->dx_dir_info);
851 ctx->dx_dir_info_size = 0;
852 ctx->dx_dir_info_count = 0;
856 * A simple interator function
858 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
860 if (*control >= ctx->dx_dir_info_count)
863 return ctx->dx_dir_info + (*control)++;
866 #endif /* ENABLE_HTREE */
868 * e2fsck.c - a consistency checker for the new extended file system.
873 * This function allocates an e2fsck context
875 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
880 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
884 memset(context, 0, sizeof(struct e2fsck_struct));
886 context->process_inode_size = 256;
887 context->ext_attr_ver = 2;
893 struct ea_refcount_el {
902 struct ea_refcount_el *list;
905 static void ea_refcount_free(ext2_refcount_t refcount)
910 ext2fs_free_mem(&refcount->list);
911 ext2fs_free_mem(&refcount);
915 * This function resets an e2fsck context; it is called when e2fsck
916 * needs to be restarted.
918 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
921 ctx->lost_and_found = 0;
922 ctx->bad_lost_and_found = 0;
923 ext2fs_free_inode_bitmap(ctx->inode_used_map);
924 ctx->inode_used_map = 0;
925 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
926 ctx->inode_dir_map = 0;
927 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
928 ctx->inode_reg_map = 0;
929 ext2fs_free_block_bitmap(ctx->block_found_map);
930 ctx->block_found_map = 0;
931 ext2fs_free_icount(ctx->inode_link_info);
932 ctx->inode_link_info = 0;
933 if (ctx->journal_io) {
934 if (ctx->fs && ctx->fs->io != ctx->journal_io)
935 io_channel_close(ctx->journal_io);
939 ext2fs_free_dblist(ctx->fs->dblist);
942 e2fsck_free_dir_info(ctx);
944 e2fsck_free_dx_dir_info(ctx);
946 ea_refcount_free(ctx->refcount);
948 ea_refcount_free(ctx->refcount_extra);
949 ctx->refcount_extra = 0;
950 ext2fs_free_block_bitmap(ctx->block_dup_map);
951 ctx->block_dup_map = 0;
952 ext2fs_free_block_bitmap(ctx->block_ea_map);
953 ctx->block_ea_map = 0;
954 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
955 ctx->inode_bad_map = 0;
956 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
957 ctx->inode_imagic_map = 0;
958 ext2fs_u32_list_free(ctx->dirs_to_hash);
959 ctx->dirs_to_hash = 0;
962 * Clear the array of invalid meta-data flags
964 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
965 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
966 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
968 /* Clear statistic counters */
969 ctx->fs_directory_count = 0;
970 ctx->fs_regular_count = 0;
971 ctx->fs_blockdev_count = 0;
972 ctx->fs_chardev_count = 0;
973 ctx->fs_links_count = 0;
974 ctx->fs_symlinks_count = 0;
975 ctx->fs_fast_symlinks_count = 0;
976 ctx->fs_fifo_count = 0;
977 ctx->fs_total_count = 0;
978 ctx->fs_sockets_count = 0;
979 ctx->fs_ind_count = 0;
980 ctx->fs_dind_count = 0;
981 ctx->fs_tind_count = 0;
982 ctx->fs_fragmented = 0;
983 ctx->large_files = 0;
985 /* Reset the superblock to the user's requested value */
986 ctx->superblock = ctx->use_superblock;
991 static void e2fsck_free_context(e2fsck_t ctx)
996 e2fsck_reset_context(ctx);
998 blkid_put_cache(ctx->blkid);
1000 ext2fs_free_mem(&ctx);
1008 * The strategy we use for keeping track of EA refcounts is as
1009 * follows. We keep a sorted array of first EA blocks and its
1010 * reference counts. Once the refcount has dropped to zero, it is
1011 * removed from the array to save memory space. Once the EA block is
1012 * checked, its bit is set in the block_ea_map bitmap.
1016 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1018 ext2_refcount_t refcount;
1022 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1025 memset(refcount, 0, sizeof(struct ea_refcount));
1029 refcount->size = size;
1030 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1032 printf("Refcount allocated %d entries, %d bytes.\n",
1033 refcount->size, bytes);
1035 retval = ext2fs_get_mem(bytes, &refcount->list);
1038 memset(refcount->list, 0, bytes);
1040 refcount->count = 0;
1041 refcount->cursor = 0;
1047 ea_refcount_free(refcount);
1052 * collapse_refcount() --- go through the refcount array, and get rid
1053 * of any count == zero entries
1055 static void refcount_collapse(ext2_refcount_t refcount)
1058 struct ea_refcount_el *list;
1060 list = refcount->list;
1061 for (i = 0, j = 0; i < refcount->count; i++) {
1062 if (list[i].ea_count) {
1068 #if defined(DEBUG) || defined(TEST_PROGRAM)
1069 printf("Refcount_collapse: size was %d, now %d\n",
1070 refcount->count, j);
1072 refcount->count = j;
1077 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1078 * specified position.
1080 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1083 struct ea_refcount_el *el;
1088 if (refcount->count >= refcount->size) {
1089 new_size = refcount->size + 100;
1091 printf("Reallocating refcount %d entries...\n", new_size);
1093 retval = ext2fs_resize_mem((size_t) refcount->size *
1094 sizeof(struct ea_refcount_el),
1096 sizeof(struct ea_refcount_el),
1100 refcount->size = new_size;
1102 num = (int) refcount->count - pos;
1104 return 0; /* should never happen */
1106 memmove(&refcount->list[pos+1], &refcount->list[pos],
1107 sizeof(struct ea_refcount_el) * num);
1110 el = &refcount->list[pos];
1118 * get_refcount_el() --- given an block number, try to find refcount
1119 * information in the sorted list. If the create flag is set,
1120 * and we can't find an entry, create one in the sorted list.
1122 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1123 blk_t blk, int create)
1127 blk_t lowval, highval;
1129 if (!refcount || !refcount->list)
1133 high = (int) refcount->count-1;
1134 if (create && ((refcount->count == 0) ||
1135 (blk > refcount->list[high].ea_blk))) {
1136 if (refcount->count >= refcount->size)
1137 refcount_collapse(refcount);
1139 return insert_refcount_el(refcount, blk,
1140 (unsigned) refcount->count);
1142 if (refcount->count == 0)
1145 if (refcount->cursor >= refcount->count)
1146 refcount->cursor = 0;
1147 if (blk == refcount->list[refcount->cursor].ea_blk)
1148 return &refcount->list[refcount->cursor++];
1150 printf("Non-cursor get_refcount_el: %u\n", blk);
1152 while (low <= high) {
1156 /* Interpolate for efficiency */
1157 lowval = refcount->list[low].ea_blk;
1158 highval = refcount->list[high].ea_blk;
1162 else if (blk > highval)
1165 range = ((float) (blk - lowval)) /
1167 mid = low + ((int) (range * (high-low)));
1170 if (blk == refcount->list[mid].ea_blk) {
1171 refcount->cursor = mid+1;
1172 return &refcount->list[mid];
1174 if (blk < refcount->list[mid].ea_blk)
1180 * If we need to create a new entry, it should be right at
1181 * low (where high will be left at low-1).
1184 if (refcount->count >= refcount->size) {
1185 refcount_collapse(refcount);
1186 if (refcount->count < refcount->size)
1189 return insert_refcount_el(refcount, blk, low);
1195 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1197 struct ea_refcount_el *el;
1199 el = get_refcount_el(refcount, blk, 1);
1201 return EXT2_ET_NO_MEMORY;
1205 *ret = el->ea_count;
1210 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1212 struct ea_refcount_el *el;
1214 el = get_refcount_el(refcount, blk, 0);
1215 if (!el || el->ea_count == 0)
1216 return EXT2_ET_INVALID_ARGUMENT;
1221 *ret = el->ea_count;
1226 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1228 struct ea_refcount_el *el;
1231 * Get the refcount element
1233 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1235 return count ? EXT2_ET_NO_MEMORY : 0;
1236 el->ea_count = count;
1240 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1242 refcount->cursor = 0;
1246 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1248 struct ea_refcount_el *list;
1251 if (refcount->cursor >= refcount->count)
1253 list = refcount->list;
1254 if (list[refcount->cursor].ea_count) {
1256 *ret = list[refcount->cursor].ea_count;
1257 return list[refcount->cursor++].ea_blk;
1265 * ehandler.c --- handle bad block errors which come up during the
1266 * course of an e2fsck session.
1270 static const char *operation;
1273 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1274 void *data, size_t size FSCK_ATTR((unused)),
1275 int actual FSCK_ATTR((unused)), errcode_t error)
1279 ext2_filsys fs = (ext2_filsys) channel->app_data;
1282 ctx = (e2fsck_t) fs->priv_data;
1285 * If more than one block was read, try reading each block
1286 * separately. We could use the actual bytes read to figure
1287 * out where to start, but we don't bother.
1291 for (i=0; i < count; i++, p += channel->block_size, block++) {
1292 error = io_channel_read_blk(channel, block,
1300 printf(_("Error reading block %lu (%s) while %s. "), block,
1301 error_message(error), operation);
1303 printf(_("Error reading block %lu (%s). "), block,
1304 error_message(error));
1306 if (ask(ctx, _("Ignore error"), 1)) {
1307 if (ask(ctx, _("Force rewrite"), 1))
1308 io_channel_write_blk(channel, block, 1, data);
1316 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1317 const void *data, size_t size FSCK_ATTR((unused)),
1318 int actual FSCK_ATTR((unused)), errcode_t error)
1322 ext2_filsys fs = (ext2_filsys) channel->app_data;
1325 ctx = (e2fsck_t) fs->priv_data;
1328 * If more than one block was written, try writing each block
1329 * separately. We could use the actual bytes read to figure
1330 * out where to start, but we don't bother.
1333 p = (const char *) data;
1334 for (i=0; i < count; i++, p += channel->block_size, block++) {
1335 error = io_channel_write_blk(channel, block,
1344 printf(_("Error writing block %lu (%s) while %s. "), block,
1345 error_message(error), operation);
1347 printf(_("Error writing block %lu (%s). "), block,
1348 error_message(error));
1350 if (ask(ctx, _("Ignore error"), 1))
1356 static const char *ehandler_operation(const char *op)
1358 const char *ret = operation;
1364 static void ehandler_init(io_channel channel)
1366 channel->read_error = e2fsck_handle_read_error;
1367 channel->write_error = e2fsck_handle_write_error;
1371 * journal.c --- code for handling the "ext3" journal
1373 * Copyright (C) 2000 Andreas Dilger
1374 * Copyright (C) 2000 Theodore Ts'o
1376 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1377 * Copyright (C) 1999 Red Hat Software
1379 * This file may be redistributed under the terms of the
1380 * GNU General Public License version 2 or at your discretion
1381 * any later version.
1385 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1386 * This creates a larger static binary, and a smaller binary using
1387 * shared libraries. It's also probably slightly less CPU-efficient,
1388 * which is why it's not on by default. But, it's a good way of
1389 * testing the functions in inode_io.c and fileio.c.
1393 /* Kernel compatibility functions for handling the journal. These allow us
1394 * to use the recovery.c file virtually unchanged from the kernel, so we
1395 * don't have to do much to keep kernel and user recovery in sync.
1397 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1403 struct inode *inode = journal->j_inode;
1412 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1413 &inode->i_ext2, NULL, 0, block, &pblk);
1419 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1421 struct buffer_head *bh;
1423 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1427 bh->b_ctx = kdev->k_ctx;
1428 if (kdev->k_dev == K_DEV_FS)
1429 bh->b_io = kdev->k_ctx->fs->io;
1431 bh->b_io = kdev->k_ctx->journal_io;
1432 bh->b_size = blocksize;
1433 bh->b_blocknr = blocknr;
1438 static void sync_blockdev(kdev_t kdev)
1442 if (kdev->k_dev == K_DEV_FS)
1443 io = kdev->k_ctx->fs->io;
1445 io = kdev->k_ctx->journal_io;
1447 io_channel_flush(io);
1450 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1453 struct buffer_head *bh;
1455 for (; nr > 0; --nr) {
1457 if (rw == READ && !bh->b_uptodate) {
1458 retval = io_channel_read_blk(bh->b_io,
1462 bb_error_msg("while reading block %lu",
1463 (unsigned long) bh->b_blocknr);
1468 } else if (rw == WRITE && bh->b_dirty) {
1469 retval = io_channel_write_blk(bh->b_io,
1473 bb_error_msg("while writing block %lu",
1474 (unsigned long) bh->b_blocknr);
1484 static void mark_buffer_dirty(struct buffer_head *bh)
1489 static inline void mark_buffer_clean(struct buffer_head * bh)
1494 static void brelse(struct buffer_head *bh)
1497 ll_rw_block(WRITE, 1, &bh);
1498 ext2fs_free_mem(&bh);
1501 static int buffer_uptodate(struct buffer_head *bh)
1503 return bh->b_uptodate;
1506 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1508 bh->b_uptodate = val;
1511 static void wait_on_buffer(struct buffer_head *bh)
1513 if (!bh->b_uptodate)
1514 ll_rw_block(READ, 1, &bh);
1518 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1520 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1522 /* if we had an error doing journal recovery, we need a full fsck */
1524 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1525 ext2fs_mark_super_dirty(ctx->fs);
1528 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1530 struct ext2_super_block *sb = ctx->fs->super;
1531 struct ext2_super_block jsuper;
1532 struct problem_context pctx;
1533 struct buffer_head *bh;
1534 struct inode *j_inode = NULL;
1535 struct kdev_s *dev_fs = NULL, *dev_journal;
1536 const char *journal_name = NULL;
1537 journal_t *journal = NULL;
1538 errcode_t retval = 0;
1539 io_manager io_ptr = 0;
1540 unsigned long start = 0;
1542 int ext_journal = 0;
1543 int tried_backup_jnl = 0;
1546 clear_problem_context(&pctx);
1548 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1550 return EXT2_ET_NO_MEMORY;
1553 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1555 retval = EXT2_ET_NO_MEMORY;
1558 dev_journal = dev_fs+1;
1560 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1561 dev_fs->k_dev = K_DEV_FS;
1562 dev_journal->k_dev = K_DEV_JOURNAL;
1564 journal->j_dev = dev_journal;
1565 journal->j_fs_dev = dev_fs;
1566 journal->j_inode = NULL;
1567 journal->j_blocksize = ctx->fs->blocksize;
1569 if (uuid_is_null(sb->s_journal_uuid)) {
1570 if (!sb->s_journal_inum)
1571 return EXT2_ET_BAD_INODE_NUM;
1572 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1575 retval = EXT2_ET_NO_MEMORY;
1579 j_inode->i_ctx = ctx;
1580 j_inode->i_ino = sb->s_journal_inum;
1582 if ((retval = ext2fs_read_inode(ctx->fs,
1584 &j_inode->i_ext2))) {
1586 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1589 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1590 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1592 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1593 j_inode->i_ext2.i_links_count = 1;
1594 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1597 if (!j_inode->i_ext2.i_links_count ||
1598 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1599 retval = EXT2_ET_NO_JOURNAL;
1600 goto try_backup_journal;
1602 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1603 JFS_MIN_JOURNAL_BLOCKS) {
1604 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1605 goto try_backup_journal;
1607 for (i=0; i < EXT2_N_BLOCKS; i++) {
1608 blk = j_inode->i_ext2.i_block[i];
1610 if (i < EXT2_NDIR_BLOCKS) {
1611 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1612 goto try_backup_journal;
1616 if (blk < sb->s_first_data_block ||
1617 blk >= sb->s_blocks_count) {
1618 retval = EXT2_ET_BAD_BLOCK_NUM;
1619 goto try_backup_journal;
1622 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1625 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1631 io_ptr = inode_io_manager;
1633 journal->j_inode = j_inode;
1634 ctx->journal_io = ctx->fs->io;
1635 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1640 if (!ctx->journal_name) {
1643 uuid_unparse(sb->s_journal_uuid, uuid);
1644 ctx->journal_name = blkid_get_devname(ctx->blkid,
1646 if (!ctx->journal_name)
1647 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1649 journal_name = ctx->journal_name;
1651 if (!journal_name) {
1652 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1653 return EXT2_ET_LOAD_EXT_JOURNAL;
1656 io_ptr = unix_io_manager;
1659 #ifndef USE_INODE_IO
1662 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1667 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1670 if (ctx->fs->blocksize == 1024)
1672 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1674 retval = EXT2_ET_NO_MEMORY;
1677 ll_rw_block(READ, 1, &bh);
1678 if ((retval = bh->b_err) != 0)
1680 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1684 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1685 ext2fs_swap_super(&jsuper);
1687 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1688 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1689 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1690 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1693 /* Make sure the journal UUID is correct */
1694 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1695 sizeof(jsuper.s_uuid))) {
1696 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1697 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1701 journal->j_maxlen = jsuper.s_blocks_count;
1705 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1706 retval = EXT2_ET_NO_MEMORY;
1710 journal->j_sb_buffer = bh;
1711 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1714 ext2fs_free_mem(&j_inode);
1717 *ret_journal = journal;
1721 ext2fs_free_mem(&dev_fs);
1722 ext2fs_free_mem(&j_inode);
1723 ext2fs_free_mem(&journal);
1727 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1728 struct problem_context *pctx)
1730 struct ext2_super_block *sb = ctx->fs->super;
1731 int recover = ctx->fs->super->s_feature_incompat &
1732 EXT3_FEATURE_INCOMPAT_RECOVER;
1733 int has_journal = ctx->fs->super->s_feature_compat &
1734 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1736 if (has_journal || sb->s_journal_inum) {
1737 /* The journal inode is bogus, remove and force full fsck */
1738 pctx->ino = sb->s_journal_inum;
1739 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1740 if (has_journal && sb->s_journal_inum)
1741 printf("*** ext3 journal has been deleted - "
1742 "filesystem is now ext2 only ***\n\n");
1743 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1744 sb->s_journal_inum = 0;
1745 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1746 e2fsck_clear_recover(ctx, 1);
1749 return EXT2_ET_BAD_INODE_NUM;
1750 } else if (recover) {
1751 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1752 e2fsck_clear_recover(ctx, 1);
1755 return EXT2_ET_UNSUPP_FEATURE;
1760 #define V1_SB_SIZE 0x0024
1761 static void clear_v2_journal_fields(journal_t *journal)
1763 e2fsck_t ctx = journal->j_dev->k_ctx;
1764 struct problem_context pctx;
1766 clear_problem_context(&pctx);
1768 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1771 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1772 ctx->fs->blocksize-V1_SB_SIZE);
1773 mark_buffer_dirty(journal->j_sb_buffer);
1777 static errcode_t e2fsck_journal_load(journal_t *journal)
1779 e2fsck_t ctx = journal->j_dev->k_ctx;
1780 journal_superblock_t *jsb;
1781 struct buffer_head *jbh = journal->j_sb_buffer;
1782 struct problem_context pctx;
1784 clear_problem_context(&pctx);
1786 ll_rw_block(READ, 1, &jbh);
1788 bb_error_msg(_("reading journal superblock"));
1792 jsb = journal->j_superblock;
1793 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1794 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1795 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1797 switch (ntohl(jsb->s_header.h_blocktype)) {
1798 case JFS_SUPERBLOCK_V1:
1799 journal->j_format_version = 1;
1800 if (jsb->s_feature_compat ||
1801 jsb->s_feature_incompat ||
1802 jsb->s_feature_ro_compat ||
1804 clear_v2_journal_fields(journal);
1807 case JFS_SUPERBLOCK_V2:
1808 journal->j_format_version = 2;
1809 if (ntohl(jsb->s_nr_users) > 1 &&
1810 uuid_is_null(ctx->fs->super->s_journal_uuid))
1811 clear_v2_journal_fields(journal);
1812 if (ntohl(jsb->s_nr_users) > 1) {
1813 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1814 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1819 * These should never appear in a journal super block, so if
1820 * they do, the journal is badly corrupted.
1822 case JFS_DESCRIPTOR_BLOCK:
1823 case JFS_COMMIT_BLOCK:
1824 case JFS_REVOKE_BLOCK:
1825 return EXT2_ET_CORRUPT_SUPERBLOCK;
1827 /* If we don't understand the superblock major type, but there
1828 * is a magic number, then it is likely to be a new format we
1829 * just don't understand, so leave it alone. */
1831 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1834 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1835 return EXT2_ET_UNSUPP_FEATURE;
1837 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1838 return EXT2_ET_RO_UNSUPP_FEATURE;
1840 /* We have now checked whether we know enough about the journal
1841 * format to be able to proceed safely, so any other checks that
1842 * fail we should attempt to recover from. */
1843 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1844 bb_error_msg(_("%s: no valid journal superblock found"),
1846 return EXT2_ET_CORRUPT_SUPERBLOCK;
1849 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1850 journal->j_maxlen = ntohl(jsb->s_maxlen);
1851 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1852 bb_error_msg(_("%s: journal too short"),
1854 return EXT2_ET_CORRUPT_SUPERBLOCK;
1857 journal->j_tail_sequence = ntohl(jsb->s_sequence);
1858 journal->j_transaction_sequence = journal->j_tail_sequence;
1859 journal->j_tail = ntohl(jsb->s_start);
1860 journal->j_first = ntohl(jsb->s_first);
1861 journal->j_last = ntohl(jsb->s_maxlen);
1866 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
1877 /* Leave a valid existing V1 superblock signature alone.
1878 * Anything unrecognizable we overwrite with a new V2
1881 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
1882 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
1883 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
1884 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
1887 /* Zero out everything else beyond the superblock header */
1889 p = ((char *) jsb) + sizeof(journal_header_t);
1890 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
1892 jsb->s_blocksize = htonl(ctx->fs->blocksize);
1893 jsb->s_maxlen = htonl(journal->j_maxlen);
1894 jsb->s_first = htonl(1);
1896 /* Initialize the journal sequence number so that there is "no"
1897 * chance we will find old "valid" transactions in the journal.
1898 * This avoids the need to zero the whole journal (slow to do,
1899 * and risky when we are just recovering the filesystem).
1901 uuid_generate(u.uuid);
1902 for (i = 0; i < 4; i ++)
1903 new_seq ^= u.val[i];
1904 jsb->s_sequence = htonl(new_seq);
1906 mark_buffer_dirty(journal->j_sb_buffer);
1907 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
1910 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
1912 struct problem_context *pctx)
1914 struct ext2_super_block *sb = ctx->fs->super;
1915 int recover = ctx->fs->super->s_feature_incompat &
1916 EXT3_FEATURE_INCOMPAT_RECOVER;
1918 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
1919 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
1920 e2fsck_journal_reset_super(ctx, journal->j_superblock,
1922 journal->j_transaction_sequence = 1;
1923 e2fsck_clear_recover(ctx, recover);
1926 return EXT2_ET_CORRUPT_SUPERBLOCK;
1927 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
1928 return EXT2_ET_CORRUPT_SUPERBLOCK;
1933 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
1934 int reset, int drop)
1936 journal_superblock_t *jsb;
1939 mark_buffer_clean(journal->j_sb_buffer);
1940 else if (!(ctx->options & E2F_OPT_READONLY)) {
1941 jsb = journal->j_superblock;
1942 jsb->s_sequence = htonl(journal->j_transaction_sequence);
1944 jsb->s_start = 0; /* this marks the journal as empty */
1945 mark_buffer_dirty(journal->j_sb_buffer);
1947 brelse(journal->j_sb_buffer);
1949 if (ctx->journal_io) {
1950 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1951 io_channel_close(ctx->journal_io);
1952 ctx->journal_io = 0;
1955 #ifndef USE_INODE_IO
1956 ext2fs_free_mem(&journal->j_inode);
1958 ext2fs_free_mem(&journal->j_fs_dev);
1959 ext2fs_free_mem(&journal);
1963 * This function makes sure that the superblock fields regarding the
1964 * journal are consistent.
1966 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
1968 struct ext2_super_block *sb = ctx->fs->super;
1970 int recover = ctx->fs->super->s_feature_incompat &
1971 EXT3_FEATURE_INCOMPAT_RECOVER;
1972 struct problem_context pctx;
1974 int reset = 0, force_fsck = 0;
1977 /* If we don't have any journal features, don't do anything more */
1978 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
1979 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
1980 uuid_is_null(sb->s_journal_uuid))
1983 clear_problem_context(&pctx);
1984 pctx.num = sb->s_journal_inum;
1986 retval = e2fsck_get_journal(ctx, &journal);
1988 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
1989 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
1990 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
1991 (retval == EXT2_ET_NO_JOURNAL))
1992 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1996 retval = e2fsck_journal_load(journal);
1998 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
1999 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2000 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2002 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2003 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2005 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2006 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2007 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2009 e2fsck_journal_release(ctx, journal, 0, 1);
2014 * We want to make the flags consistent here. We will not leave with
2015 * needs_recovery set but has_journal clear. We can't get in a loop
2016 * with -y, -n, or -p, only if a user isn't making up their mind.
2019 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2020 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2022 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2024 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2025 goto no_has_journal;
2027 * Need a full fsck if we are releasing a
2028 * journal stored on a reserved inode.
2030 force_fsck = recover ||
2031 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2032 /* Clear all of the journal fields */
2033 sb->s_journal_inum = 0;
2034 sb->s_journal_dev = 0;
2035 memset(sb->s_journal_uuid, 0,
2036 sizeof(sb->s_journal_uuid));
2037 e2fsck_clear_recover(ctx, force_fsck);
2038 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2039 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2040 ext2fs_mark_super_dirty(ctx->fs);
2044 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2045 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2046 journal->j_superblock->s_start != 0) {
2047 /* Print status information */
2048 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2049 if (ctx->superblock)
2050 problem = PR_0_JOURNAL_RUN_DEFAULT;
2052 problem = PR_0_JOURNAL_RUN;
2053 if (fix_problem(ctx, problem, &pctx)) {
2054 ctx->options |= E2F_OPT_FORCE;
2055 sb->s_feature_incompat |=
2056 EXT3_FEATURE_INCOMPAT_RECOVER;
2057 ext2fs_mark_super_dirty(ctx->fs);
2058 } else if (fix_problem(ctx,
2059 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2061 sb->s_state &= ~EXT2_VALID_FS;
2062 ext2fs_mark_super_dirty(ctx->fs);
2065 * If the user answers no to the above question, we
2066 * ignore the fact that journal apparently has data;
2067 * accidentally replaying over valid data would be far
2068 * worse than skipping a questionable recovery.
2070 * XXX should we abort with a fatal error here? What
2071 * will the ext3 kernel code do if a filesystem with
2072 * !NEEDS_RECOVERY but with a non-zero
2073 * journal->j_superblock->s_start is mounted?
2077 e2fsck_journal_release(ctx, journal, reset, 0);
2081 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2086 journal_init_revoke_caches();
2087 retval = e2fsck_get_journal(ctx, &journal);
2091 retval = e2fsck_journal_load(journal);
2095 retval = journal_init_revoke(journal, 1024);
2099 retval = -journal_recover(journal);
2103 if (journal->j_superblock->s_errno) {
2104 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2105 ext2fs_mark_super_dirty(ctx->fs);
2106 journal->j_superblock->s_errno = 0;
2107 mark_buffer_dirty(journal->j_sb_buffer);
2111 journal_destroy_revoke(journal);
2112 journal_destroy_revoke_caches();
2113 e2fsck_journal_release(ctx, journal, 1, 0);
2117 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2119 io_manager io_ptr = ctx->fs->io->manager;
2120 int blocksize = ctx->fs->blocksize;
2121 errcode_t retval, recover_retval;
2123 printf(_("%s: recovering journal\n"), ctx->device_name);
2124 if (ctx->options & E2F_OPT_READONLY) {
2125 printf(_("%s: won't do journal recovery while read-only\n"),
2127 return EXT2_ET_FILE_RO;
2130 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2131 ext2fs_flush(ctx->fs); /* Force out any modifications */
2133 recover_retval = recover_ext3_journal(ctx);
2136 * Reload the filesystem context to get up-to-date data from disk
2137 * because journal recovery will change the filesystem under us.
2139 ext2fs_close(ctx->fs);
2140 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2141 ctx->superblock, blocksize, io_ptr,
2145 bb_error_msg(_("while trying to re-open %s"),
2147 bb_error_msg_and_die(0);
2149 ctx->fs->priv_data = ctx;
2151 /* Set the superblock flags */
2152 e2fsck_clear_recover(ctx, recover_retval);
2153 return recover_retval;
2157 * This function will move the journal inode from a visible file in
2158 * the filesystem directory hierarchy to the reserved inode if necessary.
2160 static const char *const journal_names[] = {
2161 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2163 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2165 struct ext2_super_block *sb = ctx->fs->super;
2166 struct problem_context pctx;
2167 struct ext2_inode inode;
2168 ext2_filsys fs = ctx->fs;
2171 const char *const * cpp;
2172 int group, mount_flags;
2174 clear_problem_context(&pctx);
2177 * If the filesystem is opened read-only, or there is no
2178 * journal, then do nothing.
2180 if ((ctx->options & E2F_OPT_READONLY) ||
2181 (sb->s_journal_inum == 0) ||
2182 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2186 * Read in the journal inode
2188 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2192 * If it's necessary to backup the journal inode, do so.
2194 if ((sb->s_jnl_backup_type == 0) ||
2195 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2196 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2197 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2198 memcpy(sb->s_jnl_blocks, inode.i_block,
2200 sb->s_jnl_blocks[16] = inode.i_size;
2201 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2202 ext2fs_mark_super_dirty(fs);
2203 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2208 * If the journal is already the hidden inode, then do nothing
2210 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2214 * The journal inode had better have only one link and not be readable.
2216 if (inode.i_links_count != 1)
2220 * If the filesystem is mounted, or we can't tell whether
2221 * or not it's mounted, do nothing.
2223 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2224 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2228 * If we can't find the name of the journal inode, then do
2231 for (cpp = journal_names; *cpp; cpp++) {
2232 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2233 strlen(*cpp), 0, &ino);
2234 if ((retval == 0) && (ino == sb->s_journal_inum))
2240 /* We need the inode bitmap to be loaded */
2241 retval = ext2fs_read_bitmaps(fs);
2246 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2250 * OK, we've done all the checks, let's actually move the
2251 * journal inode. Errors at this point mean we need to force
2252 * an ext2 filesystem check.
2254 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2256 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2258 sb->s_journal_inum = EXT2_JOURNAL_INO;
2259 ext2fs_mark_super_dirty(fs);
2260 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2261 inode.i_links_count = 0;
2262 inode.i_dtime = time(NULL);
2263 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2266 group = ext2fs_group_of_ino(fs, ino);
2267 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2268 ext2fs_mark_ib_dirty(fs);
2269 fs->group_desc[group].bg_free_inodes_count++;
2270 fs->super->s_free_inodes_count++;
2274 pctx.errcode = retval;
2275 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2276 fs->super->s_state &= ~EXT2_VALID_FS;
2277 ext2fs_mark_super_dirty(fs);
2281 * message.c --- print e2fsck messages (with compression)
2283 * print_e2fsck_message() prints a message to the user, using
2284 * compression techniques and expansions of abbreviations.
2286 * The following % expansions are supported:
2288 * %b <blk> block number
2289 * %B <blkcount> integer
2290 * %c <blk2> block number
2291 * %Di <dirent>->ino inode number
2292 * %Dn <dirent>->name string
2293 * %Dr <dirent>->rec_len
2294 * %Dl <dirent>->name_len
2295 * %Dt <dirent>->filetype
2296 * %d <dir> inode number
2297 * %g <group> integer
2298 * %i <ino> inode number
2299 * %Is <inode> -> i_size
2300 * %IS <inode> -> i_extra_isize
2301 * %Ib <inode> -> i_blocks
2302 * %Il <inode> -> i_links_count
2303 * %Im <inode> -> i_mode
2304 * %IM <inode> -> i_mtime
2305 * %IF <inode> -> i_faddr
2306 * %If <inode> -> i_file_acl
2307 * %Id <inode> -> i_dir_acl
2308 * %Iu <inode> -> i_uid
2309 * %Ig <inode> -> i_gid
2310 * %j <ino2> inode number
2311 * %m <com_err error message>
2313 * %p ext2fs_get_pathname of directory <ino>
2314 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2315 * the containing directory. (If dirent is NULL
2316 * then return the pathname of directory <ino2>)
2317 * %q ext2fs_get_pathname of directory <dir>
2318 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2319 * the containing directory.
2320 * %s <str> miscellaneous string
2321 * %S backup superblock
2322 * %X <num> hexadecimal format
2324 * The following '@' expansions are supported:
2326 * @a extended attribute
2327 * @A error allocating
2331 * @C conflicts with some other fs block
2335 * @E Entry '%Dn' in %p (%i)
2337 * @F for @i %i (%Q) is
2339 * @h HTREE directory inode
2345 * @m multiply-claimed
2359 * This structure defines the abbreviations used by the text strings
2360 * below. The first character in the string is the index letter. An
2361 * abbreviation of the form '@<i>' is expanded by looking up the index
2362 * letter <i> in the table below.
2364 static const char *const abbrevs[] = {
2365 N_("aextended attribute"),
2366 N_("Aerror allocating"),
2370 N_("Cconflicts with some other fs @b"),
2377 N_("E@e '%Dn' in %p (%i)"),
2379 N_("Ffor @i %i (%Q) is"),
2384 N_("mmultiply-claimed"),
2399 * Give more user friendly names to the "special" inodes.
2401 #define num_special_inodes 11
2402 static const char *const special_inode_name[] =
2404 N_("<The NULL inode>"), /* 0 */
2405 N_("<The bad blocks inode>"), /* 1 */
2407 N_("<The ACL index inode>"), /* 3 */
2408 N_("<The ACL data inode>"), /* 4 */
2409 N_("<The boot loader inode>"), /* 5 */
2410 N_("<The undelete directory inode>"), /* 6 */
2411 N_("<The group descriptor inode>"), /* 7 */
2412 N_("<The journal inode>"), /* 8 */
2413 N_("<Reserved inode 9>"), /* 9 */
2414 N_("<Reserved inode 10>"), /* 10 */
2418 * This function does "safe" printing. It will convert non-printable
2419 * ASCII characters using '^' and M- notation.
2421 static void safe_print(const char *cp, int len)
2431 fputs("M-", stdout);
2434 if ((ch < 32) || (ch == 0x7f)) {
2436 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2444 * This function prints a pathname, using the ext2fs_get_pathname
2447 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2452 if (!dir && (ino < num_special_inodes)) {
2453 fputs(_(special_inode_name[ino]), stdout);
2457 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2459 fputs("???", stdout);
2461 safe_print(path, -1);
2462 ext2fs_free_mem(&path);
2466 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2467 struct problem_context *pctx, int first);
2469 * This function handles the '@' expansion. We allow recursive
2470 * expansion; an @ expression can contain further '@' and '%'
2473 static void expand_at_expression(e2fsck_t ctx, char ch,
2474 struct problem_context *pctx,
2477 const char *const *cpp;
2480 /* Search for the abbreviation */
2481 for (cpp = abbrevs; *cpp; cpp++) {
2487 if (*first && islower(*str)) {
2489 bb_putchar(toupper(*str++));
2491 print_e2fsck_message(ctx, str, pctx, *first);
2497 * This function expands '%IX' expressions
2499 static void expand_inode_expression(char ch,
2500 struct problem_context *ctx)
2502 struct ext2_inode *inode;
2503 struct ext2_inode_large *large_inode;
2508 if (!ctx || !ctx->inode)
2512 large_inode = (struct ext2_inode_large *) inode;
2516 if (LINUX_S_ISDIR(inode->i_mode))
2517 printf("%u", inode->i_size);
2519 printf("%"PRIu64, (inode->i_size |
2520 ((uint64_t) inode->i_size_high << 32)));
2524 printf("%u", large_inode->i_extra_isize);
2527 printf("%u", inode->i_blocks);
2530 printf("%d", inode->i_links_count);
2533 printf("0%o", inode->i_mode);
2536 /* The diet libc doesn't respect the TZ environemnt variable */
2538 time_str = getenv("TZ");
2541 do_gmt = !strcmp(time_str, "GMT");
2544 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2545 printf("%.24s", time_str);
2548 printf("%u", inode->i_faddr);
2551 printf("%u", inode->i_file_acl);
2554 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2555 inode->i_dir_acl : 0));
2558 printf("%d", (inode->i_uid |
2559 (inode->osd2.linux2.l_i_uid_high << 16)));
2562 printf("%d", (inode->i_gid |
2563 (inode->osd2.linux2.l_i_gid_high << 16)));
2567 printf("%%I%c", ch);
2573 * This function expands '%dX' expressions
2575 static void expand_dirent_expression(char ch,
2576 struct problem_context *ctx)
2578 struct ext2_dir_entry *dirent;
2581 if (!ctx || !ctx->dirent)
2584 dirent = ctx->dirent;
2588 printf("%u", dirent->inode);
2591 len = dirent->name_len & 0xFF;
2592 if (len > EXT2_NAME_LEN)
2593 len = EXT2_NAME_LEN;
2594 if (len > dirent->rec_len)
2595 len = dirent->rec_len;
2596 safe_print(dirent->name, len);
2599 printf("%u", dirent->rec_len);
2602 printf("%u", dirent->name_len & 0xFF);
2605 printf("%u", dirent->name_len >> 8);
2609 printf("%%D%c", ch);
2614 static void expand_percent_expression(ext2_filsys fs, char ch,
2615 struct problem_context *ctx)
2625 printf("%u", ctx->blk);
2628 printf("%"PRIi64, ctx->blkcount);
2631 printf("%u", ctx->blk2);
2634 printf("%u", ctx->dir);
2637 printf("%d", ctx->group);
2640 printf("%u", ctx->ino);
2643 printf("%u", ctx->ino2);
2646 fputs(error_message(ctx->errcode), stdout);
2649 printf("%"PRIi64, ctx->num);
2652 print_pathname(fs, ctx->ino, 0);
2655 print_pathname(fs, ctx->ino2,
2656 ctx->dirent ? ctx->dirent->inode : 0);
2659 print_pathname(fs, ctx->dir, 0);
2662 print_pathname(fs, ctx->dir, ctx->ino);
2665 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2668 fputs((ctx->str ? ctx->str : "NULL"), stdout);
2671 printf("0x%"PRIi64, ctx->num);
2681 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2682 struct problem_context *pctx, int first)
2684 ext2_filsys fs = ctx->fs;
2688 e2fsck_clear_progbar(ctx);
2689 for (cp = msg; *cp; cp++) {
2692 expand_at_expression(ctx, *cp, pctx, &first);
2693 } else if (cp[0] == '%' && cp[1] == 'I') {
2695 expand_inode_expression(*cp, pctx);
2696 } else if (cp[0] == '%' && cp[1] == 'D') {
2698 expand_dirent_expression(*cp, pctx);
2699 } else if ((cp[0] == '%')) {
2701 expand_percent_expression(fs, *cp, pctx);
2703 for (i=0; cp[i]; i++)
2704 if ((cp[i] == '@') || cp[i] == '%')
2706 printf("%.*s", i, cp);
2715 * region.c --- code which manages allocations within a region.
2719 region_addr_t start;
2721 struct region_el *next;
2724 struct region_struct {
2727 struct region_el *allocated;
2730 static region_t region_create(region_addr_t min, region_addr_t max)
2734 region = xzalloc(sizeof(struct region_struct));
2740 static void region_free(region_t region)
2742 struct region_el *r, *next;
2744 for (r = region->allocated; r; r = next) {
2748 memset(region, 0, sizeof(struct region_struct));
2752 static int region_allocate(region_t region, region_addr_t start, int n)
2754 struct region_el *r, *new_region, *prev, *next;
2758 if ((start < region->min) || (end > region->max))
2764 * Search through the linked list. If we find that it
2765 * conflicts witih something that's already allocated, return
2766 * 1; if we can find an existing region which we can grow, do
2767 * so. Otherwise, stop when we find the appropriate place
2768 * insert a new region element into the linked list.
2770 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2771 if (((start >= r->start) && (start < r->end)) ||
2772 ((end > r->start) && (end <= r->end)) ||
2773 ((start <= r->start) && (end >= r->end)))
2775 if (end == r->start) {
2779 if (start == r->end) {
2780 if ((next = r->next)) {
2781 if (end > next->start)
2783 if (end == next->start) {
2785 r->next = next->next;
2793 if (start < r->start)
2797 * Insert a new region element structure into the linked list
2799 new_region = xmalloc(sizeof(struct region_el));
2800 new_region->start = start;
2801 new_region->end = start + n;
2802 new_region->next = r;
2804 prev->next = new_region;
2806 region->allocated = new_region;
2811 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2813 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2814 * and applies the following tests to each inode:
2816 * - The mode field of the inode must be legal.
2817 * - The size and block count fields of the inode are correct.
2818 * - A data block must not be used by another inode
2820 * Pass 1 also gathers the collects the following information:
2822 * - A bitmap of which inodes are in use. (inode_used_map)
2823 * - A bitmap of which inodes are directories. (inode_dir_map)
2824 * - A bitmap of which inodes are regular files. (inode_reg_map)
2825 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2826 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2827 * - A bitmap of which blocks are in use. (block_found_map)
2828 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2829 * - The data blocks of the directory inodes. (dir_map)
2831 * Pass 1 is designed to stash away enough information so that the
2832 * other passes should not need to read in the inode information
2833 * during the normal course of a filesystem check. (Althogh if an
2834 * inconsistency is detected, other passes may need to read in an
2837 * Note that pass 1B will be invoked if there are any duplicate blocks
2842 static int process_block(ext2_filsys fs, blk_t *blocknr,
2843 e2_blkcnt_t blockcnt, blk_t ref_blk,
2844 int ref_offset, void *priv_data);
2845 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2846 e2_blkcnt_t blockcnt, blk_t ref_blk,
2847 int ref_offset, void *priv_data);
2848 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2850 static void mark_table_blocks(e2fsck_t ctx);
2851 static void alloc_imagic_map(e2fsck_t ctx);
2852 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2853 static void handle_fs_bad_blocks(e2fsck_t ctx);
2854 static void process_inodes(e2fsck_t ctx, char *block_buf);
2855 static int process_inode_cmp(const void *a, const void *b);
2856 static errcode_t scan_callback(ext2_filsys fs,
2857 dgrp_t group, void * priv_data);
2858 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2859 char *block_buf, int adjust_sign);
2860 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2862 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2863 struct ext2_inode * inode, int bufsize,
2866 struct process_block_struct_1 {
2868 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
2869 fragmented:1, compressed:1, bbcheck:1;
2872 e2_blkcnt_t last_block;
2873 int num_illegal_blocks;
2874 blk_t previous_block;
2875 struct ext2_inode *inode;
2876 struct problem_context *pctx;
2877 ext2fs_block_bitmap fs_meta_blocks;
2881 struct process_inode_block {
2883 struct ext2_inode inode;
2886 struct scan_callback_struct {
2892 * For the inodes to process list.
2894 static struct process_inode_block *inodes_to_process;
2895 static int process_inode_count;
2897 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2898 EXT2_MIN_BLOCK_LOG_SIZE + 1];
2901 * Free all memory allocated by pass1 in preparation for restarting
2904 static void unwind_pass1(void)
2906 ext2fs_free_mem(&inodes_to_process);
2910 * Check to make sure a device inode is real. Returns 1 if the device
2911 * checks out, 0 if not.
2913 * Note: this routine is now also used to check FIFO's and Sockets,
2914 * since they have the same requirement; the i_block fields should be
2918 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2923 * If i_blocks is non-zero, or the index flag is set, then
2924 * this is a bogus device/fifo/socket
2926 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2927 (inode->i_flags & EXT2_INDEX_FL))
2931 * We should be able to do the test below all the time, but
2932 * because the kernel doesn't forcibly clear the device
2933 * inode's additional i_block fields, there are some rare
2934 * occasions when a legitimate device inode will have non-zero
2935 * additional i_block fields. So for now, we only complain
2936 * when the immutable flag is set, which should never happen
2937 * for devices. (And that's when the problem is caused, since
2938 * you can't set or clear immutable flags for devices.) Once
2939 * the kernel has been fixed we can change this...
2941 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2942 for (i=4; i < EXT2_N_BLOCKS; i++)
2943 if (inode->i_block[i])
2950 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2951 * checks out, 0 if not.
2954 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
2960 if ((inode->i_size_high || inode->i_size == 0) ||
2961 (inode->i_flags & EXT2_INDEX_FL))
2964 blocks = ext2fs_inode_data_blocks(fs, inode);
2966 if ((inode->i_size >= fs->blocksize) ||
2967 (blocks != fs->blocksize >> 9) ||
2968 (inode->i_block[0] < fs->super->s_first_data_block) ||
2969 (inode->i_block[0] >= fs->super->s_blocks_count))
2972 for (i = 1; i < EXT2_N_BLOCKS; i++)
2973 if (inode->i_block[i])
2976 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
2979 len = strnlen(buf, fs->blocksize);
2980 if (len == fs->blocksize)
2983 if (inode->i_size >= sizeof(inode->i_block))
2986 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
2987 if (len == sizeof(inode->i_block))
2990 if (len != inode->i_size)
2996 * If the immutable (or append-only) flag is set on the inode, offer
2999 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3000 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3002 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3005 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3008 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3009 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3013 * If device, fifo or socket, check size is zero -- if not offer to
3016 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3018 struct ext2_inode *inode = pctx->inode;
3020 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3023 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3027 inode->i_size_high = 0;
3028 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3031 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3033 struct ext2_super_block *sb = ctx->fs->super;
3034 struct ext2_inode_large *inode;
3035 struct ext2_ext_attr_entry *entry;
3037 int storage_size, remain, offs;
3040 inode = (struct ext2_inode_large *) pctx->inode;
3041 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3042 inode->i_extra_isize;
3043 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3044 inode->i_extra_isize + sizeof(__u32);
3045 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3046 entry = (struct ext2_ext_attr_entry *) start;
3048 /* scan all entry's headers first */
3050 /* take finish entry 0UL into account */
3051 remain = storage_size - sizeof(__u32);
3054 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3056 /* header eats this space */
3057 remain -= sizeof(struct ext2_ext_attr_entry);
3059 /* is attribute name valid? */
3060 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3061 pctx->num = entry->e_name_len;
3062 problem = PR_1_ATTR_NAME_LEN;
3066 /* attribute len eats this space */
3067 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3069 /* check value size */
3070 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3071 pctx->num = entry->e_value_size;
3072 problem = PR_1_ATTR_VALUE_SIZE;
3076 /* check value placement */
3077 if (entry->e_value_offs +
3078 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3079 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3080 pctx->num = entry->e_value_offs;
3081 problem = PR_1_ATTR_VALUE_OFFSET;
3085 /* e_value_block must be 0 in inode's ea */
3086 if (entry->e_value_block != 0) {
3087 pctx->num = entry->e_value_block;
3088 problem = PR_1_ATTR_VALUE_BLOCK;
3092 /* e_hash must be 0 in inode's ea */
3093 if (entry->e_hash != 0) {
3094 pctx->num = entry->e_hash;
3095 problem = PR_1_ATTR_HASH;
3099 remain -= entry->e_value_size;
3100 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3102 entry = EXT2_EXT_ATTR_NEXT(entry);
3106 * it seems like a corruption. it's very unlikely we could repair
3107 * EA(s) in automatic fashion -bzzz
3109 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3112 /* simple remove all possible EA(s) */
3113 *((__u32 *)start) = 0UL;
3114 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3115 EXT2_INODE_SIZE(sb), "pass1");
3118 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3120 struct ext2_super_block *sb = ctx->fs->super;
3121 struct ext2_inode_large *inode;
3125 inode = (struct ext2_inode_large *) pctx->inode;
3126 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3127 /* this isn't large inode. so, nothing to check */
3131 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3132 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3133 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3135 * For now we will allow i_extra_isize to be 0, but really
3136 * implementations should never allow i_extra_isize to be 0
3138 if (inode->i_extra_isize &&
3139 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3140 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3142 inode->i_extra_isize = min;
3143 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3144 EXT2_INODE_SIZE(sb), "pass1");
3148 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3149 inode->i_extra_isize);
3150 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3151 /* it seems inode has an extended attribute(s) in body */
3152 check_ea_in_inode(ctx, pctx);
3156 static void e2fsck_pass1(e2fsck_t ctx)
3160 ext2_filsys fs = ctx->fs;
3162 struct ext2_inode *inode;
3163 ext2_inode_scan scan;
3165 unsigned char frag, fsize;
3166 struct problem_context pctx;
3167 struct scan_callback_struct scan_struct;
3168 struct ext2_super_block *sb = ctx->fs->super;
3170 int busted_fs_time = 0;
3173 clear_problem_context(&pctx);
3175 if (!(ctx->options & E2F_OPT_PREEN))
3176 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3178 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3179 !(ctx->options & E2F_OPT_NO)) {
3180 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3181 ctx->dirs_to_hash = 0;
3186 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3188 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3189 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3190 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3191 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3192 max_sizes = (max_sizes * (1UL << i)) - 1;
3193 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3197 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3200 * Allocate bitmaps structures
3202 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3203 &ctx->inode_used_map);
3206 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3207 ctx->flags |= E2F_FLAG_ABORT;
3210 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3211 _("directory inode map"), &ctx->inode_dir_map);
3214 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3215 ctx->flags |= E2F_FLAG_ABORT;
3218 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3219 _("regular file inode map"), &ctx->inode_reg_map);
3222 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3223 ctx->flags |= E2F_FLAG_ABORT;
3226 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3227 &ctx->block_found_map);
3230 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3231 ctx->flags |= E2F_FLAG_ABORT;
3234 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3235 &ctx->inode_link_info);
3237 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3238 ctx->flags |= E2F_FLAG_ABORT;
3241 inode_size = EXT2_INODE_SIZE(fs->super);
3242 inode = (struct ext2_inode *)
3243 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3245 inodes_to_process = (struct process_inode_block *)
3246 e2fsck_allocate_memory(ctx,
3247 (ctx->process_inode_size *
3248 sizeof(struct process_inode_block)),
3249 "array of inodes to process");
3250 process_inode_count = 0;
3252 pctx.errcode = ext2fs_init_dblist(fs, 0);
3254 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3255 ctx->flags |= E2F_FLAG_ABORT;
3260 * If the last orphan field is set, clear it, since the pass1
3261 * processing will automatically find and clear the orphans.
3262 * In the future, we may want to try using the last_orphan
3263 * linked list ourselves, but for now, we clear it so that the
3264 * ext3 mount code won't get confused.
3266 if (!(ctx->options & E2F_OPT_READONLY)) {
3267 if (fs->super->s_last_orphan) {
3268 fs->super->s_last_orphan = 0;
3269 ext2fs_mark_super_dirty(fs);
3273 mark_table_blocks(ctx);
3274 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3275 "block interate buffer");
3276 e2fsck_use_inode_shortcuts(ctx, 1);
3277 ehandler_operation(_("doing inode scan"));
3278 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3281 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3282 ctx->flags |= E2F_FLAG_ABORT;
3285 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3286 ctx->stashed_inode = inode;
3287 scan_struct.ctx = ctx;
3288 scan_struct.block_buf = block_buf;
3289 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3291 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3293 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3294 (fs->super->s_mtime < fs->super->s_inodes_count))
3298 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3300 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3302 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3306 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3307 ctx->flags |= E2F_FLAG_ABORT;
3314 ctx->stashed_ino = ino;
3315 if (inode->i_links_count) {
3316 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3317 ino, inode->i_links_count);
3319 pctx.num = inode->i_links_count;
3320 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3321 ctx->flags |= E2F_FLAG_ABORT;
3325 if (ino == EXT2_BAD_INO) {
3326 struct process_block_struct_1 pb;
3328 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3329 &pb.fs_meta_blocks);
3332 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3333 ctx->flags |= E2F_FLAG_ABORT;
3336 pb.ino = EXT2_BAD_INO;
3337 pb.num_blocks = pb.last_block = 0;
3338 pb.num_illegal_blocks = 0;
3339 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3340 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3344 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3345 block_buf, process_bad_block, &pb);
3346 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3348 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3349 ctx->flags |= E2F_FLAG_ABORT;
3353 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3354 ctx->flags |= E2F_FLAG_ABORT;
3357 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3358 clear_problem_context(&pctx);
3360 } else if (ino == EXT2_ROOT_INO) {
3362 * Make sure the root inode is a directory; if
3363 * not, offer to clear it. It will be
3364 * regnerated in pass #3.
3366 if (!LINUX_S_ISDIR(inode->i_mode)) {
3367 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3368 inode->i_dtime = time(NULL);
3369 inode->i_links_count = 0;
3370 ext2fs_icount_store(ctx->inode_link_info,
3372 e2fsck_write_inode(ctx, ino, inode,
3377 * If dtime is set, offer to clear it. mke2fs
3378 * version 0.2b created filesystems with the
3379 * dtime field set for the root and lost+found
3380 * directories. We won't worry about
3381 * /lost+found, since that can be regenerated
3382 * easily. But we will fix the root directory
3383 * as a special case.
3385 if (inode->i_dtime && inode->i_links_count) {
3386 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3388 e2fsck_write_inode(ctx, ino, inode,
3392 } else if (ino == EXT2_JOURNAL_INO) {
3393 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3394 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3395 if (!LINUX_S_ISREG(inode->i_mode) &&
3396 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3398 inode->i_mode = LINUX_S_IFREG;
3399 e2fsck_write_inode(ctx, ino, inode,
3402 check_blocks(ctx, &pctx, block_buf);
3405 if ((inode->i_links_count || inode->i_blocks ||
3406 inode->i_blocks || inode->i_block[0]) &&
3407 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3409 memset(inode, 0, inode_size);
3410 ext2fs_icount_store(ctx->inode_link_info,
3412 e2fsck_write_inode_full(ctx, ino, inode,
3413 inode_size, "pass1");
3415 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3418 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3419 if (ino == EXT2_BOOT_LOADER_INO) {
3420 if (LINUX_S_ISDIR(inode->i_mode))
3421 problem = PR_1_RESERVED_BAD_MODE;
3422 } else if (ino == EXT2_RESIZE_INO) {
3423 if (inode->i_mode &&
3424 !LINUX_S_ISREG(inode->i_mode))
3425 problem = PR_1_RESERVED_BAD_MODE;
3427 if (inode->i_mode != 0)
3428 problem = PR_1_RESERVED_BAD_MODE;
3431 if (fix_problem(ctx, problem, &pctx)) {
3433 e2fsck_write_inode(ctx, ino, inode,
3437 check_blocks(ctx, &pctx, block_buf);
3441 * Check for inodes who might have been part of the
3442 * orphaned list linked list. They should have gotten
3443 * dealt with by now, unless the list had somehow been
3446 * FIXME: In the future, inodes which are still in use
3447 * (and which are therefore) pending truncation should
3448 * be handled specially. Right now we just clear the
3449 * dtime field, and the normal e2fsck handling of
3450 * inodes where i_size and the inode blocks are
3451 * inconsistent is to fix i_size, instead of releasing
3452 * the extra blocks. This won't catch the inodes that
3453 * was at the end of the orphan list, but it's better
3454 * than nothing. The right answer is that there
3455 * shouldn't be any bugs in the orphan list handling. :-)
3457 if (inode->i_dtime && !busted_fs_time &&
3458 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3459 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3460 inode->i_dtime = inode->i_links_count ?
3462 e2fsck_write_inode(ctx, ino, inode,
3468 * This code assumes that deleted inodes have
3469 * i_links_count set to 0.
3471 if (!inode->i_links_count) {
3472 if (!inode->i_dtime && inode->i_mode) {
3473 if (fix_problem(ctx,
3474 PR_1_ZERO_DTIME, &pctx)) {
3475 inode->i_dtime = time(NULL);
3476 e2fsck_write_inode(ctx, ino, inode,
3483 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3484 * deleted files. Oops.
3486 * Since all new ext2 implementations get this right,
3487 * we now assume that the case of non-zero
3488 * i_links_count and non-zero dtime means that we
3489 * should keep the file, not delete it.
3492 if (inode->i_dtime) {
3493 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3495 e2fsck_write_inode(ctx, ino, inode, "pass1");
3499 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3500 switch (fs->super->s_creator_os) {
3502 frag = inode->osd2.linux2.l_i_frag;
3503 fsize = inode->osd2.linux2.l_i_fsize;
3506 frag = inode->osd2.hurd2.h_i_frag;
3507 fsize = inode->osd2.hurd2.h_i_fsize;
3510 frag = inode->osd2.masix2.m_i_frag;
3511 fsize = inode->osd2.masix2.m_i_fsize;
3517 if (inode->i_faddr || frag || fsize ||
3518 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3519 mark_inode_bad(ctx, ino);
3520 if (inode->i_flags & EXT2_IMAGIC_FL) {
3522 if (!ctx->inode_imagic_map)
3523 alloc_imagic_map(ctx);
3524 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3527 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3528 inode->i_flags &= ~EXT2_IMAGIC_FL;
3529 e2fsck_write_inode(ctx, ino,
3535 check_inode_extra_space(ctx, &pctx);
3537 if (LINUX_S_ISDIR(inode->i_mode)) {
3538 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3539 e2fsck_add_dir_info(ctx, ino, 0);
3540 ctx->fs_directory_count++;
3541 } else if (LINUX_S_ISREG (inode->i_mode)) {
3542 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3543 ctx->fs_regular_count++;
3544 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3545 e2fsck_pass1_check_device_inode(fs, inode)) {
3546 check_immutable(ctx, &pctx);
3547 check_size(ctx, &pctx);
3548 ctx->fs_chardev_count++;
3549 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3550 e2fsck_pass1_check_device_inode(fs, inode)) {
3551 check_immutable(ctx, &pctx);
3552 check_size(ctx, &pctx);
3553 ctx->fs_blockdev_count++;
3554 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3555 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3556 check_immutable(ctx, &pctx);
3557 ctx->fs_symlinks_count++;
3558 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3559 ctx->fs_fast_symlinks_count++;
3560 check_blocks(ctx, &pctx, block_buf);
3564 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3565 e2fsck_pass1_check_device_inode(fs, inode)) {
3566 check_immutable(ctx, &pctx);
3567 check_size(ctx, &pctx);
3568 ctx->fs_fifo_count++;
3569 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3570 e2fsck_pass1_check_device_inode(fs, inode)) {
3571 check_immutable(ctx, &pctx);
3572 check_size(ctx, &pctx);
3573 ctx->fs_sockets_count++;
3575 mark_inode_bad(ctx, ino);
3576 if (inode->i_block[EXT2_IND_BLOCK])
3577 ctx->fs_ind_count++;
3578 if (inode->i_block[EXT2_DIND_BLOCK])
3579 ctx->fs_dind_count++;
3580 if (inode->i_block[EXT2_TIND_BLOCK])
3581 ctx->fs_tind_count++;
3582 if (inode->i_block[EXT2_IND_BLOCK] ||
3583 inode->i_block[EXT2_DIND_BLOCK] ||
3584 inode->i_block[EXT2_TIND_BLOCK] ||
3585 inode->i_file_acl) {
3586 inodes_to_process[process_inode_count].ino = ino;
3587 inodes_to_process[process_inode_count].inode = *inode;
3588 process_inode_count++;
3590 check_blocks(ctx, &pctx, block_buf);
3592 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3595 if (process_inode_count >= ctx->process_inode_size) {
3596 process_inodes(ctx, block_buf);
3598 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3602 process_inodes(ctx, block_buf);
3603 ext2fs_close_inode_scan(scan);
3604 ehandler_operation(0);
3607 * If any extended attribute blocks' reference counts need to
3608 * be adjusted, either up (ctx->refcount_extra), or down
3609 * (ctx->refcount), then fix them.
3611 if (ctx->refcount) {
3612 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3613 ea_refcount_free(ctx->refcount);
3616 if (ctx->refcount_extra) {
3617 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3619 ea_refcount_free(ctx->refcount_extra);
3620 ctx->refcount_extra = 0;
3623 if (ctx->invalid_bitmaps)
3624 handle_fs_bad_blocks(ctx);
3626 /* We don't need the block_ea_map any more */
3627 ext2fs_free_block_bitmap(ctx->block_ea_map);
3628 ctx->block_ea_map = 0;
3630 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3631 ext2fs_block_bitmap save_bmap;
3633 save_bmap = fs->block_map;
3634 fs->block_map = ctx->block_found_map;
3635 clear_problem_context(&pctx);
3636 pctx.errcode = ext2fs_create_resize_inode(fs);
3638 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3639 /* Should never get here */
3640 ctx->flags |= E2F_FLAG_ABORT;
3643 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3645 inode->i_mtime = time(NULL);
3646 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3648 fs->block_map = save_bmap;
3649 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3652 if (ctx->flags & E2F_FLAG_RESTART) {
3654 * Only the master copy of the superblock and block
3655 * group descriptors are going to be written during a
3656 * restart, so set the superblock to be used to be the
3657 * master superblock.
3659 ctx->use_superblock = 0;
3664 if (ctx->block_dup_map) {
3665 if (ctx->options & E2F_OPT_PREEN) {
3666 clear_problem_context(&pctx);
3667 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3669 e2fsck_pass1_dupblocks(ctx, block_buf);
3671 ext2fs_free_mem(&inodes_to_process);
3673 e2fsck_use_inode_shortcuts(ctx, 0);
3675 ext2fs_free_mem(&block_buf);
3676 ext2fs_free_mem(&inode);
3680 * When the inode_scan routines call this callback at the end of the
3681 * glock group, call process_inodes.
3683 static errcode_t scan_callback(ext2_filsys fs,
3684 dgrp_t group, void * priv_data)
3686 struct scan_callback_struct *scan_struct;
3689 scan_struct = (struct scan_callback_struct *) priv_data;
3690 ctx = scan_struct->ctx;
3692 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3695 if ((ctx->progress)(ctx, 1, group+1,
3696 ctx->fs->group_desc_count))
3697 return EXT2_ET_CANCEL_REQUESTED;
3703 * Process the inodes in the "inodes to process" list.
3705 static void process_inodes(e2fsck_t ctx, char *block_buf)
3708 struct ext2_inode *old_stashed_inode;
3709 ext2_ino_t old_stashed_ino;
3710 const char *old_operation;
3712 struct problem_context pctx;
3714 /* begin process_inodes */
3715 if (process_inode_count == 0)
3717 old_operation = ehandler_operation(0);
3718 old_stashed_inode = ctx->stashed_inode;
3719 old_stashed_ino = ctx->stashed_ino;
3720 qsort(inodes_to_process, process_inode_count,
3721 sizeof(struct process_inode_block), process_inode_cmp);
3722 clear_problem_context(&pctx);
3723 for (i=0; i < process_inode_count; i++) {
3724 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3725 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3726 sprintf(buf, _("reading indirect blocks of inode %u"),
3728 ehandler_operation(buf);
3729 check_blocks(ctx, &pctx, block_buf);
3730 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3733 ctx->stashed_inode = old_stashed_inode;
3734 ctx->stashed_ino = old_stashed_ino;
3735 process_inode_count = 0;
3736 /* end process inodes */
3738 ehandler_operation(old_operation);
3741 static int process_inode_cmp(const void *a, const void *b)
3743 const struct process_inode_block *ib_a =
3744 (const struct process_inode_block *) a;
3745 const struct process_inode_block *ib_b =
3746 (const struct process_inode_block *) b;
3749 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3750 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3752 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3757 * Mark an inode as being bad in some what
3759 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3761 struct problem_context pctx;
3763 if (!ctx->inode_bad_map) {
3764 clear_problem_context(&pctx);
3766 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3767 _("bad inode map"), &ctx->inode_bad_map);
3770 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3771 /* Should never get here */
3772 ctx->flags |= E2F_FLAG_ABORT;
3776 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3781 * This procedure will allocate the inode imagic table
3783 static void alloc_imagic_map(e2fsck_t ctx)
3785 struct problem_context pctx;
3787 clear_problem_context(&pctx);
3788 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3789 _("imagic inode map"),
3790 &ctx->inode_imagic_map);
3793 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3794 /* Should never get here */
3795 ctx->flags |= E2F_FLAG_ABORT;
3801 * Marks a block as in use, setting the dup_map if it's been set
3802 * already. Called by process_block and process_bad_block.
3804 * WARNING: Assumes checks have already been done to make sure block
3805 * is valid. This is true in both process_block and process_bad_block.
3807 static void mark_block_used(e2fsck_t ctx, blk_t block)
3809 struct problem_context pctx;
3811 clear_problem_context(&pctx);
3813 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3814 if (!ctx->block_dup_map) {
3815 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3816 _("multiply claimed block map"),
3817 &ctx->block_dup_map);
3820 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3822 /* Should never get here */
3823 ctx->flags |= E2F_FLAG_ABORT;
3827 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3829 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3834 * Adjust the extended attribute block's reference counts at the end
3835 * of pass 1, either by subtracting out references for EA blocks that
3836 * are still referenced in ctx->refcount, or by adding references for
3837 * EA blocks that had extra references as accounted for in
3838 * ctx->refcount_extra.
3840 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3841 char *block_buf, int adjust_sign)
3843 struct ext2_ext_attr_header *header;
3844 struct problem_context pctx;
3845 ext2_filsys fs = ctx->fs;
3850 clear_problem_context(&pctx);
3852 ea_refcount_intr_begin(refcount);
3854 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3857 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3859 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3862 header = (struct ext2_ext_attr_header *) block_buf;
3863 pctx.blkcount = header->h_refcount;
3864 should_be = header->h_refcount + adjust_sign * count;
3865 pctx.num = should_be;
3866 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3867 header->h_refcount = should_be;
3868 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3871 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3879 * Handle processing the extended attribute blocks
3881 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3884 ext2_filsys fs = ctx->fs;
3885 ext2_ino_t ino = pctx->ino;
3886 struct ext2_inode *inode = pctx->inode;
3889 struct ext2_ext_attr_header *header;
3890 struct ext2_ext_attr_entry *entry;
3894 blk = inode->i_file_acl;
3899 * If the Extended attribute flag isn't set, then a non-zero
3900 * file acl means that the inode is corrupted.
3902 * Or if the extended attribute block is an invalid block,
3903 * then the inode is also corrupted.
3905 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3906 (blk < fs->super->s_first_data_block) ||
3907 (blk >= fs->super->s_blocks_count)) {
3908 mark_inode_bad(ctx, ino);
3912 /* If ea bitmap hasn't been allocated, create it */
3913 if (!ctx->block_ea_map) {
3914 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3915 _("ext attr block map"),
3916 &ctx->block_ea_map);
3917 if (pctx->errcode) {
3919 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3920 ctx->flags |= E2F_FLAG_ABORT;
3925 /* Create the EA refcount structure if necessary */
3926 if (!ctx->refcount) {
3927 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3928 if (pctx->errcode) {
3930 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3931 ctx->flags |= E2F_FLAG_ABORT;
3936 /* Have we seen this EA block before? */
3937 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3938 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3940 /* Ooops, this EA was referenced more than it stated */
3941 if (!ctx->refcount_extra) {
3942 pctx->errcode = ea_refcount_create(0,
3943 &ctx->refcount_extra);
3944 if (pctx->errcode) {
3946 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3947 ctx->flags |= E2F_FLAG_ABORT;
3951 ea_refcount_increment(ctx->refcount_extra, blk, 0);
3956 * OK, we haven't seen this EA block yet. So we need to
3960 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3961 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
3963 header = (struct ext2_ext_attr_header *) block_buf;
3964 pctx->blk = inode->i_file_acl;
3965 if (((ctx->ext_attr_ver == 1) &&
3966 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
3967 ((ctx->ext_attr_ver == 2) &&
3968 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
3969 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
3973 if (header->h_blocks != 1) {
3974 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
3978 region = region_create(0, fs->blocksize);
3980 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
3981 ctx->flags |= E2F_FLAG_ABORT;
3984 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
3985 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
3989 entry = (struct ext2_ext_attr_entry *)(header+1);
3990 end = block_buf + fs->blocksize;
3991 while ((char *)entry < end && *(__u32 *)entry) {
3992 if (region_allocate(region, (char *)entry - (char *)header,
3993 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
3994 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
3997 if ((ctx->ext_attr_ver == 1 &&
3998 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
3999 (ctx->ext_attr_ver == 2 &&
4000 entry->e_name_index == 0)) {
4001 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4004 if (entry->e_value_block != 0) {
4005 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4008 if (entry->e_value_size &&
4009 region_allocate(region, entry->e_value_offs,
4010 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4011 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4014 entry = EXT2_EXT_ATTR_NEXT(entry);
4016 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4017 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4020 region_free(region);
4022 count = header->h_refcount - 1;
4024 ea_refcount_store(ctx->refcount, blk, count);
4025 mark_block_used(ctx, blk);
4026 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4031 inode->i_file_acl = 0;
4032 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4036 /* Returns 1 if bad htree, 0 if OK */
4037 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4038 ext2_ino_t ino FSCK_ATTR((unused)),
4039 struct ext2_inode *inode,
4042 struct ext2_dx_root_info *root;
4043 ext2_filsys fs = ctx->fs;
4047 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4048 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4049 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4050 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4053 blk = inode->i_block[0];
4055 (blk < fs->super->s_first_data_block) ||
4056 (blk >= fs->super->s_blocks_count)) &&
4057 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4060 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4061 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4064 /* XXX should check that beginning matches a directory */
4065 root = (struct ext2_dx_root_info *) (block_buf + 24);
4067 if ((root->reserved_zero || root->info_length < 8) &&
4068 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4071 pctx->num = root->hash_version;
4072 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4073 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4074 (root->hash_version != EXT2_HASH_TEA) &&
4075 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4078 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4079 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4082 pctx->num = root->indirect_levels;
4083 if ((root->indirect_levels > 1) &&
4084 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4091 * This subroutine is called on each inode to account for all of the
4092 * blocks used by that inode.
4094 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4097 ext2_filsys fs = ctx->fs;
4098 struct process_block_struct_1 pb;
4099 ext2_ino_t ino = pctx->ino;
4100 struct ext2_inode *inode = pctx->inode;
4102 int dirty_inode = 0;
4108 pb.num_illegal_blocks = 0;
4109 pb.suppress = 0; pb.clear = 0;
4112 pb.previous_block = 0;
4113 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4114 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4115 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4122 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4123 if (fs->super->s_feature_incompat &
4124 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4127 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4128 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4134 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4137 if (ext2fs_inode_has_valid_blocks(inode))
4138 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4139 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4140 block_buf, process_block, &pb);
4141 end_problem_latch(ctx, PR_LATCH_BLOCK);
4142 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4143 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4146 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4148 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4149 ctx->fs_fragmented++;
4152 inode->i_links_count = 0;
4153 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4154 inode->i_dtime = time(NULL);
4156 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4157 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4158 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4160 * The inode was probably partially accounted for
4161 * before processing was aborted, so we need to
4162 * restart the pass 1 scan.
4164 ctx->flags |= E2F_FLAG_RESTART;
4168 if (inode->i_flags & EXT2_INDEX_FL) {
4169 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4170 inode->i_flags &= ~EXT2_INDEX_FL;
4174 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4178 if (ctx->dirs_to_hash && pb.is_dir &&
4179 !(inode->i_flags & EXT2_INDEX_FL) &&
4180 ((inode->i_size / fs->blocksize) >= 3))
4181 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4183 if (!pb.num_blocks && pb.is_dir) {
4184 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4185 inode->i_links_count = 0;
4186 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4187 inode->i_dtime = time(NULL);
4189 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4190 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4191 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4192 ctx->fs_directory_count--;
4197 pb.num_blocks *= (fs->blocksize / 512);
4200 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4201 if (nblock > (pb.last_block + 1))
4203 else if (nblock < (pb.last_block + 1)) {
4204 if (((pb.last_block + 1) - nblock) >
4205 fs->super->s_prealloc_dir_blocks)
4209 size = EXT2_I_SIZE(inode);
4210 if ((pb.last_block >= 0) &&
4211 (size < (__u64) pb.last_block * fs->blocksize))
4213 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4216 /* i_size for symlinks is checked elsewhere */
4217 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4218 pctx->num = (pb.last_block+1) * fs->blocksize;
4219 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4220 inode->i_size = pctx->num;
4221 if (!LINUX_S_ISDIR(inode->i_mode))
4222 inode->i_size_high = pctx->num >> 32;
4227 if (LINUX_S_ISREG(inode->i_mode) &&
4228 (inode->i_size_high || inode->i_size & 0x80000000UL))
4230 if (pb.num_blocks != inode->i_blocks) {
4231 pctx->num = pb.num_blocks;
4232 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4233 inode->i_blocks = pb.num_blocks;
4240 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4245 * This is a helper function for check_blocks().
4247 static int process_block(ext2_filsys fs,
4249 e2_blkcnt_t blockcnt,
4250 blk_t ref_block FSCK_ATTR((unused)),
4251 int ref_offset FSCK_ATTR((unused)),
4254 struct process_block_struct_1 *p;
4255 struct problem_context *pctx;
4256 blk_t blk = *block_nr;
4261 p = (struct process_block_struct_1 *) priv_data;
4265 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4266 /* todo: Check that the comprblk_fl is high, that the
4267 blkaddr pattern looks right (all non-holes up to
4268 first EXT2FS_COMPRESSED_BLKADDR, then all
4269 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4270 that the feature_incompat bit is high, and that the
4271 inode is a regular file. If we're doing a "full
4272 check" (a concept introduced to e2fsck by e2compr,
4273 meaning that we look at data blocks as well as
4274 metadata) then call some library routine that
4275 checks the compressed data. I'll have to think
4276 about this, because one particularly important
4277 problem to be able to fix is to recalculate the
4278 cluster size if necessary. I think that perhaps
4279 we'd better do most/all e2compr-specific checks
4280 separately, after the non-e2compr checks. If not
4281 doing a full check, it may be useful to test that
4282 the personality is linux; e.g. if it isn't then
4283 perhaps this really is just an illegal block. */
4288 if (p->is_dir == 0) {
4290 * Should never happen, since only directories
4291 * get called with BLOCK_FLAG_HOLE
4294 printf("process_block() called with blk == 0, "
4295 "blockcnt=%d, inode %lu???\n",
4302 if (blockcnt * fs->blocksize < p->inode->i_size) {
4309 * Simplistic fragmentation check. We merely require that the
4310 * file be contiguous. (Which can never be true for really
4311 * big files that are greater than a block group.)
4313 if (!HOLE_BLKADDR(p->previous_block)) {
4314 if (p->previous_block+1 != blk)
4317 p->previous_block = blk;
4319 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4320 problem = PR_1_TOOBIG_DIR;
4321 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4322 problem = PR_1_TOOBIG_REG;
4323 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4324 problem = PR_1_TOOBIG_SYMLINK;
4326 if (blk < fs->super->s_first_data_block ||
4327 blk >= fs->super->s_blocks_count)
4328 problem = PR_1_ILLEGAL_BLOCK_NUM;
4331 p->num_illegal_blocks++;
4332 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4333 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4337 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4339 set_latch_flags(PR_LATCH_BLOCK,
4344 pctx->blkcount = blockcnt;
4345 if (fix_problem(ctx, problem, pctx)) {
4346 blk = *block_nr = 0;
4347 ret_code = BLOCK_CHANGED;
4353 if (p->ino == EXT2_RESIZE_INO) {
4355 * The resize inode has already be sanity checked
4356 * during pass #0 (the superblock checks). All we
4357 * have to do is mark the double indirect block as
4358 * being in use; all of the other blocks are handled
4359 * by mark_table_blocks()).
4361 if (blockcnt == BLOCK_COUNT_DIND)
4362 mark_block_used(ctx, blk);
4364 mark_block_used(ctx, blk);
4367 p->last_block = blockcnt;
4369 if (p->is_dir && (blockcnt >= 0)) {
4370 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4372 if (pctx->errcode) {
4374 pctx->num = blockcnt;
4375 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4376 /* Should never get here */
4377 ctx->flags |= E2F_FLAG_ABORT;
4384 static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4386 e2_blkcnt_t blockcnt,
4387 blk_t ref_block FSCK_ATTR((unused)),
4388 int ref_offset FSCK_ATTR((unused)),
4389 void *priv_data EXT2FS_ATTR((unused)))
4392 * Note: This function processes blocks for the bad blocks
4393 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4396 printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4401 * This routine gets called at the end of pass 1 if bad blocks are
4402 * detected in the superblock, group descriptors, inode_bitmaps, or
4403 * block bitmaps. At this point, all of the blocks have been mapped
4404 * out, so we can try to allocate new block(s) to replace the bad
4407 static void handle_fs_bad_blocks(e2fsck_t ctx)
4409 printf("Bad blocks detected on your filesystem\n"
4410 "You should get your data off as the device will soon die\n");
4414 * This routine marks all blocks which are used by the superblock,
4415 * group descriptors, inode bitmaps, and block bitmaps.
4417 static void mark_table_blocks(e2fsck_t ctx)
4419 ext2_filsys fs = ctx->fs;
4423 struct problem_context pctx;
4425 clear_problem_context(&pctx);
4427 block = fs->super->s_first_data_block;
4428 for (i = 0; i < fs->group_desc_count; i++) {
4431 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4434 * Mark the blocks used for the inode table
4436 if (fs->group_desc[i].bg_inode_table) {
4437 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4438 j < fs->inode_blocks_per_group;
4440 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4443 if (fix_problem(ctx,
4444 PR_1_ITABLE_CONFLICT, &pctx)) {
4445 ctx->invalid_inode_table_flag[i]++;
4446 ctx->invalid_bitmaps++;
4449 ext2fs_mark_block_bitmap(ctx->block_found_map, b);
4455 * Mark block used for the block bitmap
4457 if (fs->group_desc[i].bg_block_bitmap) {
4458 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4459 fs->group_desc[i].bg_block_bitmap)) {
4460 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4461 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4462 ctx->invalid_block_bitmap_flag[i]++;
4463 ctx->invalid_bitmaps++;
4466 ext2fs_mark_block_bitmap(ctx->block_found_map,
4467 fs->group_desc[i].bg_block_bitmap);
4471 * Mark block used for the inode bitmap
4473 if (fs->group_desc[i].bg_inode_bitmap) {
4474 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4475 fs->group_desc[i].bg_inode_bitmap)) {
4476 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4477 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4478 ctx->invalid_inode_bitmap_flag[i]++;
4479 ctx->invalid_bitmaps++;
4482 ext2fs_mark_block_bitmap(ctx->block_found_map,
4483 fs->group_desc[i].bg_inode_bitmap);
4486 block += fs->super->s_blocks_per_group;
4491 * Thes subroutines short circuits ext2fs_get_blocks and
4492 * ext2fs_check_directory; we use them since we already have the inode
4493 * structure, so there's no point in letting the ext2fs library read
4496 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4499 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4502 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4503 return EXT2_ET_CALLBACK_NOTHANDLED;
4505 for (i=0; i < EXT2_N_BLOCKS; i++)
4506 blocks[i] = ctx->stashed_inode->i_block[i];
4510 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4511 struct ext2_inode *inode)
4513 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4515 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4516 return EXT2_ET_CALLBACK_NOTHANDLED;
4517 *inode = *ctx->stashed_inode;
4521 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4522 struct ext2_inode *inode)
4524 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4526 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4527 *ctx->stashed_inode = *inode;
4528 return EXT2_ET_CALLBACK_NOTHANDLED;
4531 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4533 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4535 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4536 return EXT2_ET_CALLBACK_NOTHANDLED;
4538 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4539 return EXT2_ET_NO_DIRECTORY;
4543 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4545 ext2_filsys fs = ctx->fs;
4548 fs->get_blocks = pass1_get_blocks;
4549 fs->check_directory = pass1_check_directory;
4550 fs->read_inode = pass1_read_inode;
4551 fs->write_inode = pass1_write_inode;
4552 ctx->stashed_ino = 0;
4555 fs->check_directory = 0;
4557 fs->write_inode = 0;
4562 * pass1b.c --- Pass #1b of e2fsck
4564 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4565 * only invoked if pass 1 discovered blocks which are in use by more
4568 * Pass1B scans the data blocks of all the inodes again, generating a
4569 * complete list of duplicate blocks and which inodes have claimed
4572 * Pass1C does a tree-traversal of the filesystem, to determine the
4573 * parent directories of these inodes. This step is necessary so that
4574 * e2fsck can print out the pathnames of affected inodes.
4576 * Pass1D is a reconciliation pass. For each inode with duplicate
4577 * blocks, the user is prompted if s/he would like to clone the file
4578 * (so that the file gets a fresh copy of the duplicated blocks) or
4579 * simply to delete the file.
4584 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4585 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4586 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4588 /* Define an extension to the ext2 library's block count information */
4589 #define BLOCK_COUNT_EXTATTR (-5)
4593 struct block_el *next;
4598 struct inode_el *next;
4603 struct inode_el *inode_list;
4607 * This structure stores information about a particular inode which
4608 * is sharing blocks with other inodes. This information is collected
4609 * to display to the user, so that the user knows what files he or she
4610 * is dealing with, when trying to decide how to resolve the conflict
4611 * of multiply-claimed blocks.
4616 struct ext2_inode inode;
4617 struct block_el *block_list;
4620 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
4621 e2_blkcnt_t blockcnt, blk_t ref_blk,
4622 int ref_offset, void *priv_data);
4623 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4624 struct dup_inode *dp, char *block_buf);
4625 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4626 struct dup_inode *dp, char* block_buf);
4627 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4629 static void pass1b(e2fsck_t ctx, char *block_buf);
4630 static void pass1c(e2fsck_t ctx, char *block_buf);
4631 static void pass1d(e2fsck_t ctx, char *block_buf);
4633 static int dup_inode_count = 0;
4635 static dict_t blk_dict, ino_dict;
4637 static ext2fs_inode_bitmap inode_dup_map;
4639 static int dict_int_cmp(const void *a, const void *b)
4650 * Add a duplicate block record
4652 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4653 struct ext2_inode *inode)
4656 struct dup_block *db;
4657 struct dup_inode *di;
4658 struct block_el *blk_el;
4659 struct inode_el *ino_el;
4661 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4663 db = (struct dup_block *) dnode_get(n);
4665 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4666 sizeof(struct dup_block), "duplicate block header");
4669 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4671 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4672 sizeof(struct inode_el), "inode element");
4673 ino_el->inode = ino;
4674 ino_el->next = db->inode_list;
4675 db->inode_list = ino_el;
4678 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4680 di = (struct dup_inode *) dnode_get(n);
4682 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4683 sizeof(struct dup_inode), "duplicate inode header");
4684 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0;
4685 di->num_dupblocks = 0;
4688 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4690 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4691 sizeof(struct block_el), "block element");
4692 blk_el->block = blk;
4693 blk_el->next = di->block_list;
4694 di->block_list = blk_el;
4695 di->num_dupblocks++;
4699 * Free a duplicate inode record
4701 static void inode_dnode_free(dnode_t *node)
4703 struct dup_inode *di;
4704 struct block_el *p, *next;
4706 di = (struct dup_inode *) dnode_get(node);
4707 for (p = di->block_list; p; p = next) {
4715 * Free a duplicate block record
4717 static void block_dnode_free(dnode_t *node)
4719 struct dup_block *db;
4720 struct inode_el *p, *next;
4722 db = (struct dup_block *) dnode_get(node);
4723 for (p = db->inode_list; p; p = next) {
4732 * Main procedure for handling duplicate blocks
4734 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4736 ext2_filsys fs = ctx->fs;
4737 struct problem_context pctx;
4739 clear_problem_context(&pctx);
4741 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4742 _("multiply claimed inode map"), &inode_dup_map);
4744 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4745 ctx->flags |= E2F_FLAG_ABORT;
4749 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4750 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4751 dict_set_allocator(&ino_dict, inode_dnode_free);
4752 dict_set_allocator(&blk_dict, block_dnode_free);
4754 pass1b(ctx, block_buf);
4755 pass1c(ctx, block_buf);
4756 pass1d(ctx, block_buf);
4759 * Time to free all of the accumulated data structures that we
4760 * don't need anymore.
4762 dict_free_nodes(&ino_dict);
4763 dict_free_nodes(&blk_dict);
4767 * Scan the inodes looking for inodes that contain duplicate blocks.
4769 struct process_block_struct_1b {
4773 struct ext2_inode *inode;
4774 struct problem_context *pctx;
4777 static void pass1b(e2fsck_t ctx, char *block_buf)
4779 ext2_filsys fs = ctx->fs;
4781 struct ext2_inode inode;
4782 ext2_inode_scan scan;
4783 struct process_block_struct_1b pb;
4784 struct problem_context pctx;
4786 clear_problem_context(&pctx);
4788 if (!(ctx->options & E2F_OPT_PREEN))
4789 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4790 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4793 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4794 ctx->flags |= E2F_FLAG_ABORT;
4797 ctx->stashed_inode = &inode;
4800 pctx.str = "pass1b";
4802 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4803 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4806 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4807 ctx->flags |= E2F_FLAG_ABORT;
4812 pctx.ino = ctx->stashed_ino = ino;
4813 if ((ino != EXT2_BAD_INO) &&
4814 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4821 if (ext2fs_inode_has_valid_blocks(&inode) ||
4822 (ino == EXT2_BAD_INO))
4823 pctx.errcode = ext2fs_block_iterate2(fs, ino,
4824 0, block_buf, process_pass1b_block, &pb);
4825 if (inode.i_file_acl)
4826 process_pass1b_block(fs, &inode.i_file_acl,
4827 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4828 if (pb.dup_blocks) {
4829 end_problem_latch(ctx, PR_LATCH_DBLOCK);
4830 if (ino >= EXT2_FIRST_INODE(fs->super) ||
4831 ino == EXT2_ROOT_INO)
4835 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4837 ext2fs_close_inode_scan(scan);
4838 e2fsck_use_inode_shortcuts(ctx, 0);
4841 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4843 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4844 blk_t ref_blk FSCK_ATTR((unused)),
4845 int ref_offset FSCK_ATTR((unused)),
4848 struct process_block_struct_1b *p;
4851 if (HOLE_BLKADDR(*block_nr))
4853 p = (struct process_block_struct_1b *) priv_data;
4856 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4859 /* OK, this is a duplicate block */
4860 if (p->ino != EXT2_BAD_INO) {
4861 p->pctx->blk = *block_nr;
4862 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4865 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4867 add_dupe(ctx, p->ino, *block_nr, p->inode);
4873 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4874 * is used so that we can print pathnames when prompting the user for
4877 struct search_dir_struct {
4879 ext2_ino_t first_inode;
4880 ext2_ino_t max_inode;
4883 static int search_dirent_proc(ext2_ino_t dir, int entry,
4884 struct ext2_dir_entry *dirent,
4885 int offset FSCK_ATTR((unused)),
4886 int blocksize FSCK_ATTR((unused)),
4887 char *buf FSCK_ATTR((unused)),
4890 struct search_dir_struct *sd;
4891 struct dup_inode *p;
4894 sd = (struct search_dir_struct *) priv_data;
4896 if (dirent->inode > sd->max_inode)
4897 /* Should abort this inode, but not everything */
4900 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4901 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4904 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4907 p = (struct dup_inode *) dnode_get(n);
4911 return sd->count ? 0 : DIRENT_ABORT;
4915 static void pass1c(e2fsck_t ctx, char *block_buf)
4917 ext2_filsys fs = ctx->fs;
4918 struct search_dir_struct sd;
4919 struct problem_context pctx;
4921 clear_problem_context(&pctx);
4923 if (!(ctx->options & E2F_OPT_PREEN))
4924 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4927 * Search through all directories to translate inodes to names
4928 * (by searching for the containing directory for that inode.)
4930 sd.count = dup_inode_count;
4931 sd.first_inode = EXT2_FIRST_INODE(fs->super);
4932 sd.max_inode = fs->super->s_inodes_count;
4933 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4934 search_dirent_proc, &sd);
4937 static void pass1d(e2fsck_t ctx, char *block_buf)
4939 ext2_filsys fs = ctx->fs;
4940 struct dup_inode *p, *t;
4941 struct dup_block *q;
4942 ext2_ino_t *shared, ino;
4947 struct problem_context pctx;
4952 clear_problem_context(&pctx);
4954 if (!(ctx->options & E2F_OPT_PREEN))
4955 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
4956 e2fsck_read_bitmaps(ctx);
4958 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
4959 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
4960 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
4961 sizeof(ext2_ino_t) * dict_count(&ino_dict),
4962 "Shared inode list");
4963 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
4964 p = (struct dup_inode *) dnode_get(n);
4967 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
4968 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
4972 * Find all of the inodes which share blocks with this
4973 * one. First we find all of the duplicate blocks
4974 * belonging to this inode, and then search each block
4975 * get the list of inodes, and merge them together.
4977 for (s = p->block_list; s; s = s->next) {
4978 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
4980 continue; /* Should never happen... */
4981 q = (struct dup_block *) dnode_get(m);
4984 if (check_if_fs_block(ctx, s->block)) {
4990 * Add all inodes used by this block to the
4991 * shared[] --- which is a unique list, so
4992 * if an inode is already in shared[], don't
4995 for (r = q->inode_list; r; r = r->next) {
4996 if (r->inode == ino)
4998 for (i = 0; i < shared_len; i++)
4999 if (shared[i] == r->inode)
5001 if (i == shared_len) {
5002 shared[shared_len++] = r->inode;
5008 * Report the inode that we are working on
5010 pctx.inode = &p->inode;
5013 pctx.blkcount = p->num_dupblocks;
5014 pctx.num = meta_data ? shared_len+1 : shared_len;
5015 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5020 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5022 for (i = 0; i < shared_len; i++) {
5023 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5025 continue; /* should never happen */
5026 t = (struct dup_inode *) dnode_get(m);
5028 * Report the inode that we are sharing with
5030 pctx.inode = &t->inode;
5031 pctx.ino = shared[i];
5033 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5036 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5039 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5040 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5042 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5046 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5047 delete_file(ctx, ino, p, block_buf);
5049 ext2fs_unmark_valid(fs);
5051 ext2fs_free_mem(&shared);
5055 * Drop the refcount on the dup_block structure, and clear the entry
5056 * in the block_dup_map if appropriate.
5058 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5061 if (p->num_bad <= 0 ||
5062 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5063 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5066 static int delete_file_block(ext2_filsys fs,
5068 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5069 blk_t ref_block FSCK_ATTR((unused)),
5070 int ref_offset FSCK_ATTR((unused)),
5073 struct process_block_struct_1b *pb;
5074 struct dup_block *p;
5078 pb = (struct process_block_struct_1b *) priv_data;
5081 if (HOLE_BLKADDR(*block_nr))
5084 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5085 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5087 p = (struct dup_block *) dnode_get(n);
5088 decrement_badcount(ctx, *block_nr, p);
5090 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5093 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5094 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5100 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5101 struct dup_inode *dp, char* block_buf)
5103 ext2_filsys fs = ctx->fs;
5104 struct process_block_struct_1b pb;
5105 struct ext2_inode inode;
5106 struct problem_context pctx;
5109 clear_problem_context(&pctx);
5110 pctx.ino = pb.ino = ino;
5111 pb.dup_blocks = dp->num_dupblocks;
5113 pctx.str = "delete_file";
5115 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5116 if (ext2fs_inode_has_valid_blocks(&inode))
5117 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5118 delete_file_block, &pb);
5120 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5121 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5122 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5123 if (ctx->inode_bad_map)
5124 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5125 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5127 /* Inode may have changed by block_iterate, so reread it */
5128 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5129 inode.i_links_count = 0;
5130 inode.i_dtime = time(NULL);
5131 if (inode.i_file_acl &&
5132 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5134 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5135 block_buf, -1, &count);
5136 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5141 pctx.blk = inode.i_file_acl;
5142 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5145 * If the count is zero, then arrange to have the
5146 * block deleted. If the block is in the block_dup_map,
5147 * also call delete_file_block since it will take care
5148 * of keeping the accounting straight.
5151 ext2fs_test_block_bitmap(ctx->block_dup_map,
5153 delete_file_block(fs, &inode.i_file_acl,
5154 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5156 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5159 struct clone_struct {
5166 static int clone_file_block(ext2_filsys fs,
5168 e2_blkcnt_t blockcnt,
5169 blk_t ref_block FSCK_ATTR((unused)),
5170 int ref_offset FSCK_ATTR((unused)),
5173 struct dup_block *p;
5176 struct clone_struct *cs = (struct clone_struct *) priv_data;
5182 if (HOLE_BLKADDR(*block_nr))
5185 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5186 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5188 p = (struct dup_block *) dnode_get(n);
5189 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5192 cs->errcode = retval;
5195 if (cs->dir && (blockcnt >= 0)) {
5196 retval = ext2fs_set_dir_block(fs->dblist,
5197 cs->dir, new_block, blockcnt);
5199 cs->errcode = retval;
5204 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5207 cs->errcode = retval;
5210 retval = io_channel_write_blk(fs->io, new_block, 1,
5213 cs->errcode = retval;
5216 decrement_badcount(ctx, *block_nr, p);
5217 *block_nr = new_block;
5218 ext2fs_mark_block_bitmap(ctx->block_found_map,
5220 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5221 return BLOCK_CHANGED;
5223 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5229 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5230 struct dup_inode *dp, char* block_buf)
5232 ext2_filsys fs = ctx->fs;
5234 struct clone_struct cs;
5235 struct problem_context pctx;
5238 struct inode_el *ino_el;
5239 struct dup_block *db;
5240 struct dup_inode *di;
5242 clear_problem_context(&pctx);
5246 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5250 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5254 pctx.str = "clone_file";
5255 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5256 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5257 clone_file_block, &cs);
5258 ext2fs_mark_bb_dirty(fs);
5260 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5261 retval = pctx.errcode;
5265 bb_error_msg(_("returned from clone_file_block"));
5266 retval = cs.errcode;
5269 /* The inode may have changed on disk, so we have to re-read it */
5270 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5271 blk = dp->inode.i_file_acl;
5272 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5273 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5275 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5277 * If we cloned the EA block, find all other inodes
5278 * which refered to that EA block, and modify
5279 * them to point to the new EA block.
5281 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5282 db = (struct dup_block *) dnode_get(n);
5283 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5284 if (ino_el->inode == ino)
5286 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5287 di = (struct dup_inode *) dnode_get(n);
5288 if (di->inode.i_file_acl == blk) {
5289 di->inode.i_file_acl = dp->inode.i_file_acl;
5290 e2fsck_write_inode(ctx, ino_el->inode,
5291 &di->inode, "clone file EA");
5292 decrement_badcount(ctx, blk, db);
5298 ext2fs_free_mem(&cs.buf);
5303 * This routine returns 1 if a block overlaps with one of the superblocks,
5304 * group descriptors, inode bitmaps, or block bitmaps.
5306 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5308 ext2_filsys fs = ctx->fs;
5312 block = fs->super->s_first_data_block;
5313 for (i = 0; i < fs->group_desc_count; i++) {
5315 /* Check superblocks/block group descriptros */
5316 if (ext2fs_bg_has_super(fs, i)) {
5317 if (test_block >= block &&
5318 (test_block <= block + fs->desc_blocks))
5322 /* Check the inode table */
5323 if ((fs->group_desc[i].bg_inode_table) &&
5324 (test_block >= fs->group_desc[i].bg_inode_table) &&
5325 (test_block < (fs->group_desc[i].bg_inode_table +
5326 fs->inode_blocks_per_group)))
5329 /* Check the bitmap blocks */
5330 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5331 (test_block == fs->group_desc[i].bg_inode_bitmap))
5334 block += fs->super->s_blocks_per_group;
5339 * pass2.c --- check directory structure
5341 * Pass 2 of e2fsck iterates through all active directory inodes, and
5342 * applies to following tests to each directory entry in the directory
5343 * blocks in the inodes:
5345 * - The length of the directory entry (rec_len) should be at
5346 * least 8 bytes, and no more than the remaining space
5347 * left in the directory block.
5348 * - The length of the name in the directory entry (name_len)
5349 * should be less than (rec_len - 8).
5350 * - The inode number in the directory entry should be within
5352 * - The inode number should refer to a in-use inode.
5353 * - The first entry should be '.', and its inode should be
5354 * the inode of the directory.
5355 * - The second entry should be '..'.
5357 * To minimize disk seek time, the directory blocks are processed in
5358 * sorted order of block numbers.
5360 * Pass 2 also collects the following information:
5361 * - The inode numbers of the subdirectories for each directory.
5363 * Pass 2 relies on the following information from previous passes:
5364 * - The directory information collected in pass 1.
5365 * - The inode_used_map bitmap
5366 * - The inode_bad_map bitmap
5367 * - The inode_dir_map bitmap
5369 * Pass 2 frees the following data structures
5370 * - The inode_bad_map bitmap
5371 * - The inode_reg_map bitmap
5375 * Keeps track of how many times an inode is referenced.
5377 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5378 static int check_dir_block(ext2_filsys fs,
5379 struct ext2_db_entry *dir_blocks_info,
5381 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5382 struct problem_context *pctx);
5383 static int update_dir_block(ext2_filsys fs,
5385 e2_blkcnt_t blockcnt,
5389 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5390 static int htree_depth(struct dx_dir_info *dx_dir,
5391 struct dx_dirblock_info *dx_db);
5392 static int special_dir_block_cmp(const void *a, const void *b);
5394 struct check_dir_struct {
5396 struct problem_context pctx;
5401 static void e2fsck_pass2(e2fsck_t ctx)
5403 struct ext2_super_block *sb = ctx->fs->super;
5404 struct problem_context pctx;
5405 ext2_filsys fs = ctx->fs;
5407 struct dir_info *dir;
5408 struct check_dir_struct cd;
5409 struct dx_dir_info *dx_dir;
5410 struct dx_dirblock_info *dx_db, *dx_parent;
5416 clear_problem_context(&cd.pctx);
5420 if (!(ctx->options & E2F_OPT_PREEN))
5421 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5423 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5424 0, ctx->inode_link_info,
5426 if (cd.pctx.errcode) {
5427 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5428 ctx->flags |= E2F_FLAG_ABORT;
5431 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5432 "directory scan buffer");
5435 * Set up the parent pointer for the root directory, if
5436 * present. (If the root directory is not present, we will
5437 * create it in pass 3.)
5439 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5441 dir->parent = EXT2_ROOT_INO;
5446 cd.max = ext2fs_dblist_count(fs->dblist);
5449 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5451 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5452 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5454 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5456 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5458 if (cd.pctx.errcode) {
5459 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5460 ctx->flags |= E2F_FLAG_ABORT;
5465 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5466 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5468 if (dx_dir->numblocks == 0)
5470 clear_problem_context(&pctx);
5472 pctx.dir = dx_dir->ino;
5473 dx_db = dx_dir->dx_block;
5474 if (dx_db->flags & DX_FLAG_REFERENCED)
5475 dx_db->flags |= DX_FLAG_DUP_REF;
5477 dx_db->flags |= DX_FLAG_REFERENCED;
5479 * Find all of the first and last leaf blocks, and
5480 * update their parent's min and max hash values
5482 for (b=0, dx_db = dx_dir->dx_block;
5483 b < dx_dir->numblocks;
5485 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5486 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5488 dx_parent = &dx_dir->dx_block[dx_db->parent];
5490 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5492 if (dx_db->flags & DX_FLAG_FIRST)
5493 dx_parent->min_hash = dx_db->min_hash;
5495 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5497 if (dx_db->flags & DX_FLAG_LAST)
5498 dx_parent->max_hash = dx_db->max_hash;
5501 for (b=0, dx_db = dx_dir->dx_block;
5502 b < dx_dir->numblocks;
5505 pctx.group = dx_db->parent;
5507 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5508 (dx_db->min_hash < dx_db->node_min_hash)) {
5509 pctx.blk = dx_db->min_hash;
5510 pctx.blk2 = dx_db->node_min_hash;
5511 code = PR_2_HTREE_MIN_HASH;
5512 fix_problem(ctx, code, &pctx);
5515 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5516 depth = htree_depth(dx_dir, dx_db);
5517 if (depth != dx_dir->depth) {
5518 code = PR_2_HTREE_BAD_DEPTH;
5519 fix_problem(ctx, code, &pctx);
5524 * This test doesn't apply for the root block
5528 (dx_db->max_hash > dx_db->node_max_hash)) {
5529 pctx.blk = dx_db->max_hash;
5530 pctx.blk2 = dx_db->node_max_hash;
5531 code = PR_2_HTREE_MAX_HASH;
5532 fix_problem(ctx, code, &pctx);
5535 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5536 code = PR_2_HTREE_NOTREF;
5537 fix_problem(ctx, code, &pctx);
5539 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5540 code = PR_2_HTREE_DUPREF;
5541 fix_problem(ctx, code, &pctx);
5547 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5548 clear_htree(ctx, dx_dir->ino);
5549 dx_dir->numblocks = 0;
5553 ext2fs_free_mem(&buf);
5554 ext2fs_free_dblist(fs->dblist);
5556 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5557 ctx->inode_bad_map = 0;
5558 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5559 ctx->inode_reg_map = 0;
5561 clear_problem_context(&pctx);
5562 if (ctx->large_files) {
5563 if (!(sb->s_feature_ro_compat &
5564 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5565 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5566 sb->s_feature_ro_compat |=
5567 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5568 ext2fs_mark_super_dirty(fs);
5570 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5571 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5572 ext2fs_update_dynamic_rev(fs);
5573 ext2fs_mark_super_dirty(fs);
5575 } else if (!ctx->large_files &&
5576 (sb->s_feature_ro_compat &
5577 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5578 if (fs->flags & EXT2_FLAG_RW) {
5579 sb->s_feature_ro_compat &=
5580 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5581 ext2fs_mark_super_dirty(fs);
5586 #define MAX_DEPTH 32000
5587 static int htree_depth(struct dx_dir_info *dx_dir,
5588 struct dx_dirblock_info *dx_db)
5592 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5593 dx_db = &dx_dir->dx_block[dx_db->parent];
5599 static int dict_de_cmp(const void *a, const void *b)
5601 const struct ext2_dir_entry *de_a, *de_b;
5604 de_a = (const struct ext2_dir_entry *) a;
5605 a_len = de_a->name_len & 0xFF;
5606 de_b = (const struct ext2_dir_entry *) b;
5607 b_len = de_b->name_len & 0xFF;
5610 return (a_len - b_len);
5612 return strncmp(de_a->name, de_b->name, a_len);
5616 * This is special sort function that makes sure that directory blocks
5617 * with a dirblock of zero are sorted to the beginning of the list.
5618 * This guarantees that the root node of the htree directories are
5619 * processed first, so we know what hash version to use.
5621 static int special_dir_block_cmp(const void *a, const void *b)
5623 const struct ext2_db_entry *db_a =
5624 (const struct ext2_db_entry *) a;
5625 const struct ext2_db_entry *db_b =
5626 (const struct ext2_db_entry *) b;
5628 if (db_a->blockcnt && !db_b->blockcnt)
5631 if (!db_a->blockcnt && db_b->blockcnt)
5634 if (db_a->blk != db_b->blk)
5635 return (int) (db_a->blk - db_b->blk);
5637 if (db_a->ino != db_b->ino)
5638 return (int) (db_a->ino - db_b->ino);
5640 return (int) (db_a->blockcnt - db_b->blockcnt);
5645 * Make sure the first entry in the directory is '.', and that the
5646 * directory entry is sane.
5648 static int check_dot(e2fsck_t ctx,
5649 struct ext2_dir_entry *dirent,
5650 ext2_ino_t ino, struct problem_context *pctx)
5652 struct ext2_dir_entry *nextdir;
5659 problem = PR_2_MISSING_DOT;
5660 else if (((dirent->name_len & 0xFF) != 1) ||
5661 (dirent->name[0] != '.'))
5662 problem = PR_2_1ST_NOT_DOT;
5663 else if (dirent->name[1] != '\0')
5664 problem = PR_2_DOT_NULL_TERM;
5667 if (fix_problem(ctx, problem, pctx)) {
5668 if (dirent->rec_len < 12)
5669 dirent->rec_len = 12;
5670 dirent->inode = ino;
5671 dirent->name_len = 1;
5672 dirent->name[0] = '.';
5673 dirent->name[1] = '\0';
5678 if (dirent->inode != ino) {
5679 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5680 dirent->inode = ino;
5684 if (dirent->rec_len > 12) {
5685 new_len = dirent->rec_len - 12;
5688 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5689 nextdir = (struct ext2_dir_entry *)
5690 ((char *) dirent + 12);
5691 dirent->rec_len = 12;
5692 nextdir->rec_len = new_len;
5694 nextdir->name_len = 0;
5703 * Make sure the second entry in the directory is '..', and that the
5704 * directory entry is sane. We do not check the inode number of '..'
5705 * here; this gets done in pass 3.
5707 static int check_dotdot(e2fsck_t ctx,
5708 struct ext2_dir_entry *dirent,
5709 struct dir_info *dir, struct problem_context *pctx)
5714 problem = PR_2_MISSING_DOT_DOT;
5715 else if (((dirent->name_len & 0xFF) != 2) ||
5716 (dirent->name[0] != '.') ||
5717 (dirent->name[1] != '.'))
5718 problem = PR_2_2ND_NOT_DOT_DOT;
5719 else if (dirent->name[2] != '\0')
5720 problem = PR_2_DOT_DOT_NULL_TERM;
5723 if (fix_problem(ctx, problem, pctx)) {
5724 if (dirent->rec_len < 12)
5725 dirent->rec_len = 12;
5727 * Note: we don't have the parent inode just
5728 * yet, so we will fill it in with the root
5729 * inode. This will get fixed in pass 3.
5731 dirent->inode = EXT2_ROOT_INO;
5732 dirent->name_len = 2;
5733 dirent->name[0] = '.';
5734 dirent->name[1] = '.';
5735 dirent->name[2] = '\0';
5740 dir->dotdot = dirent->inode;
5745 * Check to make sure a directory entry doesn't contain any illegal
5748 static int check_name(e2fsck_t ctx,
5749 struct ext2_dir_entry *dirent,
5750 struct problem_context *pctx)
5756 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5757 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5759 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5762 dirent->name[i] = '.';
5771 * Check the directory filetype (if present)
5775 * Given a mode, return the ext2 file type
5777 static int ext2_file_type(unsigned int mode)
5779 if (LINUX_S_ISREG(mode))
5780 return EXT2_FT_REG_FILE;
5782 if (LINUX_S_ISDIR(mode))
5785 if (LINUX_S_ISCHR(mode))
5786 return EXT2_FT_CHRDEV;
5788 if (LINUX_S_ISBLK(mode))
5789 return EXT2_FT_BLKDEV;
5791 if (LINUX_S_ISLNK(mode))
5792 return EXT2_FT_SYMLINK;
5794 if (LINUX_S_ISFIFO(mode))
5795 return EXT2_FT_FIFO;
5797 if (LINUX_S_ISSOCK(mode))
5798 return EXT2_FT_SOCK;
5803 static int check_filetype(e2fsck_t ctx,
5804 struct ext2_dir_entry *dirent,
5805 struct problem_context *pctx)
5807 int filetype = dirent->name_len >> 8;
5808 int should_be = EXT2_FT_UNKNOWN;
5809 struct ext2_inode inode;
5811 if (!(ctx->fs->super->s_feature_incompat &
5812 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5813 if (filetype == 0 ||
5814 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5816 dirent->name_len = dirent->name_len & 0xFF;
5820 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5821 should_be = EXT2_FT_DIR;
5822 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5824 should_be = EXT2_FT_REG_FILE;
5825 } else if (ctx->inode_bad_map &&
5826 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5830 e2fsck_read_inode(ctx, dirent->inode, &inode,
5832 should_be = ext2_file_type(inode.i_mode);
5834 if (filetype == should_be)
5836 pctx->num = should_be;
5838 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5842 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5847 static void parse_int_node(ext2_filsys fs,
5848 struct ext2_db_entry *db,
5849 struct check_dir_struct *cd,
5850 struct dx_dir_info *dx_dir,
5853 struct ext2_dx_root_info *root;
5854 struct ext2_dx_entry *ent;
5855 struct ext2_dx_countlimit *limit;
5856 struct dx_dirblock_info *dx_db;
5857 int i, expect_limit, count;
5859 ext2_dirhash_t min_hash = 0xffffffff;
5860 ext2_dirhash_t max_hash = 0;
5861 ext2_dirhash_t hash = 0, prev_hash;
5863 if (db->blockcnt == 0) {
5864 root = (struct ext2_dx_root_info *) (block_buf + 24);
5865 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5867 ent = (struct ext2_dx_entry *) (block_buf+8);
5869 limit = (struct ext2_dx_countlimit *) ent;
5871 count = ext2fs_le16_to_cpu(limit->count);
5872 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5873 sizeof(struct ext2_dx_entry);
5874 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5875 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5876 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5877 goto clear_and_exit;
5879 if (count > expect_limit) {
5880 cd->pctx.num = count;
5881 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5882 goto clear_and_exit;
5883 count = expect_limit;
5886 for (i=0; i < count; i++) {
5888 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5889 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5890 /* Check to make sure the block is valid */
5891 if (blk > (blk_t) dx_dir->numblocks) {
5893 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5895 goto clear_and_exit;
5897 if (hash < prev_hash &&
5898 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5899 goto clear_and_exit;
5900 dx_db = &dx_dir->dx_block[blk];
5901 if (dx_db->flags & DX_FLAG_REFERENCED) {
5902 dx_db->flags |= DX_FLAG_DUP_REF;
5904 dx_db->flags |= DX_FLAG_REFERENCED;
5905 dx_db->parent = db->blockcnt;
5907 if (hash < min_hash)
5909 if (hash > max_hash)
5911 dx_db->node_min_hash = hash;
5913 dx_db->node_max_hash =
5914 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5916 dx_db->node_max_hash = 0xfffffffe;
5917 dx_db->flags |= DX_FLAG_LAST;
5920 dx_db->flags |= DX_FLAG_FIRST;
5922 dx_db = &dx_dir->dx_block[db->blockcnt];
5923 dx_db->min_hash = min_hash;
5924 dx_db->max_hash = max_hash;
5928 clear_htree(cd->ctx, cd->pctx.ino);
5929 dx_dir->numblocks = 0;
5931 #endif /* ENABLE_HTREE */
5934 * Given a busted directory, try to salvage it somehow.
5937 static void salvage_directory(ext2_filsys fs,
5938 struct ext2_dir_entry *dirent,
5939 struct ext2_dir_entry *prev,
5940 unsigned int *offset)
5942 char *cp = (char *) dirent;
5943 int left = fs->blocksize - *offset - dirent->rec_len;
5944 int name_len = dirent->name_len & 0xFF;
5947 * Special case of directory entry of size 8: copy what's left
5948 * of the directory block up to cover up the invalid hole.
5950 if ((left >= 12) && (dirent->rec_len == 8)) {
5951 memmove(cp, cp+8, left);
5952 memset(cp + left, 0, 8);
5956 * If the directory entry overruns the end of the directory
5957 * block, and the name is small enough to fit, then adjust the
5961 (name_len + 8 <= dirent->rec_len + left) &&
5962 dirent->inode <= fs->super->s_inodes_count &&
5963 strnlen(dirent->name, name_len) == name_len) {
5964 dirent->rec_len += left;
5968 * If the directory entry is a multiple of four, so it is
5969 * valid, let the previous directory entry absorb the invalid
5972 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
5973 prev->rec_len += dirent->rec_len;
5974 *offset += dirent->rec_len;
5978 * Default salvage method --- kill all of the directory
5979 * entries for the rest of the block. We will either try to
5980 * absorb it into the previous directory entry, or create a
5981 * new empty directory entry the rest of the directory block.
5984 prev->rec_len += fs->blocksize - *offset;
5985 *offset = fs->blocksize;
5987 dirent->rec_len = fs->blocksize - *offset;
5988 dirent->name_len = 0;
5993 static int check_dir_block(ext2_filsys fs,
5994 struct ext2_db_entry *db,
5997 struct dir_info *subdir, *dir;
5998 struct dx_dir_info *dx_dir;
6000 struct dx_dirblock_info *dx_db = NULL;
6001 #endif /* ENABLE_HTREE */
6002 struct ext2_dir_entry *dirent, *prev;
6003 ext2_dirhash_t hash;
6004 unsigned int offset = 0;
6005 int dir_modified = 0;
6007 blk_t block_nr = db->blk;
6008 ext2_ino_t ino = db->ino;
6010 struct check_dir_struct *cd;
6014 struct ext2_dx_root_info *root;
6015 struct ext2_dx_countlimit *limit;
6016 static dict_t de_dict;
6017 struct problem_context pctx;
6020 cd = (struct check_dir_struct *) priv_data;
6024 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6025 return DIRENT_ABORT;
6027 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6028 return DIRENT_ABORT;
6031 * Make sure the inode is still in use (could have been
6032 * deleted in the duplicate/bad blocks pass.
6034 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6038 cd->pctx.blk = block_nr;
6039 cd->pctx.blkcount = db->blockcnt;
6041 cd->pctx.dirent = 0;
6045 if (allocate_dir_block(ctx, db, &cd->pctx))
6055 if (ctx->dirs_to_hash &&
6056 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6059 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6060 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6061 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6062 if (cd->pctx.errcode) {
6063 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6064 ctx->flags |= E2F_FLAG_ABORT;
6065 return DIRENT_ABORT;
6067 memset(buf, 0, fs->blocksize);
6070 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6071 if (dx_dir && dx_dir->numblocks) {
6072 if (db->blockcnt >= dx_dir->numblocks) {
6073 printf("XXX should never happen!!!\n");
6076 dx_db = &dx_dir->dx_block[db->blockcnt];
6077 dx_db->type = DX_DIRBLOCK_LEAF;
6078 dx_db->phys = block_nr;
6079 dx_db->min_hash = ~0;
6080 dx_db->max_hash = 0;
6082 dirent = (struct ext2_dir_entry *) buf;
6083 limit = (struct ext2_dx_countlimit *) (buf+8);
6084 if (db->blockcnt == 0) {
6085 root = (struct ext2_dx_root_info *) (buf + 24);
6086 dx_db->type = DX_DIRBLOCK_ROOT;
6087 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6088 if ((root->reserved_zero ||
6089 root->info_length < 8 ||
6090 root->indirect_levels > 1) &&
6091 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6092 clear_htree(ctx, ino);
6093 dx_dir->numblocks = 0;
6096 dx_dir->hashversion = root->hash_version;
6097 dx_dir->depth = root->indirect_levels + 1;
6098 } else if ((dirent->inode == 0) &&
6099 (dirent->rec_len == fs->blocksize) &&
6100 (dirent->name_len == 0) &&
6101 (ext2fs_le16_to_cpu(limit->limit) ==
6102 ((fs->blocksize-8) /
6103 sizeof(struct ext2_dx_entry))))
6104 dx_db->type = DX_DIRBLOCK_NODE;
6106 #endif /* ENABLE_HTREE */
6108 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6112 dirent = (struct ext2_dir_entry *) (buf + offset);
6113 cd->pctx.dirent = dirent;
6114 cd->pctx.num = offset;
6115 if (((offset + dirent->rec_len) > fs->blocksize) ||
6116 (dirent->rec_len < 12) ||
6117 ((dirent->rec_len % 4) != 0) ||
6118 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6119 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6120 salvage_directory(fs, dirent, prev, &offset);
6124 goto abort_free_dict;
6126 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6127 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6128 dirent->name_len = EXT2_NAME_LEN;
6133 if (dot_state == 0) {
6134 if (check_dot(ctx, dirent, ino, &cd->pctx))
6136 } else if (dot_state == 1) {
6137 dir = e2fsck_get_dir_info(ctx, ino);
6139 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6140 goto abort_free_dict;
6142 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6144 } else if (dirent->inode == ino) {
6145 problem = PR_2_LINK_DOT;
6146 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6156 * Make sure the inode listed is a legal one.
6158 if (((dirent->inode != EXT2_ROOT_INO) &&
6159 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6160 (dirent->inode > fs->super->s_inodes_count)) {
6161 problem = PR_2_BAD_INO;
6162 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6165 * If the inode is unused, offer to clear it.
6167 problem = PR_2_UNUSED_INODE;
6168 } else if ((dot_state > 1) &&
6169 ((dirent->name_len & 0xFF) == 1) &&
6170 (dirent->name[0] == '.')) {
6172 * If there's a '.' entry in anything other
6173 * than the first directory entry, it's a
6174 * duplicate entry that should be removed.
6176 problem = PR_2_DUP_DOT;
6177 } else if ((dot_state > 1) &&
6178 ((dirent->name_len & 0xFF) == 2) &&
6179 (dirent->name[0] == '.') &&
6180 (dirent->name[1] == '.')) {
6182 * If there's a '..' entry in anything other
6183 * than the second directory entry, it's a
6184 * duplicate entry that should be removed.
6186 problem = PR_2_DUP_DOT_DOT;
6187 } else if ((dot_state > 1) &&
6188 (dirent->inode == EXT2_ROOT_INO)) {
6190 * Don't allow links to the root directory.
6191 * We check this specially to make sure we
6192 * catch this error case even if the root
6193 * directory hasn't been created yet.
6195 problem = PR_2_LINK_ROOT;
6196 } else if ((dot_state > 1) &&
6197 (dirent->name_len & 0xFF) == 0) {
6199 * Don't allow zero-length directory names.
6201 problem = PR_2_NULL_NAME;
6205 if (fix_problem(ctx, problem, &cd->pctx)) {
6210 ext2fs_unmark_valid(fs);
6211 if (problem == PR_2_BAD_INO)
6217 * If the inode was marked as having bad fields in
6218 * pass1, process it and offer to fix/clear it.
6219 * (We wait until now so that we can display the
6220 * pathname to the user.)
6222 if (ctx->inode_bad_map &&
6223 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6225 if (e2fsck_process_bad_inode(ctx, ino,
6227 buf + fs->blocksize)) {
6232 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6233 return DIRENT_ABORT;
6236 if (check_name(ctx, dirent, &cd->pctx))
6239 if (check_filetype(ctx, dirent, &cd->pctx))
6244 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6245 (dirent->name_len & 0xFF),
6246 fs->super->s_hash_seed, &hash, 0);
6247 if (hash < dx_db->min_hash)
6248 dx_db->min_hash = hash;
6249 if (hash > dx_db->max_hash)
6250 dx_db->max_hash = hash;
6255 * If this is a directory, then mark its parent in its
6256 * dir_info structure. If the parent field is already
6257 * filled in, then this directory has more than one
6258 * hard link. We assume the first link is correct,
6259 * and ask the user if he/she wants to clear this one.
6261 if ((dot_state > 1) &&
6262 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6264 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6266 cd->pctx.ino = dirent->inode;
6267 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6268 goto abort_free_dict;
6270 if (subdir->parent) {
6271 cd->pctx.ino2 = subdir->parent;
6272 if (fix_problem(ctx, PR_2_LINK_DIR,
6280 subdir->parent = ino;
6285 } else if (dict_lookup(&de_dict, dirent)) {
6286 clear_problem_context(&pctx);
6288 pctx.dirent = dirent;
6289 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6290 if (!ctx->dirs_to_hash)
6291 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6292 if (ctx->dirs_to_hash)
6293 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6296 dict_alloc_insert(&de_dict, dirent, dirent);
6298 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6301 ctx->fs_links_count++;
6302 ctx->fs_total_count++;
6305 offset += dirent->rec_len;
6307 } while (offset < fs->blocksize);
6310 cd->pctx.dir = cd->pctx.ino;
6311 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6312 (dx_db->type == DX_DIRBLOCK_NODE))
6313 parse_int_node(fs, db, cd, dx_dir, buf);
6315 #endif /* ENABLE_HTREE */
6316 if (offset != fs->blocksize) {
6317 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6318 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6319 dirent->rec_len = cd->pctx.num;
6324 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6325 if (cd->pctx.errcode) {
6326 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6328 goto abort_free_dict;
6330 ext2fs_mark_changed(fs);
6332 dict_free_nodes(&de_dict);
6335 dict_free_nodes(&de_dict);
6336 ctx->flags |= E2F_FLAG_ABORT;
6337 return DIRENT_ABORT;
6341 * This function is called to deallocate a block, and is an interator
6342 * functioned called by deallocate inode via ext2fs_iterate_block().
6344 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6345 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6346 blk_t ref_block FSCK_ATTR((unused)),
6347 int ref_offset FSCK_ATTR((unused)),
6350 e2fsck_t ctx = (e2fsck_t) priv_data;
6352 if (HOLE_BLKADDR(*block_nr))
6354 if ((*block_nr < fs->super->s_first_data_block) ||
6355 (*block_nr >= fs->super->s_blocks_count))
6357 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6358 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6363 * This fuction deallocates an inode
6365 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6367 ext2_filsys fs = ctx->fs;
6368 struct ext2_inode inode;
6369 struct problem_context pctx;
6372 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6373 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6374 inode.i_links_count = 0;
6375 inode.i_dtime = time(NULL);
6376 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6377 clear_problem_context(&pctx);
6381 * Fix up the bitmaps...
6383 e2fsck_read_bitmaps(ctx);
6384 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6385 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6386 if (ctx->inode_bad_map)
6387 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6388 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6390 if (inode.i_file_acl &&
6391 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6392 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6393 block_buf, -1, &count);
6394 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6399 pctx.blk = inode.i_file_acl;
6400 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6401 ctx->flags |= E2F_FLAG_ABORT;
6405 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6407 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6409 inode.i_file_acl = 0;
6412 if (!ext2fs_inode_has_valid_blocks(&inode))
6415 if (LINUX_S_ISREG(inode.i_mode) &&
6416 (inode.i_size_high || inode.i_size & 0x80000000UL))
6419 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6420 deallocate_inode_block, ctx);
6422 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6423 ctx->flags |= E2F_FLAG_ABORT;
6429 * This fuction clears the htree flag on an inode
6431 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6433 struct ext2_inode inode;
6435 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6436 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6437 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6438 if (ctx->dirs_to_hash)
6439 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6443 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6444 ext2_ino_t ino, char *buf)
6446 ext2_filsys fs = ctx->fs;
6447 struct ext2_inode inode;
6448 int inode_modified = 0;
6450 unsigned char *frag, *fsize;
6451 struct problem_context pctx;
6454 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6456 clear_problem_context(&pctx);
6459 pctx.inode = &inode;
6461 if (inode.i_file_acl &&
6462 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6463 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6464 inode.i_file_acl = 0;
6467 * This is a special kludge to deal with long symlinks
6468 * on big endian systems. i_blocks had already been
6469 * decremented earlier in pass 1, but since i_file_acl
6470 * hadn't yet been cleared, ext2fs_read_inode()
6471 * assumed that the file was short symlink and would
6472 * not have byte swapped i_block[0]. Hence, we have
6473 * to byte-swap it here.
6475 if (LINUX_S_ISLNK(inode.i_mode) &&
6476 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6477 (inode.i_blocks == fs->blocksize >> 9))
6478 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6484 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6485 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6486 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6487 !(LINUX_S_ISSOCK(inode.i_mode)))
6488 problem = PR_2_BAD_MODE;
6489 else if (LINUX_S_ISCHR(inode.i_mode)
6490 && !e2fsck_pass1_check_device_inode(fs, &inode))
6491 problem = PR_2_BAD_CHAR_DEV;
6492 else if (LINUX_S_ISBLK(inode.i_mode)
6493 && !e2fsck_pass1_check_device_inode(fs, &inode))
6494 problem = PR_2_BAD_BLOCK_DEV;
6495 else if (LINUX_S_ISFIFO(inode.i_mode)
6496 && !e2fsck_pass1_check_device_inode(fs, &inode))
6497 problem = PR_2_BAD_FIFO;
6498 else if (LINUX_S_ISSOCK(inode.i_mode)
6499 && !e2fsck_pass1_check_device_inode(fs, &inode))
6500 problem = PR_2_BAD_SOCKET;
6501 else if (LINUX_S_ISLNK(inode.i_mode)
6502 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6503 problem = PR_2_INVALID_SYMLINK;
6507 if (fix_problem(ctx, problem, &pctx)) {
6508 deallocate_inode(ctx, ino, 0);
6509 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6517 if (inode.i_faddr) {
6518 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6525 switch (fs->super->s_creator_os) {
6527 frag = &inode.osd2.linux2.l_i_frag;
6528 fsize = &inode.osd2.linux2.l_i_fsize;
6531 frag = &inode.osd2.hurd2.h_i_frag;
6532 fsize = &inode.osd2.hurd2.h_i_fsize;
6535 frag = &inode.osd2.masix2.m_i_frag;
6536 fsize = &inode.osd2.masix2.m_i_fsize;
6541 if (frag && *frag) {
6543 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6550 if (fsize && *fsize) {
6552 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6560 if (inode.i_file_acl &&
6561 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6562 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6563 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6564 inode.i_file_acl = 0;
6569 if (inode.i_dir_acl &&
6570 LINUX_S_ISDIR(inode.i_mode)) {
6571 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6572 inode.i_dir_acl = 0;
6579 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6581 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6587 * allocate_dir_block --- this function allocates a new directory
6588 * block for a particular inode; this is done if a directory has
6589 * a "hole" in it, or if a directory has a illegal block number
6590 * that was zeroed out and now needs to be replaced.
6592 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6593 struct problem_context *pctx)
6595 ext2_filsys fs = ctx->fs;
6598 struct ext2_inode inode;
6600 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6604 * Read the inode and block bitmaps in; we'll be messing with
6607 e2fsck_read_bitmaps(ctx);
6610 * First, find a free block
6612 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6613 if (pctx->errcode) {
6614 pctx->str = "ext2fs_new_block";
6615 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6618 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6619 ext2fs_mark_block_bitmap(fs->block_map, blk);
6620 ext2fs_mark_bb_dirty(fs);
6623 * Now let's create the actual data block for the inode
6626 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6628 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6629 EXT2_ROOT_INO, &block);
6631 if (pctx->errcode) {
6632 pctx->str = "ext2fs_new_dir_block";
6633 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6637 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6638 ext2fs_free_mem(&block);
6639 if (pctx->errcode) {
6640 pctx->str = "ext2fs_write_dir_block";
6641 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6646 * Update the inode block count
6648 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6649 inode.i_blocks += fs->blocksize / 512;
6650 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6651 inode.i_size = (db->blockcnt+1) * fs->blocksize;
6652 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6655 * Finally, update the block pointers for the inode
6658 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6659 0, update_dir_block, db);
6660 if (pctx->errcode) {
6661 pctx->str = "ext2fs_block_iterate";
6662 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6670 * This is a helper function for allocate_dir_block().
6672 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6674 e2_blkcnt_t blockcnt,
6675 blk_t ref_block FSCK_ATTR((unused)),
6676 int ref_offset FSCK_ATTR((unused)),
6679 struct ext2_db_entry *db;
6681 db = (struct ext2_db_entry *) priv_data;
6682 if (db->blockcnt == (int) blockcnt) {
6683 *block_nr = db->blk;
6684 return BLOCK_CHANGED;
6690 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6692 * Pass #3 assures that all directories are connected to the
6693 * filesystem tree, using the following algorithm:
6695 * First, the root directory is checked to make sure it exists; if
6696 * not, e2fsck will offer to create a new one. It is then marked as
6699 * Then, pass3 interates over all directory inodes; for each directory
6700 * it attempts to trace up the filesystem tree, using dirinfo.parent
6701 * until it reaches a directory which has been marked "done". If it
6702 * cannot do so, then the directory must be disconnected, and e2fsck
6703 * will offer to reconnect it to /lost+found. While it is chasing
6704 * parent pointers up the filesystem tree, if pass3 sees a directory
6705 * twice, then it has detected a filesystem loop, and it will again
6706 * offer to reconnect the directory to /lost+found in to break the
6709 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6710 * reconnect inodes to /lost+found; this subroutine is also used by
6711 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6712 * is responsible for creating /lost+found if it does not exist.
6714 * Pass 3 frees the following data structures:
6715 * - The dirinfo directory information cache.
6718 static void check_root(e2fsck_t ctx);
6719 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6720 struct problem_context *pctx);
6721 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6723 static ext2fs_inode_bitmap inode_loop_detect;
6724 static ext2fs_inode_bitmap inode_done_map;
6726 static void e2fsck_pass3(e2fsck_t ctx)
6728 ext2_filsys fs = ctx->fs;
6730 struct problem_context pctx;
6731 struct dir_info *dir;
6732 unsigned long maxdirs, count;
6734 clear_problem_context(&pctx);
6738 if (!(ctx->options & E2F_OPT_PREEN))
6739 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6742 * Allocate some bitmaps to do loop detection.
6744 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6748 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6749 ctx->flags |= E2F_FLAG_ABORT;
6753 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6756 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6758 maxdirs = e2fsck_get_num_dirinfo(ctx);
6762 if ((ctx->progress)(ctx, 3, 0, maxdirs))
6765 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6766 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6768 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6770 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6771 if (check_directory(ctx, dir, &pctx))
6776 * Force the creation of /lost+found if not present
6778 if ((ctx->flags & E2F_OPT_READONLY) == 0)
6779 e2fsck_get_lost_and_found(ctx, 1);
6782 * If there are any directories that need to be indexed or
6783 * optimized, do it here.
6785 e2fsck_rehash_directories(ctx);
6788 e2fsck_free_dir_info(ctx);
6789 ext2fs_free_inode_bitmap(inode_loop_detect);
6790 inode_loop_detect = 0;
6791 ext2fs_free_inode_bitmap(inode_done_map);
6796 * This makes sure the root inode is present; if not, we ask if the
6797 * user wants us to create it. Not creating it is a fatal error.
6799 static void check_root(e2fsck_t ctx)
6801 ext2_filsys fs = ctx->fs;
6803 struct ext2_inode inode;
6805 struct problem_context pctx;
6807 clear_problem_context(&pctx);
6809 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6811 * If the root inode is not a directory, die here. The
6812 * user must have answered 'no' in pass1 when we
6813 * offered to clear it.
6815 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6817 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6818 ctx->flags |= E2F_FLAG_ABORT;
6823 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6824 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6825 ctx->flags |= E2F_FLAG_ABORT;
6829 e2fsck_read_bitmaps(ctx);
6832 * First, find a free block
6834 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6836 pctx.str = "ext2fs_new_block";
6837 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6838 ctx->flags |= E2F_FLAG_ABORT;
6841 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6842 ext2fs_mark_block_bitmap(fs->block_map, blk);
6843 ext2fs_mark_bb_dirty(fs);
6846 * Now let's create the actual data block for the inode
6848 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6851 pctx.str = "ext2fs_new_dir_block";
6852 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6853 ctx->flags |= E2F_FLAG_ABORT;
6857 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6859 pctx.str = "ext2fs_write_dir_block";
6860 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6861 ctx->flags |= E2F_FLAG_ABORT;
6864 ext2fs_free_mem(&block);
6867 * Set up the inode structure
6869 memset(&inode, 0, sizeof(inode));
6870 inode.i_mode = 040755;
6871 inode.i_size = fs->blocksize;
6872 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
6873 inode.i_links_count = 2;
6874 inode.i_blocks = fs->blocksize / 512;
6875 inode.i_block[0] = blk;
6878 * Write out the inode.
6880 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6882 pctx.str = "ext2fs_write_inode";
6883 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6884 ctx->flags |= E2F_FLAG_ABORT;
6889 * Miscellaneous bookkeeping...
6891 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6892 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6893 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6895 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6896 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6897 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6898 ext2fs_mark_ib_dirty(fs);
6902 * This subroutine is responsible for making sure that a particular
6903 * directory is connected to the root; if it isn't we trace it up as
6904 * far as we can go, and then offer to connect the resulting parent to
6905 * the lost+found. We have to do loop detection; if we ever discover
6906 * a loop, we treat that as a disconnected directory and offer to
6907 * reparent it to lost+found.
6909 * However, loop detection is expensive, because for very large
6910 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6911 * is non-trivial. Loops in filesystems are also a rare error case,
6912 * and we shouldn't optimize for error cases. So we try two passes of
6913 * the algorithm. The first time, we ignore loop detection and merely
6914 * increment a counter; if the counter exceeds some extreme threshold,
6915 * then we try again with the loop detection bitmap enabled.
6917 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6918 struct problem_context *pctx)
6920 ext2_filsys fs = ctx->fs;
6921 struct dir_info *p = dir;
6922 int loop_pass = 0, parent_count = 0;
6929 * Mark this inode as being "done"; by the time we
6930 * return from this function, the inode we either be
6931 * verified as being connected to the directory tree,
6932 * or we will have offered to reconnect this to
6935 * If it was marked done already, then we've reached a
6936 * parent we've already checked.
6938 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6942 * If this directory doesn't have a parent, or we've
6943 * seen the parent once already, then offer to
6944 * reparent it to lost+found
6948 (ext2fs_test_inode_bitmap(inode_loop_detect,
6951 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6952 if (e2fsck_reconnect_file(ctx, pctx->ino))
6953 ext2fs_unmark_valid(fs);
6955 p = e2fsck_get_dir_info(ctx, pctx->ino);
6956 p->parent = ctx->lost_and_found;
6957 fix_dotdot(ctx, p, ctx->lost_and_found);
6962 p = e2fsck_get_dir_info(ctx, p->parent);
6964 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
6968 ext2fs_mark_inode_bitmap(inode_loop_detect,
6970 } else if (parent_count++ > 2048) {
6972 * If we've run into a path depth that's
6973 * greater than 2048, try again with the inode
6974 * loop bitmap turned on and start from the
6978 if (inode_loop_detect)
6979 ext2fs_clear_inode_bitmap(inode_loop_detect);
6981 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
6982 if (pctx->errcode) {
6985 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
6986 ctx->flags |= E2F_FLAG_ABORT;
6995 * Make sure that .. and the parent directory are the same;
6996 * offer to fix it if not.
6998 if (dir->parent != dir->dotdot) {
6999 pctx->ino = dir->ino;
7000 pctx->ino2 = dir->dotdot;
7001 pctx->dir = dir->parent;
7002 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7003 fix_dotdot(ctx, dir, dir->parent);
7009 * This routine gets the lost_and_found inode, making it a directory
7012 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7014 ext2_filsys fs = ctx->fs;
7018 struct ext2_inode inode;
7020 static const char name[] = "lost+found";
7021 struct problem_context pctx;
7022 struct dir_info *dirinfo;
7024 if (ctx->lost_and_found)
7025 return ctx->lost_and_found;
7027 clear_problem_context(&pctx);
7029 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7030 sizeof(name)-1, 0, &ino);
7034 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7035 ctx->lost_and_found = ino;
7039 /* Lost+found isn't a directory! */
7043 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7046 /* OK, unlink the old /lost+found file. */
7047 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7049 pctx.str = "ext2fs_unlink";
7050 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7053 dirinfo = e2fsck_get_dir_info(ctx, ino);
7055 dirinfo->parent = 0;
7056 e2fsck_adjust_inode_count(ctx, ino, -1);
7057 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7058 pctx.errcode = retval;
7059 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7061 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7065 * Read the inode and block bitmaps in; we'll be messing with
7068 e2fsck_read_bitmaps(ctx);
7071 * First, find a free block
7073 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7075 pctx.errcode = retval;
7076 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7079 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7080 ext2fs_block_alloc_stats(fs, blk, +1);
7083 * Next find a free inode.
7085 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7086 ctx->inode_used_map, &ino);
7088 pctx.errcode = retval;
7089 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7092 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7093 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7094 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7097 * Now let's create the actual data block for the inode
7099 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7101 pctx.errcode = retval;
7102 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7106 retval = ext2fs_write_dir_block(fs, blk, block);
7107 ext2fs_free_mem(&block);
7109 pctx.errcode = retval;
7110 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7115 * Set up the inode structure
7117 memset(&inode, 0, sizeof(inode));
7118 inode.i_mode = 040700;
7119 inode.i_size = fs->blocksize;
7120 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
7121 inode.i_links_count = 2;
7122 inode.i_blocks = fs->blocksize / 512;
7123 inode.i_block[0] = blk;
7126 * Next, write out the inode.
7128 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7130 pctx.str = "ext2fs_write_inode";
7131 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7135 * Finally, create the directory link
7137 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7139 pctx.str = "ext2fs_link";
7140 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7145 * Miscellaneous bookkeeping that needs to be kept straight.
7147 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7148 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7149 ext2fs_icount_store(ctx->inode_count, ino, 2);
7150 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7151 ctx->lost_and_found = ino;
7156 * This routine will connect a file to lost+found
7158 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7160 ext2_filsys fs = ctx->fs;
7163 struct problem_context pctx;
7164 struct ext2_inode inode;
7167 clear_problem_context(&pctx);
7170 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7171 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7172 ctx->bad_lost_and_found++;
7174 if (ctx->bad_lost_and_found) {
7175 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7179 sprintf(name, "#%u", ino);
7180 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7181 file_type = ext2_file_type(inode.i_mode);
7182 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7183 if (retval == EXT2_ET_DIR_NO_SPACE) {
7184 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7186 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7189 pctx.errcode = retval;
7190 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7193 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7197 pctx.errcode = retval;
7198 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7201 e2fsck_adjust_inode_count(ctx, ino, 1);
7207 * Utility routine to adjust the inode counts on an inode.
7209 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7211 ext2_filsys fs = ctx->fs;
7213 struct ext2_inode inode;
7218 retval = ext2fs_read_inode(fs, ino, &inode);
7223 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7224 if (inode.i_links_count == (__u16) ~0)
7226 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7227 inode.i_links_count++;
7228 } else if (adj == -1) {
7229 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7230 if (inode.i_links_count == 0)
7232 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7233 inode.i_links_count--;
7236 retval = ext2fs_write_inode(fs, ino, &inode);
7244 * Fix parent --- this routine fixes up the parent of a directory.
7246 struct fix_dotdot_struct {
7253 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7254 int offset FSCK_ATTR((unused)),
7255 int blocksize FSCK_ATTR((unused)),
7256 char *buf FSCK_ATTR((unused)),
7259 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7261 struct problem_context pctx;
7263 if ((dirent->name_len & 0xFF) != 2)
7265 if (strncmp(dirent->name, "..", 2))
7268 clear_problem_context(&pctx);
7270 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7272 pctx.errcode = retval;
7273 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7275 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7277 pctx.errcode = retval;
7278 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7280 dirent->inode = fp->parent;
7283 return DIRENT_ABORT | DIRENT_CHANGED;
7286 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7288 ext2_filsys fs = ctx->fs;
7290 struct fix_dotdot_struct fp;
7291 struct problem_context pctx;
7298 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7299 0, fix_dotdot_proc, &fp);
7300 if (retval || !fp.done) {
7301 clear_problem_context(&pctx);
7302 pctx.ino = dir->ino;
7303 pctx.errcode = retval;
7304 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7305 PR_3_FIX_PARENT_NOFIND, &pctx);
7306 ext2fs_unmark_valid(fs);
7308 dir->dotdot = parent;
7312 * These routines are responsible for expanding a /lost+found if it is
7316 struct expand_dir_struct {
7318 int guaranteed_size;
7325 static int expand_dir_proc(ext2_filsys fs,
7327 e2_blkcnt_t blockcnt,
7328 blk_t ref_block FSCK_ATTR((unused)),
7329 int ref_offset FSCK_ATTR((unused)),
7332 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7334 static blk_t last_blk = 0;
7341 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7345 es->last_block = blockcnt;
7347 last_blk = *blocknr;
7350 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7357 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7363 retval = ext2fs_write_dir_block(fs, new_blk, block);
7365 retval = ext2fs_get_mem(fs->blocksize, &block);
7370 memset(block, 0, fs->blocksize);
7371 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7377 ext2fs_free_mem(&block);
7379 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7380 ext2fs_block_alloc_stats(fs, new_blk, +1);
7384 return (BLOCK_CHANGED | BLOCK_ABORT);
7386 return BLOCK_CHANGED;
7389 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7390 int num, int guaranteed_size)
7392 ext2_filsys fs = ctx->fs;
7394 struct expand_dir_struct es;
7395 struct ext2_inode inode;
7397 if (!(fs->flags & EXT2_FLAG_RW))
7398 return EXT2_ET_RO_FILSYS;
7401 * Read the inode and block bitmaps in; we'll be messing with
7404 e2fsck_read_bitmaps(ctx);
7406 retval = ext2fs_check_directory(fs, dir);
7411 es.guaranteed_size = guaranteed_size;
7417 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7418 0, expand_dir_proc, &es);
7424 * Update the size and block count fields in the inode.
7426 retval = ext2fs_read_inode(fs, dir, &inode);
7430 inode.i_size = (es.last_block + 1) * fs->blocksize;
7431 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7433 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7439 * pass4.c -- pass #4 of e2fsck: Check reference counts
7441 * Pass 4 frees the following data structures:
7442 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7446 * This routine is called when an inode is not connected to the
7449 * This subroutine returns 1 then the caller shouldn't bother with the
7450 * rest of the pass 4 tests.
7452 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7454 ext2_filsys fs = ctx->fs;
7455 struct ext2_inode inode;
7456 struct problem_context pctx;
7458 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7459 clear_problem_context(&pctx);
7461 pctx.inode = &inode;
7464 * Offer to delete any zero-length files that does not have
7465 * blocks. If there is an EA block, it might have useful
7466 * information, so we won't prompt to delete it, but let it be
7467 * reconnected to lost+found.
7469 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7470 LINUX_S_ISDIR(inode.i_mode))) {
7471 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7472 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7473 inode.i_links_count = 0;
7474 inode.i_dtime = time(NULL);
7475 e2fsck_write_inode(ctx, i, &inode,
7476 "disconnect_inode");
7478 * Fix up the bitmaps...
7480 e2fsck_read_bitmaps(ctx);
7481 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7482 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7483 ext2fs_inode_alloc_stats2(fs, i, -1,
7484 LINUX_S_ISDIR(inode.i_mode));
7490 * Prompt to reconnect.
7492 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7493 if (e2fsck_reconnect_file(ctx, i))
7494 ext2fs_unmark_valid(fs);
7497 * If we don't attach the inode, then skip the
7498 * i_links_test since there's no point in trying to
7499 * force i_links_count to zero.
7501 ext2fs_unmark_valid(fs);
7508 static void e2fsck_pass4(e2fsck_t ctx)
7510 ext2_filsys fs = ctx->fs;
7512 struct ext2_inode inode;
7513 struct problem_context pctx;
7514 __u16 link_count, link_counted;
7516 int group, maxgroup;
7520 clear_problem_context(&pctx);
7522 if (!(ctx->options & E2F_OPT_PREEN))
7523 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7526 maxgroup = fs->group_desc_count;
7528 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7531 for (i=1; i <= fs->super->s_inodes_count; i++) {
7532 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7534 if ((i % fs->super->s_inodes_per_group) == 0) {
7537 if ((ctx->progress)(ctx, 4, group, maxgroup))
7540 if (i == EXT2_BAD_INO ||
7541 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7543 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7544 (ctx->inode_imagic_map &&
7545 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7547 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7548 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7549 if (link_counted == 0) {
7551 buf = e2fsck_allocate_memory(ctx,
7552 fs->blocksize, "bad_inode buffer");
7553 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7555 if (disconnect_inode(ctx, i))
7557 ext2fs_icount_fetch(ctx->inode_link_info, i,
7559 ext2fs_icount_fetch(ctx->inode_count, i,
7562 if (link_counted != link_count) {
7563 e2fsck_read_inode(ctx, i, &inode, "pass4");
7565 pctx.inode = &inode;
7566 if (link_count != inode.i_links_count) {
7567 pctx.num = link_count;
7569 PR_4_INCONSISTENT_COUNT, &pctx);
7571 pctx.num = link_counted;
7572 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7573 inode.i_links_count = link_counted;
7574 e2fsck_write_inode(ctx, i, &inode, "pass4");
7578 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7579 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7580 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7581 ctx->inode_imagic_map = 0;
7582 ext2fs_free_mem(&buf);
7586 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7589 #define NO_BLK ((blk_t) -1)
7591 static void print_bitmap_problem(e2fsck_t ctx, int problem,
7592 struct problem_context *pctx)
7595 case PR_5_BLOCK_UNUSED:
7596 if (pctx->blk == pctx->blk2)
7599 problem = PR_5_BLOCK_RANGE_UNUSED;
7601 case PR_5_BLOCK_USED:
7602 if (pctx->blk == pctx->blk2)
7605 problem = PR_5_BLOCK_RANGE_USED;
7607 case PR_5_INODE_UNUSED:
7608 if (pctx->ino == pctx->ino2)
7611 problem = PR_5_INODE_RANGE_UNUSED;
7613 case PR_5_INODE_USED:
7614 if (pctx->ino == pctx->ino2)
7617 problem = PR_5_INODE_RANGE_USED;
7620 fix_problem(ctx, problem, pctx);
7621 pctx->blk = pctx->blk2 = NO_BLK;
7622 pctx->ino = pctx->ino2 = 0;
7625 static void check_block_bitmaps(e2fsck_t ctx)
7627 ext2_filsys fs = ctx->fs;
7631 unsigned int blocks = 0;
7632 unsigned int free_blocks = 0;
7635 struct problem_context pctx;
7636 int problem, save_problem, fixit, had_problem;
7639 clear_problem_context(&pctx);
7640 free_array = (int *) e2fsck_allocate_memory(ctx,
7641 fs->group_desc_count * sizeof(int), "free block count array");
7643 if ((fs->super->s_first_data_block <
7644 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7645 (fs->super->s_blocks_count-1 >
7646 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7648 pctx.blk = fs->super->s_first_data_block;
7649 pctx.blk2 = fs->super->s_blocks_count -1;
7650 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7651 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7652 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7654 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7658 if ((fs->super->s_first_data_block <
7659 ext2fs_get_block_bitmap_start(fs->block_map)) ||
7660 (fs->super->s_blocks_count-1 >
7661 ext2fs_get_block_bitmap_end(fs->block_map))) {
7663 pctx.blk = fs->super->s_first_data_block;
7664 pctx.blk2 = fs->super->s_blocks_count -1;
7665 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7666 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7667 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7669 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7676 pctx.blk = pctx.blk2 = NO_BLK;
7677 for (i = fs->super->s_first_data_block;
7678 i < fs->super->s_blocks_count;
7680 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7681 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7683 if (actual == bitmap)
7686 if (!actual && bitmap) {
7688 * Block not used, but marked in use in the bitmap.
7690 problem = PR_5_BLOCK_UNUSED;
7693 * Block used, but not marked in use in the bitmap.
7695 problem = PR_5_BLOCK_USED;
7697 if (pctx.blk == NO_BLK) {
7698 pctx.blk = pctx.blk2 = i;
7699 save_problem = problem;
7701 if ((problem == save_problem) &&
7705 print_bitmap_problem(ctx, save_problem, &pctx);
7706 pctx.blk = pctx.blk2 = i;
7707 save_problem = problem;
7710 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7719 if ((blocks == fs->super->s_blocks_per_group) ||
7720 (i == fs->super->s_blocks_count-1)) {
7721 free_array[group] = group_free;
7726 if ((ctx->progress)(ctx, 5, group,
7727 fs->group_desc_count*2))
7731 if (pctx.blk != NO_BLK)
7732 print_bitmap_problem(ctx, save_problem, &pctx);
7734 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7737 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7740 ext2fs_free_block_bitmap(fs->block_map);
7741 retval = ext2fs_copy_bitmap(ctx->block_found_map,
7744 clear_problem_context(&pctx);
7745 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7746 ctx->flags |= E2F_FLAG_ABORT;
7749 ext2fs_set_bitmap_padding(fs->block_map);
7750 ext2fs_mark_bb_dirty(fs);
7752 /* Redo the counts */
7753 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7754 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7756 } else if (fixit == 0)
7757 ext2fs_unmark_valid(fs);
7759 for (i = 0; i < fs->group_desc_count; i++) {
7760 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7762 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7763 pctx.blk2 = free_array[i];
7765 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7767 fs->group_desc[i].bg_free_blocks_count =
7769 ext2fs_mark_super_dirty(fs);
7771 ext2fs_unmark_valid(fs);
7774 if (free_blocks != fs->super->s_free_blocks_count) {
7776 pctx.blk = fs->super->s_free_blocks_count;
7777 pctx.blk2 = free_blocks;
7779 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7780 fs->super->s_free_blocks_count = free_blocks;
7781 ext2fs_mark_super_dirty(fs);
7783 ext2fs_unmark_valid(fs);
7785 ext2fs_free_mem(&free_array);
7788 static void check_inode_bitmaps(e2fsck_t ctx)
7790 ext2_filsys fs = ctx->fs;
7792 unsigned int free_inodes = 0;
7796 unsigned int inodes = 0;
7801 struct problem_context pctx;
7802 int problem, save_problem, fixit, had_problem;
7804 clear_problem_context(&pctx);
7805 free_array = (int *) e2fsck_allocate_memory(ctx,
7806 fs->group_desc_count * sizeof(int), "free inode count array");
7808 dir_array = (int *) e2fsck_allocate_memory(ctx,
7809 fs->group_desc_count * sizeof(int), "directory count array");
7811 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7812 (fs->super->s_inodes_count >
7813 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7816 pctx.blk2 = fs->super->s_inodes_count;
7817 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7818 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7819 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7821 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7824 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7825 (fs->super->s_inodes_count >
7826 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7829 pctx.blk2 = fs->super->s_inodes_count;
7830 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7831 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7832 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7834 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7841 pctx.ino = pctx.ino2 = 0;
7842 for (i = 1; i <= fs->super->s_inodes_count; i++) {
7843 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7844 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7846 if (actual == bitmap)
7849 if (!actual && bitmap) {
7851 * Inode wasn't used, but marked in bitmap
7853 problem = PR_5_INODE_UNUSED;
7854 } else /* if (actual && !bitmap) */ {
7856 * Inode used, but not in bitmap
7858 problem = PR_5_INODE_USED;
7860 if (pctx.ino == 0) {
7861 pctx.ino = pctx.ino2 = i;
7862 save_problem = problem;
7864 if ((problem == save_problem) &&
7868 print_bitmap_problem(ctx, save_problem, &pctx);
7869 pctx.ino = pctx.ino2 = i;
7870 save_problem = problem;
7873 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7881 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7885 if ((inodes == fs->super->s_inodes_per_group) ||
7886 (i == fs->super->s_inodes_count)) {
7887 free_array[group] = group_free;
7888 dir_array[group] = dirs_count;
7894 if ((ctx->progress)(ctx, 5,
7895 group + fs->group_desc_count,
7896 fs->group_desc_count*2))
7901 print_bitmap_problem(ctx, save_problem, &pctx);
7904 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7907 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7910 ext2fs_free_inode_bitmap(fs->inode_map);
7911 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7914 clear_problem_context(&pctx);
7915 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7916 ctx->flags |= E2F_FLAG_ABORT;
7919 ext2fs_set_bitmap_padding(fs->inode_map);
7920 ext2fs_mark_ib_dirty(fs);
7923 inodes = 0; free_inodes = 0; group_free = 0;
7924 dirs_count = 0; group = 0;
7925 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7926 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7928 } else if (fixit == 0)
7929 ext2fs_unmark_valid(fs);
7931 for (i = 0; i < fs->group_desc_count; i++) {
7932 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7934 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7935 pctx.ino2 = free_array[i];
7936 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7938 fs->group_desc[i].bg_free_inodes_count =
7940 ext2fs_mark_super_dirty(fs);
7942 ext2fs_unmark_valid(fs);
7944 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7946 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7947 pctx.ino2 = dir_array[i];
7949 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7951 fs->group_desc[i].bg_used_dirs_count =
7953 ext2fs_mark_super_dirty(fs);
7955 ext2fs_unmark_valid(fs);
7958 if (free_inodes != fs->super->s_free_inodes_count) {
7960 pctx.ino = fs->super->s_free_inodes_count;
7961 pctx.ino2 = free_inodes;
7963 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
7964 fs->super->s_free_inodes_count = free_inodes;
7965 ext2fs_mark_super_dirty(fs);
7967 ext2fs_unmark_valid(fs);
7969 ext2fs_free_mem(&free_array);
7970 ext2fs_free_mem(&dir_array);
7973 static void check_inode_end(e2fsck_t ctx)
7975 ext2_filsys fs = ctx->fs;
7976 ext2_ino_t end, save_inodes_count, i;
7977 struct problem_context pctx;
7979 clear_problem_context(&pctx);
7981 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
7982 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
7983 &save_inodes_count);
7986 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
7987 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7990 if (save_inodes_count == end)
7993 for (i = save_inodes_count + 1; i <= end; i++) {
7994 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
7995 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
7996 for (i = save_inodes_count + 1; i <= end; i++)
7997 ext2fs_mark_inode_bitmap(fs->inode_map,
7999 ext2fs_mark_ib_dirty(fs);
8001 ext2fs_unmark_valid(fs);
8006 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8007 save_inodes_count, 0);
8010 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8011 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8016 static void check_block_end(e2fsck_t ctx)
8018 ext2_filsys fs = ctx->fs;
8019 blk_t end, save_blocks_count, i;
8020 struct problem_context pctx;
8022 clear_problem_context(&pctx);
8024 end = fs->block_map->start +
8025 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8026 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8027 &save_blocks_count);
8030 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8031 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8034 if (save_blocks_count == end)
8037 for (i = save_blocks_count + 1; i <= end; i++) {
8038 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8039 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8040 for (i = save_blocks_count + 1; i <= end; i++)
8041 ext2fs_mark_block_bitmap(fs->block_map,
8043 ext2fs_mark_bb_dirty(fs);
8045 ext2fs_unmark_valid(fs);
8050 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8051 save_blocks_count, 0);
8054 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8055 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8060 static void e2fsck_pass5(e2fsck_t ctx)
8062 struct problem_context pctx;
8066 clear_problem_context(&pctx);
8068 if (!(ctx->options & E2F_OPT_PREEN))
8069 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8072 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8075 e2fsck_read_bitmaps(ctx);
8077 check_block_bitmaps(ctx);
8078 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8080 check_inode_bitmaps(ctx);
8081 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8083 check_inode_end(ctx);
8084 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8086 check_block_end(ctx);
8087 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8090 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8091 ctx->inode_used_map = 0;
8092 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8093 ctx->inode_dir_map = 0;
8094 ext2fs_free_block_bitmap(ctx->block_found_map);
8095 ctx->block_found_map = 0;
8099 * problem.c --- report filesystem problems to the user
8102 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8103 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8104 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8105 #define PR_MSG_ONLY 0x000008 /* Print message only */
8107 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8109 #define PR_FATAL 0x001000 /* Fatal error */
8110 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8112 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8113 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8114 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8115 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8116 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8119 #define PROMPT_NONE 0
8120 #define PROMPT_FIX 1
8121 #define PROMPT_CLEAR 2
8122 #define PROMPT_RELOCATE 3
8123 #define PROMPT_ALLOCATE 4
8124 #define PROMPT_EXPAND 5
8125 #define PROMPT_CONNECT 6
8126 #define PROMPT_CREATE 7
8127 #define PROMPT_SALVAGE 8
8128 #define PROMPT_TRUNCATE 9
8129 #define PROMPT_CLEAR_INODE 10
8130 #define PROMPT_ABORT 11
8131 #define PROMPT_SPLIT 12
8132 #define PROMPT_CONTINUE 13
8133 #define PROMPT_CLONE 14
8134 #define PROMPT_DELETE 15
8135 #define PROMPT_SUPPRESS 16
8136 #define PROMPT_UNLINK 17
8137 #define PROMPT_CLEAR_HTREE 18
8138 #define PROMPT_RECREATE 19
8139 #define PROMPT_NULL 20
8141 struct e2fsck_problem {
8143 const char * e2p_description;
8146 problem_t second_code;
8149 struct latch_descr {
8152 problem_t end_message;
8157 * These are the prompts which are used to ask the user if they want
8160 static const char *const prompt[] = {
8161 N_("(no prompt)"), /* 0 */
8163 N_("Clear"), /* 2 */
8164 N_("Relocate"), /* 3 */
8165 N_("Allocate"), /* 4 */
8166 N_("Expand"), /* 5 */
8167 N_("Connect to /lost+found"), /* 6 */
8168 N_("Create"), /* 7 */
8169 N_("Salvage"), /* 8 */
8170 N_("Truncate"), /* 9 */
8171 N_("Clear inode"), /* 10 */
8172 N_("Abort"), /* 11 */
8173 N_("Split"), /* 12 */
8174 N_("Continue"), /* 13 */
8175 N_("Clone multiply-claimed blocks"), /* 14 */
8176 N_("Delete file"), /* 15 */
8177 N_("Suppress messages"),/* 16 */
8178 N_("Unlink"), /* 17 */
8179 N_("Clear HTree index"),/* 18 */
8180 N_("Recreate"), /* 19 */
8185 * These messages are printed when we are preen mode and we will be
8186 * automatically fixing the problem.
8188 static const char *const preen_msg[] = {
8189 N_("(NONE)"), /* 0 */
8190 N_("FIXED"), /* 1 */
8191 N_("CLEARED"), /* 2 */
8192 N_("RELOCATED"), /* 3 */
8193 N_("ALLOCATED"), /* 4 */
8194 N_("EXPANDED"), /* 5 */
8195 N_("RECONNECTED"), /* 6 */
8196 N_("CREATED"), /* 7 */
8197 N_("SALVAGED"), /* 8 */
8198 N_("TRUNCATED"), /* 9 */
8199 N_("INODE CLEARED"), /* 10 */
8200 N_("ABORTED"), /* 11 */
8201 N_("SPLIT"), /* 12 */
8202 N_("CONTINUING"), /* 13 */
8203 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8204 N_("FILE DELETED"), /* 15 */
8205 N_("SUPPRESSED"), /* 16 */
8206 N_("UNLINKED"), /* 17 */
8207 N_("HTREE INDEX CLEARED"),/* 18 */
8208 N_("WILL RECREATE"), /* 19 */
8212 static const struct e2fsck_problem problem_table[] = {
8214 /* Pre-Pass 1 errors */
8216 /* Block bitmap not in group */
8217 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8218 PROMPT_RELOCATE, PR_LATCH_RELOC },
8220 /* Inode bitmap not in group */
8221 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8222 PROMPT_RELOCATE, PR_LATCH_RELOC },
8224 /* Inode table not in group */
8225 { PR_0_ITABLE_NOT_GROUP,
8226 N_("@i table for @g %g is not in @g. (@b %b)\n"
8227 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8228 PROMPT_RELOCATE, PR_LATCH_RELOC },
8230 /* Superblock corrupt */
8232 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8233 "@f. If the @v is valid and it really contains an ext2\n"
8234 "@f (and not swap or ufs or something else), then the @S\n"
8235 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8236 " e2fsck -b %S <@v>\n\n"),
8237 PROMPT_NONE, PR_FATAL },
8239 /* Filesystem size is wrong */
8240 { PR_0_FS_SIZE_WRONG,
8241 N_("The @f size (according to the @S) is %b @bs\n"
8242 "The physical size of the @v is %c @bs\n"
8243 "Either the @S or the partition table is likely to be corrupt!\n"),
8246 /* Fragments not supported */
8247 { PR_0_NO_FRAGMENTS,
8248 N_("@S @b_size = %b, fragsize = %c.\n"
8249 "This version of e2fsck does not support fragment sizes different\n"
8250 "from the @b size.\n"),
8251 PROMPT_NONE, PR_FATAL },
8253 /* Bad blocks_per_group */
8254 { PR_0_BLOCKS_PER_GROUP,
8255 N_("@S @bs_per_group = %b, should have been %c\n"),
8256 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8258 /* Bad first_data_block */
8259 { PR_0_FIRST_DATA_BLOCK,
8260 N_("@S first_data_@b = %b, should have been %c\n"),
8261 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8263 /* Adding UUID to filesystem */
8265 N_("@f did not have a UUID; generating one.\n\n"),
8269 { PR_0_RELOCATE_HINT,
8270 N_("Note: if several inode or block bitmap blocks or part\n"
8271 "of the inode table require relocation, you may wish to try\n"
8272 "running e2fsck with the '-b %S' option first. The problem\n"
8273 "may lie only with the primary block group descriptors, and\n"
8274 "the backup block group descriptors may be OK.\n\n"),
8275 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8277 /* Miscellaneous superblock corruption */
8278 { PR_0_MISC_CORRUPT_SUPER,
8279 N_("Corruption found in @S. (%s = %N).\n"),
8280 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8282 /* Error determing physical device size of filesystem */
8283 { PR_0_GETSIZE_ERROR,
8284 N_("Error determining size of the physical @v: %m\n"),
8285 PROMPT_NONE, PR_FATAL },
8287 /* Inode count in superblock is incorrect */
8288 { PR_0_INODE_COUNT_WRONG,
8289 N_("@i count in @S is %i, @s %j.\n"),
8292 { PR_0_HURD_CLEAR_FILETYPE,
8293 N_("The Hurd does not support the filetype feature.\n"),
8296 /* Journal inode is invalid */
8297 { PR_0_JOURNAL_BAD_INODE,
8298 N_("@S has an @n ext3 @j (@i %i).\n"),
8299 PROMPT_CLEAR, PR_PREEN_OK },
8301 /* The external journal has (unsupported) multiple filesystems */
8302 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8303 N_("External @j has multiple @f users (unsupported).\n"),
8304 PROMPT_NONE, PR_FATAL },
8306 /* Can't find external journal */
8307 { PR_0_CANT_FIND_JOURNAL,
8308 N_("Can't find external @j\n"),
8309 PROMPT_NONE, PR_FATAL },
8311 /* External journal has bad superblock */
8312 { PR_0_EXT_JOURNAL_BAD_SUPER,
8313 N_("External @j has bad @S\n"),
8314 PROMPT_NONE, PR_FATAL },
8316 /* Superblock has a bad journal UUID */
8317 { PR_0_JOURNAL_BAD_UUID,
8318 N_("External @j does not support this @f\n"),
8319 PROMPT_NONE, PR_FATAL },
8321 /* Journal has an unknown superblock type */
8322 { PR_0_JOURNAL_UNSUPP_SUPER,
8323 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8324 "It is likely that your copy of e2fsck is old and/or doesn't "
8325 "support this @j format.\n"
8326 "It is also possible the @j @S is corrupt.\n"),
8327 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8329 /* Journal superblock is corrupt */
8330 { PR_0_JOURNAL_BAD_SUPER,
8331 N_("Ext3 @j @S is corrupt.\n"),
8332 PROMPT_FIX, PR_PREEN_OK },
8334 /* Superblock flag should be cleared */
8335 { PR_0_JOURNAL_HAS_JOURNAL,
8336 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8337 PROMPT_CLEAR, PR_PREEN_OK },
8339 /* Superblock flag is incorrect */
8340 { PR_0_JOURNAL_RECOVER_SET,
8341 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8342 PROMPT_CLEAR, PR_PREEN_OK },
8344 /* Journal has data, but recovery flag is clear */
8345 { PR_0_JOURNAL_RECOVERY_CLEAR,
8346 N_("ext3 recovery flag is clear, but @j has data.\n"),
8349 /* Ask if we should clear the journal */
8350 { PR_0_JOURNAL_RESET_JOURNAL,
8352 PROMPT_NULL, PR_PREEN_NOMSG },
8354 /* Ask if we should run the journal anyway */
8356 N_("Run @j anyway"),
8359 /* Run the journal by default */
8360 { PR_0_JOURNAL_RUN_DEFAULT,
8361 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8364 /* Clearing orphan inode */
8365 { PR_0_ORPHAN_CLEAR_INODE,
8366 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8369 /* Illegal block found in orphaned inode */
8370 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8371 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8374 /* Already cleared block found in orphaned inode */
8375 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8376 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8379 /* Illegal orphan inode in superblock */
8380 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8381 N_("@I @o @i %i in @S.\n"),
8384 /* Illegal inode in orphaned inode list */
8385 { PR_0_ORPHAN_ILLEGAL_INODE,
8386 N_("@I @i %i in @o @i list.\n"),
8389 /* Filesystem revision is 0, but feature flags are set */
8390 { PR_0_FS_REV_LEVEL,
8391 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8392 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8394 /* Journal superblock has an unknown read-only feature flag set */
8395 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8396 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8399 /* Journal superblock has an unknown incompatible feature flag set */
8400 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8401 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8404 /* Journal has unsupported version number */
8405 { PR_0_JOURNAL_UNSUPP_VERSION,
8406 N_("@j version not supported by this e2fsck.\n"),
8409 /* Moving journal to hidden file */
8410 { PR_0_MOVE_JOURNAL,
8411 N_("Moving @j from /%s to hidden @i.\n\n"),
8414 /* Error moving journal to hidden file */
8415 { PR_0_ERR_MOVE_JOURNAL,
8416 N_("Error moving @j: %m\n\n"),
8419 /* Clearing V2 journal superblock */
8420 { PR_0_CLEAR_V2_JOURNAL,
8421 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8422 "Clearing fields beyond the V1 @j @S...\n\n"),
8425 /* Backup journal inode blocks */
8427 N_("Backing up @j @i @b information.\n\n"),
8430 /* Reserved blocks w/o resize_inode */
8431 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8432 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8433 "is %N; @s zero. "),
8436 /* Resize_inode not enabled, but resize inode is non-zero */
8437 { PR_0_CLEAR_RESIZE_INODE,
8438 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8441 /* Resize inode invalid */
8442 { PR_0_RESIZE_INODE_INVALID,
8443 N_("Resize @i not valid. "),
8444 PROMPT_RECREATE, 0 },
8448 /* Pass 1: Checking inodes, blocks, and sizes */
8450 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8453 /* Root directory is not an inode */
8454 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8457 /* Root directory has dtime set */
8459 N_("@r has dtime set (probably due to old mke2fs). "),
8460 PROMPT_FIX, PR_PREEN_OK },
8462 /* Reserved inode has bad mode */
8463 { PR_1_RESERVED_BAD_MODE,
8464 N_("Reserved @i %i (%Q) has @n mode. "),
8465 PROMPT_CLEAR, PR_PREEN_OK },
8467 /* Deleted inode has zero dtime */
8469 N_("@D @i %i has zero dtime. "),
8470 PROMPT_FIX, PR_PREEN_OK },
8472 /* Inode in use, but dtime set */
8474 N_("@i %i is in use, but has dtime set. "),
8475 PROMPT_FIX, PR_PREEN_OK },
8477 /* Zero-length directory */
8478 { PR_1_ZERO_LENGTH_DIR,
8479 N_("@i %i is a @z @d. "),
8480 PROMPT_CLEAR, PR_PREEN_OK },
8482 /* Block bitmap conflicts with some other fs block */
8484 N_("@g %g's @b @B at %b @C.\n"),
8485 PROMPT_RELOCATE, 0 },
8487 /* Inode bitmap conflicts with some other fs block */
8489 N_("@g %g's @i @B at %b @C.\n"),
8490 PROMPT_RELOCATE, 0 },
8492 /* Inode table conflicts with some other fs block */
8493 { PR_1_ITABLE_CONFLICT,
8494 N_("@g %g's @i table at %b @C.\n"),
8495 PROMPT_RELOCATE, 0 },
8497 /* Block bitmap is on a bad block */
8498 { PR_1_BB_BAD_BLOCK,
8499 N_("@g %g's @b @B (%b) is bad. "),
8500 PROMPT_RELOCATE, 0 },
8502 /* Inode bitmap is on a bad block */
8503 { PR_1_IB_BAD_BLOCK,
8504 N_("@g %g's @i @B (%b) is bad. "),
8505 PROMPT_RELOCATE, 0 },
8507 /* Inode has incorrect i_size */
8509 N_("@i %i, i_size is %Is, @s %N. "),
8510 PROMPT_FIX, PR_PREEN_OK },
8512 /* Inode has incorrect i_blocks */
8513 { PR_1_BAD_I_BLOCKS,
8514 N_("@i %i, i_@bs is %Ib, @s %N. "),
8515 PROMPT_FIX, PR_PREEN_OK },
8517 /* Illegal blocknumber in inode */
8518 { PR_1_ILLEGAL_BLOCK_NUM,
8519 N_("@I @b #%B (%b) in @i %i. "),
8520 PROMPT_CLEAR, PR_LATCH_BLOCK },
8522 /* Block number overlaps fs metadata */
8523 { PR_1_BLOCK_OVERLAPS_METADATA,
8524 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8525 PROMPT_CLEAR, PR_LATCH_BLOCK },
8527 /* Inode has illegal blocks (latch question) */
8528 { PR_1_INODE_BLOCK_LATCH,
8529 N_("@i %i has illegal @b(s). "),
8532 /* Too many bad blocks in inode */
8533 { PR_1_TOO_MANY_BAD_BLOCKS,
8534 N_("Too many illegal @bs in @i %i.\n"),
8535 PROMPT_CLEAR_INODE, PR_NO_OK },
8537 /* Illegal block number in bad block inode */
8538 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8539 N_("@I @b #%B (%b) in bad @b @i. "),
8540 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8542 /* Bad block inode has illegal blocks (latch question) */
8543 { PR_1_INODE_BBLOCK_LATCH,
8544 N_("Bad @b @i has illegal @b(s). "),
8547 /* Duplicate or bad blocks in use! */
8548 { PR_1_DUP_BLOCKS_PREENSTOP,
8549 N_("Duplicate or bad @b in use!\n"),
8552 /* Bad block used as bad block indirect block */
8553 { PR_1_BBINODE_BAD_METABLOCK,
8554 N_("Bad @b %b used as bad @b @i indirect @b. "),
8555 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8557 /* Inconsistency can't be fixed prompt */
8558 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8559 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8560 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8562 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8564 /* Bad primary block */
8565 { PR_1_BAD_PRIMARY_BLOCK,
8566 N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
8567 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8569 /* Bad primary block prompt */
8570 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8571 N_("You can remove this @b from the bad @b list and hope\n"
8572 "that the @b is really OK. But there are no guarantees.\n\n"),
8573 PROMPT_CLEAR, PR_PREEN_NOMSG },
8575 /* Bad primary superblock */
8576 { PR_1_BAD_PRIMARY_SUPERBLOCK,
8577 N_("The primary @S (%b) is on the bad @b list.\n"),
8578 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8580 /* Bad primary block group descriptors */
8581 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8582 N_("Block %b in the primary @g descriptors "
8583 "is on the bad @b list\n"),
8584 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8586 /* Bad superblock in group */
8587 { PR_1_BAD_SUPERBLOCK,
8588 N_("Warning: Group %g's @S (%b) is bad.\n"),
8589 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8591 /* Bad block group descriptors in group */
8592 { PR_1_BAD_GROUP_DESCRIPTORS,
8593 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8595 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8597 /* Block claimed for no reason */
8598 { PR_1_PROGERR_CLAIMED_BLOCK,
8599 N_("Programming error? @b #%b claimed for no reason in "
8600 "process_bad_@b.\n"),
8601 PROMPT_NONE, PR_PREEN_OK },
8603 /* Error allocating blocks for relocating metadata */
8604 { PR_1_RELOC_BLOCK_ALLOCATE,
8605 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8606 PROMPT_NONE, PR_PREEN_OK },
8608 /* Error allocating block buffer during relocation process */
8609 { PR_1_RELOC_MEMORY_ALLOCATE,
8610 N_("@A @b buffer for relocating %s\n"),
8611 PROMPT_NONE, PR_PREEN_OK },
8613 /* Relocating metadata group information from X to Y */
8614 { PR_1_RELOC_FROM_TO,
8615 N_("Relocating @g %g's %s from %b to %c...\n"),
8616 PROMPT_NONE, PR_PREEN_OK },
8618 /* Relocating metatdata group information to X */
8620 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8621 PROMPT_NONE, PR_PREEN_OK },
8623 /* Block read error during relocation process */
8624 { PR_1_RELOC_READ_ERR,
8625 N_("Warning: could not read @b %b of %s: %m\n"),
8626 PROMPT_NONE, PR_PREEN_OK },
8628 /* Block write error during relocation process */
8629 { PR_1_RELOC_WRITE_ERR,
8630 N_("Warning: could not write @b %b for %s: %m\n"),
8631 PROMPT_NONE, PR_PREEN_OK },
8633 /* Error allocating inode bitmap */
8634 { PR_1_ALLOCATE_IBITMAP_ERROR,
8635 N_("@A @i @B (%N): %m\n"),
8636 PROMPT_NONE, PR_FATAL },
8638 /* Error allocating block bitmap */
8639 { PR_1_ALLOCATE_BBITMAP_ERROR,
8640 N_("@A @b @B (%N): %m\n"),
8641 PROMPT_NONE, PR_FATAL },
8643 /* Error allocating icount structure */
8644 { PR_1_ALLOCATE_ICOUNT,
8645 N_("@A icount link information: %m\n"),
8646 PROMPT_NONE, PR_FATAL },
8648 /* Error allocating dbcount */
8649 { PR_1_ALLOCATE_DBCOUNT,
8650 N_("@A @d @b array: %m\n"),
8651 PROMPT_NONE, PR_FATAL },
8653 /* Error while scanning inodes */
8655 N_("Error while scanning @is (%i): %m\n"),
8656 PROMPT_NONE, PR_FATAL },
8658 /* Error while iterating over blocks */
8659 { PR_1_BLOCK_ITERATE,
8660 N_("Error while iterating over @bs in @i %i: %m\n"),
8661 PROMPT_NONE, PR_FATAL },
8663 /* Error while storing inode count information */
8664 { PR_1_ICOUNT_STORE,
8665 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8666 PROMPT_NONE, PR_FATAL },
8668 /* Error while storing directory block information */
8670 N_("Error storing @d @b information "
8671 "(@i=%i, @b=%b, num=%N): %m\n"),
8672 PROMPT_NONE, PR_FATAL },
8674 /* Error while reading inode (for clearing) */
8676 N_("Error reading @i %i: %m\n"),
8677 PROMPT_NONE, PR_FATAL },
8679 /* Suppress messages prompt */
8680 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8682 /* Imagic flag set on an inode when filesystem doesn't support it */
8684 N_("@i %i has imagic flag set. "),
8687 /* Immutable flag set on a device or socket inode */
8688 { PR_1_SET_IMMUTABLE,
8689 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8690 "or append-only flag set. "),
8691 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8693 /* Compression flag set on an inode when filesystem doesn't support it */
8695 N_("@i %i has @cion flag set on @f without @cion support. "),
8698 /* Non-zero size for device, fifo or socket inode */
8699 { PR_1_SET_NONZSIZE,
8700 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8701 PROMPT_FIX, PR_PREEN_OK },
8703 /* Filesystem revision is 0, but feature flags are set */
8704 { PR_1_FS_REV_LEVEL,
8705 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8706 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8708 /* Journal inode is not in use, but contains data */
8709 { PR_1_JOURNAL_INODE_NOT_CLEAR,
8710 N_("@j @i is not in use, but contains data. "),
8711 PROMPT_CLEAR, PR_PREEN_OK },
8713 /* Journal has bad mode */
8714 { PR_1_JOURNAL_BAD_MODE,
8715 N_("@j is not regular file. "),
8716 PROMPT_FIX, PR_PREEN_OK },
8718 /* Deal with inodes that were part of orphan linked list */
8720 N_("@i %i was part of the @o @i list. "),
8721 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8723 /* Deal with inodes that were part of corrupted orphan linked
8724 list (latch question) */
8725 { PR_1_ORPHAN_LIST_REFUGEES,
8726 N_("@is that were part of a corrupted orphan linked list found. "),
8729 /* Error allocating refcount structure */
8730 { PR_1_ALLOCATE_REFCOUNT,
8731 N_("@A refcount structure (%N): %m\n"),
8732 PROMPT_NONE, PR_FATAL },
8734 /* Error reading extended attribute block */
8735 { PR_1_READ_EA_BLOCK,
8736 N_("Error reading @a @b %b for @i %i. "),
8739 /* Invalid extended attribute block */
8740 { PR_1_BAD_EA_BLOCK,
8741 N_("@i %i has a bad @a @b %b. "),
8744 /* Error reading Extended Attribute block while fixing refcount */
8745 { PR_1_EXTATTR_READ_ABORT,
8746 N_("Error reading @a @b %b (%m). "),
8749 /* Extended attribute reference count incorrect */
8750 { PR_1_EXTATTR_REFCOUNT,
8751 N_("@a @b %b has reference count %B, @s %N. "),
8754 /* Error writing Extended Attribute block while fixing refcount */
8755 { PR_1_EXTATTR_WRITE,
8756 N_("Error writing @a @b %b (%m). "),
8759 /* Multiple EA blocks not supported */
8760 { PR_1_EA_MULTI_BLOCK,
8761 N_("@a @b %b has h_@bs > 1. "),
8764 /* Error allocating EA region allocation structure */
8765 { PR_1_EA_ALLOC_REGION,
8766 N_("@A @a @b %b. "),
8769 /* Error EA allocation collision */
8770 { PR_1_EA_ALLOC_COLLISION,
8771 N_("@a @b %b is corrupt (allocation collision). "),
8774 /* Bad extended attribute name */
8776 N_("@a @b %b is corrupt (@n name). "),
8779 /* Bad extended attribute value */
8780 { PR_1_EA_BAD_VALUE,
8781 N_("@a @b %b is corrupt (@n value). "),
8784 /* Inode too big (latch question) */
8785 { PR_1_INODE_TOOBIG,
8786 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
8788 /* Directory too big */
8790 N_("@b #%B (%b) causes @d to be too big. "),
8791 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8793 /* Regular file too big */
8795 N_("@b #%B (%b) causes file to be too big. "),
8796 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8798 /* Symlink too big */
8799 { PR_1_TOOBIG_SYMLINK,
8800 N_("@b #%B (%b) causes symlink to be too big. "),
8801 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8803 /* INDEX_FL flag set on a non-HTREE filesystem */
8805 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8806 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8808 /* INDEX_FL flag set on a non-directory */
8810 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8811 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8813 /* Invalid root node in HTREE directory */
8814 { PR_1_HTREE_BADROOT,
8815 N_("@h %i has an @n root node.\n"),
8816 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8818 /* Unsupported hash version in HTREE directory */
8820 N_("@h %i has an unsupported hash version (%N)\n"),
8821 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8823 /* Incompatible flag in HTREE root node */
8824 { PR_1_HTREE_INCOMPAT,
8825 N_("@h %i uses an incompatible htree root node flag.\n"),
8826 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8828 /* HTREE too deep */
8830 N_("@h %i has a tree depth (%N) which is too big\n"),
8831 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8833 /* Bad block has indirect block that conflicts with filesystem block */
8835 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8837 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8839 /* Resize inode failed */
8840 { PR_1_RESIZE_INODE_CREATE,
8841 N_("Resize @i (re)creation failed: %m."),
8844 /* invalid inode->i_extra_isize */
8846 N_("@i %i has a extra size (%IS) which is @n\n"),
8847 PROMPT_FIX, PR_PREEN_OK },
8849 /* invalid ea entry->e_name_len */
8850 { PR_1_ATTR_NAME_LEN,
8851 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8852 PROMPT_CLEAR, PR_PREEN_OK },
8854 /* invalid ea entry->e_value_size */
8855 { PR_1_ATTR_VALUE_SIZE,
8856 N_("@a in @i %i has a value size (%N) which is @n\n"),
8857 PROMPT_CLEAR, PR_PREEN_OK },
8859 /* invalid ea entry->e_value_offs */
8860 { PR_1_ATTR_VALUE_OFFSET,
8861 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8862 PROMPT_CLEAR, PR_PREEN_OK },
8864 /* invalid ea entry->e_value_block */
8865 { PR_1_ATTR_VALUE_BLOCK,
8866 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8867 PROMPT_CLEAR, PR_PREEN_OK },
8869 /* invalid ea entry->e_hash */
8871 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8872 PROMPT_CLEAR, PR_PREEN_OK },
8874 /* Pass 1b errors */
8876 /* Pass 1B: Rescan for duplicate/bad blocks */
8877 { PR_1B_PASS_HEADER,
8878 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8879 "Pass 1B: Rescanning for @m @bs\n"),
8882 /* Duplicate/bad block(s) header */
8883 { PR_1B_DUP_BLOCK_HEADER,
8884 N_("@m @b(s) in @i %i:"),
8887 /* Duplicate/bad block(s) in inode */
8890 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8892 /* Duplicate/bad block(s) end */
8893 { PR_1B_DUP_BLOCK_END,
8895 PROMPT_NONE, PR_PREEN_NOHDR },
8897 /* Error while scanning inodes */
8898 { PR_1B_ISCAN_ERROR,
8899 N_("Error while scanning inodes (%i): %m\n"),
8900 PROMPT_NONE, PR_FATAL },
8902 /* Error allocating inode bitmap */
8903 { PR_1B_ALLOCATE_IBITMAP_ERROR,
8904 N_("@A @i @B (@i_dup_map): %m\n"),
8905 PROMPT_NONE, PR_FATAL },
8907 /* Error while iterating over blocks */
8908 { PR_1B_BLOCK_ITERATE,
8909 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8912 /* Error adjusting EA refcount */
8913 { PR_1B_ADJ_EA_REFCOUNT,
8914 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8918 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8919 { PR_1C_PASS_HEADER,
8920 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8924 /* Pass 1D: Reconciling multiply-claimed blocks */
8925 { PR_1D_PASS_HEADER,
8926 N_("Pass 1D: Reconciling @m @bs\n"),
8929 /* File has duplicate blocks */
8931 N_("File %Q (@i #%i, mod time %IM)\n"
8932 " has %B @m @b(s), shared with %N file(s):\n"),
8935 /* List of files sharing duplicate blocks */
8936 { PR_1D_DUP_FILE_LIST,
8937 N_("\t%Q (@i #%i, mod time %IM)\n"),
8940 /* File sharing blocks with filesystem metadata */
8941 { PR_1D_SHARE_METADATA,
8942 N_("\t<@f metadata>\n"),
8945 /* Report of how many duplicate/bad inodes */
8946 { PR_1D_NUM_DUP_INODES,
8947 N_("(There are %N @is containing @m @bs.)\n\n"),
8950 /* Duplicated blocks already reassigned or cloned. */
8951 { PR_1D_DUP_BLOCKS_DEALT,
8952 N_("@m @bs already reassigned or cloned.\n\n"),
8955 /* Clone duplicate/bad blocks? */
8956 { PR_1D_CLONE_QUESTION,
8957 "", PROMPT_CLONE, PR_NO_OK },
8960 { PR_1D_DELETE_QUESTION,
8961 "", PROMPT_DELETE, 0 },
8963 /* Couldn't clone file (error) */
8964 { PR_1D_CLONE_ERROR,
8965 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
8969 /* Pass 2: Checking directory structure */
8971 N_("Pass 2: Checking @d structure\n"),
8974 /* Bad inode number for '.' */
8975 { PR_2_BAD_INODE_DOT,
8976 N_("@n @i number for '.' in @d @i %i.\n"),
8979 /* Directory entry has bad inode number */
8981 N_("@E has @n @i #: %Di.\n"),
8984 /* Directory entry has deleted or unused inode */
8985 { PR_2_UNUSED_INODE,
8986 N_("@E has @D/unused @i %Di. "),
8987 PROMPT_CLEAR, PR_PREEN_OK },
8989 /* Directry entry is link to '.' */
8991 N_("@E @L to '.' "),
8994 /* Directory entry points to inode now located in a bad block */
8996 N_("@E points to @i (%Di) located in a bad @b.\n"),
8999 /* Directory entry contains a link to a directory */
9001 N_("@E @L to @d %P (%Di).\n"),
9004 /* Directory entry contains a link to the root directry */
9006 N_("@E @L to the @r.\n"),
9009 /* Directory entry has illegal characters in its name */
9011 N_("@E has illegal characters in its name.\n"),
9014 /* Missing '.' in directory inode */
9016 N_("Missing '.' in @d @i %i.\n"),
9019 /* Missing '..' in directory inode */
9020 { PR_2_MISSING_DOT_DOT,
9021 N_("Missing '..' in @d @i %i.\n"),
9024 /* First entry in directory inode doesn't contain '.' */
9026 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9029 /* Second entry in directory inode doesn't contain '..' */
9030 { PR_2_2ND_NOT_DOT_DOT,
9031 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9034 /* i_faddr should be zero */
9036 N_("i_faddr @F %IF, @s zero.\n"),
9039 /* i_file_acl should be zero */
9040 { PR_2_FILE_ACL_ZERO,
9041 N_("i_file_acl @F %If, @s zero.\n"),
9044 /* i_dir_acl should be zero */
9045 { PR_2_DIR_ACL_ZERO,
9046 N_("i_dir_acl @F %Id, @s zero.\n"),
9049 /* i_frag should be zero */
9051 N_("i_frag @F %N, @s zero.\n"),
9054 /* i_fsize should be zero */
9056 N_("i_fsize @F %N, @s zero.\n"),
9059 /* inode has bad mode */
9061 N_("@i %i (%Q) has @n mode (%Im).\n"),
9064 /* directory corrupted */
9065 { PR_2_DIR_CORRUPTED,
9066 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9067 PROMPT_SALVAGE, 0 },
9069 /* filename too long */
9070 { PR_2_FILENAME_LONG,
9071 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9072 PROMPT_TRUNCATE, 0 },
9074 /* Directory inode has a missing block (hole) */
9075 { PR_2_DIRECTORY_HOLE,
9076 N_("@d @i %i has an unallocated @b #%B. "),
9077 PROMPT_ALLOCATE, 0 },
9079 /* '.' is not NULL terminated */
9080 { PR_2_DOT_NULL_TERM,
9081 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9084 /* '..' is not NULL terminated */
9085 { PR_2_DOT_DOT_NULL_TERM,
9086 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9089 /* Illegal character device inode */
9090 { PR_2_BAD_CHAR_DEV,
9091 N_("@i %i (%Q) is an @I character @v.\n"),
9094 /* Illegal block device inode */
9095 { PR_2_BAD_BLOCK_DEV,
9096 N_("@i %i (%Q) is an @I @b @v.\n"),
9099 /* Duplicate '.' entry */
9101 N_("@E is duplicate '.' @e.\n"),
9104 /* Duplicate '..' entry */
9106 N_("@E is duplicate '..' @e.\n"),
9109 /* Internal error: couldn't find dir_info */
9111 N_("Internal error: cannot find dir_info for %i.\n"),
9112 PROMPT_NONE, PR_FATAL },
9114 /* Final rec_len is wrong */
9115 { PR_2_FINAL_RECLEN,
9116 N_("@E has rec_len of %Dr, @s %N.\n"),
9119 /* Error allocating icount structure */
9120 { PR_2_ALLOCATE_ICOUNT,
9121 N_("@A icount structure: %m\n"),
9122 PROMPT_NONE, PR_FATAL },
9124 /* Error iterating over directory blocks */
9125 { PR_2_DBLIST_ITERATE,
9126 N_("Error iterating over @d @bs: %m\n"),
9127 PROMPT_NONE, PR_FATAL },
9129 /* Error reading directory block */
9130 { PR_2_READ_DIRBLOCK,
9131 N_("Error reading @d @b %b (@i %i): %m\n"),
9132 PROMPT_CONTINUE, 0 },
9134 /* Error writing directory block */
9135 { PR_2_WRITE_DIRBLOCK,
9136 N_("Error writing @d @b %b (@i %i): %m\n"),
9137 PROMPT_CONTINUE, 0 },
9139 /* Error allocating new directory block */
9140 { PR_2_ALLOC_DIRBOCK,
9141 N_("@A new @d @b for @i %i (%s): %m\n"),
9144 /* Error deallocating inode */
9145 { PR_2_DEALLOC_INODE,
9146 N_("Error deallocating @i %i: %m\n"),
9147 PROMPT_NONE, PR_FATAL },
9149 /* Directory entry for '.' is big. Split? */
9151 N_("@d @e for '.' is big. "),
9152 PROMPT_SPLIT, PR_NO_OK },
9154 /* Illegal FIFO inode */
9156 N_("@i %i (%Q) is an @I FIFO.\n"),
9159 /* Illegal socket inode */
9161 N_("@i %i (%Q) is an @I socket.\n"),
9164 /* Directory filetype not set */
9165 { PR_2_SET_FILETYPE,
9166 N_("Setting filetype for @E to %N.\n"),
9167 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9169 /* Directory filetype incorrect */
9170 { PR_2_BAD_FILETYPE,
9171 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9174 /* Directory filetype set on filesystem */
9175 { PR_2_CLEAR_FILETYPE,
9176 N_("@E has filetype set.\n"),
9177 PROMPT_CLEAR, PR_PREEN_OK },
9179 /* Directory filename is null */
9181 N_("@E has a @z name.\n"),
9184 /* Invalid symlink */
9185 { PR_2_INVALID_SYMLINK,
9186 N_("Symlink %Q (@i #%i) is @n.\n"),
9189 /* i_file_acl (extended attribute block) is bad */
9190 { PR_2_FILE_ACL_BAD,
9191 N_("@a @b @F @n (%If).\n"),
9194 /* Filesystem contains large files, but has no such flag in sb */
9195 { PR_2_FEATURE_LARGE_FILES,
9196 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9199 /* Node in HTREE directory not referenced */
9200 { PR_2_HTREE_NOTREF,
9201 N_("@p @h %d: node (%B) not referenced\n"),
9204 /* Node in HTREE directory referenced twice */
9205 { PR_2_HTREE_DUPREF,
9206 N_("@p @h %d: node (%B) referenced twice\n"),
9209 /* Node in HTREE directory has bad min hash */
9210 { PR_2_HTREE_MIN_HASH,
9211 N_("@p @h %d: node (%B) has bad min hash\n"),
9214 /* Node in HTREE directory has bad max hash */
9215 { PR_2_HTREE_MAX_HASH,
9216 N_("@p @h %d: node (%B) has bad max hash\n"),
9219 /* Clear invalid HTREE directory */
9221 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9223 /* Bad block in htree interior node */
9224 { PR_2_HTREE_BADBLK,
9225 N_("@p @h %d (%q): bad @b number %b.\n"),
9226 PROMPT_CLEAR_HTREE, 0 },
9228 /* Error adjusting EA refcount */
9229 { PR_2_ADJ_EA_REFCOUNT,
9230 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9231 PROMPT_NONE, PR_FATAL },
9233 /* Invalid HTREE root node */
9234 { PR_2_HTREE_BAD_ROOT,
9235 N_("@p @h %d: root node is @n\n"),
9236 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9238 /* Invalid HTREE limit */
9239 { PR_2_HTREE_BAD_LIMIT,
9240 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9241 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9243 /* Invalid HTREE count */
9244 { PR_2_HTREE_BAD_COUNT,
9245 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9246 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9248 /* HTREE interior node has out-of-order hashes in table */
9249 { PR_2_HTREE_HASH_ORDER,
9250 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9251 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9253 /* Node in HTREE directory has invalid depth */
9254 { PR_2_HTREE_BAD_DEPTH,
9255 N_("@p @h %d: node (%B) has @n depth\n"),
9258 /* Duplicate directory entry found */
9259 { PR_2_DUPLICATE_DIRENT,
9260 N_("Duplicate @E found. "),
9263 /* Non-unique filename found */
9264 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9265 N_("@E has a non-unique filename.\nRename to %s"),
9268 /* Duplicate directory entry found */
9269 { PR_2_REPORT_DUP_DIRENT,
9270 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9275 /* Pass 3: Checking directory connectivity */
9277 N_("Pass 3: Checking @d connectivity\n"),
9280 /* Root inode not allocated */
9281 { PR_3_NO_ROOT_INODE,
9282 N_("@r not allocated. "),
9283 PROMPT_ALLOCATE, 0 },
9285 /* No room in lost+found */
9286 { PR_3_EXPAND_LF_DIR,
9287 N_("No room in @l @d. "),
9290 /* Unconnected directory inode */
9291 { PR_3_UNCONNECTED_DIR,
9292 N_("Unconnected @d @i %i (%p)\n"),
9293 PROMPT_CONNECT, 0 },
9295 /* /lost+found not found */
9297 N_("/@l not found. "),
9298 PROMPT_CREATE, PR_PREEN_OK },
9300 /* .. entry is incorrect */
9302 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9305 /* Bad or non-existent /lost+found. Cannot reconnect */
9307 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9310 /* Could not expand /lost+found */
9311 { PR_3_CANT_EXPAND_LPF,
9312 N_("Could not expand /@l: %m\n"),
9315 /* Could not reconnect inode */
9316 { PR_3_CANT_RECONNECT,
9317 N_("Could not reconnect %i: %m\n"),
9320 /* Error while trying to find /lost+found */
9321 { PR_3_ERR_FIND_LPF,
9322 N_("Error while trying to find /@l: %m\n"),
9325 /* Error in ext2fs_new_block while creating /lost+found */
9326 { PR_3_ERR_LPF_NEW_BLOCK,
9327 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9330 /* Error in ext2fs_new_inode while creating /lost+found */
9331 { PR_3_ERR_LPF_NEW_INODE,
9332 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9335 /* Error in ext2fs_new_dir_block while creating /lost+found */
9336 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9337 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9340 /* Error while writing directory block for /lost+found */
9341 { PR_3_ERR_LPF_WRITE_BLOCK,
9342 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9345 /* Error while adjusting inode count */
9346 { PR_3_ADJUST_INODE,
9347 N_("Error while adjusting @i count on @i %i\n"),
9350 /* Couldn't fix parent directory -- error */
9351 { PR_3_FIX_PARENT_ERR,
9352 N_("Couldn't fix parent of @i %i: %m\n\n"),
9355 /* Couldn't fix parent directory -- couldn't find it */
9356 { PR_3_FIX_PARENT_NOFIND,
9357 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9360 /* Error allocating inode bitmap */
9361 { PR_3_ALLOCATE_IBITMAP_ERROR,
9362 N_("@A @i @B (%N): %m\n"),
9363 PROMPT_NONE, PR_FATAL },
9365 /* Error creating root directory */
9366 { PR_3_CREATE_ROOT_ERROR,
9367 N_("Error creating root @d (%s): %m\n"),
9368 PROMPT_NONE, PR_FATAL },
9370 /* Error creating lost and found directory */
9371 { PR_3_CREATE_LPF_ERROR,
9372 N_("Error creating /@l @d (%s): %m\n"),
9373 PROMPT_NONE, PR_FATAL },
9375 /* Root inode is not directory; aborting */
9376 { PR_3_ROOT_NOT_DIR_ABORT,
9377 N_("@r is not a @d; aborting.\n"),
9378 PROMPT_NONE, PR_FATAL },
9380 /* Cannot proceed without a root inode. */
9381 { PR_3_NO_ROOT_INODE_ABORT,
9382 N_("can't proceed without a @r.\n"),
9383 PROMPT_NONE, PR_FATAL },
9385 /* Internal error: couldn't find dir_info */
9387 N_("Internal error: cannot find dir_info for %i.\n"),
9388 PROMPT_NONE, PR_FATAL },
9390 /* Lost+found not a directory */
9392 N_("/@l is not a @d (ino=%i)\n"),
9395 /* Pass 3A Directory Optimization */
9397 /* Pass 3A: Optimizing directories */
9398 { PR_3A_PASS_HEADER,
9399 N_("Pass 3A: Optimizing directories\n"),
9400 PROMPT_NONE, PR_PREEN_NOMSG },
9402 /* Error iterating over directories */
9403 { PR_3A_OPTIMIZE_ITER,
9404 N_("Failed to create dirs_to_hash iterator: %m"),
9407 /* Error rehash directory */
9408 { PR_3A_OPTIMIZE_DIR_ERR,
9409 N_("Failed to optimize directory %q (%d): %m"),
9412 /* Rehashing dir header */
9413 { PR_3A_OPTIMIZE_DIR_HEADER,
9414 N_("Optimizing directories: "),
9415 PROMPT_NONE, PR_MSG_ONLY },
9417 /* Rehashing directory %d */
9418 { PR_3A_OPTIMIZE_DIR,
9420 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9422 /* Rehashing dir end */
9423 { PR_3A_OPTIMIZE_DIR_END,
9425 PROMPT_NONE, PR_PREEN_NOHDR },
9429 /* Pass 4: Checking reference counts */
9431 N_("Pass 4: Checking reference counts\n"),
9434 /* Unattached zero-length inode */
9435 { PR_4_ZERO_LEN_INODE,
9436 N_("@u @z @i %i. "),
9437 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9439 /* Unattached inode */
9440 { PR_4_UNATTACHED_INODE,
9442 PROMPT_CONNECT, 0 },
9444 /* Inode ref count wrong */
9445 { PR_4_BAD_REF_COUNT,
9446 N_("@i %i ref count is %Il, @s %N. "),
9447 PROMPT_FIX, PR_PREEN_OK },
9449 { PR_4_INCONSISTENT_COUNT,
9450 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9451 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9452 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9453 "They @s the same!\n"),
9458 /* Pass 5: Checking group summary information */
9460 N_("Pass 5: Checking @g summary information\n"),
9463 /* Padding at end of inode bitmap is not set. */
9464 { PR_5_INODE_BMAP_PADDING,
9465 N_("Padding at end of @i @B is not set. "),
9466 PROMPT_FIX, PR_PREEN_OK },
9468 /* Padding at end of block bitmap is not set. */
9469 { PR_5_BLOCK_BMAP_PADDING,
9470 N_("Padding at end of @b @B is not set. "),
9471 PROMPT_FIX, PR_PREEN_OK },
9473 /* Block bitmap differences header */
9474 { PR_5_BLOCK_BITMAP_HEADER,
9475 N_("@b @B differences: "),
9476 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9478 /* Block not used, but marked in bitmap */
9479 { PR_5_BLOCK_UNUSED,
9481 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9483 /* Block used, but not marked used in bitmap */
9486 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9488 /* Block bitmap differences end */
9489 { PR_5_BLOCK_BITMAP_END,
9491 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9493 /* Inode bitmap differences header */
9494 { PR_5_INODE_BITMAP_HEADER,
9495 N_("@i @B differences: "),
9496 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9498 /* Inode not used, but marked in bitmap */
9499 { PR_5_INODE_UNUSED,
9501 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9503 /* Inode used, but not marked used in bitmap */
9506 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9508 /* Inode bitmap differences end */
9509 { PR_5_INODE_BITMAP_END,
9511 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9513 /* Free inodes count for group wrong */
9514 { PR_5_FREE_INODE_COUNT_GROUP,
9515 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9516 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9518 /* Directories count for group wrong */
9519 { PR_5_FREE_DIR_COUNT_GROUP,
9520 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9521 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9523 /* Free inodes count wrong */
9524 { PR_5_FREE_INODE_COUNT,
9525 N_("Free @is count wrong (%i, counted=%j).\n"),
9526 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9528 /* Free blocks count for group wrong */
9529 { PR_5_FREE_BLOCK_COUNT_GROUP,
9530 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9531 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9533 /* Free blocks count wrong */
9534 { PR_5_FREE_BLOCK_COUNT,
9535 N_("Free @bs count wrong (%b, counted=%c).\n"),
9536 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9538 /* Programming error: bitmap endpoints don't match */
9539 { PR_5_BMAP_ENDPOINTS,
9540 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9541 "match calculated @B endpoints (%i, %j)\n"),
9542 PROMPT_NONE, PR_FATAL },
9544 /* Internal error: fudging end of bitmap */
9545 { PR_5_FUDGE_BITMAP_ERROR,
9546 N_("Internal error: fudging end of bitmap (%N)\n"),
9547 PROMPT_NONE, PR_FATAL },
9549 /* Error copying in replacement inode bitmap */
9550 { PR_5_COPY_IBITMAP_ERROR,
9551 N_("Error copying in replacement @i @B: %m\n"),
9552 PROMPT_NONE, PR_FATAL },
9554 /* Error copying in replacement block bitmap */
9555 { PR_5_COPY_BBITMAP_ERROR,
9556 N_("Error copying in replacement @b @B: %m\n"),
9557 PROMPT_NONE, PR_FATAL },
9559 /* Block range not used, but marked in bitmap */
9560 { PR_5_BLOCK_RANGE_UNUSED,
9562 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9564 /* Block range used, but not marked used in bitmap */
9565 { PR_5_BLOCK_RANGE_USED,
9567 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9569 /* Inode range not used, but marked in bitmap */
9570 { PR_5_INODE_RANGE_UNUSED,
9572 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9574 /* Inode range used, but not marked used in bitmap */
9575 { PR_5_INODE_RANGE_USED,
9577 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9583 * This is the latch flags register. It allows several problems to be
9584 * "latched" together. This means that the user has to answer but one
9585 * question for the set of problems, and all of the associated
9586 * problems will be either fixed or not fixed.
9588 static struct latch_descr pr_latch_info[] = {
9589 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9590 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9591 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9592 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9593 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9594 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9595 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9596 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9597 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9601 static const struct e2fsck_problem *find_problem(problem_t code)
9605 for (i=0; problem_table[i].e2p_code; i++) {
9606 if (problem_table[i].e2p_code == code)
9607 return &problem_table[i];
9612 static struct latch_descr *find_latch(int code)
9616 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9617 if (pr_latch_info[i].latch_code == code)
9618 return &pr_latch_info[i];
9623 int end_problem_latch(e2fsck_t ctx, int mask)
9625 struct latch_descr *ldesc;
9626 struct problem_context pctx;
9629 ldesc = find_latch(mask);
9630 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9631 clear_problem_context(&pctx);
9632 answer = fix_problem(ctx, ldesc->end_message, &pctx);
9634 ldesc->flags &= ~(PRL_VARIABLE);
9638 int set_latch_flags(int mask, int setflags, int clearflags)
9640 struct latch_descr *ldesc;
9642 ldesc = find_latch(mask);
9645 ldesc->flags |= setflags;
9646 ldesc->flags &= ~clearflags;
9650 void clear_problem_context(struct problem_context *ctx)
9652 memset(ctx, 0, sizeof(struct problem_context));
9657 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9659 ext2_filsys fs = ctx->fs;
9660 const struct e2fsck_problem *ptr;
9661 struct latch_descr *ldesc = NULL;
9662 const char *message;
9663 int def_yn, answer, ans;
9664 int print_answer = 0;
9667 ptr = find_problem(code);
9669 printf(_("Unhandled error code (0x%x)!\n"), code);
9673 if ((ptr->flags & PR_NO_DEFAULT) ||
9674 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9675 (ctx->options & E2F_OPT_NO))
9679 * Do special latch processing. This is where we ask the
9680 * latch question, if it exists
9682 if (ptr->flags & PR_LATCH_MASK) {
9683 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9684 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9685 ans = fix_problem(ctx, ldesc->question, pctx);
9687 ldesc->flags |= PRL_YES;
9689 ldesc->flags |= PRL_NO;
9690 ldesc->flags |= PRL_LATCHED;
9692 if (ldesc->flags & PRL_SUPPRESS)
9695 if ((ptr->flags & PR_PREEN_NOMSG) &&
9696 (ctx->options & E2F_OPT_PREEN))
9698 if ((ptr->flags & PR_NO_NOMSG) &&
9699 (ctx->options & E2F_OPT_NO))
9702 message = ptr->e2p_description;
9703 if ((ctx->options & E2F_OPT_PREEN) &&
9704 !(ptr->flags & PR_PREEN_NOHDR)) {
9705 printf("%s: ", ctx->device_name ?
9706 ctx->device_name : ctx->filesystem_name);
9709 print_e2fsck_message(ctx, _(message), pctx, 1);
9711 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9714 if (ptr->flags & PR_FATAL)
9715 bb_error_msg_and_die(0);
9717 if (ptr->prompt == PROMPT_NONE) {
9718 if (ptr->flags & PR_NOCOLLATE)
9723 if (ctx->options & E2F_OPT_PREEN) {
9725 if (!(ptr->flags & PR_PREEN_NOMSG))
9727 } else if ((ptr->flags & PR_LATCH_MASK) &&
9728 (ldesc->flags & (PRL_YES | PRL_NO))) {
9731 if (ldesc->flags & PRL_YES)
9736 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9737 if (!answer && !(ptr->flags & PR_NO_OK))
9738 ext2fs_unmark_valid(fs);
9741 printf("%s.\n", answer ?
9742 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9745 if ((ptr->prompt == PROMPT_ABORT) && answer)
9746 bb_error_msg_and_die(0);
9748 if (ptr->flags & PR_AFTER_CODE)
9749 answer = fix_problem(ctx, ptr->second_code, pctx);
9755 * linux/fs/recovery.c
9757 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9761 * Maintain information about the progress of the recovery job, so that
9762 * the different passes can carry information between them.
9764 struct recovery_info
9766 tid_t start_transaction;
9767 tid_t end_transaction;
9774 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9775 static int do_one_pass(journal_t *journal,
9776 struct recovery_info *info, enum passtype pass);
9777 static int scan_revoke_records(journal_t *, struct buffer_head *,
9778 tid_t, struct recovery_info *);
9781 * Read a block from the journal
9784 static int jread(struct buffer_head **bhp, journal_t *journal,
9785 unsigned int offset)
9788 unsigned long blocknr;
9789 struct buffer_head *bh;
9793 err = journal_bmap(journal, offset, &blocknr);
9796 printf("JBD: bad block at offset %u\n", offset);
9800 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9804 if (!buffer_uptodate(bh)) {
9805 /* If this is a brand new buffer, start readahead.
9806 Otherwise, we assume we are already reading it. */
9807 if (!buffer_req(bh))
9808 do_readahead(journal, offset);
9812 if (!buffer_uptodate(bh)) {
9813 printf("JBD: Failed to read block at offset %u\n", offset);
9824 * Count the number of in-use tags in a journal descriptor block.
9827 static int count_tags(struct buffer_head *bh, int size)
9830 journal_block_tag_t * tag;
9833 tagp = &bh->b_data[sizeof(journal_header_t)];
9835 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9836 tag = (journal_block_tag_t *) tagp;
9839 tagp += sizeof(journal_block_tag_t);
9840 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9843 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9851 /* Make sure we wrap around the log correctly! */
9852 #define wrap(journal, var) \
9854 if (var >= (journal)->j_last) \
9855 var -= ((journal)->j_last - (journal)->j_first); \
9859 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9860 * @journal: the journal to recover
9862 * The primary function for recovering the log contents when mounting a
9865 * Recovery is done in three passes. In the first pass, we look for the
9866 * end of the log. In the second, we assemble the list of revoke
9867 * blocks. In the third and final pass, we replay any un-revoked blocks
9870 int journal_recover(journal_t *journal)
9873 journal_superblock_t * sb;
9875 struct recovery_info info;
9877 memset(&info, 0, sizeof(info));
9878 sb = journal->j_superblock;
9881 * The journal superblock's s_start field (the current log head)
9882 * is always zero if, and only if, the journal was cleanly
9887 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9891 err = do_one_pass(journal, &info, PASS_SCAN);
9893 err = do_one_pass(journal, &info, PASS_REVOKE);
9895 err = do_one_pass(journal, &info, PASS_REPLAY);
9897 /* Restart the log at the next transaction ID, thus invalidating
9898 * any existing commit records in the log. */
9899 journal->j_transaction_sequence = ++info.end_transaction;
9901 journal_clear_revoke(journal);
9902 sync_blockdev(journal->j_fs_dev);
9906 static int do_one_pass(journal_t *journal,
9907 struct recovery_info *info, enum passtype pass)
9909 unsigned int first_commit_ID, next_commit_ID;
9910 unsigned long next_log_block;
9911 int err, success = 0;
9912 journal_superblock_t * sb;
9913 journal_header_t * tmp;
9914 struct buffer_head * bh;
9915 unsigned int sequence;
9918 /* Precompute the maximum metadata descriptors in a descriptor block */
9919 int MAX_BLOCKS_PER_DESC;
9920 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9921 / sizeof(journal_block_tag_t));
9924 * First thing is to establish what we expect to find in the log
9925 * (in terms of transaction IDs), and where (in terms of log
9926 * block offsets): query the superblock.
9929 sb = journal->j_superblock;
9930 next_commit_ID = ntohl(sb->s_sequence);
9931 next_log_block = ntohl(sb->s_start);
9933 first_commit_ID = next_commit_ID;
9934 if (pass == PASS_SCAN)
9935 info->start_transaction = first_commit_ID;
9938 * Now we walk through the log, transaction by transaction,
9939 * making sure that each transaction has a commit block in the
9940 * expected place. Each complete transaction gets replayed back
9941 * into the main filesystem.
9947 journal_block_tag_t * tag;
9948 struct buffer_head * obh;
9949 struct buffer_head * nbh;
9951 /* If we already know where to stop the log traversal,
9952 * check right now that we haven't gone past the end of
9955 if (pass != PASS_SCAN)
9956 if (tid_geq(next_commit_ID, info->end_transaction))
9959 /* Skip over each chunk of the transaction looking
9960 * either the next descriptor block or the final commit
9963 err = jread(&bh, journal, next_log_block);
9968 wrap(journal, next_log_block);
9970 /* What kind of buffer is it?
9972 * If it is a descriptor block, check that it has the
9973 * expected sequence number. Otherwise, we're all done
9976 tmp = (journal_header_t *)bh->b_data;
9978 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
9983 blocktype = ntohl(tmp->h_blocktype);
9984 sequence = ntohl(tmp->h_sequence);
9986 if (sequence != next_commit_ID) {
9991 /* OK, we have a valid descriptor block which matches
9992 * all of the sequence number checks. What are we going
9993 * to do with it? That depends on the pass... */
9995 switch (blocktype) {
9996 case JFS_DESCRIPTOR_BLOCK:
9997 /* If it is a valid descriptor block, replay it
9998 * in pass REPLAY; otherwise, just skip over the
9999 * blocks it describes. */
10000 if (pass != PASS_REPLAY) {
10002 count_tags(bh, journal->j_blocksize);
10003 wrap(journal, next_log_block);
10008 /* A descriptor block: we can now write all of
10009 * the data blocks. Yay, useful work is finally
10010 * getting done here! */
10012 tagp = &bh->b_data[sizeof(journal_header_t)];
10013 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10014 <= journal->j_blocksize) {
10015 unsigned long io_block;
10017 tag = (journal_block_tag_t *) tagp;
10018 flags = ntohl(tag->t_flags);
10020 io_block = next_log_block++;
10021 wrap(journal, next_log_block);
10022 err = jread(&obh, journal, io_block);
10024 /* Recover what we can, but
10025 * report failure at the end. */
10027 printf("JBD: IO error %d recovering "
10028 "block %ld in log\n",
10031 unsigned long blocknr;
10033 blocknr = ntohl(tag->t_blocknr);
10035 /* If the block has been
10036 * revoked, then we're all done
10038 if (journal_test_revoke
10042 ++info->nr_revoke_hits;
10046 /* Find a buffer for the new
10047 * data being restored */
10048 nbh = getblk(journal->j_fs_dev,
10050 journal->j_blocksize);
10052 printf("JBD: Out of memory "
10053 "during recovery.\n");
10061 memcpy(nbh->b_data, obh->b_data,
10062 journal->j_blocksize);
10063 if (flags & JFS_FLAG_ESCAPE) {
10064 *((unsigned int *)bh->b_data) =
10065 htonl(JFS_MAGIC_NUMBER);
10068 mark_buffer_uptodate(nbh, 1);
10069 mark_buffer_dirty(nbh);
10070 ++info->nr_replays;
10071 /* ll_rw_block(WRITE, 1, &nbh); */
10072 unlock_buffer(nbh);
10078 tagp += sizeof(journal_block_tag_t);
10079 if (!(flags & JFS_FLAG_SAME_UUID))
10082 if (flags & JFS_FLAG_LAST_TAG)
10089 case JFS_COMMIT_BLOCK:
10090 /* Found an expected commit block: not much to
10091 * do other than move on to the next sequence
10097 case JFS_REVOKE_BLOCK:
10098 /* If we aren't in the REVOKE pass, then we can
10099 * just skip over this block. */
10100 if (pass != PASS_REVOKE) {
10105 err = scan_revoke_records(journal, bh,
10106 next_commit_ID, info);
10119 * We broke out of the log scan loop: either we came to the
10120 * known end of the log or we found an unexpected block in the
10121 * log. If the latter happened, then we know that the "current"
10122 * transaction marks the end of the valid log.
10125 if (pass == PASS_SCAN)
10126 info->end_transaction = next_commit_ID;
10128 /* It's really bad news if different passes end up at
10129 * different places (but possible due to IO errors). */
10130 if (info->end_transaction != next_commit_ID) {
10131 printf("JBD: recovery pass %d ended at "
10132 "transaction %u, expected %u\n",
10133 pass, next_commit_ID, info->end_transaction);
10146 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10148 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10149 tid_t sequence, struct recovery_info *info)
10151 journal_revoke_header_t *header;
10154 header = (journal_revoke_header_t *) bh->b_data;
10155 offset = sizeof(journal_revoke_header_t);
10156 max = ntohl(header->r_count);
10158 while (offset < max) {
10159 unsigned long blocknr;
10162 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10164 err = journal_set_revoke(journal, blocknr, sequence);
10167 ++info->nr_revokes;
10174 * rehash.c --- rebuild hash tree directories
10176 * This algorithm is designed for simplicity of implementation and to
10177 * pack the directory as much as possible. It however requires twice
10178 * as much memory as the size of the directory. The maximum size
10179 * directory supported using a 4k blocksize is roughly a gigabyte, and
10180 * so there may very well be problems with machines that don't have
10181 * virtual memory, and obscenely large directories.
10183 * An alternate algorithm which is much more disk intensive could be
10184 * written, and probably will need to be written in the future. The
10185 * design goals of such an algorithm are: (a) use (roughly) constant
10186 * amounts of memory, no matter how large the directory, (b) the
10187 * directory must be safe at all times, even if e2fsck is interrupted
10188 * in the middle, (c) we must use minimal amounts of extra disk
10189 * blocks. This pretty much requires an incremental approach, where
10190 * we are reading from one part of the directory, and inserting into
10191 * the front half. So the algorithm will have to keep track of a
10192 * moving block boundary between the new tree and the old tree, and
10193 * files will need to be moved from the old directory and inserted
10194 * into the new tree. If the new directory requires space which isn't
10195 * yet available, blocks from the beginning part of the old directory
10196 * may need to be moved to the end of the directory to make room for
10199 * --------------------------------------------------------
10200 * | new tree | | old tree |
10201 * --------------------------------------------------------
10203 * tail new head old
10205 * This is going to be a pain in the tuckus to implement, and will
10206 * require a lot more disk accesses. So I'm going to skip it for now;
10207 * it's only really going to be an issue for really, really big
10208 * filesystems (when we reach the level of tens of millions of files
10209 * in a single directory). It will probably be easier to simply
10210 * require that e2fsck use VM first.
10213 struct fill_dir_struct {
10215 struct ext2_inode *inode;
10218 struct hash_entry *harray;
10219 int max_array, num_array;
10225 struct hash_entry {
10226 ext2_dirhash_t hash;
10227 ext2_dirhash_t minor_hash;
10228 struct ext2_dir_entry *dir;
10235 ext2_dirhash_t *hashes;
10238 static int fill_dir_block(ext2_filsys fs,
10240 e2_blkcnt_t blockcnt,
10241 blk_t ref_block FSCK_ATTR((unused)),
10242 int ref_offset FSCK_ATTR((unused)),
10245 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10246 struct hash_entry *new_array, *ent;
10247 struct ext2_dir_entry *dirent;
10249 unsigned int offset, dir_offset;
10254 offset = blockcnt * fs->blocksize;
10255 if (offset + fs->blocksize > fd->inode->i_size) {
10256 fd->err = EXT2_ET_DIR_CORRUPTED;
10257 return BLOCK_ABORT;
10259 dir = (fd->buf+offset);
10260 if (HOLE_BLKADDR(*block_nr)) {
10261 memset(dir, 0, fs->blocksize);
10262 dirent = (struct ext2_dir_entry *) dir;
10263 dirent->rec_len = fs->blocksize;
10265 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10267 return BLOCK_ABORT;
10269 /* While the directory block is "hot", index it. */
10271 while (dir_offset < fs->blocksize) {
10272 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10273 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10274 (dirent->rec_len < 8) ||
10275 ((dirent->rec_len % 4) != 0) ||
10276 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10277 fd->err = EXT2_ET_DIR_CORRUPTED;
10278 return BLOCK_ABORT;
10280 dir_offset += dirent->rec_len;
10281 if (dirent->inode == 0)
10283 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10284 (dirent->name[0] == '.'))
10286 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10287 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10288 fd->parent = dirent->inode;
10291 if (fd->num_array >= fd->max_array) {
10292 new_array = xrealloc(fd->harray,
10293 sizeof(struct hash_entry) * (fd->max_array+500));
10294 fd->harray = new_array;
10295 fd->max_array += 500;
10297 ent = fd->harray + fd->num_array++;
10299 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10301 ent->hash = ent->minor_hash = 0;
10303 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10305 dirent->name_len & 0xFF,
10306 fs->super->s_hash_seed,
10307 &ent->hash, &ent->minor_hash);
10309 return BLOCK_ABORT;
10316 /* Used for sorting the hash entry */
10317 static int name_cmp(const void *a, const void *b)
10319 const struct hash_entry *he_a = (const struct hash_entry *) a;
10320 const struct hash_entry *he_b = (const struct hash_entry *) b;
10324 min_len = he_a->dir->name_len;
10325 if (min_len > he_b->dir->name_len)
10326 min_len = he_b->dir->name_len;
10328 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10330 if (he_a->dir->name_len > he_b->dir->name_len)
10332 else if (he_a->dir->name_len < he_b->dir->name_len)
10335 ret = he_b->dir->inode - he_a->dir->inode;
10340 /* Used for sorting the hash entry */
10341 static int hash_cmp(const void *a, const void *b)
10343 const struct hash_entry *he_a = (const struct hash_entry *) a;
10344 const struct hash_entry *he_b = (const struct hash_entry *) b;
10347 if (he_a->hash > he_b->hash)
10349 else if (he_a->hash < he_b->hash)
10352 if (he_a->minor_hash > he_b->minor_hash)
10354 else if (he_a->minor_hash < he_b->minor_hash)
10357 ret = name_cmp(a, b);
10362 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10368 new_mem = xrealloc(outdir->buf, blocks * fs->blocksize);
10369 outdir->buf = new_mem;
10370 new_mem = xrealloc(outdir->hashes,
10371 blocks * sizeof(ext2_dirhash_t));
10372 outdir->hashes = new_mem;
10374 outdir->buf = xmalloc(blocks * fs->blocksize);
10375 outdir->hashes = xmalloc(blocks * sizeof(ext2_dirhash_t));
10378 outdir->max = blocks;
10382 static void free_out_dir(struct out_dir *outdir)
10385 free(outdir->hashes);
10390 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10395 if (outdir->num >= outdir->max) {
10396 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10400 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10401 memset(*ret, 0, fs->blocksize);
10406 * This function is used to make a unique filename. We do this by
10407 * appending ~0, and then incrementing the number. However, we cannot
10408 * expand the length of the filename beyond the padding available in
10409 * the directory entry.
10411 static void mutate_name(char *str, __u16 *len)
10414 __u16 l = *len & 0xFF, h = *len & 0xff00;
10417 * First check to see if it looks the name has been mutated
10420 for (i = l-1; i > 0; i--) {
10421 if (!isdigit(str[i]))
10424 if ((i == l-1) || (str[i] != '~')) {
10425 if (((l-1) & 3) < 2)
10434 for (i = l-1; i >= 0; i--) {
10435 if (isdigit(str[i])) {
10447 else if (str[0] == 'Z') {
10452 } else if (i > 0) {
10465 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10467 struct fill_dir_struct *fd)
10469 struct problem_context pctx;
10470 struct hash_entry *ent, *prev;
10473 char new_name[256];
10476 clear_problem_context(&pctx);
10479 for (i=1; i < fd->num_array; i++) {
10480 ent = fd->harray + i;
10482 if (!ent->dir->inode ||
10483 ((ent->dir->name_len & 0xFF) !=
10484 (prev->dir->name_len & 0xFF)) ||
10485 (strncmp(ent->dir->name, prev->dir->name,
10486 ent->dir->name_len & 0xFF)))
10488 pctx.dirent = ent->dir;
10489 if ((ent->dir->inode == prev->dir->inode) &&
10490 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10491 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10492 ent->dir->inode = 0;
10496 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10497 new_len = ent->dir->name_len;
10498 mutate_name(new_name, &new_len);
10499 for (j=0; j < fd->num_array; j++) {
10501 ((ent->dir->name_len & 0xFF) !=
10502 (fd->harray[j].dir->name_len & 0xFF)) ||
10503 (strncmp(new_name, fd->harray[j].dir->name,
10506 mutate_name(new_name, &new_len);
10510 new_name[new_len & 0xFF] = 0;
10511 pctx.str = new_name;
10512 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10513 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10514 ent->dir->name_len = new_len;
10515 ext2fs_dirhash(fs->super->s_def_hash_version,
10517 ent->dir->name_len & 0xFF,
10518 fs->super->s_hash_seed,
10519 &ent->hash, &ent->minor_hash);
10527 static errcode_t copy_dir_entries(ext2_filsys fs,
10528 struct fill_dir_struct *fd,
10529 struct out_dir *outdir)
10533 struct hash_entry *ent;
10534 struct ext2_dir_entry *dirent;
10535 int i, rec_len, left;
10536 ext2_dirhash_t prev_hash;
10540 retval = alloc_size_dir(fs, outdir,
10541 (fd->dir_size / fs->blocksize) + 2);
10544 outdir->num = fd->compress ? 0 : 1;
10546 outdir->hashes[0] = 0;
10548 if ((retval = get_next_block(fs, outdir, &block_start)))
10550 dirent = (struct ext2_dir_entry *) block_start;
10551 left = fs->blocksize;
10552 for (i=0; i < fd->num_array; i++) {
10553 ent = fd->harray + i;
10554 if (ent->dir->inode == 0)
10556 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10557 if (rec_len > left) {
10559 dirent->rec_len += left;
10560 if ((retval = get_next_block(fs, outdir,
10565 left = fs->blocksize - offset;
10566 dirent = (struct ext2_dir_entry *) (block_start + offset);
10568 if (ent->hash == prev_hash)
10569 outdir->hashes[outdir->num-1] = ent->hash | 1;
10571 outdir->hashes[outdir->num-1] = ent->hash;
10573 dirent->inode = ent->dir->inode;
10574 dirent->name_len = ent->dir->name_len;
10575 dirent->rec_len = rec_len;
10576 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10580 dirent->rec_len += left;
10584 prev_hash = ent->hash;
10587 dirent->rec_len += left;
10593 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10594 ext2_ino_t ino, ext2_ino_t parent)
10596 struct ext2_dir_entry *dir;
10597 struct ext2_dx_root_info *root;
10598 struct ext2_dx_countlimit *limits;
10601 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10602 filetype = EXT2_FT_DIR << 8;
10604 memset(buf, 0, fs->blocksize);
10605 dir = (struct ext2_dir_entry *) buf;
10607 dir->name[0] = '.';
10608 dir->name_len = 1 | filetype;
10610 dir = (struct ext2_dir_entry *) (buf + 12);
10611 dir->inode = parent;
10612 dir->name[0] = '.';
10613 dir->name[1] = '.';
10614 dir->name_len = 2 | filetype;
10615 dir->rec_len = fs->blocksize - 12;
10617 root = (struct ext2_dx_root_info *) (buf+24);
10618 root->reserved_zero = 0;
10619 root->hash_version = fs->super->s_def_hash_version;
10620 root->info_length = 8;
10621 root->indirect_levels = 0;
10622 root->unused_flags = 0;
10624 limits = (struct ext2_dx_countlimit *) (buf+32);
10625 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10632 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10634 struct ext2_dir_entry *dir;
10635 struct ext2_dx_countlimit *limits;
10637 memset(buf, 0, fs->blocksize);
10638 dir = (struct ext2_dir_entry *) buf;
10640 dir->rec_len = fs->blocksize;
10642 limits = (struct ext2_dx_countlimit *) (buf+8);
10643 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10646 return (struct ext2_dx_entry *) limits;
10650 * This function takes the leaf nodes which have been written in
10651 * outdir, and populates the root node and any necessary interior nodes.
10653 static errcode_t calculate_tree(ext2_filsys fs,
10654 struct out_dir *outdir,
10658 struct ext2_dx_root_info *root_info;
10659 struct ext2_dx_entry *root, *dx_ent = NULL;
10660 struct ext2_dx_countlimit *root_limit, *limit;
10662 char * block_start;
10663 int i, c1, c2, nblks;
10664 int limit_offset, root_offset;
10666 root_info = set_root_node(fs, outdir->buf, ino, parent);
10667 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10668 root_info->info_length;
10669 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10670 c1 = root_limit->limit;
10671 nblks = outdir->num;
10673 /* Write out the pointer blocks */
10674 if (nblks-1 <= c1) {
10675 /* Just write out the root block, and we're done */
10676 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10677 for (i=1; i < nblks; i++) {
10678 root->block = ext2fs_cpu_to_le32(i);
10681 ext2fs_cpu_to_le32(outdir->hashes[i]);
10688 root_info->indirect_levels = 1;
10689 for (i=1; i < nblks; i++) {
10694 limit->limit = limit->count =
10695 ext2fs_cpu_to_le16(limit->limit);
10696 root = (struct ext2_dx_entry *)
10697 (outdir->buf + root_offset);
10698 root->block = ext2fs_cpu_to_le32(outdir->num);
10701 ext2fs_cpu_to_le32(outdir->hashes[i]);
10702 if ((retval = get_next_block(fs, outdir,
10705 dx_ent = set_int_node(fs, block_start);
10706 limit = (struct ext2_dx_countlimit *) dx_ent;
10708 root_offset += sizeof(struct ext2_dx_entry);
10711 dx_ent->block = ext2fs_cpu_to_le32(i);
10712 if (c2 != limit->limit)
10714 ext2fs_cpu_to_le32(outdir->hashes[i]);
10718 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10719 limit->limit = ext2fs_cpu_to_le16(limit->limit);
10721 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10722 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10723 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10728 struct write_dir_struct {
10729 struct out_dir *outdir;
10736 * Helper function which writes out a directory block.
10738 static int write_dir_block(ext2_filsys fs,
10740 e2_blkcnt_t blockcnt,
10741 blk_t ref_block FSCK_ATTR((unused)),
10742 int ref_offset FSCK_ATTR((unused)),
10745 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10749 if (*block_nr == 0)
10751 if (blockcnt >= wd->outdir->num) {
10752 e2fsck_read_bitmaps(wd->ctx);
10754 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10755 ext2fs_block_alloc_stats(fs, blk, -1);
10758 return BLOCK_CHANGED;
10763 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10764 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10766 return BLOCK_ABORT;
10770 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10771 struct out_dir *outdir,
10772 ext2_ino_t ino, int compress)
10774 struct write_dir_struct wd;
10776 struct ext2_inode inode;
10778 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10782 wd.outdir = outdir;
10787 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10788 write_dir_block, &wd);
10794 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10796 inode.i_flags &= ~EXT2_INDEX_FL;
10798 inode.i_flags |= EXT2_INDEX_FL;
10799 inode.i_size = outdir->num * fs->blocksize;
10800 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10801 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10806 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10808 ext2_filsys fs = ctx->fs;
10810 struct ext2_inode inode;
10811 char *dir_buf = NULL;
10812 struct fill_dir_struct fd;
10813 struct out_dir outdir;
10815 outdir.max = outdir.num = 0;
10818 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10822 dir_buf = xmalloc(inode.i_size);
10824 fd.max_array = inode.i_size / 32;
10826 fd.harray = xmalloc(fd.max_array * sizeof(struct hash_entry));
10834 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10835 (inode.i_size / fs->blocksize) < 2)
10839 /* Read in the entire directory into memory */
10840 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10841 fill_dir_block, &fd);
10847 /* Sort the list */
10850 qsort(fd.harray+2, fd.num_array-2,
10851 sizeof(struct hash_entry), name_cmp);
10853 qsort(fd.harray, fd.num_array,
10854 sizeof(struct hash_entry), hash_cmp);
10857 * Look for duplicates
10859 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10862 if (ctx->options & E2F_OPT_NO) {
10868 * Copy the directory entries. In a htree directory these
10869 * will become the leaf nodes.
10871 retval = copy_dir_entries(fs, &fd, &outdir);
10875 free(dir_buf); dir_buf = 0;
10877 if (!fd.compress) {
10878 /* Calculate the interior nodes */
10879 retval = calculate_tree(fs, &outdir, ino, fd.parent);
10884 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10890 free_out_dir(&outdir);
10894 void e2fsck_rehash_directories(e2fsck_t ctx)
10896 struct problem_context pctx;
10897 struct dir_info *dir;
10898 ext2_u32_iterate iter;
10901 int i, cur, max, all_dirs, dir_index, first = 1;
10903 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10905 if (!ctx->dirs_to_hash && !all_dirs)
10908 e2fsck_get_lost_and_found(ctx, 0);
10910 clear_problem_context(&pctx);
10912 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10916 max = e2fsck_get_num_dirinfo(ctx);
10918 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10921 pctx.errcode = retval;
10922 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10925 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10929 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10933 if (!ext2fs_u32_list_iterate(iter, &ino))
10936 if (ino == ctx->lost_and_found)
10940 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
10943 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
10944 if (pctx.errcode) {
10945 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10946 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
10948 if (ctx->progress && !ctx->progress_fd)
10949 e2fsck_simple_progress(ctx, "Rebuilding directory",
10950 100.0 * (float) (++cur) / (float) max, ino);
10952 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10954 ext2fs_u32_list_iterate_end(iter);
10956 ext2fs_u32_list_free(ctx->dirs_to_hash);
10957 ctx->dirs_to_hash = 0;
10961 * linux/fs/revoke.c
10963 * Journal revoke routines for the generic filesystem journaling code;
10964 * part of the ext2fs journaling system.
10966 * Revoke is the mechanism used to prevent old log records for deleted
10967 * metadata from being replayed on top of newer data using the same
10968 * blocks. The revoke mechanism is used in two separate places:
10970 * + Commit: during commit we write the entire list of the current
10971 * transaction's revoked blocks to the journal
10973 * + Recovery: during recovery we record the transaction ID of all
10974 * revoked blocks. If there are multiple revoke records in the log
10975 * for a single block, only the last one counts, and if there is a log
10976 * entry for a block beyond the last revoke, then that log entry still
10979 * We can get interactions between revokes and new log data within a
10980 * single transaction:
10982 * Block is revoked and then journaled:
10983 * The desired end result is the journaling of the new block, so we
10984 * cancel the revoke before the transaction commits.
10986 * Block is journaled and then revoked:
10987 * The revoke must take precedence over the write of the block, so we
10988 * need either to cancel the journal entry or to write the revoke
10989 * later in the log than the log block. In this case, we choose the
10990 * latter: journaling a block cancels any revoke record for that block
10991 * in the current transaction, so any revoke for that block in the
10992 * transaction must have happened after the block was journaled and so
10993 * the revoke must take precedence.
10995 * Block is revoked and then written as data:
10996 * The data write is allowed to succeed, but the revoke is _not_
10997 * cancelled. We still need to prevent old log records from
10998 * overwriting the new data. We don't even need to clear the revoke
11001 * Revoke information on buffers is a tri-state value:
11003 * RevokeValid clear: no cached revoke status, need to look it up
11004 * RevokeValid set, Revoked clear:
11005 * buffer has not been revoked, and cancel_revoke
11007 * RevokeValid set, Revoked set:
11008 * buffer has been revoked.
11011 static kmem_cache_t *revoke_record_cache;
11012 static kmem_cache_t *revoke_table_cache;
11014 /* Each revoke record represents one single revoked block. During
11015 journal replay, this involves recording the transaction ID of the
11016 last transaction to revoke this block. */
11018 struct jbd_revoke_record_s
11020 struct list_head hash;
11021 tid_t sequence; /* Used for recovery only */
11022 unsigned long blocknr;
11026 /* The revoke table is just a simple hash table of revoke records. */
11027 struct jbd_revoke_table_s
11029 /* It is conceivable that we might want a larger hash table
11030 * for recovery. Must be a power of two. */
11033 struct list_head *hash_table;
11037 /* Utility functions to maintain the revoke table */
11039 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11040 static int hash(journal_t *journal, unsigned long block)
11042 struct jbd_revoke_table_s *table = journal->j_revoke;
11043 int hash_shift = table->hash_shift;
11045 return ((block << (hash_shift - 6)) ^
11047 (block << (hash_shift - 12))) & (table->hash_size - 1);
11050 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11053 struct list_head *hash_list;
11054 struct jbd_revoke_record_s *record;
11056 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11060 record->sequence = seq;
11061 record->blocknr = blocknr;
11062 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11063 list_add(&record->hash, hash_list);
11070 /* Find a revoke record in the journal's hash table. */
11072 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11073 unsigned long blocknr)
11075 struct list_head *hash_list;
11076 struct jbd_revoke_record_s *record;
11078 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11080 record = (struct jbd_revoke_record_s *) hash_list->next;
11081 while (&(record->hash) != hash_list) {
11082 if (record->blocknr == blocknr)
11084 record = (struct jbd_revoke_record_s *) record->hash.next;
11089 int journal_init_revoke_caches(void)
11091 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11092 if (revoke_record_cache == 0)
11095 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11096 if (revoke_table_cache == 0) {
11097 do_cache_destroy(revoke_record_cache);
11098 revoke_record_cache = NULL;
11104 void journal_destroy_revoke_caches(void)
11106 do_cache_destroy(revoke_record_cache);
11107 revoke_record_cache = 0;
11108 do_cache_destroy(revoke_table_cache);
11109 revoke_table_cache = 0;
11112 /* Initialise the revoke table for a given journal to a given size. */
11114 int journal_init_revoke(journal_t *journal, int hash_size)
11118 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11119 if (!journal->j_revoke)
11122 /* Check that the hash_size is a power of two */
11123 journal->j_revoke->hash_size = hash_size;
11127 while ((tmp >>= 1UL) != 0UL)
11129 journal->j_revoke->hash_shift = shift;
11131 journal->j_revoke->hash_table = xmalloc(hash_size * sizeof(struct list_head));
11133 for (tmp = 0; tmp < hash_size; tmp++)
11134 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11139 /* Destoy a journal's revoke table. The table must already be empty! */
11141 void journal_destroy_revoke(journal_t *journal)
11143 struct jbd_revoke_table_s *table;
11144 struct list_head *hash_list;
11147 table = journal->j_revoke;
11151 for (i=0; i<table->hash_size; i++) {
11152 hash_list = &table->hash_table[i];
11155 free(table->hash_table);
11157 journal->j_revoke = NULL;
11161 * Revoke support for recovery.
11163 * Recovery needs to be able to:
11165 * record all revoke records, including the tid of the latest instance
11166 * of each revoke in the journal
11168 * check whether a given block in a given transaction should be replayed
11169 * (ie. has not been revoked by a revoke record in that or a subsequent
11172 * empty the revoke table after recovery.
11176 * First, setting revoke records. We create a new revoke record for
11177 * every block ever revoked in the log as we scan it for recovery, and
11178 * we update the existing records if we find multiple revokes for a
11182 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11185 struct jbd_revoke_record_s *record;
11187 record = find_revoke_record(journal, blocknr);
11189 /* If we have multiple occurences, only record the
11190 * latest sequence number in the hashed record */
11191 if (tid_gt(sequence, record->sequence))
11192 record->sequence = sequence;
11195 return insert_revoke_hash(journal, blocknr, sequence);
11199 * Test revoke records. For a given block referenced in the log, has
11200 * that block been revoked? A revoke record with a given transaction
11201 * sequence number revokes all blocks in that transaction and earlier
11202 * ones, but later transactions still need replayed.
11205 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11208 struct jbd_revoke_record_s *record;
11210 record = find_revoke_record(journal, blocknr);
11213 if (tid_gt(sequence, record->sequence))
11219 * Finally, once recovery is over, we need to clear the revoke table so
11220 * that it can be reused by the running filesystem.
11223 void journal_clear_revoke(journal_t *journal)
11226 struct list_head *hash_list;
11227 struct jbd_revoke_record_s *record;
11228 struct jbd_revoke_table_s *revoke_var;
11230 revoke_var = journal->j_revoke;
11232 for (i = 0; i < revoke_var->hash_size; i++) {
11233 hash_list = &revoke_var->hash_table[i];
11234 while (!list_empty(hash_list)) {
11235 record = (struct jbd_revoke_record_s*) hash_list->next;
11236 list_del(&record->hash);
11243 * e2fsck.c - superblock checks
11246 #define MIN_CHECK 1
11247 #define MAX_CHECK 2
11249 static void check_super_value(e2fsck_t ctx, const char *descr,
11250 unsigned long value, int flags,
11251 unsigned long min_val, unsigned long max_val)
11253 struct problem_context pctx;
11255 if (((flags & MIN_CHECK) && (value < min_val)) ||
11256 ((flags & MAX_CHECK) && (value > max_val))) {
11257 clear_problem_context(&pctx);
11260 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11261 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11266 * This routine may get stubbed out in special compilations of the
11269 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11270 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11272 return (ext2fs_get_device_size(ctx->filesystem_name,
11273 EXT2_BLOCK_SIZE(ctx->fs->super),
11274 &ctx->num_blocks));
11279 * helper function to release an inode
11281 struct process_block_struct {
11284 struct problem_context *pctx;
11286 int truncate_offset;
11287 e2_blkcnt_t truncate_block;
11288 int truncated_blocks;
11293 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11294 e2_blkcnt_t blockcnt,
11295 blk_t ref_blk FSCK_ATTR((unused)),
11296 int ref_offset FSCK_ATTR((unused)),
11299 struct process_block_struct *pb;
11301 struct problem_context *pctx;
11302 blk_t blk = *block_nr;
11305 pb = (struct process_block_struct *) priv_data;
11310 pctx->blkcount = blockcnt;
11312 if (HOLE_BLKADDR(blk))
11315 if ((blk < fs->super->s_first_data_block) ||
11316 (blk >= fs->super->s_blocks_count)) {
11317 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11320 return BLOCK_ABORT;
11323 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11324 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11329 * If we are deleting an orphan, then we leave the fields alone.
11330 * If we are truncating an orphan, then update the inode fields
11331 * and clean up any partial block data.
11333 if (pb->truncating) {
11335 * We only remove indirect blocks if they are
11336 * completely empty.
11338 if (blockcnt < 0) {
11342 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11347 limit = fs->blocksize >> 2;
11348 for (i = 0, bp = (blk_t *) pb->buf;
11349 i < limit; i++, bp++)
11354 * We don't remove direct blocks until we've reached
11355 * the truncation block.
11357 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11360 * If part of the last block needs truncating, we do
11363 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11364 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11368 memset(pb->buf + pb->truncate_offset, 0,
11369 fs->blocksize - pb->truncate_offset);
11370 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11375 pb->truncated_blocks++;
11377 retval |= BLOCK_CHANGED;
11380 ext2fs_block_alloc_stats(fs, blk, -1);
11385 * This function releases an inode. Returns 1 if an inconsistency was
11386 * found. If the inode has a link count, then it is being truncated and
11389 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11390 struct ext2_inode *inode, char *block_buf,
11391 struct problem_context *pctx)
11393 struct process_block_struct pb;
11394 ext2_filsys fs = ctx->fs;
11398 if (!ext2fs_inode_has_valid_blocks(inode))
11401 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11406 if (inode->i_links_count) {
11408 pb.truncate_block = (e2_blkcnt_t)
11409 ((((long long)inode->i_size_high << 32) +
11410 inode->i_size + fs->blocksize - 1) /
11412 pb.truncate_offset = inode->i_size % fs->blocksize;
11415 pb.truncate_block = 0;
11416 pb.truncate_offset = 0;
11418 pb.truncated_blocks = 0;
11419 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11420 block_buf, release_inode_block, &pb);
11422 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11429 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11430 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11432 if (pb.truncated_blocks)
11433 inode->i_blocks -= pb.truncated_blocks *
11434 (fs->blocksize / 512);
11436 if (inode->i_file_acl) {
11437 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11438 block_buf, -1, &count);
11439 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11444 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11449 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11450 inode->i_file_acl = 0;
11456 * This function releases all of the orphan inodes. It returns 1 if
11457 * it hit some error, and 0 on success.
11459 static int release_orphan_inodes(e2fsck_t ctx)
11461 ext2_filsys fs = ctx->fs;
11462 ext2_ino_t ino, next_ino;
11463 struct ext2_inode inode;
11464 struct problem_context pctx;
11467 if ((ino = fs->super->s_last_orphan) == 0)
11471 * Win or lose, we won't be using the head of the orphan inode
11474 fs->super->s_last_orphan = 0;
11475 ext2fs_mark_super_dirty(fs);
11478 * If the filesystem contains errors, don't run the orphan
11479 * list, since the orphan list can't be trusted; and we're
11480 * going to be running a full e2fsck run anyway...
11482 if (fs->super->s_state & EXT2_ERROR_FS)
11485 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11486 (ino > fs->super->s_inodes_count)) {
11487 clear_problem_context(&pctx);
11489 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11493 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11494 "block iterate buffer");
11495 e2fsck_read_bitmaps(ctx);
11498 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11499 clear_problem_context(&pctx);
11501 pctx.inode = &inode;
11502 pctx.str = inode.i_links_count ? _("Truncating") :
11505 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11507 next_ino = inode.i_dtime;
11509 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11510 (next_ino > fs->super->s_inodes_count))) {
11511 pctx.ino = next_ino;
11512 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11516 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11519 if (!inode.i_links_count) {
11520 ext2fs_inode_alloc_stats2(fs, ino, -1,
11521 LINUX_S_ISDIR(inode.i_mode));
11522 inode.i_dtime = time(NULL);
11526 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11529 ext2fs_free_mem(&block_buf);
11532 ext2fs_free_mem(&block_buf);
11537 * Check the resize inode to make sure it is sane. We check both for
11538 * the case where on-line resizing is not enabled (in which case the
11539 * resize inode should be cleared) as well as the case where on-line
11540 * resizing is enabled.
11542 static void check_resize_inode(e2fsck_t ctx)
11544 ext2_filsys fs = ctx->fs;
11545 struct ext2_inode inode;
11546 struct problem_context pctx;
11547 int i, j, gdt_off, ind_off;
11548 blk_t blk, pblk, expect;
11549 __u32 *dind_buf = NULL, *ind_buf;
11552 clear_problem_context(&pctx);
11555 * If the resize inode feature isn't set, then
11556 * s_reserved_gdt_blocks must be zero.
11558 if (!(fs->super->s_feature_compat &
11559 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11560 if (fs->super->s_reserved_gdt_blocks) {
11561 pctx.num = fs->super->s_reserved_gdt_blocks;
11562 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11564 fs->super->s_reserved_gdt_blocks = 0;
11565 ext2fs_mark_super_dirty(fs);
11570 /* Read the resize inode */
11571 pctx.ino = EXT2_RESIZE_INO;
11572 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11574 if (fs->super->s_feature_compat &
11575 EXT2_FEATURE_COMPAT_RESIZE_INODE)
11576 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11581 * If the resize inode feature isn't set, check to make sure
11582 * the resize inode is cleared; then we're done.
11584 if (!(fs->super->s_feature_compat &
11585 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11586 for (i=0; i < EXT2_N_BLOCKS; i++) {
11587 if (inode.i_block[i])
11590 if ((i < EXT2_N_BLOCKS) &&
11591 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11592 memset(&inode, 0, sizeof(inode));
11593 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11600 * The resize inode feature is enabled; check to make sure the
11601 * only block in use is the double indirect block
11603 blk = inode.i_block[EXT2_DIND_BLOCK];
11604 for (i=0; i < EXT2_N_BLOCKS; i++) {
11605 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11608 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11609 !(inode.i_mode & LINUX_S_IFREG) ||
11610 (blk < fs->super->s_first_data_block ||
11611 blk >= fs->super->s_blocks_count)) {
11612 resize_inode_invalid:
11613 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11614 memset(&inode, 0, sizeof(inode));
11615 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11617 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11619 if (!(ctx->options & E2F_OPT_READONLY)) {
11620 fs->super->s_state &= ~EXT2_VALID_FS;
11621 ext2fs_mark_super_dirty(fs);
11625 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11626 "resize dind buffer");
11627 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11629 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11631 goto resize_inode_invalid;
11633 gdt_off = fs->desc_blocks;
11634 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11635 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11636 i++, gdt_off++, pblk++) {
11637 gdt_off %= fs->blocksize/4;
11638 if (dind_buf[gdt_off] != pblk)
11639 goto resize_inode_invalid;
11640 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11642 goto resize_inode_invalid;
11644 for (j = 1; j < fs->group_desc_count; j++) {
11645 if (!ext2fs_bg_has_super(fs, j))
11647 expect = pblk + (j * fs->super->s_blocks_per_group);
11648 if (ind_buf[ind_off] != expect)
11649 goto resize_inode_invalid;
11655 ext2fs_free_mem(&dind_buf);
11658 static void check_super_block(e2fsck_t ctx)
11660 ext2_filsys fs = ctx->fs;
11661 blk_t first_block, last_block;
11662 struct ext2_super_block *sb = fs->super;
11663 struct ext2_group_desc *gd;
11664 blk_t blocks_per_group = fs->super->s_blocks_per_group;
11666 int inodes_per_block;
11671 struct problem_context pctx;
11672 __u32 free_blocks = 0, free_inodes = 0;
11674 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11675 ipg_max = inodes_per_block * (blocks_per_group - 4);
11676 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11677 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11678 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11679 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11680 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11682 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11683 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11684 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11685 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11686 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11687 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11689 clear_problem_context(&pctx);
11692 * Verify the super block constants...
11694 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11696 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11698 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11699 MAX_CHECK, 0, sb->s_blocks_count);
11700 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11701 MIN_CHECK | MAX_CHECK, 0,
11702 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11703 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11704 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11705 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11706 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11708 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11709 MIN_CHECK | MAX_CHECK, 8, bpg_max);
11710 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11711 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11712 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11713 MAX_CHECK, 0, sb->s_blocks_count / 2);
11714 check_super_value(ctx, "reserved_gdt_blocks",
11715 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11717 inode_size = EXT2_INODE_SIZE(sb);
11718 check_super_value(ctx, "inode_size",
11719 inode_size, MIN_CHECK | MAX_CHECK,
11720 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11721 if (inode_size & (inode_size - 1)) {
11722 pctx.num = inode_size;
11723 pctx.str = "inode_size";
11724 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11725 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11729 if (!ctx->num_blocks) {
11730 pctx.errcode = e2fsck_get_device_size(ctx);
11731 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11732 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11733 ctx->flags |= E2F_FLAG_ABORT;
11736 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11737 (ctx->num_blocks < sb->s_blocks_count)) {
11738 pctx.blk = sb->s_blocks_count;
11739 pctx.blk2 = ctx->num_blocks;
11740 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11741 ctx->flags |= E2F_FLAG_ABORT;
11747 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11748 pctx.blk = EXT2_BLOCK_SIZE(sb);
11749 pctx.blk2 = EXT2_FRAG_SIZE(sb);
11750 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11751 ctx->flags |= E2F_FLAG_ABORT;
11755 should_be = sb->s_frags_per_group >>
11756 (sb->s_log_block_size - sb->s_log_frag_size);
11757 if (sb->s_blocks_per_group != should_be) {
11758 pctx.blk = sb->s_blocks_per_group;
11759 pctx.blk2 = should_be;
11760 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11761 ctx->flags |= E2F_FLAG_ABORT;
11765 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11766 if (sb->s_first_data_block != should_be) {
11767 pctx.blk = sb->s_first_data_block;
11768 pctx.blk2 = should_be;
11769 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11770 ctx->flags |= E2F_FLAG_ABORT;
11774 should_be = sb->s_inodes_per_group * fs->group_desc_count;
11775 if (sb->s_inodes_count != should_be) {
11776 pctx.ino = sb->s_inodes_count;
11777 pctx.ino2 = should_be;
11778 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11779 sb->s_inodes_count = should_be;
11780 ext2fs_mark_super_dirty(fs);
11785 * Verify the group descriptors....
11787 first_block = sb->s_first_data_block;
11788 last_block = first_block + blocks_per_group;
11790 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11793 if (i == fs->group_desc_count - 1)
11794 last_block = sb->s_blocks_count;
11795 if ((gd->bg_block_bitmap < first_block) ||
11796 (gd->bg_block_bitmap >= last_block)) {
11797 pctx.blk = gd->bg_block_bitmap;
11798 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11799 gd->bg_block_bitmap = 0;
11801 if (gd->bg_block_bitmap == 0) {
11802 ctx->invalid_block_bitmap_flag[i]++;
11803 ctx->invalid_bitmaps++;
11805 if ((gd->bg_inode_bitmap < first_block) ||
11806 (gd->bg_inode_bitmap >= last_block)) {
11807 pctx.blk = gd->bg_inode_bitmap;
11808 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11809 gd->bg_inode_bitmap = 0;
11811 if (gd->bg_inode_bitmap == 0) {
11812 ctx->invalid_inode_bitmap_flag[i]++;
11813 ctx->invalid_bitmaps++;
11815 if ((gd->bg_inode_table < first_block) ||
11816 ((gd->bg_inode_table +
11817 fs->inode_blocks_per_group - 1) >= last_block)) {
11818 pctx.blk = gd->bg_inode_table;
11819 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11820 gd->bg_inode_table = 0;
11822 if (gd->bg_inode_table == 0) {
11823 ctx->invalid_inode_table_flag[i]++;
11824 ctx->invalid_bitmaps++;
11826 free_blocks += gd->bg_free_blocks_count;
11827 free_inodes += gd->bg_free_inodes_count;
11828 first_block += sb->s_blocks_per_group;
11829 last_block += sb->s_blocks_per_group;
11831 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11832 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11833 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11834 ext2fs_unmark_valid(fs);
11838 * Update the global counts from the block group counts. This
11839 * is needed for an experimental patch which eliminates
11840 * locking the entire filesystem when allocating blocks or
11841 * inodes; if the filesystem is not unmounted cleanly, the
11842 * global counts may not be accurate.
11844 if ((free_blocks != sb->s_free_blocks_count) ||
11845 (free_inodes != sb->s_free_inodes_count)) {
11846 if (ctx->options & E2F_OPT_READONLY)
11847 ext2fs_unmark_valid(fs);
11849 sb->s_free_blocks_count = free_blocks;
11850 sb->s_free_inodes_count = free_inodes;
11851 ext2fs_mark_super_dirty(fs);
11855 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11856 (sb->s_free_inodes_count > sb->s_inodes_count))
11857 ext2fs_unmark_valid(fs);
11861 * If we have invalid bitmaps, set the error state of the
11864 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11865 sb->s_state &= ~EXT2_VALID_FS;
11866 ext2fs_mark_super_dirty(fs);
11869 clear_problem_context(&pctx);
11872 * If the UUID field isn't assigned, assign it.
11874 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11875 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11876 uuid_generate(sb->s_uuid);
11877 ext2fs_mark_super_dirty(fs);
11878 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11882 /* FIXME - HURD support?
11883 * For the Hurd, check to see if the filetype option is set,
11884 * since it doesn't support it.
11886 if (!(ctx->options & E2F_OPT_READONLY) &&
11887 fs->super->s_creator_os == EXT2_OS_HURD &&
11888 (fs->super->s_feature_incompat &
11889 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11890 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11891 fs->super->s_feature_incompat &=
11892 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11893 ext2fs_mark_super_dirty(fs);
11898 * If we have any of the compatibility flags set, we need to have a
11899 * revision 1 filesystem. Most kernels will not check the flags on
11900 * a rev 0 filesystem and we may have corruption issues because of
11901 * the incompatible changes to the filesystem.
11903 if (!(ctx->options & E2F_OPT_READONLY) &&
11904 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11905 (fs->super->s_feature_compat ||
11906 fs->super->s_feature_ro_compat ||
11907 fs->super->s_feature_incompat) &&
11908 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11909 ext2fs_update_dynamic_rev(fs);
11910 ext2fs_mark_super_dirty(fs);
11913 check_resize_inode(ctx);
11916 * Clean up any orphan inodes, if present.
11918 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11919 fs->super->s_state &= ~EXT2_VALID_FS;
11920 ext2fs_mark_super_dirty(fs);
11924 * Move the ext3 journal file, if necessary.
11926 e2fsck_move_ext3_journal(ctx);
11930 * swapfs.c --- byte-swap an ext2 filesystem
11933 #ifdef ENABLE_SWAPFS
11935 struct swap_block_struct {
11940 struct ext2_inode *inode;
11944 * This is a helper function for block_iterate. We mark all of the
11945 * indirect and direct blocks as changed, so that block_iterate will
11948 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
11953 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
11955 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
11956 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
11958 sb->errcode = retval;
11959 return BLOCK_ABORT;
11961 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
11963 sb->errcode = retval;
11964 return BLOCK_ABORT;
11967 if (blockcnt >= 0) {
11968 if (blockcnt < EXT2_NDIR_BLOCKS)
11970 return BLOCK_CHANGED;
11972 if (blockcnt == BLOCK_COUNT_IND) {
11973 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
11975 return BLOCK_CHANGED;
11977 if (blockcnt == BLOCK_COUNT_DIND) {
11978 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
11980 return BLOCK_CHANGED;
11982 if (blockcnt == BLOCK_COUNT_TIND) {
11983 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
11985 return BLOCK_CHANGED;
11987 return BLOCK_CHANGED;
11991 * This function is responsible for byte-swapping all of the indirect,
11992 * block pointers. It is also responsible for byte-swapping directories.
11994 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
11995 struct ext2_inode *inode)
11998 struct swap_block_struct sb;
12002 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12005 if (LINUX_S_ISDIR(inode->i_mode))
12008 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12011 bb_error_msg(_("while calling ext2fs_block_iterate"));
12012 ctx->flags |= E2F_FLAG_ABORT;
12016 bb_error_msg(_("while calling iterator function"));
12017 ctx->flags |= E2F_FLAG_ABORT;
12022 static void swap_inodes(e2fsck_t ctx)
12024 ext2_filsys fs = ctx->fs;
12027 ext2_ino_t ino = 1;
12028 char *buf, *block_buf;
12030 struct ext2_inode * inode;
12032 e2fsck_use_inode_shortcuts(ctx, 1);
12034 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12037 bb_error_msg(_("while allocating inode buffer"));
12038 ctx->flags |= E2F_FLAG_ABORT;
12041 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12042 "block interate buffer");
12043 for (group = 0; group < fs->group_desc_count; group++) {
12044 retval = io_channel_read_blk(fs->io,
12045 fs->group_desc[group].bg_inode_table,
12046 fs->inode_blocks_per_group, buf);
12048 bb_error_msg(_("while reading inode table (group %d)"),
12050 ctx->flags |= E2F_FLAG_ABORT;
12053 inode = (struct ext2_inode *) buf;
12054 for (i=0; i < fs->super->s_inodes_per_group;
12055 i++, ino++, inode++) {
12056 ctx->stashed_ino = ino;
12057 ctx->stashed_inode = inode;
12059 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12060 ext2fs_swap_inode(fs, inode, inode, 0);
12063 * Skip deleted files.
12065 if (inode->i_links_count == 0)
12068 if (LINUX_S_ISDIR(inode->i_mode) ||
12069 ((inode->i_block[EXT2_IND_BLOCK] ||
12070 inode->i_block[EXT2_DIND_BLOCK] ||
12071 inode->i_block[EXT2_TIND_BLOCK]) &&
12072 ext2fs_inode_has_valid_blocks(inode)))
12073 swap_inode_blocks(ctx, ino, block_buf, inode);
12075 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12078 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12079 ext2fs_swap_inode(fs, inode, inode, 1);
12081 retval = io_channel_write_blk(fs->io,
12082 fs->group_desc[group].bg_inode_table,
12083 fs->inode_blocks_per_group, buf);
12085 bb_error_msg(_("while writing inode table (group %d)"),
12087 ctx->flags |= E2F_FLAG_ABORT;
12091 ext2fs_free_mem(&buf);
12092 ext2fs_free_mem(&block_buf);
12093 e2fsck_use_inode_shortcuts(ctx, 0);
12094 ext2fs_flush_icache(fs);
12097 #if defined(__powerpc__) && BB_BIG_ENDIAN
12099 * On the PowerPC, the big-endian variant of the ext2 filesystem
12100 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12101 * of each word. Thus a bitmap with only bit 0 set would be, as
12102 * a string of bytes, 00 00 00 01 00 ...
12103 * To cope with this, we byte-reverse each word of a bitmap if
12104 * we have a big-endian filesystem, that is, if we are *not*
12105 * byte-swapping other word-sized numbers.
12107 #define EXT2_BIG_ENDIAN_BITMAPS
12110 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12111 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12113 __u32 *p = (__u32 *) bmap->bitmap;
12114 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12116 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12117 *p = ext2fs_swab32(*p);
12122 #ifdef ENABLE_SWAPFS
12123 static void swap_filesys(e2fsck_t ctx)
12125 ext2_filsys fs = ctx->fs;
12126 if (!(ctx->options & E2F_OPT_PREEN))
12127 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12131 if (fs->super->s_mnt_count) {
12132 fprintf(stderr, _("%s: the filesystem must be freshly "
12133 "checked using fsck\n"
12134 "and not mounted before trying to "
12135 "byte-swap it.\n"), ctx->device_name);
12136 ctx->flags |= E2F_FLAG_ABORT;
12139 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12140 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12141 EXT2_FLAG_SWAP_BYTES_WRITE);
12142 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12144 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12145 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12148 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12150 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12151 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12152 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12153 EXT2_FLAG_SWAP_BYTES_WRITE);
12155 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12156 e2fsck_read_bitmaps(ctx);
12157 ext2fs_swap_bitmap(fs->inode_map);
12158 ext2fs_swap_bitmap(fs->block_map);
12159 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12161 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12163 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12165 #endif /* ENABLE_SWAPFS */
12170 * util.c --- miscellaneous utilities
12174 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12175 const char *description)
12180 ret = xzalloc(size);
12184 static char *string_copy(const char *str, int len)
12192 ret = xmalloc(len+1);
12193 strncpy(ret, str, len);
12198 #ifndef HAVE_CONIO_H
12199 static int read_a_char(void)
12206 if (e2fsck_global_ctx &&
12207 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12210 r = read(0, &c, 1);
12220 static int ask_yn(const char * string, int def)
12223 const char *defstr;
12224 static const char short_yes[] = "yY";
12225 static const char short_no[] = "nN";
12227 #ifdef HAVE_TERMIOS_H
12228 struct termios termios, tmp;
12230 tcgetattr (0, &termios);
12232 tmp.c_lflag &= ~(ICANON | ECHO);
12233 tmp.c_cc[VMIN] = 1;
12234 tmp.c_cc[VTIME] = 0;
12235 tcsetattr_stdin_TCSANOW(&tmp);
12244 printf("%s%s? ", string, defstr);
12247 if ((c = read_a_char()) == EOF)
12250 #ifdef HAVE_TERMIOS_H
12251 tcsetattr_stdin_TCSANOW(&termios);
12253 if (e2fsck_global_ctx &&
12254 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12256 longjmp(e2fsck_global_ctx->abort_loc, 1);
12258 puts(_("cancelled!\n"));
12261 if (strchr(short_yes, (char) c)) {
12265 else if (strchr(short_no, (char) c)) {
12269 else if ((c == ' ' || c == '\n') && (def != -1))
12276 #ifdef HAVE_TERMIOS_H
12277 tcsetattr_stdin_TCSANOW(&termios);
12282 int ask (e2fsck_t ctx, const char * string, int def)
12284 if (ctx->options & E2F_OPT_NO) {
12285 printf(_("%s? no\n\n"), string);
12288 if (ctx->options & E2F_OPT_YES) {
12289 printf(_("%s? yes\n\n"), string);
12292 if (ctx->options & E2F_OPT_PREEN) {
12293 printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
12296 return ask_yn(string, def);
12299 void e2fsck_read_bitmaps(e2fsck_t ctx)
12301 ext2_filsys fs = ctx->fs;
12304 if (ctx->invalid_bitmaps) {
12305 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12307 bb_error_msg_and_die(0);
12310 ehandler_operation(_("reading inode and block bitmaps"));
12311 retval = ext2fs_read_bitmaps(fs);
12312 ehandler_operation(0);
12314 bb_error_msg(_("while retrying to read bitmaps for %s"),
12316 bb_error_msg_and_die(0);
12320 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12322 ext2_filsys fs = ctx->fs;
12325 if (ext2fs_test_bb_dirty(fs)) {
12326 ehandler_operation(_("writing block bitmaps"));
12327 retval = ext2fs_write_block_bitmap(fs);
12328 ehandler_operation(0);
12330 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12332 bb_error_msg_and_die(0);
12336 if (ext2fs_test_ib_dirty(fs)) {
12337 ehandler_operation(_("writing inode bitmaps"));
12338 retval = ext2fs_write_inode_bitmap(fs);
12339 ehandler_operation(0);
12341 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12343 bb_error_msg_and_die(0);
12348 void preenhalt(e2fsck_t ctx)
12350 ext2_filsys fs = ctx->fs;
12352 if (!(ctx->options & E2F_OPT_PREEN))
12354 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12355 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12358 fs->super->s_state |= EXT2_ERROR_FS;
12359 ext2fs_mark_super_dirty(fs);
12362 exit(EXIT_UNCORRECTED);
12365 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12366 struct ext2_inode * inode, const char *proc)
12370 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12372 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12373 bb_error_msg_and_die(0);
12377 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12378 struct ext2_inode * inode, int bufsize,
12383 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12385 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12386 bb_error_msg_and_die(0);
12390 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12391 struct ext2_inode * inode, const char *proc)
12395 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12397 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12398 bb_error_msg_and_die(0);
12402 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12403 io_manager manager)
12405 struct ext2_super_block *sb;
12406 io_channel io = NULL;
12409 blk_t superblock, ret_sb = 8193;
12411 if (fs && fs->super) {
12412 ret_sb = (fs->super->s_blocks_per_group +
12413 fs->super->s_first_data_block);
12415 ctx->superblock = ret_sb;
12416 ctx->blocksize = fs->blocksize;
12422 if (ctx->blocksize) {
12423 ret_sb = ctx->blocksize * 8;
12424 if (ctx->blocksize == 1024)
12426 ctx->superblock = ret_sb;
12429 ctx->superblock = ret_sb;
12430 ctx->blocksize = 1024;
12433 if (!name || !manager)
12436 if (manager->open(name, 0, &io) != 0)
12439 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12441 sb = (struct ext2_super_block *) buf;
12443 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12444 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
12445 superblock = blocksize*8;
12446 if (blocksize == 1024)
12448 io_channel_set_blksize(io, blocksize);
12449 if (io_channel_read_blk(io, superblock,
12450 -SUPERBLOCK_SIZE, buf))
12453 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12454 ext2fs_swap_super(sb);
12456 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12457 ret_sb = superblock;
12459 ctx->superblock = superblock;
12460 ctx->blocksize = blocksize;
12468 io_channel_close(io);
12469 ext2fs_free_mem(&buf);
12475 * This function runs through the e2fsck passes and calls them all,
12476 * returning restart, abort, or cancel as necessary...
12478 typedef void (*pass_t)(e2fsck_t ctx);
12480 static const pass_t e2fsck_passes[] = {
12481 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12484 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12486 static int e2fsck_run(e2fsck_t ctx)
12489 pass_t e2fsck_pass;
12491 if (setjmp(ctx->abort_loc)) {
12492 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12493 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12495 ctx->flags |= E2F_FLAG_SETJMP_OK;
12497 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12498 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12502 (void) (ctx->progress)(ctx, 0, 0, 0);
12504 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12506 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12507 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12513 * unix.c - The unix-specific code for e2fsck
12517 /* Command line options */
12519 #ifdef ENABLE_SWAPFS
12520 static int normalize_swapfs;
12522 static int cflag; /* check disk */
12523 static int show_version_only;
12524 static int verbose;
12526 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12528 static void show_stats(e2fsck_t ctx)
12530 ext2_filsys fs = ctx->fs;
12531 int inodes, inodes_used, blocks, blocks_used;
12533 int num_files, num_links;
12536 dir_links = 2 * ctx->fs_directory_count - 1;
12537 num_files = ctx->fs_total_count - dir_links;
12538 num_links = ctx->fs_links_count - dir_links;
12539 inodes = fs->super->s_inodes_count;
12540 inodes_used = (fs->super->s_inodes_count -
12541 fs->super->s_free_inodes_count);
12542 blocks = fs->super->s_blocks_count;
12543 blocks_used = (fs->super->s_blocks_count -
12544 fs->super->s_free_blocks_count);
12546 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12547 frag_percent = (frag_percent + 5) / 10;
12550 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12551 ctx->device_name, inodes_used, inodes,
12552 frag_percent / 10, frag_percent % 10,
12553 blocks_used, blocks);
12556 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12557 100 * inodes_used / inodes);
12558 printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12559 P_E2("", "s", ctx->fs_fragmented),
12560 frag_percent / 10, frag_percent % 10);
12561 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12562 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12563 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12564 (int) ((long long) 100 * blocks_used / blocks));
12565 printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12566 printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12567 printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12568 printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12569 printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12570 printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12571 printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12572 printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12573 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12574 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12575 printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12578 static void check_mount(e2fsck_t ctx)
12583 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12584 &ctx->mount_flags);
12586 bb_error_msg(_("while determining whether %s is mounted"),
12587 ctx->filesystem_name);
12592 * If the filesystem isn't mounted, or it's the root filesystem
12593 * and it's mounted read-only, then everything's fine.
12595 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12596 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12597 (ctx->mount_flags & EXT2_MF_READONLY)))
12600 if (ctx->options & E2F_OPT_READONLY) {
12601 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
12605 printf(_("%s is mounted. "), ctx->filesystem_name);
12606 if (!ctx->interactive)
12607 bb_error_msg_and_die(_("can't continue, aborting"));
12608 printf(_("\n\n\007\007\007\007WARNING!!! "
12609 "Running e2fsck on a mounted filesystem may cause\n"
12610 "SEVERE filesystem damage.\007\007\007\n\n"));
12611 cont = ask_yn(_("Do you really want to continue"), -1);
12613 printf(_("check aborted.\n"));
12618 static int is_on_batt(void)
12622 char tmp[80], tmp2[80], fname[80];
12623 unsigned int acflag;
12626 f = fopen_for_read("/proc/apm");
12628 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12631 return (acflag != 1);
12633 d = opendir("/proc/acpi/ac_adapter");
12635 while ((de=readdir(d)) != NULL) {
12636 if (!strncmp(".", de->d_name, 1))
12638 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12640 f = fopen_for_read(fname);
12643 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12646 if (strncmp(tmp, "off-line", 8) == 0) {
12657 * This routine checks to see if a filesystem can be skipped; if so,
12658 * it will exit with EXIT_OK. Under some conditions it will print a
12659 * message explaining why a check is being forced.
12661 static void check_if_skip(e2fsck_t ctx)
12663 ext2_filsys fs = ctx->fs;
12664 const char *reason = NULL;
12665 unsigned int reason_arg = 0;
12667 int batt = is_on_batt();
12668 time_t now = time(NULL);
12670 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12673 if ((fs->super->s_state & EXT2_ERROR_FS) ||
12674 !ext2fs_test_valid(fs))
12675 reason = _(" contains a file system with errors");
12676 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12677 reason = _(" was not cleanly unmounted");
12678 else if ((fs->super->s_max_mnt_count > 0) &&
12679 (fs->super->s_mnt_count >=
12680 (unsigned) fs->super->s_max_mnt_count)) {
12681 reason = _(" has been mounted %u times without being checked");
12682 reason_arg = fs->super->s_mnt_count;
12683 if (batt && (fs->super->s_mnt_count <
12684 (unsigned) fs->super->s_max_mnt_count*2))
12686 } else if (fs->super->s_checkinterval &&
12687 ((now - fs->super->s_lastcheck) >=
12688 fs->super->s_checkinterval)) {
12689 reason = _(" has gone %u days without being checked");
12690 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12691 if (batt && ((now - fs->super->s_lastcheck) <
12692 fs->super->s_checkinterval*2))
12696 fputs(ctx->device_name, stdout);
12697 printf(reason, reason_arg);
12698 fputs(_(", check forced.\n"), stdout);
12701 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12702 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12703 fs->super->s_inodes_count,
12704 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12705 fs->super->s_blocks_count);
12706 next_check = 100000;
12707 if (fs->super->s_max_mnt_count > 0) {
12708 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12709 if (next_check <= 0)
12712 if (fs->super->s_checkinterval &&
12713 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12715 if (next_check <= 5) {
12716 if (next_check == 1)
12717 fputs(_(" (check after next mount)"), stdout);
12719 printf(_(" (check in %ld mounts)"), next_check);
12724 e2fsck_free_context(ctx);
12729 * For completion notice
12731 struct percent_tbl {
12735 static const struct percent_tbl e2fsck_tbl = {
12736 5, { 0, 70, 90, 92, 95, 100 }
12739 static char bar[128], spaces[128];
12741 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12748 if (pass > tbl->max_pass || max == 0)
12750 percent = ((float) curr) / ((float) max);
12751 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12752 + tbl->table[pass-1]);
12755 void e2fsck_clear_progbar(e2fsck_t ctx)
12757 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12760 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12763 ctx->flags &= ~E2F_FLAG_PROG_BAR;
12766 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12767 unsigned int dpynum)
12769 static const char spinner[] = "\\|/-";
12776 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12780 * Calculate the new progress position. If the
12781 * percentage hasn't changed, then we skip out right
12784 fixed_percent = (int) ((10 * percent) + 0.5);
12785 if (ctx->progress_last_percent == fixed_percent)
12787 ctx->progress_last_percent = fixed_percent;
12790 * If we've already updated the spinner once within
12791 * the last 1/8th of a second, no point doing it
12794 gettimeofday(&tv, NULL);
12795 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12796 if ((tick == ctx->progress_last_time) &&
12797 (fixed_percent != 0) && (fixed_percent != 1000))
12799 ctx->progress_last_time = tick;
12802 * Advance the spinner, and note that the progress bar
12803 * will be on the screen
12805 ctx->progress_pos = (ctx->progress_pos+1) & 3;
12806 ctx->flags |= E2F_FLAG_PROG_BAR;
12808 dpywidth = 66 - strlen(label);
12809 dpywidth = 8 * (dpywidth / 8);
12813 i = ((percent * dpywidth) + 50) / 100;
12814 printf("%s%s: |%s%s", ctx->start_meta, label,
12815 bar + (sizeof(bar) - (i+1)),
12816 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12817 if (fixed_percent == 1000)
12820 bb_putchar(spinner[ctx->progress_pos & 3]);
12821 printf(" %4.1f%% ", percent);
12823 printf("%u\r", dpynum);
12825 fputs(" \r", stdout);
12826 fputs(ctx->stop_meta, stdout);
12828 if (fixed_percent == 1000)
12829 e2fsck_clear_progbar(ctx);
12835 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12836 unsigned long cur, unsigned long max)
12844 if (ctx->progress_fd) {
12845 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12846 xwrite_str(ctx->progress_fd, buf);
12848 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12849 e2fsck_simple_progress(ctx, ctx->device_name,
12855 static void reserve_stdio_fds(void)
12860 fd = open(bb_dev_null, O_RDWR);
12864 fprintf(stderr, _("ERROR: Cannot open "
12865 "/dev/null (%s)\n"),
12873 static void signal_progress_on(int sig FSCK_ATTR((unused)))
12875 e2fsck_t ctx = e2fsck_global_ctx;
12880 ctx->progress = e2fsck_update_progress;
12881 ctx->progress_fd = 0;
12884 static void signal_progress_off(int sig FSCK_ATTR((unused)))
12886 e2fsck_t ctx = e2fsck_global_ctx;
12891 e2fsck_clear_progbar(ctx);
12895 static void signal_cancel(int sig FSCK_ATTR((unused)))
12897 e2fsck_t ctx = e2fsck_global_ctx;
12900 exit(FSCK_CANCELED);
12902 ctx->flags |= E2F_FLAG_CANCEL;
12905 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12907 char *buf, *token, *next, *p, *arg;
12909 int extended_usage = 0;
12911 buf = string_copy(opts, 0);
12912 for (token = buf; token && *token; token = next) {
12913 p = strchr(token, ',');
12919 arg = strchr(token, '=');
12924 if (strcmp(token, "ea_ver") == 0) {
12929 ea_ver = strtoul(arg, &p, 0);
12931 ((ea_ver != 1) && (ea_ver != 2))) {
12933 _("Invalid EA version.\n"));
12937 ctx->ext_attr_ver = ea_ver;
12939 fprintf(stderr, _("Unknown extended option: %s\n"),
12944 if (extended_usage) {
12945 bb_error_msg_and_die(
12946 "Extended options are separated by commas, "
12947 "and may take an argument which\n"
12948 "is set off by an equals ('=') sign. "
12949 "Valid extended options are:\n"
12950 "\tea_ver=<ea_version (1 or 2)>\n\n");
12955 static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx)
12961 struct sigaction sa;
12962 char *extended_opts = NULL;
12964 retval = e2fsck_allocate_context(&ctx);
12970 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
12971 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
12972 if (isatty(0) && isatty(1)) {
12973 ctx->interactive = 1;
12975 ctx->start_meta[0] = '\001';
12976 ctx->stop_meta[0] = '\002';
12978 memset(bar, '=', sizeof(bar)-1);
12979 memset(spaces, ' ', sizeof(spaces)-1);
12980 blkid_get_cache(&ctx->blkid, NULL);
12983 ctx->program_name = *argv;
12985 ctx->program_name = "e2fsck";
12986 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
12989 ctx->progress = e2fsck_update_progress;
12990 ctx->progress_fd = atoi(optarg);
12991 if (!ctx->progress_fd)
12993 /* Validate the file descriptor to avoid disasters */
12994 fd = dup(ctx->progress_fd);
12997 _("Error validating file descriptor %d: %s\n"),
12999 error_message(errno));
13000 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13005 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13008 extended_opts = optarg;
13012 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13014 bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
13016 ctx->options |= E2F_OPT_PREEN;
13019 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13021 ctx->options |= E2F_OPT_NO;
13024 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13026 ctx->options |= E2F_OPT_YES;
13029 /* FIXME - This needs to go away in a future path - will change binary */
13030 fprintf(stderr, _("The -t option is not "
13031 "supported on this version of e2fsck.\n"));
13035 ctx->options |= E2F_OPT_WRITECHECK;
13036 ctx->options |= E2F_OPT_CHECKBLOCKS;
13039 /* What we do by default, anyway! */
13042 ctx->use_superblock = atoi(optarg);
13043 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13046 ctx->blocksize = atoi(optarg);
13049 ctx->inode_buffer_blocks = atoi(optarg);
13052 ctx->journal_name = string_copy(optarg, 0);
13055 ctx->process_inode_size = atoi(optarg);
13058 ctx->options |= E2F_OPT_DEBUG;
13061 ctx->options |= E2F_OPT_FORCE;
13070 show_version_only = 1;
13073 ctx->device_name = optarg;
13075 #ifdef ENABLE_SWAPFS
13077 normalize_swapfs = 1;
13084 fprintf(stderr, _("Byte-swapping filesystems "
13085 "not compiled in this version "
13092 if (show_version_only)
13094 if (optind != argc - 1)
13096 if ((ctx->options & E2F_OPT_NO) &&
13097 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13098 ctx->options |= E2F_OPT_READONLY;
13099 ctx->io_options = strchr(argv[optind], '?');
13100 if (ctx->io_options)
13101 *ctx->io_options++ = 0;
13102 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13103 if (!ctx->filesystem_name) {
13104 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13105 bb_error_msg_and_die(0);
13108 parse_extended_opts(ctx, extended_opts);
13111 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13113 bb_error_msg(_("while opening %s for flushing"),
13114 ctx->filesystem_name);
13115 bb_error_msg_and_die(0);
13117 if ((retval = ext2fs_sync_device(fd, 1))) {
13118 bb_error_msg(_("while trying to flush %s"),
13119 ctx->filesystem_name);
13120 bb_error_msg_and_die(0);
13124 #ifdef ENABLE_SWAPFS
13125 if (swapfs && cflag) {
13126 fprintf(stderr, _("Incompatible options not "
13127 "allowed when byte-swapping.\n"));
13132 * Set up signal action
13134 memset(&sa, 0, sizeof(struct sigaction));
13135 sa.sa_handler = signal_cancel;
13136 sigaction(SIGINT, &sa, 0);
13137 sigaction(SIGTERM, &sa, 0);
13139 sa.sa_flags = SA_RESTART;
13141 e2fsck_global_ctx = ctx;
13142 sa.sa_handler = signal_progress_on;
13143 sigaction(SIGUSR1, &sa, 0);
13144 sa.sa_handler = signal_progress_off;
13145 sigaction(SIGUSR2, &sa, 0);
13147 /* Update our PATH to include /sbin if we need to run badblocks */
13149 e2fs_set_sbin_path();
13153 static const char my_ver_string[] = E2FSPROGS_VERSION;
13154 static const char my_ver_date[] = E2FSPROGS_DATE;
13156 int e2fsck_main (int argc, char **argv);
13157 int e2fsck_main (int argc, char **argv)
13160 int exit_value = EXIT_OK;
13161 ext2_filsys fs = 0;
13163 struct ext2_super_block *sb;
13164 const char *lib_ver_date;
13165 int my_ver, lib_ver;
13167 struct problem_context pctx;
13168 int flags, run_result;
13170 clear_problem_context(&pctx);
13172 my_ver = ext2fs_parse_version_string(my_ver_string);
13173 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13174 if (my_ver > lib_ver) {
13175 fprintf( stderr, _("Error: ext2fs library version "
13176 "out of date!\n"));
13177 show_version_only++;
13180 retval = PRS(argc, argv, &ctx);
13182 bb_error_msg(_("while trying to initialize program"));
13185 reserve_stdio_fds();
13187 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13188 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13191 if (show_version_only) {
13192 fprintf(stderr, _("\tUsing %s, %s\n"),
13193 error_message(EXT2_ET_BASE), lib_ver_date);
13199 if (!(ctx->options & E2F_OPT_PREEN) &&
13200 !(ctx->options & E2F_OPT_NO) &&
13201 !(ctx->options & E2F_OPT_YES)) {
13202 if (!ctx->interactive)
13203 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13205 ctx->superblock = ctx->use_superblock;
13207 #ifdef CONFIG_TESTIO_DEBUG
13208 io_ptr = test_io_manager;
13209 test_io_backing_manager = unix_io_manager;
13211 io_ptr = unix_io_manager;
13214 if ((ctx->options & E2F_OPT_READONLY) == 0)
13215 flags |= EXT2_FLAG_RW;
13217 if (ctx->superblock && ctx->blocksize) {
13218 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13219 flags, ctx->superblock, ctx->blocksize,
13221 } else if (ctx->superblock) {
13223 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13224 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13225 retval = ext2fs_open2(ctx->filesystem_name,
13226 ctx->io_options, flags,
13227 ctx->superblock, blocksize,
13233 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13234 flags, 0, 0, io_ptr, &fs);
13235 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13236 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13237 ((retval == EXT2_ET_BAD_MAGIC) ||
13238 ((retval == 0) && ext2fs_check_desc(fs)))) {
13239 if (!fs || (fs->group_desc_count > 1)) {
13240 printf(_("%s trying backup blocks...\n"),
13241 retval ? _("Couldn't find ext2 superblock,") :
13242 _("Group descriptors look bad..."));
13243 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13250 bb_error_msg(_("while trying to open %s"),
13251 ctx->filesystem_name);
13252 if (retval == EXT2_ET_REV_TOO_HIGH) {
13253 printf(_("The filesystem revision is apparently "
13254 "too high for this version of e2fsck.\n"
13255 "(Or the filesystem superblock "
13256 "is corrupt)\n\n"));
13257 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13258 } else if (retval == EXT2_ET_SHORT_READ)
13259 printf(_("Could this be a zero-length partition?\n"));
13260 else if ((retval == EPERM) || (retval == EACCES))
13261 printf(_("You must have %s access to the "
13262 "filesystem or be root\n"),
13263 (ctx->options & E2F_OPT_READONLY) ?
13265 else if (retval == ENXIO)
13266 printf(_("Possibly non-existent or swap device?\n"));
13268 else if (retval == EROFS)
13269 printf(_("Disk write-protected; use the -n option "
13270 "to do a read-only\n"
13271 "check of the device.\n"));
13274 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13275 bb_error_msg_and_die(0);
13278 fs->priv_data = ctx;
13280 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13281 bb_error_msg(_("while trying to open %s"),
13282 ctx->filesystem_name);
13284 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13288 * Set the device name, which is used whenever we print error
13289 * or informational messages to the user.
13291 if (ctx->device_name == 0 &&
13292 (sb->s_volume_name[0] != 0)) {
13293 ctx->device_name = string_copy(sb->s_volume_name,
13294 sizeof(sb->s_volume_name));
13296 if (ctx->device_name == 0)
13297 ctx->device_name = ctx->filesystem_name;
13300 * Make sure the ext3 superblock fields are consistent.
13302 retval = e2fsck_check_ext3_journal(ctx);
13304 bb_error_msg(_("while checking ext3 journal for %s"),
13306 bb_error_msg_and_die(0);
13310 * Check to see if we need to do ext3-style recovery. If so,
13311 * do it, and then restart the fsck.
13313 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13314 if (ctx->options & E2F_OPT_READONLY) {
13315 printf(_("Warning: skipping journal recovery "
13316 "because doing a read-only filesystem "
13318 io_channel_flush(ctx->fs->io);
13320 if (ctx->flags & E2F_FLAG_RESTARTED) {
13322 * Whoops, we attempted to run the
13323 * journal twice. This should never
13324 * happen, unless the hardware or
13325 * device driver is being bogus.
13327 bb_error_msg(_("can't set superblock flags on %s"), ctx->device_name);
13328 bb_error_msg_and_die(0);
13330 retval = e2fsck_run_ext3_journal(ctx);
13332 bb_error_msg(_("while recovering ext3 journal of %s"),
13334 bb_error_msg_and_die(0);
13336 ext2fs_close(ctx->fs);
13338 ctx->flags |= E2F_FLAG_RESTARTED;
13344 * Check for compatibility with the feature sets. We need to
13345 * be more stringent than ext2fs_open().
13347 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13348 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13349 bb_error_msg("(%s)", ctx->device_name);
13352 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13353 bb_error_msg("(%s)", ctx->device_name);
13356 #ifdef ENABLE_COMPRESSION
13357 /* FIXME - do we support this at all? */
13358 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13359 bb_error_msg(_("warning: compression support is experimental"));
13361 #ifndef ENABLE_HTREE
13362 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13363 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13364 "but filesystem %s has HTREE directories."),
13371 * If the user specified a specific superblock, presumably the
13372 * master superblock has been trashed. So we mark the
13373 * superblock as dirty, so it can be written out.
13375 if (ctx->superblock &&
13376 !(ctx->options & E2F_OPT_READONLY))
13377 ext2fs_mark_super_dirty(fs);
13380 * We only update the master superblock because (a) paranoia;
13381 * we don't want to corrupt the backup superblocks, and (b) we
13382 * don't need to update the mount count and last checked
13383 * fields in the backup superblock (the kernel doesn't
13384 * update the backup superblocks anyway).
13386 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13388 ehandler_init(fs->io);
13390 if (ctx->superblock)
13391 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13392 ext2fs_mark_valid(fs);
13393 check_super_block(ctx);
13394 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13395 bb_error_msg_and_die(0);
13396 check_if_skip(ctx);
13397 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13398 bb_error_msg_and_die(0);
13399 #ifdef ENABLE_SWAPFS
13401 #ifdef WORDS_BIGENDIAN
13402 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13404 #define NATIVE_FLAG 0
13408 if (normalize_swapfs) {
13409 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13410 fprintf(stderr, _("%s: Filesystem byte order "
13411 "already normalized.\n"), ctx->device_name);
13412 bb_error_msg_and_die(0);
13417 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13418 bb_error_msg_and_die(0);
13423 * Mark the system as valid, 'til proven otherwise
13425 ext2fs_mark_valid(fs);
13427 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13429 bb_error_msg(_("while reading bad blocks inode"));
13431 printf(_("This doesn't bode well,"
13432 " but we'll try to go on...\n"));
13435 run_result = e2fsck_run(ctx);
13436 e2fsck_clear_progbar(ctx);
13437 if (run_result == E2F_FLAG_RESTART) {
13438 printf(_("Restarting e2fsck from the beginning...\n"));
13439 retval = e2fsck_reset_context(ctx);
13441 bb_error_msg(_("while resetting context"));
13442 bb_error_msg_and_die(0);
13447 if (run_result & E2F_FLAG_CANCEL) {
13448 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13449 ctx->device_name : ctx->filesystem_name);
13450 exit_value |= FSCK_CANCELED;
13452 if (run_result & E2F_FLAG_ABORT)
13453 bb_error_msg_and_die(_("aborted"));
13456 if (ext2fs_test_changed(fs)) {
13457 exit_value |= EXIT_NONDESTRUCT;
13458 if (!(ctx->options & E2F_OPT_PREEN))
13459 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13461 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13462 printf(_("%s: ***** REBOOT LINUX *****\n"),
13464 exit_value |= EXIT_DESTRUCT;
13467 if (!ext2fs_test_valid(fs)) {
13468 printf(_("\n%s: ********** WARNING: Filesystem still has "
13469 "errors **********\n\n"), ctx->device_name);
13470 exit_value |= EXIT_UNCORRECTED;
13471 exit_value &= ~EXIT_NONDESTRUCT;
13473 if (exit_value & FSCK_CANCELED)
13474 exit_value &= ~EXIT_NONDESTRUCT;
13477 if (!(ctx->options & E2F_OPT_READONLY)) {
13478 if (ext2fs_test_valid(fs)) {
13479 if (!(sb->s_state & EXT2_VALID_FS))
13480 exit_value |= EXIT_NONDESTRUCT;
13481 sb->s_state = EXT2_VALID_FS;
13483 sb->s_state &= ~EXT2_VALID_FS;
13484 sb->s_mnt_count = 0;
13485 sb->s_lastcheck = time(NULL);
13486 ext2fs_mark_super_dirty(fs);
13490 e2fsck_write_bitmaps(ctx);
13494 free(ctx->filesystem_name);
13495 free(ctx->journal_name);
13496 e2fsck_free_context(ctx);