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;
524 * Allocate a node using the dictionary's allocator routine, give it
528 static dnode_t *dnode_init(dnode_t *dnode, void *data)
531 dnode->parent = NULL;
537 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
539 dnode_t *node = xmalloc(sizeof(dnode_t));
541 dnode_init(node, data);
542 dict_insert(dict, node, key);
547 * Return the node with the lowest (leftmost) key. If the dictionary is empty
548 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
551 static dnode_t *dict_first(dict_t *dict)
553 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
556 while ((left = root->left) != nil)
559 return (root == nil) ? NULL : root;
563 * Return the given node's successor node---the node which has the
564 * next key in the the left to right ordering. If the node has
565 * no successor, a null pointer is returned rather than a pointer to
569 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
571 dnode_t *nil = dict_nil(dict), *parent, *left;
573 if (curr->right != nil) {
575 while ((left = curr->left) != nil)
580 parent = curr->parent;
582 while (parent != nil && curr == parent->right) {
584 parent = curr->parent;
587 return (parent == nil) ? NULL : parent;
591 static void dnode_free(dnode_t *node)
611 * dirinfo.c --- maintains the directory information table for e2fsck.
615 * This subroutine is called during pass1 to create a directory info
616 * entry. During pass1, the passed-in parent is 0; it will get filled
619 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
621 struct dir_info *dir;
625 unsigned long old_size;
627 if (!ctx->dir_info) {
628 ctx->dir_info_count = 0;
629 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
631 num_dirs = 1024; /* Guess */
632 ctx->dir_info_size = num_dirs + 10;
633 ctx->dir_info = (struct dir_info *)
634 e2fsck_allocate_memory(ctx, ctx->dir_info_size
635 * sizeof (struct dir_info),
639 if (ctx->dir_info_count >= ctx->dir_info_size) {
640 old_size = ctx->dir_info_size * sizeof(struct dir_info);
641 ctx->dir_info_size += 10;
642 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
643 sizeof(struct dir_info),
646 ctx->dir_info_size -= 10;
652 * Normally, add_dir_info is called with each inode in
653 * sequential order; but once in a while (like when pass 3
654 * needs to recreate the root directory or lost+found
655 * directory) it is called out of order. In those cases, we
656 * need to move the dir_info entries down to make room, since
657 * the dir_info array needs to be sorted by inode number for
658 * get_dir_info()'s sake.
660 if (ctx->dir_info_count &&
661 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
662 for (i = ctx->dir_info_count-1; i > 0; i--)
663 if (ctx->dir_info[i-1].ino < ino)
665 dir = &ctx->dir_info[i];
667 for (j = ctx->dir_info_count++; j > i; j--)
668 ctx->dir_info[j] = ctx->dir_info[j-1];
670 dir = &ctx->dir_info[ctx->dir_info_count++];
673 dir->dotdot = parent;
674 dir->parent = parent;
678 * get_dir_info() --- given an inode number, try to find the directory
679 * information entry for it.
681 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
686 high = ctx->dir_info_count-1;
689 if (ino == ctx->dir_info[low].ino)
690 return &ctx->dir_info[low];
691 if (ino == ctx->dir_info[high].ino)
692 return &ctx->dir_info[high];
696 if (mid == low || mid == high)
698 if (ino == ctx->dir_info[mid].ino)
699 return &ctx->dir_info[mid];
700 if (ino < ctx->dir_info[mid].ino)
709 * Free the dir_info structure when it isn't needed any more.
711 static void e2fsck_free_dir_info(e2fsck_t ctx)
713 ext2fs_free_mem(&ctx->dir_info);
714 ctx->dir_info_size = 0;
715 ctx->dir_info_count = 0;
719 * Return the count of number of directories in the dir_info structure
721 static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
723 return ctx->dir_info_count;
727 * A simple interator function
729 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
731 if (*control >= ctx->dir_info_count)
734 return ctx->dir_info + (*control)++;
738 * dirinfo.c --- maintains the directory information table for e2fsck.
745 * This subroutine is called during pass1 to create a directory info
746 * entry. During pass1, the passed-in parent is 0; it will get filled
749 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
751 struct dx_dir_info *dir;
754 unsigned long old_size;
756 if (!ctx->dx_dir_info) {
757 ctx->dx_dir_info_count = 0;
758 ctx->dx_dir_info_size = 100; /* Guess */
759 ctx->dx_dir_info = (struct dx_dir_info *)
760 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
761 * sizeof (struct dx_dir_info),
765 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
766 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
767 ctx->dx_dir_info_size += 10;
768 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
769 sizeof(struct dx_dir_info),
772 ctx->dx_dir_info_size -= 10;
778 * Normally, add_dx_dir_info is called with each inode in
779 * sequential order; but once in a while (like when pass 3
780 * needs to recreate the root directory or lost+found
781 * directory) it is called out of order. In those cases, we
782 * need to move the dx_dir_info entries down to make room, since
783 * the dx_dir_info array needs to be sorted by inode number for
784 * get_dx_dir_info()'s sake.
786 if (ctx->dx_dir_info_count &&
787 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
788 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
789 if (ctx->dx_dir_info[i-1].ino < ino)
791 dir = &ctx->dx_dir_info[i];
793 for (j = ctx->dx_dir_info_count++; j > i; j--)
794 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
796 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
799 dir->numblocks = num_blocks;
800 dir->hashversion = 0;
801 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
802 * sizeof (struct dx_dirblock_info),
803 "dx_block info array");
808 * get_dx_dir_info() --- given an inode number, try to find the directory
809 * information entry for it.
811 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
816 high = ctx->dx_dir_info_count-1;
817 if (!ctx->dx_dir_info)
819 if (ino == ctx->dx_dir_info[low].ino)
820 return &ctx->dx_dir_info[low];
821 if (ino == ctx->dx_dir_info[high].ino)
822 return &ctx->dx_dir_info[high];
826 if (mid == low || mid == high)
828 if (ino == ctx->dx_dir_info[mid].ino)
829 return &ctx->dx_dir_info[mid];
830 if (ino < ctx->dx_dir_info[mid].ino)
839 * Free the dx_dir_info structure when it isn't needed any more.
841 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
844 struct dx_dir_info *dir;
846 if (ctx->dx_dir_info) {
847 dir = ctx->dx_dir_info;
848 for (i=0; i < ctx->dx_dir_info_count; i++) {
849 ext2fs_free_mem(&dir->dx_block);
851 ext2fs_free_mem(&ctx->dx_dir_info);
853 ctx->dx_dir_info_size = 0;
854 ctx->dx_dir_info_count = 0;
858 * A simple interator function
860 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
862 if (*control >= ctx->dx_dir_info_count)
865 return ctx->dx_dir_info + (*control)++;
868 #endif /* ENABLE_HTREE */
870 * e2fsck.c - a consistency checker for the new extended file system.
875 * This function allocates an e2fsck context
877 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
882 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
886 memset(context, 0, sizeof(struct e2fsck_struct));
888 context->process_inode_size = 256;
889 context->ext_attr_ver = 2;
895 struct ea_refcount_el {
904 struct ea_refcount_el *list;
907 static void ea_refcount_free(ext2_refcount_t refcount)
912 ext2fs_free_mem(&refcount->list);
913 ext2fs_free_mem(&refcount);
917 * This function resets an e2fsck context; it is called when e2fsck
918 * needs to be restarted.
920 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
923 ctx->lost_and_found = 0;
924 ctx->bad_lost_and_found = 0;
925 ext2fs_free_inode_bitmap(ctx->inode_used_map);
926 ctx->inode_used_map = 0;
927 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
928 ctx->inode_dir_map = 0;
929 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
930 ctx->inode_reg_map = 0;
931 ext2fs_free_block_bitmap(ctx->block_found_map);
932 ctx->block_found_map = 0;
933 ext2fs_free_icount(ctx->inode_link_info);
934 ctx->inode_link_info = 0;
935 if (ctx->journal_io) {
936 if (ctx->fs && ctx->fs->io != ctx->journal_io)
937 io_channel_close(ctx->journal_io);
941 ext2fs_free_dblist(ctx->fs->dblist);
944 e2fsck_free_dir_info(ctx);
946 e2fsck_free_dx_dir_info(ctx);
948 ea_refcount_free(ctx->refcount);
950 ea_refcount_free(ctx->refcount_extra);
951 ctx->refcount_extra = 0;
952 ext2fs_free_block_bitmap(ctx->block_dup_map);
953 ctx->block_dup_map = 0;
954 ext2fs_free_block_bitmap(ctx->block_ea_map);
955 ctx->block_ea_map = 0;
956 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
957 ctx->inode_bad_map = 0;
958 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
959 ctx->inode_imagic_map = 0;
960 ext2fs_u32_list_free(ctx->dirs_to_hash);
961 ctx->dirs_to_hash = 0;
964 * Clear the array of invalid meta-data flags
966 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
967 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
968 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
970 /* Clear statistic counters */
971 ctx->fs_directory_count = 0;
972 ctx->fs_regular_count = 0;
973 ctx->fs_blockdev_count = 0;
974 ctx->fs_chardev_count = 0;
975 ctx->fs_links_count = 0;
976 ctx->fs_symlinks_count = 0;
977 ctx->fs_fast_symlinks_count = 0;
978 ctx->fs_fifo_count = 0;
979 ctx->fs_total_count = 0;
980 ctx->fs_sockets_count = 0;
981 ctx->fs_ind_count = 0;
982 ctx->fs_dind_count = 0;
983 ctx->fs_tind_count = 0;
984 ctx->fs_fragmented = 0;
985 ctx->large_files = 0;
987 /* Reset the superblock to the user's requested value */
988 ctx->superblock = ctx->use_superblock;
993 static void e2fsck_free_context(e2fsck_t ctx)
998 e2fsck_reset_context(ctx);
1000 blkid_put_cache(ctx->blkid);
1002 ext2fs_free_mem(&ctx);
1010 * The strategy we use for keeping track of EA refcounts is as
1011 * follows. We keep a sorted array of first EA blocks and its
1012 * reference counts. Once the refcount has dropped to zero, it is
1013 * removed from the array to save memory space. Once the EA block is
1014 * checked, its bit is set in the block_ea_map bitmap.
1018 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1020 ext2_refcount_t refcount;
1024 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1027 memset(refcount, 0, sizeof(struct ea_refcount));
1031 refcount->size = size;
1032 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1034 printf("Refcount allocated %d entries, %d bytes.\n",
1035 refcount->size, bytes);
1037 retval = ext2fs_get_mem(bytes, &refcount->list);
1040 memset(refcount->list, 0, bytes);
1042 refcount->count = 0;
1043 refcount->cursor = 0;
1049 ea_refcount_free(refcount);
1054 * collapse_refcount() --- go through the refcount array, and get rid
1055 * of any count == zero entries
1057 static void refcount_collapse(ext2_refcount_t refcount)
1060 struct ea_refcount_el *list;
1062 list = refcount->list;
1063 for (i = 0, j = 0; i < refcount->count; i++) {
1064 if (list[i].ea_count) {
1070 #if defined(DEBUG) || defined(TEST_PROGRAM)
1071 printf("Refcount_collapse: size was %d, now %d\n",
1072 refcount->count, j);
1074 refcount->count = j;
1079 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1080 * specified position.
1082 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1085 struct ea_refcount_el *el;
1090 if (refcount->count >= refcount->size) {
1091 new_size = refcount->size + 100;
1093 printf("Reallocating refcount %d entries...\n", new_size);
1095 retval = ext2fs_resize_mem((size_t) refcount->size *
1096 sizeof(struct ea_refcount_el),
1098 sizeof(struct ea_refcount_el),
1102 refcount->size = new_size;
1104 num = (int) refcount->count - pos;
1106 return 0; /* should never happen */
1108 memmove(&refcount->list[pos+1], &refcount->list[pos],
1109 sizeof(struct ea_refcount_el) * num);
1112 el = &refcount->list[pos];
1120 * get_refcount_el() --- given an block number, try to find refcount
1121 * information in the sorted list. If the create flag is set,
1122 * and we can't find an entry, create one in the sorted list.
1124 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1125 blk_t blk, int create)
1129 blk_t lowval, highval;
1131 if (!refcount || !refcount->list)
1135 high = (int) refcount->count-1;
1136 if (create && ((refcount->count == 0) ||
1137 (blk > refcount->list[high].ea_blk))) {
1138 if (refcount->count >= refcount->size)
1139 refcount_collapse(refcount);
1141 return insert_refcount_el(refcount, blk,
1142 (unsigned) refcount->count);
1144 if (refcount->count == 0)
1147 if (refcount->cursor >= refcount->count)
1148 refcount->cursor = 0;
1149 if (blk == refcount->list[refcount->cursor].ea_blk)
1150 return &refcount->list[refcount->cursor++];
1152 printf("Non-cursor get_refcount_el: %u\n", blk);
1154 while (low <= high) {
1158 /* Interpolate for efficiency */
1159 lowval = refcount->list[low].ea_blk;
1160 highval = refcount->list[high].ea_blk;
1164 else if (blk > highval)
1167 range = ((float) (blk - lowval)) /
1169 mid = low + ((int) (range * (high-low)));
1172 if (blk == refcount->list[mid].ea_blk) {
1173 refcount->cursor = mid+1;
1174 return &refcount->list[mid];
1176 if (blk < refcount->list[mid].ea_blk)
1182 * If we need to create a new entry, it should be right at
1183 * low (where high will be left at low-1).
1186 if (refcount->count >= refcount->size) {
1187 refcount_collapse(refcount);
1188 if (refcount->count < refcount->size)
1191 return insert_refcount_el(refcount, blk, low);
1197 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1199 struct ea_refcount_el *el;
1201 el = get_refcount_el(refcount, blk, 1);
1203 return EXT2_ET_NO_MEMORY;
1207 *ret = el->ea_count;
1212 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1214 struct ea_refcount_el *el;
1216 el = get_refcount_el(refcount, blk, 0);
1217 if (!el || el->ea_count == 0)
1218 return EXT2_ET_INVALID_ARGUMENT;
1223 *ret = el->ea_count;
1228 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1230 struct ea_refcount_el *el;
1233 * Get the refcount element
1235 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1237 return count ? EXT2_ET_NO_MEMORY : 0;
1238 el->ea_count = count;
1242 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1244 refcount->cursor = 0;
1248 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1250 struct ea_refcount_el *list;
1253 if (refcount->cursor >= refcount->count)
1255 list = refcount->list;
1256 if (list[refcount->cursor].ea_count) {
1258 *ret = list[refcount->cursor].ea_count;
1259 return list[refcount->cursor++].ea_blk;
1267 * ehandler.c --- handle bad block errors which come up during the
1268 * course of an e2fsck session.
1272 static const char *operation;
1275 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1276 void *data, size_t size FSCK_ATTR((unused)),
1277 int actual FSCK_ATTR((unused)), errcode_t error)
1281 ext2_filsys fs = (ext2_filsys) channel->app_data;
1284 ctx = (e2fsck_t) fs->priv_data;
1287 * If more than one block was read, try reading each block
1288 * separately. We could use the actual bytes read to figure
1289 * out where to start, but we don't bother.
1293 for (i=0; i < count; i++, p += channel->block_size, block++) {
1294 error = io_channel_read_blk(channel, block,
1302 printf(_("Error reading block %lu (%s) while %s. "), block,
1303 error_message(error), operation);
1305 printf(_("Error reading block %lu (%s). "), block,
1306 error_message(error));
1308 if (ask(ctx, _("Ignore error"), 1)) {
1309 if (ask(ctx, _("Force rewrite"), 1))
1310 io_channel_write_blk(channel, block, 1, data);
1318 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1319 const void *data, size_t size FSCK_ATTR((unused)),
1320 int actual FSCK_ATTR((unused)), errcode_t error)
1324 ext2_filsys fs = (ext2_filsys) channel->app_data;
1327 ctx = (e2fsck_t) fs->priv_data;
1330 * If more than one block was written, try writing each block
1331 * separately. We could use the actual bytes read to figure
1332 * out where to start, but we don't bother.
1335 p = (const char *) data;
1336 for (i=0; i < count; i++, p += channel->block_size, block++) {
1337 error = io_channel_write_blk(channel, block,
1346 printf(_("Error writing block %lu (%s) while %s. "), block,
1347 error_message(error), operation);
1349 printf(_("Error writing block %lu (%s). "), block,
1350 error_message(error));
1352 if (ask(ctx, _("Ignore error"), 1))
1358 static const char *ehandler_operation(const char *op)
1360 const char *ret = operation;
1366 static void ehandler_init(io_channel channel)
1368 channel->read_error = e2fsck_handle_read_error;
1369 channel->write_error = e2fsck_handle_write_error;
1373 * journal.c --- code for handling the "ext3" journal
1375 * Copyright (C) 2000 Andreas Dilger
1376 * Copyright (C) 2000 Theodore Ts'o
1378 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1379 * Copyright (C) 1999 Red Hat Software
1381 * This file may be redistributed under the terms of the
1382 * GNU General Public License version 2 or at your discretion
1383 * any later version.
1387 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1388 * This creates a larger static binary, and a smaller binary using
1389 * shared libraries. It's also probably slightly less CPU-efficient,
1390 * which is why it's not on by default. But, it's a good way of
1391 * testing the functions in inode_io.c and fileio.c.
1395 /* Kernel compatibility functions for handling the journal. These allow us
1396 * to use the recovery.c file virtually unchanged from the kernel, so we
1397 * don't have to do much to keep kernel and user recovery in sync.
1399 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1405 struct inode *inode = journal->j_inode;
1414 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1415 &inode->i_ext2, NULL, 0, block, &pblk);
1421 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1423 struct buffer_head *bh;
1425 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1429 bh->b_ctx = kdev->k_ctx;
1430 if (kdev->k_dev == K_DEV_FS)
1431 bh->b_io = kdev->k_ctx->fs->io;
1433 bh->b_io = kdev->k_ctx->journal_io;
1434 bh->b_size = blocksize;
1435 bh->b_blocknr = blocknr;
1440 static void sync_blockdev(kdev_t kdev)
1444 if (kdev->k_dev == K_DEV_FS)
1445 io = kdev->k_ctx->fs->io;
1447 io = kdev->k_ctx->journal_io;
1449 io_channel_flush(io);
1452 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1455 struct buffer_head *bh;
1457 for (; nr > 0; --nr) {
1459 if (rw == READ && !bh->b_uptodate) {
1460 retval = io_channel_read_blk(bh->b_io,
1464 bb_error_msg("while reading block %lu",
1465 (unsigned long) bh->b_blocknr);
1470 } else if (rw == WRITE && bh->b_dirty) {
1471 retval = io_channel_write_blk(bh->b_io,
1475 bb_error_msg("while writing block %lu",
1476 (unsigned long) bh->b_blocknr);
1486 static void mark_buffer_dirty(struct buffer_head *bh)
1491 static inline void mark_buffer_clean(struct buffer_head * bh)
1496 static void brelse(struct buffer_head *bh)
1499 ll_rw_block(WRITE, 1, &bh);
1500 ext2fs_free_mem(&bh);
1503 static int buffer_uptodate(struct buffer_head *bh)
1505 return bh->b_uptodate;
1508 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1510 bh->b_uptodate = val;
1513 static void wait_on_buffer(struct buffer_head *bh)
1515 if (!bh->b_uptodate)
1516 ll_rw_block(READ, 1, &bh);
1520 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1522 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1524 /* if we had an error doing journal recovery, we need a full fsck */
1526 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1527 ext2fs_mark_super_dirty(ctx->fs);
1530 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1532 struct ext2_super_block *sb = ctx->fs->super;
1533 struct ext2_super_block jsuper;
1534 struct problem_context pctx;
1535 struct buffer_head *bh;
1536 struct inode *j_inode = NULL;
1537 struct kdev_s *dev_fs = NULL, *dev_journal;
1538 const char *journal_name = NULL;
1539 journal_t *journal = NULL;
1540 errcode_t retval = 0;
1541 io_manager io_ptr = 0;
1542 unsigned long start = 0;
1544 int ext_journal = 0;
1545 int tried_backup_jnl = 0;
1548 clear_problem_context(&pctx);
1550 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1552 return EXT2_ET_NO_MEMORY;
1555 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1557 retval = EXT2_ET_NO_MEMORY;
1560 dev_journal = dev_fs+1;
1562 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1563 dev_fs->k_dev = K_DEV_FS;
1564 dev_journal->k_dev = K_DEV_JOURNAL;
1566 journal->j_dev = dev_journal;
1567 journal->j_fs_dev = dev_fs;
1568 journal->j_inode = NULL;
1569 journal->j_blocksize = ctx->fs->blocksize;
1571 if (uuid_is_null(sb->s_journal_uuid)) {
1572 if (!sb->s_journal_inum)
1573 return EXT2_ET_BAD_INODE_NUM;
1574 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1577 retval = EXT2_ET_NO_MEMORY;
1581 j_inode->i_ctx = ctx;
1582 j_inode->i_ino = sb->s_journal_inum;
1584 if ((retval = ext2fs_read_inode(ctx->fs,
1586 &j_inode->i_ext2))) {
1588 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1591 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1592 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1594 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1595 j_inode->i_ext2.i_links_count = 1;
1596 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1599 if (!j_inode->i_ext2.i_links_count ||
1600 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1601 retval = EXT2_ET_NO_JOURNAL;
1602 goto try_backup_journal;
1604 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1605 JFS_MIN_JOURNAL_BLOCKS) {
1606 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1607 goto try_backup_journal;
1609 for (i=0; i < EXT2_N_BLOCKS; i++) {
1610 blk = j_inode->i_ext2.i_block[i];
1612 if (i < EXT2_NDIR_BLOCKS) {
1613 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1614 goto try_backup_journal;
1618 if (blk < sb->s_first_data_block ||
1619 blk >= sb->s_blocks_count) {
1620 retval = EXT2_ET_BAD_BLOCK_NUM;
1621 goto try_backup_journal;
1624 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1627 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1633 io_ptr = inode_io_manager;
1635 journal->j_inode = j_inode;
1636 ctx->journal_io = ctx->fs->io;
1637 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1642 if (!ctx->journal_name) {
1645 uuid_unparse(sb->s_journal_uuid, uuid);
1646 ctx->journal_name = blkid_get_devname(ctx->blkid,
1648 if (!ctx->journal_name)
1649 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1651 journal_name = ctx->journal_name;
1653 if (!journal_name) {
1654 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1655 return EXT2_ET_LOAD_EXT_JOURNAL;
1658 io_ptr = unix_io_manager;
1661 #ifndef USE_INODE_IO
1664 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1669 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1672 if (ctx->fs->blocksize == 1024)
1674 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1676 retval = EXT2_ET_NO_MEMORY;
1679 ll_rw_block(READ, 1, &bh);
1680 if ((retval = bh->b_err) != 0)
1682 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1686 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1687 ext2fs_swap_super(&jsuper);
1689 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1690 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1691 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1692 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1695 /* Make sure the journal UUID is correct */
1696 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1697 sizeof(jsuper.s_uuid))) {
1698 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1699 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1703 journal->j_maxlen = jsuper.s_blocks_count;
1707 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1708 retval = EXT2_ET_NO_MEMORY;
1712 journal->j_sb_buffer = bh;
1713 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1716 ext2fs_free_mem(&j_inode);
1719 *ret_journal = journal;
1723 ext2fs_free_mem(&dev_fs);
1724 ext2fs_free_mem(&j_inode);
1725 ext2fs_free_mem(&journal);
1730 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1731 struct problem_context *pctx)
1733 struct ext2_super_block *sb = ctx->fs->super;
1734 int recover = ctx->fs->super->s_feature_incompat &
1735 EXT3_FEATURE_INCOMPAT_RECOVER;
1736 int has_journal = ctx->fs->super->s_feature_compat &
1737 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1739 if (has_journal || sb->s_journal_inum) {
1740 /* The journal inode is bogus, remove and force full fsck */
1741 pctx->ino = sb->s_journal_inum;
1742 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1743 if (has_journal && sb->s_journal_inum)
1744 printf("*** ext3 journal has been deleted - "
1745 "filesystem is now ext2 only ***\n\n");
1746 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1747 sb->s_journal_inum = 0;
1748 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1749 e2fsck_clear_recover(ctx, 1);
1752 return EXT2_ET_BAD_INODE_NUM;
1753 } else if (recover) {
1754 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1755 e2fsck_clear_recover(ctx, 1);
1758 return EXT2_ET_UNSUPP_FEATURE;
1763 #define V1_SB_SIZE 0x0024
1764 static void clear_v2_journal_fields(journal_t *journal)
1766 e2fsck_t ctx = journal->j_dev->k_ctx;
1767 struct problem_context pctx;
1769 clear_problem_context(&pctx);
1771 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1774 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1775 ctx->fs->blocksize-V1_SB_SIZE);
1776 mark_buffer_dirty(journal->j_sb_buffer);
1780 static errcode_t e2fsck_journal_load(journal_t *journal)
1782 e2fsck_t ctx = journal->j_dev->k_ctx;
1783 journal_superblock_t *jsb;
1784 struct buffer_head *jbh = journal->j_sb_buffer;
1785 struct problem_context pctx;
1787 clear_problem_context(&pctx);
1789 ll_rw_block(READ, 1, &jbh);
1791 bb_error_msg(_("reading journal superblock"));
1795 jsb = journal->j_superblock;
1796 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1797 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1798 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1800 switch (ntohl(jsb->s_header.h_blocktype)) {
1801 case JFS_SUPERBLOCK_V1:
1802 journal->j_format_version = 1;
1803 if (jsb->s_feature_compat ||
1804 jsb->s_feature_incompat ||
1805 jsb->s_feature_ro_compat ||
1807 clear_v2_journal_fields(journal);
1810 case JFS_SUPERBLOCK_V2:
1811 journal->j_format_version = 2;
1812 if (ntohl(jsb->s_nr_users) > 1 &&
1813 uuid_is_null(ctx->fs->super->s_journal_uuid))
1814 clear_v2_journal_fields(journal);
1815 if (ntohl(jsb->s_nr_users) > 1) {
1816 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1817 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1822 * These should never appear in a journal super block, so if
1823 * they do, the journal is badly corrupted.
1825 case JFS_DESCRIPTOR_BLOCK:
1826 case JFS_COMMIT_BLOCK:
1827 case JFS_REVOKE_BLOCK:
1828 return EXT2_ET_CORRUPT_SUPERBLOCK;
1830 /* If we don't understand the superblock major type, but there
1831 * is a magic number, then it is likely to be a new format we
1832 * just don't understand, so leave it alone. */
1834 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1837 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1838 return EXT2_ET_UNSUPP_FEATURE;
1840 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1841 return EXT2_ET_RO_UNSUPP_FEATURE;
1843 /* We have now checked whether we know enough about the journal
1844 * format to be able to proceed safely, so any other checks that
1845 * fail we should attempt to recover from. */
1846 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1847 bb_error_msg(_("%s: no valid journal superblock found"),
1849 return EXT2_ET_CORRUPT_SUPERBLOCK;
1852 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1853 journal->j_maxlen = ntohl(jsb->s_maxlen);
1854 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1855 bb_error_msg(_("%s: journal too short"),
1857 return EXT2_ET_CORRUPT_SUPERBLOCK;
1860 journal->j_tail_sequence = ntohl(jsb->s_sequence);
1861 journal->j_transaction_sequence = journal->j_tail_sequence;
1862 journal->j_tail = ntohl(jsb->s_start);
1863 journal->j_first = ntohl(jsb->s_first);
1864 journal->j_last = ntohl(jsb->s_maxlen);
1869 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
1880 /* Leave a valid existing V1 superblock signature alone.
1881 * Anything unrecognizable we overwrite with a new V2
1884 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
1885 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
1886 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
1887 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
1890 /* Zero out everything else beyond the superblock header */
1892 p = ((char *) jsb) + sizeof(journal_header_t);
1893 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
1895 jsb->s_blocksize = htonl(ctx->fs->blocksize);
1896 jsb->s_maxlen = htonl(journal->j_maxlen);
1897 jsb->s_first = htonl(1);
1899 /* Initialize the journal sequence number so that there is "no"
1900 * chance we will find old "valid" transactions in the journal.
1901 * This avoids the need to zero the whole journal (slow to do,
1902 * and risky when we are just recovering the filesystem).
1904 uuid_generate(u.uuid);
1905 for (i = 0; i < 4; i ++)
1906 new_seq ^= u.val[i];
1907 jsb->s_sequence = htonl(new_seq);
1909 mark_buffer_dirty(journal->j_sb_buffer);
1910 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
1913 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
1915 struct problem_context *pctx)
1917 struct ext2_super_block *sb = ctx->fs->super;
1918 int recover = ctx->fs->super->s_feature_incompat &
1919 EXT3_FEATURE_INCOMPAT_RECOVER;
1921 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
1922 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
1923 e2fsck_journal_reset_super(ctx, journal->j_superblock,
1925 journal->j_transaction_sequence = 1;
1926 e2fsck_clear_recover(ctx, recover);
1929 return EXT2_ET_CORRUPT_SUPERBLOCK;
1930 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
1931 return EXT2_ET_CORRUPT_SUPERBLOCK;
1936 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
1937 int reset, int drop)
1939 journal_superblock_t *jsb;
1942 mark_buffer_clean(journal->j_sb_buffer);
1943 else if (!(ctx->options & E2F_OPT_READONLY)) {
1944 jsb = journal->j_superblock;
1945 jsb->s_sequence = htonl(journal->j_transaction_sequence);
1947 jsb->s_start = 0; /* this marks the journal as empty */
1948 mark_buffer_dirty(journal->j_sb_buffer);
1950 brelse(journal->j_sb_buffer);
1952 if (ctx->journal_io) {
1953 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1954 io_channel_close(ctx->journal_io);
1955 ctx->journal_io = 0;
1958 #ifndef USE_INODE_IO
1959 ext2fs_free_mem(&journal->j_inode);
1961 ext2fs_free_mem(&journal->j_fs_dev);
1962 ext2fs_free_mem(&journal);
1966 * This function makes sure that the superblock fields regarding the
1967 * journal are consistent.
1969 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
1971 struct ext2_super_block *sb = ctx->fs->super;
1973 int recover = ctx->fs->super->s_feature_incompat &
1974 EXT3_FEATURE_INCOMPAT_RECOVER;
1975 struct problem_context pctx;
1977 int reset = 0, force_fsck = 0;
1980 /* If we don't have any journal features, don't do anything more */
1981 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
1982 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
1983 uuid_is_null(sb->s_journal_uuid))
1986 clear_problem_context(&pctx);
1987 pctx.num = sb->s_journal_inum;
1989 retval = e2fsck_get_journal(ctx, &journal);
1991 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
1992 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
1993 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
1994 (retval == EXT2_ET_NO_JOURNAL))
1995 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1999 retval = e2fsck_journal_load(journal);
2001 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2002 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2003 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2005 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2006 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2008 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2009 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2010 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2012 e2fsck_journal_release(ctx, journal, 0, 1);
2017 * We want to make the flags consistent here. We will not leave with
2018 * needs_recovery set but has_journal clear. We can't get in a loop
2019 * with -y, -n, or -p, only if a user isn't making up their mind.
2022 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2023 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2025 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2027 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2028 goto no_has_journal;
2030 * Need a full fsck if we are releasing a
2031 * journal stored on a reserved inode.
2033 force_fsck = recover ||
2034 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2035 /* Clear all of the journal fields */
2036 sb->s_journal_inum = 0;
2037 sb->s_journal_dev = 0;
2038 memset(sb->s_journal_uuid, 0,
2039 sizeof(sb->s_journal_uuid));
2040 e2fsck_clear_recover(ctx, force_fsck);
2041 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2042 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2043 ext2fs_mark_super_dirty(ctx->fs);
2047 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2048 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2049 journal->j_superblock->s_start != 0) {
2050 /* Print status information */
2051 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2052 if (ctx->superblock)
2053 problem = PR_0_JOURNAL_RUN_DEFAULT;
2055 problem = PR_0_JOURNAL_RUN;
2056 if (fix_problem(ctx, problem, &pctx)) {
2057 ctx->options |= E2F_OPT_FORCE;
2058 sb->s_feature_incompat |=
2059 EXT3_FEATURE_INCOMPAT_RECOVER;
2060 ext2fs_mark_super_dirty(ctx->fs);
2061 } else if (fix_problem(ctx,
2062 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2064 sb->s_state &= ~EXT2_VALID_FS;
2065 ext2fs_mark_super_dirty(ctx->fs);
2068 * If the user answers no to the above question, we
2069 * ignore the fact that journal apparently has data;
2070 * accidentally replaying over valid data would be far
2071 * worse than skipping a questionable recovery.
2073 * XXX should we abort with a fatal error here? What
2074 * will the ext3 kernel code do if a filesystem with
2075 * !NEEDS_RECOVERY but with a non-zero
2076 * journal->j_superblock->s_start is mounted?
2080 e2fsck_journal_release(ctx, journal, reset, 0);
2084 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2089 journal_init_revoke_caches();
2090 retval = e2fsck_get_journal(ctx, &journal);
2094 retval = e2fsck_journal_load(journal);
2098 retval = journal_init_revoke(journal, 1024);
2102 retval = -journal_recover(journal);
2106 if (journal->j_superblock->s_errno) {
2107 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2108 ext2fs_mark_super_dirty(ctx->fs);
2109 journal->j_superblock->s_errno = 0;
2110 mark_buffer_dirty(journal->j_sb_buffer);
2114 journal_destroy_revoke(journal);
2115 journal_destroy_revoke_caches();
2116 e2fsck_journal_release(ctx, journal, 1, 0);
2120 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2122 io_manager io_ptr = ctx->fs->io->manager;
2123 int blocksize = ctx->fs->blocksize;
2124 errcode_t retval, recover_retval;
2126 printf(_("%s: recovering journal\n"), ctx->device_name);
2127 if (ctx->options & E2F_OPT_READONLY) {
2128 printf(_("%s: won't do journal recovery while read-only\n"),
2130 return EXT2_ET_FILE_RO;
2133 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2134 ext2fs_flush(ctx->fs); /* Force out any modifications */
2136 recover_retval = recover_ext3_journal(ctx);
2139 * Reload the filesystem context to get up-to-date data from disk
2140 * because journal recovery will change the filesystem under us.
2142 ext2fs_close(ctx->fs);
2143 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2144 ctx->superblock, blocksize, io_ptr,
2148 bb_error_msg(_("while trying to re-open %s"),
2150 bb_error_msg_and_die(0);
2152 ctx->fs->priv_data = ctx;
2154 /* Set the superblock flags */
2155 e2fsck_clear_recover(ctx, recover_retval);
2156 return recover_retval;
2160 * This function will move the journal inode from a visible file in
2161 * the filesystem directory hierarchy to the reserved inode if necessary.
2163 static const char *const journal_names[] = {
2164 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2166 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2168 struct ext2_super_block *sb = ctx->fs->super;
2169 struct problem_context pctx;
2170 struct ext2_inode inode;
2171 ext2_filsys fs = ctx->fs;
2174 const char *const * cpp;
2175 int group, mount_flags;
2177 clear_problem_context(&pctx);
2180 * If the filesystem is opened read-only, or there is no
2181 * journal, then do nothing.
2183 if ((ctx->options & E2F_OPT_READONLY) ||
2184 (sb->s_journal_inum == 0) ||
2185 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2189 * Read in the journal inode
2191 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2195 * If it's necessary to backup the journal inode, do so.
2197 if ((sb->s_jnl_backup_type == 0) ||
2198 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2199 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2200 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2201 memcpy(sb->s_jnl_blocks, inode.i_block,
2203 sb->s_jnl_blocks[16] = inode.i_size;
2204 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2205 ext2fs_mark_super_dirty(fs);
2206 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2211 * If the journal is already the hidden inode, then do nothing
2213 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2217 * The journal inode had better have only one link and not be readable.
2219 if (inode.i_links_count != 1)
2223 * If the filesystem is mounted, or we can't tell whether
2224 * or not it's mounted, do nothing.
2226 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2227 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2231 * If we can't find the name of the journal inode, then do
2234 for (cpp = journal_names; *cpp; cpp++) {
2235 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2236 strlen(*cpp), 0, &ino);
2237 if ((retval == 0) && (ino == sb->s_journal_inum))
2243 /* We need the inode bitmap to be loaded */
2244 retval = ext2fs_read_bitmaps(fs);
2249 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2253 * OK, we've done all the checks, let's actually move the
2254 * journal inode. Errors at this point mean we need to force
2255 * an ext2 filesystem check.
2257 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2259 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2261 sb->s_journal_inum = EXT2_JOURNAL_INO;
2262 ext2fs_mark_super_dirty(fs);
2263 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2264 inode.i_links_count = 0;
2265 inode.i_dtime = time(NULL);
2266 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2269 group = ext2fs_group_of_ino(fs, ino);
2270 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2271 ext2fs_mark_ib_dirty(fs);
2272 fs->group_desc[group].bg_free_inodes_count++;
2273 fs->super->s_free_inodes_count++;
2277 pctx.errcode = retval;
2278 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2279 fs->super->s_state &= ~EXT2_VALID_FS;
2280 ext2fs_mark_super_dirty(fs);
2284 * message.c --- print e2fsck messages (with compression)
2286 * print_e2fsck_message() prints a message to the user, using
2287 * compression techniques and expansions of abbreviations.
2289 * The following % expansions are supported:
2291 * %b <blk> block number
2292 * %B <blkcount> integer
2293 * %c <blk2> block number
2294 * %Di <dirent>->ino inode number
2295 * %Dn <dirent>->name string
2296 * %Dr <dirent>->rec_len
2297 * %Dl <dirent>->name_len
2298 * %Dt <dirent>->filetype
2299 * %d <dir> inode number
2300 * %g <group> integer
2301 * %i <ino> inode number
2302 * %Is <inode> -> i_size
2303 * %IS <inode> -> i_extra_isize
2304 * %Ib <inode> -> i_blocks
2305 * %Il <inode> -> i_links_count
2306 * %Im <inode> -> i_mode
2307 * %IM <inode> -> i_mtime
2308 * %IF <inode> -> i_faddr
2309 * %If <inode> -> i_file_acl
2310 * %Id <inode> -> i_dir_acl
2311 * %Iu <inode> -> i_uid
2312 * %Ig <inode> -> i_gid
2313 * %j <ino2> inode number
2314 * %m <com_err error message>
2316 * %p ext2fs_get_pathname of directory <ino>
2317 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2318 * the containing directory. (If dirent is NULL
2319 * then return the pathname of directory <ino2>)
2320 * %q ext2fs_get_pathname of directory <dir>
2321 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2322 * the containing directory.
2323 * %s <str> miscellaneous string
2324 * %S backup superblock
2325 * %X <num> hexadecimal format
2327 * The following '@' expansions are supported:
2329 * @a extended attribute
2330 * @A error allocating
2334 * @C conflicts with some other fs block
2338 * @E Entry '%Dn' in %p (%i)
2340 * @F for @i %i (%Q) is
2342 * @h HTREE directory inode
2348 * @m multiply-claimed
2362 * This structure defines the abbreviations used by the text strings
2363 * below. The first character in the string is the index letter. An
2364 * abbreviation of the form '@<i>' is expanded by looking up the index
2365 * letter <i> in the table below.
2367 static const char *const abbrevs[] = {
2368 N_("aextended attribute"),
2369 N_("Aerror allocating"),
2373 N_("Cconflicts with some other fs @b"),
2380 N_("E@e '%Dn' in %p (%i)"),
2382 N_("Ffor @i %i (%Q) is"),
2387 N_("mmultiply-claimed"),
2402 * Give more user friendly names to the "special" inodes.
2404 #define num_special_inodes 11
2405 static const char *const special_inode_name[] =
2407 N_("<The NULL inode>"), /* 0 */
2408 N_("<The bad blocks inode>"), /* 1 */
2410 N_("<The ACL index inode>"), /* 3 */
2411 N_("<The ACL data inode>"), /* 4 */
2412 N_("<The boot loader inode>"), /* 5 */
2413 N_("<The undelete directory inode>"), /* 6 */
2414 N_("<The group descriptor inode>"), /* 7 */
2415 N_("<The journal inode>"), /* 8 */
2416 N_("<Reserved inode 9>"), /* 9 */
2417 N_("<Reserved inode 10>"), /* 10 */
2421 * This function does "safe" printing. It will convert non-printable
2422 * ASCII characters using '^' and M- notation.
2424 static void safe_print(const char *cp, int len)
2434 fputs("M-", stdout);
2437 if ((ch < 32) || (ch == 0x7f)) {
2439 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2447 * This function prints a pathname, using the ext2fs_get_pathname
2450 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2455 if (!dir && (ino < num_special_inodes)) {
2456 fputs(_(special_inode_name[ino]), stdout);
2460 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2462 fputs("???", stdout);
2464 safe_print(path, -1);
2465 ext2fs_free_mem(&path);
2469 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2470 struct problem_context *pctx, int first);
2472 * This function handles the '@' expansion. We allow recursive
2473 * expansion; an @ expression can contain further '@' and '%'
2476 static void expand_at_expression(e2fsck_t ctx, char ch,
2477 struct problem_context *pctx,
2480 const char *const *cpp;
2483 /* Search for the abbreviation */
2484 for (cpp = abbrevs; *cpp; cpp++) {
2490 if (*first && islower(*str)) {
2492 bb_putchar(toupper(*str++));
2494 print_e2fsck_message(ctx, str, pctx, *first);
2500 * This function expands '%IX' expressions
2502 static void expand_inode_expression(char ch,
2503 struct problem_context *ctx)
2505 struct ext2_inode *inode;
2506 struct ext2_inode_large *large_inode;
2511 if (!ctx || !ctx->inode)
2515 large_inode = (struct ext2_inode_large *) inode;
2519 if (LINUX_S_ISDIR(inode->i_mode))
2520 printf("%u", inode->i_size);
2522 printf("%"PRIu64, (inode->i_size |
2523 ((uint64_t) inode->i_size_high << 32)));
2527 printf("%u", large_inode->i_extra_isize);
2530 printf("%u", inode->i_blocks);
2533 printf("%d", inode->i_links_count);
2536 printf("0%o", inode->i_mode);
2539 /* The diet libc doesn't respect the TZ environemnt variable */
2541 time_str = getenv("TZ");
2544 do_gmt = !strcmp(time_str, "GMT");
2547 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2548 printf("%.24s", time_str);
2551 printf("%u", inode->i_faddr);
2554 printf("%u", inode->i_file_acl);
2557 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2558 inode->i_dir_acl : 0));
2561 printf("%d", (inode->i_uid |
2562 (inode->osd2.linux2.l_i_uid_high << 16)));
2565 printf("%d", (inode->i_gid |
2566 (inode->osd2.linux2.l_i_gid_high << 16)));
2570 printf("%%I%c", ch);
2576 * This function expands '%dX' expressions
2578 static void expand_dirent_expression(char ch,
2579 struct problem_context *ctx)
2581 struct ext2_dir_entry *dirent;
2584 if (!ctx || !ctx->dirent)
2587 dirent = ctx->dirent;
2591 printf("%u", dirent->inode);
2594 len = dirent->name_len & 0xFF;
2595 if (len > EXT2_NAME_LEN)
2596 len = EXT2_NAME_LEN;
2597 if (len > dirent->rec_len)
2598 len = dirent->rec_len;
2599 safe_print(dirent->name, len);
2602 printf("%u", dirent->rec_len);
2605 printf("%u", dirent->name_len & 0xFF);
2608 printf("%u", dirent->name_len >> 8);
2612 printf("%%D%c", ch);
2617 static void expand_percent_expression(ext2_filsys fs, char ch,
2618 struct problem_context *ctx)
2628 printf("%u", ctx->blk);
2631 printf("%"PRIi64, ctx->blkcount);
2634 printf("%u", ctx->blk2);
2637 printf("%u", ctx->dir);
2640 printf("%d", ctx->group);
2643 printf("%u", ctx->ino);
2646 printf("%u", ctx->ino2);
2649 fputs(error_message(ctx->errcode), stdout);
2652 printf("%"PRIi64, ctx->num);
2655 print_pathname(fs, ctx->ino, 0);
2658 print_pathname(fs, ctx->ino2,
2659 ctx->dirent ? ctx->dirent->inode : 0);
2662 print_pathname(fs, ctx->dir, 0);
2665 print_pathname(fs, ctx->dir, ctx->ino);
2668 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2671 fputs((ctx->str ? ctx->str : "NULL"), stdout);
2674 printf("0x%"PRIi64, ctx->num);
2684 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2685 struct problem_context *pctx, int first)
2687 ext2_filsys fs = ctx->fs;
2691 e2fsck_clear_progbar(ctx);
2692 for (cp = msg; *cp; cp++) {
2695 expand_at_expression(ctx, *cp, pctx, &first);
2696 } else if (cp[0] == '%' && cp[1] == 'I') {
2698 expand_inode_expression(*cp, pctx);
2699 } else if (cp[0] == '%' && cp[1] == 'D') {
2701 expand_dirent_expression(*cp, pctx);
2702 } else if ((cp[0] == '%')) {
2704 expand_percent_expression(fs, *cp, pctx);
2706 for (i=0; cp[i]; i++)
2707 if ((cp[i] == '@') || cp[i] == '%')
2709 printf("%.*s", i, cp);
2718 * region.c --- code which manages allocations within a region.
2722 region_addr_t start;
2724 struct region_el *next;
2727 struct region_struct {
2730 struct region_el *allocated;
2733 static region_t region_create(region_addr_t min, region_addr_t max)
2737 region = xzalloc(sizeof(struct region_struct));
2743 static void region_free(region_t region)
2745 struct region_el *r, *next;
2747 for (r = region->allocated; r; r = next) {
2751 memset(region, 0, sizeof(struct region_struct));
2755 static int region_allocate(region_t region, region_addr_t start, int n)
2757 struct region_el *r, *new_region, *prev, *next;
2761 if ((start < region->min) || (end > region->max))
2767 * Search through the linked list. If we find that it
2768 * conflicts witih something that's already allocated, return
2769 * 1; if we can find an existing region which we can grow, do
2770 * so. Otherwise, stop when we find the appropriate place
2771 * insert a new region element into the linked list.
2773 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2774 if (((start >= r->start) && (start < r->end)) ||
2775 ((end > r->start) && (end <= r->end)) ||
2776 ((start <= r->start) && (end >= r->end)))
2778 if (end == r->start) {
2782 if (start == r->end) {
2783 if ((next = r->next)) {
2784 if (end > next->start)
2786 if (end == next->start) {
2788 r->next = next->next;
2796 if (start < r->start)
2800 * Insert a new region element structure into the linked list
2802 new_region = xmalloc(sizeof(struct region_el));
2803 new_region->start = start;
2804 new_region->end = start + n;
2805 new_region->next = r;
2807 prev->next = new_region;
2809 region->allocated = new_region;
2814 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2816 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2817 * and applies the following tests to each inode:
2819 * - The mode field of the inode must be legal.
2820 * - The size and block count fields of the inode are correct.
2821 * - A data block must not be used by another inode
2823 * Pass 1 also gathers the collects the following information:
2825 * - A bitmap of which inodes are in use. (inode_used_map)
2826 * - A bitmap of which inodes are directories. (inode_dir_map)
2827 * - A bitmap of which inodes are regular files. (inode_reg_map)
2828 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2829 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2830 * - A bitmap of which blocks are in use. (block_found_map)
2831 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2832 * - The data blocks of the directory inodes. (dir_map)
2834 * Pass 1 is designed to stash away enough information so that the
2835 * other passes should not need to read in the inode information
2836 * during the normal course of a filesystem check. (Althogh if an
2837 * inconsistency is detected, other passes may need to read in an
2840 * Note that pass 1B will be invoked if there are any duplicate blocks
2845 static int process_block(ext2_filsys fs, blk_t *blocknr,
2846 e2_blkcnt_t blockcnt, blk_t ref_blk,
2847 int ref_offset, void *priv_data);
2848 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2849 e2_blkcnt_t blockcnt, blk_t ref_blk,
2850 int ref_offset, void *priv_data);
2851 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2853 static void mark_table_blocks(e2fsck_t ctx);
2854 static void alloc_imagic_map(e2fsck_t ctx);
2855 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2856 static void handle_fs_bad_blocks(e2fsck_t ctx);
2857 static void process_inodes(e2fsck_t ctx, char *block_buf);
2858 static int process_inode_cmp(const void *a, const void *b);
2859 static errcode_t scan_callback(ext2_filsys fs,
2860 dgrp_t group, void * priv_data);
2861 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2862 char *block_buf, int adjust_sign);
2863 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2865 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2866 struct ext2_inode * inode, int bufsize,
2869 struct process_block_struct_1 {
2871 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
2872 fragmented:1, compressed:1, bbcheck:1;
2875 e2_blkcnt_t last_block;
2876 int num_illegal_blocks;
2877 blk_t previous_block;
2878 struct ext2_inode *inode;
2879 struct problem_context *pctx;
2880 ext2fs_block_bitmap fs_meta_blocks;
2884 struct process_inode_block {
2886 struct ext2_inode inode;
2889 struct scan_callback_struct {
2895 * For the inodes to process list.
2897 static struct process_inode_block *inodes_to_process;
2898 static int process_inode_count;
2900 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2901 EXT2_MIN_BLOCK_LOG_SIZE + 1];
2904 * Free all memory allocated by pass1 in preparation for restarting
2907 static void unwind_pass1(void)
2909 ext2fs_free_mem(&inodes_to_process);
2913 * Check to make sure a device inode is real. Returns 1 if the device
2914 * checks out, 0 if not.
2916 * Note: this routine is now also used to check FIFO's and Sockets,
2917 * since they have the same requirement; the i_block fields should be
2921 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2926 * If i_blocks is non-zero, or the index flag is set, then
2927 * this is a bogus device/fifo/socket
2929 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2930 (inode->i_flags & EXT2_INDEX_FL))
2934 * We should be able to do the test below all the time, but
2935 * because the kernel doesn't forcibly clear the device
2936 * inode's additional i_block fields, there are some rare
2937 * occasions when a legitimate device inode will have non-zero
2938 * additional i_block fields. So for now, we only complain
2939 * when the immutable flag is set, which should never happen
2940 * for devices. (And that's when the problem is caused, since
2941 * you can't set or clear immutable flags for devices.) Once
2942 * the kernel has been fixed we can change this...
2944 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2945 for (i=4; i < EXT2_N_BLOCKS; i++)
2946 if (inode->i_block[i])
2953 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2954 * checks out, 0 if not.
2957 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
2963 if ((inode->i_size_high || inode->i_size == 0) ||
2964 (inode->i_flags & EXT2_INDEX_FL))
2967 blocks = ext2fs_inode_data_blocks(fs, inode);
2969 if ((inode->i_size >= fs->blocksize) ||
2970 (blocks != fs->blocksize >> 9) ||
2971 (inode->i_block[0] < fs->super->s_first_data_block) ||
2972 (inode->i_block[0] >= fs->super->s_blocks_count))
2975 for (i = 1; i < EXT2_N_BLOCKS; i++)
2976 if (inode->i_block[i])
2979 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
2982 len = strnlen(buf, fs->blocksize);
2983 if (len == fs->blocksize)
2986 if (inode->i_size >= sizeof(inode->i_block))
2989 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
2990 if (len == sizeof(inode->i_block))
2993 if (len != inode->i_size)
2999 * If the immutable (or append-only) flag is set on the inode, offer
3002 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3003 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3005 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3008 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3011 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3012 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3016 * If device, fifo or socket, check size is zero -- if not offer to
3019 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3021 struct ext2_inode *inode = pctx->inode;
3023 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3026 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3030 inode->i_size_high = 0;
3031 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3034 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3036 struct ext2_super_block *sb = ctx->fs->super;
3037 struct ext2_inode_large *inode;
3038 struct ext2_ext_attr_entry *entry;
3040 int storage_size, remain, offs;
3043 inode = (struct ext2_inode_large *) pctx->inode;
3044 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3045 inode->i_extra_isize;
3046 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3047 inode->i_extra_isize + sizeof(__u32);
3048 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3049 entry = (struct ext2_ext_attr_entry *) start;
3051 /* scan all entry's headers first */
3053 /* take finish entry 0UL into account */
3054 remain = storage_size - sizeof(__u32);
3057 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3059 /* header eats this space */
3060 remain -= sizeof(struct ext2_ext_attr_entry);
3062 /* is attribute name valid? */
3063 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3064 pctx->num = entry->e_name_len;
3065 problem = PR_1_ATTR_NAME_LEN;
3069 /* attribute len eats this space */
3070 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3072 /* check value size */
3073 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3074 pctx->num = entry->e_value_size;
3075 problem = PR_1_ATTR_VALUE_SIZE;
3079 /* check value placement */
3080 if (entry->e_value_offs +
3081 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3082 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3083 pctx->num = entry->e_value_offs;
3084 problem = PR_1_ATTR_VALUE_OFFSET;
3088 /* e_value_block must be 0 in inode's ea */
3089 if (entry->e_value_block != 0) {
3090 pctx->num = entry->e_value_block;
3091 problem = PR_1_ATTR_VALUE_BLOCK;
3095 /* e_hash must be 0 in inode's ea */
3096 if (entry->e_hash != 0) {
3097 pctx->num = entry->e_hash;
3098 problem = PR_1_ATTR_HASH;
3102 remain -= entry->e_value_size;
3103 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3105 entry = EXT2_EXT_ATTR_NEXT(entry);
3109 * it seems like a corruption. it's very unlikely we could repair
3110 * EA(s) in automatic fashion -bzzz
3112 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3115 /* simple remove all possible EA(s) */
3116 *((__u32 *)start) = 0UL;
3117 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3118 EXT2_INODE_SIZE(sb), "pass1");
3121 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3123 struct ext2_super_block *sb = ctx->fs->super;
3124 struct ext2_inode_large *inode;
3128 inode = (struct ext2_inode_large *) pctx->inode;
3129 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3130 /* this isn't large inode. so, nothing to check */
3134 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3135 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3136 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3138 * For now we will allow i_extra_isize to be 0, but really
3139 * implementations should never allow i_extra_isize to be 0
3141 if (inode->i_extra_isize &&
3142 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3143 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3145 inode->i_extra_isize = min;
3146 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3147 EXT2_INODE_SIZE(sb), "pass1");
3151 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3152 inode->i_extra_isize);
3153 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3154 /* it seems inode has an extended attribute(s) in body */
3155 check_ea_in_inode(ctx, pctx);
3159 static void e2fsck_pass1(e2fsck_t ctx)
3163 ext2_filsys fs = ctx->fs;
3165 struct ext2_inode *inode;
3166 ext2_inode_scan scan;
3168 unsigned char frag, fsize;
3169 struct problem_context pctx;
3170 struct scan_callback_struct scan_struct;
3171 struct ext2_super_block *sb = ctx->fs->super;
3173 int busted_fs_time = 0;
3176 clear_problem_context(&pctx);
3178 if (!(ctx->options & E2F_OPT_PREEN))
3179 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3181 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3182 !(ctx->options & E2F_OPT_NO)) {
3183 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3184 ctx->dirs_to_hash = 0;
3189 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3191 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3192 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3193 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3194 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3195 max_sizes = (max_sizes * (1UL << i)) - 1;
3196 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3200 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3203 * Allocate bitmaps structures
3205 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3206 &ctx->inode_used_map);
3209 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3210 ctx->flags |= E2F_FLAG_ABORT;
3213 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3214 _("directory inode map"), &ctx->inode_dir_map);
3217 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3218 ctx->flags |= E2F_FLAG_ABORT;
3221 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3222 _("regular file inode map"), &ctx->inode_reg_map);
3225 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3226 ctx->flags |= E2F_FLAG_ABORT;
3229 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3230 &ctx->block_found_map);
3233 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3234 ctx->flags |= E2F_FLAG_ABORT;
3237 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3238 &ctx->inode_link_info);
3240 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3241 ctx->flags |= E2F_FLAG_ABORT;
3244 inode_size = EXT2_INODE_SIZE(fs->super);
3245 inode = (struct ext2_inode *)
3246 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3248 inodes_to_process = (struct process_inode_block *)
3249 e2fsck_allocate_memory(ctx,
3250 (ctx->process_inode_size *
3251 sizeof(struct process_inode_block)),
3252 "array of inodes to process");
3253 process_inode_count = 0;
3255 pctx.errcode = ext2fs_init_dblist(fs, 0);
3257 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3258 ctx->flags |= E2F_FLAG_ABORT;
3263 * If the last orphan field is set, clear it, since the pass1
3264 * processing will automatically find and clear the orphans.
3265 * In the future, we may want to try using the last_orphan
3266 * linked list ourselves, but for now, we clear it so that the
3267 * ext3 mount code won't get confused.
3269 if (!(ctx->options & E2F_OPT_READONLY)) {
3270 if (fs->super->s_last_orphan) {
3271 fs->super->s_last_orphan = 0;
3272 ext2fs_mark_super_dirty(fs);
3276 mark_table_blocks(ctx);
3277 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3278 "block interate buffer");
3279 e2fsck_use_inode_shortcuts(ctx, 1);
3280 ehandler_operation(_("doing inode scan"));
3281 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3284 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3285 ctx->flags |= E2F_FLAG_ABORT;
3288 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3289 ctx->stashed_inode = inode;
3290 scan_struct.ctx = ctx;
3291 scan_struct.block_buf = block_buf;
3292 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3294 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3296 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3297 (fs->super->s_mtime < fs->super->s_inodes_count))
3301 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3303 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3305 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3309 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3310 ctx->flags |= E2F_FLAG_ABORT;
3317 ctx->stashed_ino = ino;
3318 if (inode->i_links_count) {
3319 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3320 ino, inode->i_links_count);
3322 pctx.num = inode->i_links_count;
3323 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3324 ctx->flags |= E2F_FLAG_ABORT;
3328 if (ino == EXT2_BAD_INO) {
3329 struct process_block_struct_1 pb;
3331 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3332 &pb.fs_meta_blocks);
3335 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3336 ctx->flags |= E2F_FLAG_ABORT;
3339 pb.ino = EXT2_BAD_INO;
3340 pb.num_blocks = pb.last_block = 0;
3341 pb.num_illegal_blocks = 0;
3342 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3343 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3347 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3348 block_buf, process_bad_block, &pb);
3349 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3351 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3352 ctx->flags |= E2F_FLAG_ABORT;
3356 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3357 ctx->flags |= E2F_FLAG_ABORT;
3360 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3361 clear_problem_context(&pctx);
3363 } else if (ino == EXT2_ROOT_INO) {
3365 * Make sure the root inode is a directory; if
3366 * not, offer to clear it. It will be
3367 * regnerated in pass #3.
3369 if (!LINUX_S_ISDIR(inode->i_mode)) {
3370 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3371 inode->i_dtime = time(NULL);
3372 inode->i_links_count = 0;
3373 ext2fs_icount_store(ctx->inode_link_info,
3375 e2fsck_write_inode(ctx, ino, inode,
3381 * If dtime is set, offer to clear it. mke2fs
3382 * version 0.2b created filesystems with the
3383 * dtime field set for the root and lost+found
3384 * directories. We won't worry about
3385 * /lost+found, since that can be regenerated
3386 * easily. But we will fix the root directory
3387 * as a special case.
3389 if (inode->i_dtime && inode->i_links_count) {
3390 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3392 e2fsck_write_inode(ctx, ino, inode,
3396 } else if (ino == EXT2_JOURNAL_INO) {
3397 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3398 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3399 if (!LINUX_S_ISREG(inode->i_mode) &&
3400 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3402 inode->i_mode = LINUX_S_IFREG;
3403 e2fsck_write_inode(ctx, ino, inode,
3406 check_blocks(ctx, &pctx, block_buf);
3409 if ((inode->i_links_count || inode->i_blocks ||
3410 inode->i_blocks || inode->i_block[0]) &&
3411 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3413 memset(inode, 0, inode_size);
3414 ext2fs_icount_store(ctx->inode_link_info,
3416 e2fsck_write_inode_full(ctx, ino, inode,
3417 inode_size, "pass1");
3419 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3422 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3423 if (ino == EXT2_BOOT_LOADER_INO) {
3424 if (LINUX_S_ISDIR(inode->i_mode))
3425 problem = PR_1_RESERVED_BAD_MODE;
3426 } else if (ino == EXT2_RESIZE_INO) {
3427 if (inode->i_mode &&
3428 !LINUX_S_ISREG(inode->i_mode))
3429 problem = PR_1_RESERVED_BAD_MODE;
3431 if (inode->i_mode != 0)
3432 problem = PR_1_RESERVED_BAD_MODE;
3435 if (fix_problem(ctx, problem, &pctx)) {
3437 e2fsck_write_inode(ctx, ino, inode,
3441 check_blocks(ctx, &pctx, block_buf);
3445 * Check for inodes who might have been part of the
3446 * orphaned list linked list. They should have gotten
3447 * dealt with by now, unless the list had somehow been
3450 * FIXME: In the future, inodes which are still in use
3451 * (and which are therefore) pending truncation should
3452 * be handled specially. Right now we just clear the
3453 * dtime field, and the normal e2fsck handling of
3454 * inodes where i_size and the inode blocks are
3455 * inconsistent is to fix i_size, instead of releasing
3456 * the extra blocks. This won't catch the inodes that
3457 * was at the end of the orphan list, but it's better
3458 * than nothing. The right answer is that there
3459 * shouldn't be any bugs in the orphan list handling. :-)
3461 if (inode->i_dtime && !busted_fs_time &&
3462 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3463 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3464 inode->i_dtime = inode->i_links_count ?
3466 e2fsck_write_inode(ctx, ino, inode,
3472 * This code assumes that deleted inodes have
3473 * i_links_count set to 0.
3475 if (!inode->i_links_count) {
3476 if (!inode->i_dtime && inode->i_mode) {
3477 if (fix_problem(ctx,
3478 PR_1_ZERO_DTIME, &pctx)) {
3479 inode->i_dtime = time(NULL);
3480 e2fsck_write_inode(ctx, ino, inode,
3487 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3488 * deleted files. Oops.
3490 * Since all new ext2 implementations get this right,
3491 * we now assume that the case of non-zero
3492 * i_links_count and non-zero dtime means that we
3493 * should keep the file, not delete it.
3496 if (inode->i_dtime) {
3497 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3499 e2fsck_write_inode(ctx, ino, inode, "pass1");
3503 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3504 switch (fs->super->s_creator_os) {
3506 frag = inode->osd2.linux2.l_i_frag;
3507 fsize = inode->osd2.linux2.l_i_fsize;
3510 frag = inode->osd2.hurd2.h_i_frag;
3511 fsize = inode->osd2.hurd2.h_i_fsize;
3514 frag = inode->osd2.masix2.m_i_frag;
3515 fsize = inode->osd2.masix2.m_i_fsize;
3521 if (inode->i_faddr || frag || fsize ||
3522 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3523 mark_inode_bad(ctx, ino);
3524 if (inode->i_flags & EXT2_IMAGIC_FL) {
3526 if (!ctx->inode_imagic_map)
3527 alloc_imagic_map(ctx);
3528 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3531 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3532 inode->i_flags &= ~EXT2_IMAGIC_FL;
3533 e2fsck_write_inode(ctx, ino,
3539 check_inode_extra_space(ctx, &pctx);
3541 if (LINUX_S_ISDIR(inode->i_mode)) {
3542 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3543 e2fsck_add_dir_info(ctx, ino, 0);
3544 ctx->fs_directory_count++;
3545 } else if (LINUX_S_ISREG (inode->i_mode)) {
3546 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3547 ctx->fs_regular_count++;
3548 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3549 e2fsck_pass1_check_device_inode(fs, inode)) {
3550 check_immutable(ctx, &pctx);
3551 check_size(ctx, &pctx);
3552 ctx->fs_chardev_count++;
3553 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3554 e2fsck_pass1_check_device_inode(fs, inode)) {
3555 check_immutable(ctx, &pctx);
3556 check_size(ctx, &pctx);
3557 ctx->fs_blockdev_count++;
3558 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3559 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3560 check_immutable(ctx, &pctx);
3561 ctx->fs_symlinks_count++;
3562 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3563 ctx->fs_fast_symlinks_count++;
3564 check_blocks(ctx, &pctx, block_buf);
3568 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3569 e2fsck_pass1_check_device_inode(fs, inode)) {
3570 check_immutable(ctx, &pctx);
3571 check_size(ctx, &pctx);
3572 ctx->fs_fifo_count++;
3573 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3574 e2fsck_pass1_check_device_inode(fs, inode)) {
3575 check_immutable(ctx, &pctx);
3576 check_size(ctx, &pctx);
3577 ctx->fs_sockets_count++;
3579 mark_inode_bad(ctx, ino);
3580 if (inode->i_block[EXT2_IND_BLOCK])
3581 ctx->fs_ind_count++;
3582 if (inode->i_block[EXT2_DIND_BLOCK])
3583 ctx->fs_dind_count++;
3584 if (inode->i_block[EXT2_TIND_BLOCK])
3585 ctx->fs_tind_count++;
3586 if (inode->i_block[EXT2_IND_BLOCK] ||
3587 inode->i_block[EXT2_DIND_BLOCK] ||
3588 inode->i_block[EXT2_TIND_BLOCK] ||
3589 inode->i_file_acl) {
3590 inodes_to_process[process_inode_count].ino = ino;
3591 inodes_to_process[process_inode_count].inode = *inode;
3592 process_inode_count++;
3594 check_blocks(ctx, &pctx, block_buf);
3596 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3599 if (process_inode_count >= ctx->process_inode_size) {
3600 process_inodes(ctx, block_buf);
3602 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3606 process_inodes(ctx, block_buf);
3607 ext2fs_close_inode_scan(scan);
3608 ehandler_operation(0);
3611 * If any extended attribute blocks' reference counts need to
3612 * be adjusted, either up (ctx->refcount_extra), or down
3613 * (ctx->refcount), then fix them.
3615 if (ctx->refcount) {
3616 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3617 ea_refcount_free(ctx->refcount);
3620 if (ctx->refcount_extra) {
3621 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3623 ea_refcount_free(ctx->refcount_extra);
3624 ctx->refcount_extra = 0;
3627 if (ctx->invalid_bitmaps)
3628 handle_fs_bad_blocks(ctx);
3630 /* We don't need the block_ea_map any more */
3631 ext2fs_free_block_bitmap(ctx->block_ea_map);
3632 ctx->block_ea_map = 0;
3634 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3635 ext2fs_block_bitmap save_bmap;
3637 save_bmap = fs->block_map;
3638 fs->block_map = ctx->block_found_map;
3639 clear_problem_context(&pctx);
3640 pctx.errcode = ext2fs_create_resize_inode(fs);
3642 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3643 /* Should never get here */
3644 ctx->flags |= E2F_FLAG_ABORT;
3647 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3649 inode->i_mtime = time(NULL);
3650 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3652 fs->block_map = save_bmap;
3653 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3656 if (ctx->flags & E2F_FLAG_RESTART) {
3658 * Only the master copy of the superblock and block
3659 * group descriptors are going to be written during a
3660 * restart, so set the superblock to be used to be the
3661 * master superblock.
3663 ctx->use_superblock = 0;
3668 if (ctx->block_dup_map) {
3669 if (ctx->options & E2F_OPT_PREEN) {
3670 clear_problem_context(&pctx);
3671 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3673 e2fsck_pass1_dupblocks(ctx, block_buf);
3675 ext2fs_free_mem(&inodes_to_process);
3677 e2fsck_use_inode_shortcuts(ctx, 0);
3679 ext2fs_free_mem(&block_buf);
3680 ext2fs_free_mem(&inode);
3685 * When the inode_scan routines call this callback at the end of the
3686 * glock group, call process_inodes.
3688 static errcode_t scan_callback(ext2_filsys fs,
3689 dgrp_t group, void * priv_data)
3691 struct scan_callback_struct *scan_struct;
3694 scan_struct = (struct scan_callback_struct *) priv_data;
3695 ctx = scan_struct->ctx;
3697 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3700 if ((ctx->progress)(ctx, 1, group+1,
3701 ctx->fs->group_desc_count))
3702 return EXT2_ET_CANCEL_REQUESTED;
3708 * Process the inodes in the "inodes to process" list.
3710 static void process_inodes(e2fsck_t ctx, char *block_buf)
3713 struct ext2_inode *old_stashed_inode;
3714 ext2_ino_t old_stashed_ino;
3715 const char *old_operation;
3717 struct problem_context pctx;
3719 /* begin process_inodes */
3720 if (process_inode_count == 0)
3722 old_operation = ehandler_operation(0);
3723 old_stashed_inode = ctx->stashed_inode;
3724 old_stashed_ino = ctx->stashed_ino;
3725 qsort(inodes_to_process, process_inode_count,
3726 sizeof(struct process_inode_block), process_inode_cmp);
3727 clear_problem_context(&pctx);
3728 for (i=0; i < process_inode_count; i++) {
3729 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3730 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3731 sprintf(buf, _("reading indirect blocks of inode %u"),
3733 ehandler_operation(buf);
3734 check_blocks(ctx, &pctx, block_buf);
3735 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3738 ctx->stashed_inode = old_stashed_inode;
3739 ctx->stashed_ino = old_stashed_ino;
3740 process_inode_count = 0;
3741 /* end process inodes */
3743 ehandler_operation(old_operation);
3746 static int process_inode_cmp(const void *a, const void *b)
3748 const struct process_inode_block *ib_a =
3749 (const struct process_inode_block *) a;
3750 const struct process_inode_block *ib_b =
3751 (const struct process_inode_block *) b;
3754 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3755 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3757 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3762 * Mark an inode as being bad in some what
3764 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3766 struct problem_context pctx;
3768 if (!ctx->inode_bad_map) {
3769 clear_problem_context(&pctx);
3771 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3772 _("bad inode map"), &ctx->inode_bad_map);
3775 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3776 /* Should never get here */
3777 ctx->flags |= E2F_FLAG_ABORT;
3781 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3786 * This procedure will allocate the inode imagic table
3788 static void alloc_imagic_map(e2fsck_t ctx)
3790 struct problem_context pctx;
3792 clear_problem_context(&pctx);
3793 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3794 _("imagic inode map"),
3795 &ctx->inode_imagic_map);
3798 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3799 /* Should never get here */
3800 ctx->flags |= E2F_FLAG_ABORT;
3806 * Marks a block as in use, setting the dup_map if it's been set
3807 * already. Called by process_block and process_bad_block.
3809 * WARNING: Assumes checks have already been done to make sure block
3810 * is valid. This is true in both process_block and process_bad_block.
3812 static void mark_block_used(e2fsck_t ctx, blk_t block)
3814 struct problem_context pctx;
3816 clear_problem_context(&pctx);
3818 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3819 if (!ctx->block_dup_map) {
3820 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3821 _("multiply claimed block map"),
3822 &ctx->block_dup_map);
3825 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3827 /* Should never get here */
3828 ctx->flags |= E2F_FLAG_ABORT;
3832 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3834 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3839 * Adjust the extended attribute block's reference counts at the end
3840 * of pass 1, either by subtracting out references for EA blocks that
3841 * are still referenced in ctx->refcount, or by adding references for
3842 * EA blocks that had extra references as accounted for in
3843 * ctx->refcount_extra.
3845 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3846 char *block_buf, int adjust_sign)
3848 struct ext2_ext_attr_header *header;
3849 struct problem_context pctx;
3850 ext2_filsys fs = ctx->fs;
3855 clear_problem_context(&pctx);
3857 ea_refcount_intr_begin(refcount);
3859 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3862 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3864 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3867 header = (struct ext2_ext_attr_header *) block_buf;
3868 pctx.blkcount = header->h_refcount;
3869 should_be = header->h_refcount + adjust_sign * count;
3870 pctx.num = should_be;
3871 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3872 header->h_refcount = should_be;
3873 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3876 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3884 * Handle processing the extended attribute blocks
3886 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3889 ext2_filsys fs = ctx->fs;
3890 ext2_ino_t ino = pctx->ino;
3891 struct ext2_inode *inode = pctx->inode;
3894 struct ext2_ext_attr_header *header;
3895 struct ext2_ext_attr_entry *entry;
3899 blk = inode->i_file_acl;
3904 * If the Extended attribute flag isn't set, then a non-zero
3905 * file acl means that the inode is corrupted.
3907 * Or if the extended attribute block is an invalid block,
3908 * then the inode is also corrupted.
3910 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3911 (blk < fs->super->s_first_data_block) ||
3912 (blk >= fs->super->s_blocks_count)) {
3913 mark_inode_bad(ctx, ino);
3917 /* If ea bitmap hasn't been allocated, create it */
3918 if (!ctx->block_ea_map) {
3919 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3920 _("ext attr block map"),
3921 &ctx->block_ea_map);
3922 if (pctx->errcode) {
3924 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3925 ctx->flags |= E2F_FLAG_ABORT;
3930 /* Create the EA refcount structure if necessary */
3931 if (!ctx->refcount) {
3932 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3933 if (pctx->errcode) {
3935 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3936 ctx->flags |= E2F_FLAG_ABORT;
3941 /* Have we seen this EA block before? */
3942 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3943 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3945 /* Ooops, this EA was referenced more than it stated */
3946 if (!ctx->refcount_extra) {
3947 pctx->errcode = ea_refcount_create(0,
3948 &ctx->refcount_extra);
3949 if (pctx->errcode) {
3951 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3952 ctx->flags |= E2F_FLAG_ABORT;
3956 ea_refcount_increment(ctx->refcount_extra, blk, 0);
3961 * OK, we haven't seen this EA block yet. So we need to
3965 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3966 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
3968 header = (struct ext2_ext_attr_header *) block_buf;
3969 pctx->blk = inode->i_file_acl;
3970 if (((ctx->ext_attr_ver == 1) &&
3971 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
3972 ((ctx->ext_attr_ver == 2) &&
3973 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
3974 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
3978 if (header->h_blocks != 1) {
3979 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
3983 region = region_create(0, fs->blocksize);
3985 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
3986 ctx->flags |= E2F_FLAG_ABORT;
3989 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
3990 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
3994 entry = (struct ext2_ext_attr_entry *)(header+1);
3995 end = block_buf + fs->blocksize;
3996 while ((char *)entry < end && *(__u32 *)entry) {
3997 if (region_allocate(region, (char *)entry - (char *)header,
3998 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
3999 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4002 if ((ctx->ext_attr_ver == 1 &&
4003 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4004 (ctx->ext_attr_ver == 2 &&
4005 entry->e_name_index == 0)) {
4006 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4009 if (entry->e_value_block != 0) {
4010 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4013 if (entry->e_value_size &&
4014 region_allocate(region, entry->e_value_offs,
4015 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4016 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4019 entry = EXT2_EXT_ATTR_NEXT(entry);
4021 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4022 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4025 region_free(region);
4027 count = header->h_refcount - 1;
4029 ea_refcount_store(ctx->refcount, blk, count);
4030 mark_block_used(ctx, blk);
4031 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4036 inode->i_file_acl = 0;
4037 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4041 /* Returns 1 if bad htree, 0 if OK */
4042 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4043 ext2_ino_t ino FSCK_ATTR((unused)),
4044 struct ext2_inode *inode,
4047 struct ext2_dx_root_info *root;
4048 ext2_filsys fs = ctx->fs;
4052 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4053 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4054 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4055 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4058 blk = inode->i_block[0];
4060 (blk < fs->super->s_first_data_block) ||
4061 (blk >= fs->super->s_blocks_count)) &&
4062 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4065 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4066 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4069 /* XXX should check that beginning matches a directory */
4070 root = (struct ext2_dx_root_info *) (block_buf + 24);
4072 if ((root->reserved_zero || root->info_length < 8) &&
4073 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4076 pctx->num = root->hash_version;
4077 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4078 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4079 (root->hash_version != EXT2_HASH_TEA) &&
4080 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4083 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4084 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4087 pctx->num = root->indirect_levels;
4088 if ((root->indirect_levels > 1) &&
4089 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4096 * This subroutine is called on each inode to account for all of the
4097 * blocks used by that inode.
4099 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4102 ext2_filsys fs = ctx->fs;
4103 struct process_block_struct_1 pb;
4104 ext2_ino_t ino = pctx->ino;
4105 struct ext2_inode *inode = pctx->inode;
4107 int dirty_inode = 0;
4113 pb.num_illegal_blocks = 0;
4114 pb.suppress = 0; pb.clear = 0;
4117 pb.previous_block = 0;
4118 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4119 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4120 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4127 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4128 if (fs->super->s_feature_incompat &
4129 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4132 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4133 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4139 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4142 if (ext2fs_inode_has_valid_blocks(inode))
4143 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4144 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4145 block_buf, process_block, &pb);
4146 end_problem_latch(ctx, PR_LATCH_BLOCK);
4147 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4148 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4151 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4153 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4154 ctx->fs_fragmented++;
4157 inode->i_links_count = 0;
4158 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4159 inode->i_dtime = time(NULL);
4161 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4162 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4163 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4165 * The inode was probably partially accounted for
4166 * before processing was aborted, so we need to
4167 * restart the pass 1 scan.
4169 ctx->flags |= E2F_FLAG_RESTART;
4173 if (inode->i_flags & EXT2_INDEX_FL) {
4174 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4175 inode->i_flags &= ~EXT2_INDEX_FL;
4179 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4183 if (ctx->dirs_to_hash && pb.is_dir &&
4184 !(inode->i_flags & EXT2_INDEX_FL) &&
4185 ((inode->i_size / fs->blocksize) >= 3))
4186 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4188 if (!pb.num_blocks && pb.is_dir) {
4189 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4190 inode->i_links_count = 0;
4191 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4192 inode->i_dtime = time(NULL);
4194 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4195 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4196 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4197 ctx->fs_directory_count--;
4202 pb.num_blocks *= (fs->blocksize / 512);
4205 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4206 if (nblock > (pb.last_block + 1))
4208 else if (nblock < (pb.last_block + 1)) {
4209 if (((pb.last_block + 1) - nblock) >
4210 fs->super->s_prealloc_dir_blocks)
4214 size = EXT2_I_SIZE(inode);
4215 if ((pb.last_block >= 0) &&
4216 (size < (__u64) pb.last_block * fs->blocksize))
4218 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4221 /* i_size for symlinks is checked elsewhere */
4222 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4223 pctx->num = (pb.last_block+1) * fs->blocksize;
4224 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4225 inode->i_size = pctx->num;
4226 if (!LINUX_S_ISDIR(inode->i_mode))
4227 inode->i_size_high = pctx->num >> 32;
4232 if (LINUX_S_ISREG(inode->i_mode) &&
4233 (inode->i_size_high || inode->i_size & 0x80000000UL))
4235 if (pb.num_blocks != inode->i_blocks) {
4236 pctx->num = pb.num_blocks;
4237 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4238 inode->i_blocks = pb.num_blocks;
4245 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4250 * This is a helper function for check_blocks().
4252 static int process_block(ext2_filsys fs,
4254 e2_blkcnt_t blockcnt,
4255 blk_t ref_block FSCK_ATTR((unused)),
4256 int ref_offset FSCK_ATTR((unused)),
4259 struct process_block_struct_1 *p;
4260 struct problem_context *pctx;
4261 blk_t blk = *block_nr;
4266 p = (struct process_block_struct_1 *) priv_data;
4270 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4271 /* todo: Check that the comprblk_fl is high, that the
4272 blkaddr pattern looks right (all non-holes up to
4273 first EXT2FS_COMPRESSED_BLKADDR, then all
4274 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4275 that the feature_incompat bit is high, and that the
4276 inode is a regular file. If we're doing a "full
4277 check" (a concept introduced to e2fsck by e2compr,
4278 meaning that we look at data blocks as well as
4279 metadata) then call some library routine that
4280 checks the compressed data. I'll have to think
4281 about this, because one particularly important
4282 problem to be able to fix is to recalculate the
4283 cluster size if necessary. I think that perhaps
4284 we'd better do most/all e2compr-specific checks
4285 separately, after the non-e2compr checks. If not
4286 doing a full check, it may be useful to test that
4287 the personality is linux; e.g. if it isn't then
4288 perhaps this really is just an illegal block. */
4293 if (p->is_dir == 0) {
4295 * Should never happen, since only directories
4296 * get called with BLOCK_FLAG_HOLE
4299 printf("process_block() called with blk == 0, "
4300 "blockcnt=%d, inode %lu???\n",
4307 if (blockcnt * fs->blocksize < p->inode->i_size) {
4314 * Simplistic fragmentation check. We merely require that the
4315 * file be contiguous. (Which can never be true for really
4316 * big files that are greater than a block group.)
4318 if (!HOLE_BLKADDR(p->previous_block)) {
4319 if (p->previous_block+1 != blk)
4322 p->previous_block = blk;
4324 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4325 problem = PR_1_TOOBIG_DIR;
4326 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4327 problem = PR_1_TOOBIG_REG;
4328 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4329 problem = PR_1_TOOBIG_SYMLINK;
4331 if (blk < fs->super->s_first_data_block ||
4332 blk >= fs->super->s_blocks_count)
4333 problem = PR_1_ILLEGAL_BLOCK_NUM;
4336 p->num_illegal_blocks++;
4337 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4338 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4342 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4344 set_latch_flags(PR_LATCH_BLOCK,
4349 pctx->blkcount = blockcnt;
4350 if (fix_problem(ctx, problem, pctx)) {
4351 blk = *block_nr = 0;
4352 ret_code = BLOCK_CHANGED;
4358 if (p->ino == EXT2_RESIZE_INO) {
4360 * The resize inode has already be sanity checked
4361 * during pass #0 (the superblock checks). All we
4362 * have to do is mark the double indirect block as
4363 * being in use; all of the other blocks are handled
4364 * by mark_table_blocks()).
4366 if (blockcnt == BLOCK_COUNT_DIND)
4367 mark_block_used(ctx, blk);
4369 mark_block_used(ctx, blk);
4372 p->last_block = blockcnt;
4374 if (p->is_dir && (blockcnt >= 0)) {
4375 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4377 if (pctx->errcode) {
4379 pctx->num = blockcnt;
4380 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4381 /* Should never get here */
4382 ctx->flags |= E2F_FLAG_ABORT;
4389 static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4391 e2_blkcnt_t blockcnt,
4392 blk_t ref_block FSCK_ATTR((unused)),
4393 int ref_offset FSCK_ATTR((unused)),
4394 void *priv_data EXT2FS_ATTR((unused)))
4397 * Note: This function processes blocks for the bad blocks
4398 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4401 printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4406 * This routine gets called at the end of pass 1 if bad blocks are
4407 * detected in the superblock, group descriptors, inode_bitmaps, or
4408 * block bitmaps. At this point, all of the blocks have been mapped
4409 * out, so we can try to allocate new block(s) to replace the bad
4412 static void handle_fs_bad_blocks(e2fsck_t ctx)
4414 printf("Bad blocks detected on your filesystem\n"
4415 "You should get your data off as the device will soon die\n");
4419 * This routine marks all blocks which are used by the superblock,
4420 * group descriptors, inode bitmaps, and block bitmaps.
4422 static void mark_table_blocks(e2fsck_t ctx)
4424 ext2_filsys fs = ctx->fs;
4428 struct problem_context pctx;
4430 clear_problem_context(&pctx);
4432 block = fs->super->s_first_data_block;
4433 for (i = 0; i < fs->group_desc_count; i++) {
4436 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4439 * Mark the blocks used for the inode table
4441 if (fs->group_desc[i].bg_inode_table) {
4442 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4443 j < fs->inode_blocks_per_group;
4445 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4448 if (fix_problem(ctx,
4449 PR_1_ITABLE_CONFLICT, &pctx)) {
4450 ctx->invalid_inode_table_flag[i]++;
4451 ctx->invalid_bitmaps++;
4454 ext2fs_mark_block_bitmap(ctx->block_found_map,
4461 * Mark block used for the block bitmap
4463 if (fs->group_desc[i].bg_block_bitmap) {
4464 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4465 fs->group_desc[i].bg_block_bitmap)) {
4466 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4467 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4468 ctx->invalid_block_bitmap_flag[i]++;
4469 ctx->invalid_bitmaps++;
4472 ext2fs_mark_block_bitmap(ctx->block_found_map,
4473 fs->group_desc[i].bg_block_bitmap);
4478 * Mark block used for the inode bitmap
4480 if (fs->group_desc[i].bg_inode_bitmap) {
4481 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4482 fs->group_desc[i].bg_inode_bitmap)) {
4483 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4484 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4485 ctx->invalid_inode_bitmap_flag[i]++;
4486 ctx->invalid_bitmaps++;
4489 ext2fs_mark_block_bitmap(ctx->block_found_map,
4490 fs->group_desc[i].bg_inode_bitmap);
4493 block += fs->super->s_blocks_per_group;
4498 * Thes subroutines short circuits ext2fs_get_blocks and
4499 * ext2fs_check_directory; we use them since we already have the inode
4500 * structure, so there's no point in letting the ext2fs library read
4503 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4506 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4509 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4510 return EXT2_ET_CALLBACK_NOTHANDLED;
4512 for (i=0; i < EXT2_N_BLOCKS; i++)
4513 blocks[i] = ctx->stashed_inode->i_block[i];
4517 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4518 struct ext2_inode *inode)
4520 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4522 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4523 return EXT2_ET_CALLBACK_NOTHANDLED;
4524 *inode = *ctx->stashed_inode;
4528 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4529 struct ext2_inode *inode)
4531 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4533 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4534 *ctx->stashed_inode = *inode;
4535 return EXT2_ET_CALLBACK_NOTHANDLED;
4538 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4540 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4542 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4543 return EXT2_ET_CALLBACK_NOTHANDLED;
4545 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4546 return EXT2_ET_NO_DIRECTORY;
4550 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4552 ext2_filsys fs = ctx->fs;
4555 fs->get_blocks = pass1_get_blocks;
4556 fs->check_directory = pass1_check_directory;
4557 fs->read_inode = pass1_read_inode;
4558 fs->write_inode = pass1_write_inode;
4559 ctx->stashed_ino = 0;
4562 fs->check_directory = 0;
4564 fs->write_inode = 0;
4569 * pass1b.c --- Pass #1b of e2fsck
4571 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4572 * only invoked if pass 1 discovered blocks which are in use by more
4575 * Pass1B scans the data blocks of all the inodes again, generating a
4576 * complete list of duplicate blocks and which inodes have claimed
4579 * Pass1C does a tree-traversal of the filesystem, to determine the
4580 * parent directories of these inodes. This step is necessary so that
4581 * e2fsck can print out the pathnames of affected inodes.
4583 * Pass1D is a reconciliation pass. For each inode with duplicate
4584 * blocks, the user is prompted if s/he would like to clone the file
4585 * (so that the file gets a fresh copy of the duplicated blocks) or
4586 * simply to delete the file.
4591 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4592 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4593 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4595 /* Define an extension to the ext2 library's block count information */
4596 #define BLOCK_COUNT_EXTATTR (-5)
4600 struct block_el *next;
4605 struct inode_el *next;
4610 struct inode_el *inode_list;
4614 * This structure stores information about a particular inode which
4615 * is sharing blocks with other inodes. This information is collected
4616 * to display to the user, so that the user knows what files he or she
4617 * is dealing with, when trying to decide how to resolve the conflict
4618 * of multiply-claimed blocks.
4623 struct ext2_inode inode;
4624 struct block_el *block_list;
4627 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
4628 e2_blkcnt_t blockcnt, blk_t ref_blk,
4629 int ref_offset, void *priv_data);
4630 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4631 struct dup_inode *dp, char *block_buf);
4632 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4633 struct dup_inode *dp, char* block_buf);
4634 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4636 static void pass1b(e2fsck_t ctx, char *block_buf);
4637 static void pass1c(e2fsck_t ctx, char *block_buf);
4638 static void pass1d(e2fsck_t ctx, char *block_buf);
4640 static int dup_inode_count = 0;
4642 static dict_t blk_dict, ino_dict;
4644 static ext2fs_inode_bitmap inode_dup_map;
4646 static int dict_int_cmp(const void *a, const void *b)
4657 * Add a duplicate block record
4659 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4660 struct ext2_inode *inode)
4663 struct dup_block *db;
4664 struct dup_inode *di;
4665 struct block_el *blk_el;
4666 struct inode_el *ino_el;
4668 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4670 db = (struct dup_block *) dnode_get(n);
4672 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4673 sizeof(struct dup_block), "duplicate block header");
4676 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4678 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4679 sizeof(struct inode_el), "inode element");
4680 ino_el->inode = ino;
4681 ino_el->next = db->inode_list;
4682 db->inode_list = ino_el;
4685 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4687 di = (struct dup_inode *) dnode_get(n);
4689 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4690 sizeof(struct dup_inode), "duplicate inode header");
4691 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0;
4692 di->num_dupblocks = 0;
4695 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4697 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4698 sizeof(struct block_el), "block element");
4699 blk_el->block = blk;
4700 blk_el->next = di->block_list;
4701 di->block_list = blk_el;
4702 di->num_dupblocks++;
4706 * Free a duplicate inode record
4708 static void inode_dnode_free(dnode_t *node)
4710 struct dup_inode *di;
4711 struct block_el *p, *next;
4713 di = (struct dup_inode *) dnode_get(node);
4714 for (p = di->block_list; p; p = next) {
4722 * Free a duplicate block record
4724 static void block_dnode_free(dnode_t *node)
4726 struct dup_block *db;
4727 struct inode_el *p, *next;
4729 db = (struct dup_block *) dnode_get(node);
4730 for (p = db->inode_list; p; p = next) {
4739 * Main procedure for handling duplicate blocks
4741 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4743 ext2_filsys fs = ctx->fs;
4744 struct problem_context pctx;
4746 clear_problem_context(&pctx);
4748 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4749 _("multiply claimed inode map"), &inode_dup_map);
4751 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4752 ctx->flags |= E2F_FLAG_ABORT;
4756 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4757 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4758 dict_set_allocator(&ino_dict, inode_dnode_free);
4759 dict_set_allocator(&blk_dict, block_dnode_free);
4761 pass1b(ctx, block_buf);
4762 pass1c(ctx, block_buf);
4763 pass1d(ctx, block_buf);
4766 * Time to free all of the accumulated data structures that we
4767 * don't need anymore.
4769 dict_free_nodes(&ino_dict);
4770 dict_free_nodes(&blk_dict);
4774 * Scan the inodes looking for inodes that contain duplicate blocks.
4776 struct process_block_struct_1b {
4780 struct ext2_inode *inode;
4781 struct problem_context *pctx;
4784 static void pass1b(e2fsck_t ctx, char *block_buf)
4786 ext2_filsys fs = ctx->fs;
4788 struct ext2_inode inode;
4789 ext2_inode_scan scan;
4790 struct process_block_struct_1b pb;
4791 struct problem_context pctx;
4793 clear_problem_context(&pctx);
4795 if (!(ctx->options & E2F_OPT_PREEN))
4796 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4797 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4800 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4801 ctx->flags |= E2F_FLAG_ABORT;
4804 ctx->stashed_inode = &inode;
4807 pctx.str = "pass1b";
4809 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4810 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4813 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4814 ctx->flags |= E2F_FLAG_ABORT;
4819 pctx.ino = ctx->stashed_ino = ino;
4820 if ((ino != EXT2_BAD_INO) &&
4821 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4828 if (ext2fs_inode_has_valid_blocks(&inode) ||
4829 (ino == EXT2_BAD_INO))
4830 pctx.errcode = ext2fs_block_iterate2(fs, ino,
4831 0, block_buf, process_pass1b_block, &pb);
4832 if (inode.i_file_acl)
4833 process_pass1b_block(fs, &inode.i_file_acl,
4834 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4835 if (pb.dup_blocks) {
4836 end_problem_latch(ctx, PR_LATCH_DBLOCK);
4837 if (ino >= EXT2_FIRST_INODE(fs->super) ||
4838 ino == EXT2_ROOT_INO)
4842 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4844 ext2fs_close_inode_scan(scan);
4845 e2fsck_use_inode_shortcuts(ctx, 0);
4848 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4850 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4851 blk_t ref_blk FSCK_ATTR((unused)),
4852 int ref_offset FSCK_ATTR((unused)),
4855 struct process_block_struct_1b *p;
4858 if (HOLE_BLKADDR(*block_nr))
4860 p = (struct process_block_struct_1b *) priv_data;
4863 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4866 /* OK, this is a duplicate block */
4867 if (p->ino != EXT2_BAD_INO) {
4868 p->pctx->blk = *block_nr;
4869 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4872 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4874 add_dupe(ctx, p->ino, *block_nr, p->inode);
4880 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4881 * is used so that we can print pathnames when prompting the user for
4884 struct search_dir_struct {
4886 ext2_ino_t first_inode;
4887 ext2_ino_t max_inode;
4890 static int search_dirent_proc(ext2_ino_t dir, int entry,
4891 struct ext2_dir_entry *dirent,
4892 int offset FSCK_ATTR((unused)),
4893 int blocksize FSCK_ATTR((unused)),
4894 char *buf FSCK_ATTR((unused)),
4897 struct search_dir_struct *sd;
4898 struct dup_inode *p;
4901 sd = (struct search_dir_struct *) priv_data;
4903 if (dirent->inode > sd->max_inode)
4904 /* Should abort this inode, but not everything */
4907 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4908 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4911 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4914 p = (struct dup_inode *) dnode_get(n);
4918 return sd->count ? 0 : DIRENT_ABORT;
4922 static void pass1c(e2fsck_t ctx, char *block_buf)
4924 ext2_filsys fs = ctx->fs;
4925 struct search_dir_struct sd;
4926 struct problem_context pctx;
4928 clear_problem_context(&pctx);
4930 if (!(ctx->options & E2F_OPT_PREEN))
4931 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4934 * Search through all directories to translate inodes to names
4935 * (by searching for the containing directory for that inode.)
4937 sd.count = dup_inode_count;
4938 sd.first_inode = EXT2_FIRST_INODE(fs->super);
4939 sd.max_inode = fs->super->s_inodes_count;
4940 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4941 search_dirent_proc, &sd);
4944 static void pass1d(e2fsck_t ctx, char *block_buf)
4946 ext2_filsys fs = ctx->fs;
4947 struct dup_inode *p, *t;
4948 struct dup_block *q;
4949 ext2_ino_t *shared, ino;
4954 struct problem_context pctx;
4959 clear_problem_context(&pctx);
4961 if (!(ctx->options & E2F_OPT_PREEN))
4962 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
4963 e2fsck_read_bitmaps(ctx);
4965 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
4966 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
4967 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
4968 sizeof(ext2_ino_t) * dict_count(&ino_dict),
4969 "Shared inode list");
4970 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
4971 p = (struct dup_inode *) dnode_get(n);
4974 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
4975 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
4979 * Find all of the inodes which share blocks with this
4980 * one. First we find all of the duplicate blocks
4981 * belonging to this inode, and then search each block
4982 * get the list of inodes, and merge them together.
4984 for (s = p->block_list; s; s = s->next) {
4985 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
4987 continue; /* Should never happen... */
4988 q = (struct dup_block *) dnode_get(m);
4991 if (check_if_fs_block(ctx, s->block)) {
4997 * Add all inodes used by this block to the
4998 * shared[] --- which is a unique list, so
4999 * if an inode is already in shared[], don't
5002 for (r = q->inode_list; r; r = r->next) {
5003 if (r->inode == ino)
5005 for (i = 0; i < shared_len; i++)
5006 if (shared[i] == r->inode)
5008 if (i == shared_len) {
5009 shared[shared_len++] = r->inode;
5015 * Report the inode that we are working on
5017 pctx.inode = &p->inode;
5020 pctx.blkcount = p->num_dupblocks;
5021 pctx.num = meta_data ? shared_len+1 : shared_len;
5022 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5027 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5029 for (i = 0; i < shared_len; i++) {
5030 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5032 continue; /* should never happen */
5033 t = (struct dup_inode *) dnode_get(m);
5035 * Report the inode that we are sharing with
5037 pctx.inode = &t->inode;
5038 pctx.ino = shared[i];
5040 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5043 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5046 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5047 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5049 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5053 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5054 delete_file(ctx, ino, p, block_buf);
5056 ext2fs_unmark_valid(fs);
5058 ext2fs_free_mem(&shared);
5062 * Drop the refcount on the dup_block structure, and clear the entry
5063 * in the block_dup_map if appropriate.
5065 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5068 if (p->num_bad <= 0 ||
5069 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5070 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5073 static int delete_file_block(ext2_filsys fs,
5075 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5076 blk_t ref_block FSCK_ATTR((unused)),
5077 int ref_offset FSCK_ATTR((unused)),
5080 struct process_block_struct_1b *pb;
5081 struct dup_block *p;
5085 pb = (struct process_block_struct_1b *) priv_data;
5088 if (HOLE_BLKADDR(*block_nr))
5091 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5092 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5094 p = (struct dup_block *) dnode_get(n);
5095 decrement_badcount(ctx, *block_nr, p);
5097 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5100 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5101 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5107 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5108 struct dup_inode *dp, char* block_buf)
5110 ext2_filsys fs = ctx->fs;
5111 struct process_block_struct_1b pb;
5112 struct ext2_inode inode;
5113 struct problem_context pctx;
5116 clear_problem_context(&pctx);
5117 pctx.ino = pb.ino = ino;
5118 pb.dup_blocks = dp->num_dupblocks;
5120 pctx.str = "delete_file";
5122 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5123 if (ext2fs_inode_has_valid_blocks(&inode))
5124 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5125 delete_file_block, &pb);
5127 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5128 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5129 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5130 if (ctx->inode_bad_map)
5131 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5132 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5134 /* Inode may have changed by block_iterate, so reread it */
5135 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5136 inode.i_links_count = 0;
5137 inode.i_dtime = time(NULL);
5138 if (inode.i_file_acl &&
5139 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5141 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5142 block_buf, -1, &count);
5143 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5148 pctx.blk = inode.i_file_acl;
5149 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5152 * If the count is zero, then arrange to have the
5153 * block deleted. If the block is in the block_dup_map,
5154 * also call delete_file_block since it will take care
5155 * of keeping the accounting straight.
5158 ext2fs_test_block_bitmap(ctx->block_dup_map,
5160 delete_file_block(fs, &inode.i_file_acl,
5161 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5163 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5166 struct clone_struct {
5173 static int clone_file_block(ext2_filsys fs,
5175 e2_blkcnt_t blockcnt,
5176 blk_t ref_block FSCK_ATTR((unused)),
5177 int ref_offset FSCK_ATTR((unused)),
5180 struct dup_block *p;
5183 struct clone_struct *cs = (struct clone_struct *) priv_data;
5189 if (HOLE_BLKADDR(*block_nr))
5192 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5193 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5195 p = (struct dup_block *) dnode_get(n);
5196 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5199 cs->errcode = retval;
5202 if (cs->dir && (blockcnt >= 0)) {
5203 retval = ext2fs_set_dir_block(fs->dblist,
5204 cs->dir, new_block, blockcnt);
5206 cs->errcode = retval;
5211 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5214 cs->errcode = retval;
5217 retval = io_channel_write_blk(fs->io, new_block, 1,
5220 cs->errcode = retval;
5223 decrement_badcount(ctx, *block_nr, p);
5224 *block_nr = new_block;
5225 ext2fs_mark_block_bitmap(ctx->block_found_map,
5227 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5228 return BLOCK_CHANGED;
5230 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5236 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5237 struct dup_inode *dp, char* block_buf)
5239 ext2_filsys fs = ctx->fs;
5241 struct clone_struct cs;
5242 struct problem_context pctx;
5245 struct inode_el *ino_el;
5246 struct dup_block *db;
5247 struct dup_inode *di;
5249 clear_problem_context(&pctx);
5253 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5257 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5261 pctx.str = "clone_file";
5262 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5263 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5264 clone_file_block, &cs);
5265 ext2fs_mark_bb_dirty(fs);
5267 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5268 retval = pctx.errcode;
5272 bb_error_msg(_("returned from clone_file_block"));
5273 retval = cs.errcode;
5276 /* The inode may have changed on disk, so we have to re-read it */
5277 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5278 blk = dp->inode.i_file_acl;
5279 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5280 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5282 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5284 * If we cloned the EA block, find all other inodes
5285 * which refered to that EA block, and modify
5286 * them to point to the new EA block.
5288 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5289 db = (struct dup_block *) dnode_get(n);
5290 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5291 if (ino_el->inode == ino)
5293 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5294 di = (struct dup_inode *) dnode_get(n);
5295 if (di->inode.i_file_acl == blk) {
5296 di->inode.i_file_acl = dp->inode.i_file_acl;
5297 e2fsck_write_inode(ctx, ino_el->inode,
5298 &di->inode, "clone file EA");
5299 decrement_badcount(ctx, blk, db);
5305 ext2fs_free_mem(&cs.buf);
5310 * This routine returns 1 if a block overlaps with one of the superblocks,
5311 * group descriptors, inode bitmaps, or block bitmaps.
5313 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5315 ext2_filsys fs = ctx->fs;
5319 block = fs->super->s_first_data_block;
5320 for (i = 0; i < fs->group_desc_count; i++) {
5322 /* Check superblocks/block group descriptros */
5323 if (ext2fs_bg_has_super(fs, i)) {
5324 if (test_block >= block &&
5325 (test_block <= block + fs->desc_blocks))
5329 /* Check the inode table */
5330 if ((fs->group_desc[i].bg_inode_table) &&
5331 (test_block >= fs->group_desc[i].bg_inode_table) &&
5332 (test_block < (fs->group_desc[i].bg_inode_table +
5333 fs->inode_blocks_per_group)))
5336 /* Check the bitmap blocks */
5337 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5338 (test_block == fs->group_desc[i].bg_inode_bitmap))
5341 block += fs->super->s_blocks_per_group;
5346 * pass2.c --- check directory structure
5348 * Pass 2 of e2fsck iterates through all active directory inodes, and
5349 * applies to following tests to each directory entry in the directory
5350 * blocks in the inodes:
5352 * - The length of the directory entry (rec_len) should be at
5353 * least 8 bytes, and no more than the remaining space
5354 * left in the directory block.
5355 * - The length of the name in the directory entry (name_len)
5356 * should be less than (rec_len - 8).
5357 * - The inode number in the directory entry should be within
5359 * - The inode number should refer to a in-use inode.
5360 * - The first entry should be '.', and its inode should be
5361 * the inode of the directory.
5362 * - The second entry should be '..'.
5364 * To minimize disk seek time, the directory blocks are processed in
5365 * sorted order of block numbers.
5367 * Pass 2 also collects the following information:
5368 * - The inode numbers of the subdirectories for each directory.
5370 * Pass 2 relies on the following information from previous passes:
5371 * - The directory information collected in pass 1.
5372 * - The inode_used_map bitmap
5373 * - The inode_bad_map bitmap
5374 * - The inode_dir_map bitmap
5376 * Pass 2 frees the following data structures
5377 * - The inode_bad_map bitmap
5378 * - The inode_reg_map bitmap
5382 * Keeps track of how many times an inode is referenced.
5384 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5385 static int check_dir_block(ext2_filsys fs,
5386 struct ext2_db_entry *dir_blocks_info,
5388 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5389 struct problem_context *pctx);
5390 static int update_dir_block(ext2_filsys fs,
5392 e2_blkcnt_t blockcnt,
5396 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5397 static int htree_depth(struct dx_dir_info *dx_dir,
5398 struct dx_dirblock_info *dx_db);
5399 static int special_dir_block_cmp(const void *a, const void *b);
5401 struct check_dir_struct {
5403 struct problem_context pctx;
5408 static void e2fsck_pass2(e2fsck_t ctx)
5410 struct ext2_super_block *sb = ctx->fs->super;
5411 struct problem_context pctx;
5412 ext2_filsys fs = ctx->fs;
5414 struct dir_info *dir;
5415 struct check_dir_struct cd;
5416 struct dx_dir_info *dx_dir;
5417 struct dx_dirblock_info *dx_db, *dx_parent;
5423 clear_problem_context(&cd.pctx);
5427 if (!(ctx->options & E2F_OPT_PREEN))
5428 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5430 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5431 0, ctx->inode_link_info,
5433 if (cd.pctx.errcode) {
5434 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5435 ctx->flags |= E2F_FLAG_ABORT;
5438 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5439 "directory scan buffer");
5442 * Set up the parent pointer for the root directory, if
5443 * present. (If the root directory is not present, we will
5444 * create it in pass 3.)
5446 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5448 dir->parent = EXT2_ROOT_INO;
5453 cd.max = ext2fs_dblist_count(fs->dblist);
5456 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5458 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5459 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5461 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5463 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5465 if (cd.pctx.errcode) {
5466 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5467 ctx->flags |= E2F_FLAG_ABORT;
5472 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5473 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5475 if (dx_dir->numblocks == 0)
5477 clear_problem_context(&pctx);
5479 pctx.dir = dx_dir->ino;
5480 dx_db = dx_dir->dx_block;
5481 if (dx_db->flags & DX_FLAG_REFERENCED)
5482 dx_db->flags |= DX_FLAG_DUP_REF;
5484 dx_db->flags |= DX_FLAG_REFERENCED;
5486 * Find all of the first and last leaf blocks, and
5487 * update their parent's min and max hash values
5489 for (b=0, dx_db = dx_dir->dx_block;
5490 b < dx_dir->numblocks;
5492 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5493 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5495 dx_parent = &dx_dir->dx_block[dx_db->parent];
5497 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5499 if (dx_db->flags & DX_FLAG_FIRST)
5500 dx_parent->min_hash = dx_db->min_hash;
5502 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5504 if (dx_db->flags & DX_FLAG_LAST)
5505 dx_parent->max_hash = dx_db->max_hash;
5508 for (b=0, dx_db = dx_dir->dx_block;
5509 b < dx_dir->numblocks;
5512 pctx.group = dx_db->parent;
5514 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5515 (dx_db->min_hash < dx_db->node_min_hash)) {
5516 pctx.blk = dx_db->min_hash;
5517 pctx.blk2 = dx_db->node_min_hash;
5518 code = PR_2_HTREE_MIN_HASH;
5519 fix_problem(ctx, code, &pctx);
5522 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5523 depth = htree_depth(dx_dir, dx_db);
5524 if (depth != dx_dir->depth) {
5525 code = PR_2_HTREE_BAD_DEPTH;
5526 fix_problem(ctx, code, &pctx);
5531 * This test doesn't apply for the root block
5535 (dx_db->max_hash > dx_db->node_max_hash)) {
5536 pctx.blk = dx_db->max_hash;
5537 pctx.blk2 = dx_db->node_max_hash;
5538 code = PR_2_HTREE_MAX_HASH;
5539 fix_problem(ctx, code, &pctx);
5542 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5543 code = PR_2_HTREE_NOTREF;
5544 fix_problem(ctx, code, &pctx);
5546 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5547 code = PR_2_HTREE_DUPREF;
5548 fix_problem(ctx, code, &pctx);
5554 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5555 clear_htree(ctx, dx_dir->ino);
5556 dx_dir->numblocks = 0;
5560 ext2fs_free_mem(&buf);
5561 ext2fs_free_dblist(fs->dblist);
5563 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5564 ctx->inode_bad_map = 0;
5565 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5566 ctx->inode_reg_map = 0;
5568 clear_problem_context(&pctx);
5569 if (ctx->large_files) {
5570 if (!(sb->s_feature_ro_compat &
5571 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5572 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5573 sb->s_feature_ro_compat |=
5574 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5575 ext2fs_mark_super_dirty(fs);
5577 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5578 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5579 ext2fs_update_dynamic_rev(fs);
5580 ext2fs_mark_super_dirty(fs);
5582 } else if (!ctx->large_files &&
5583 (sb->s_feature_ro_compat &
5584 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5585 if (fs->flags & EXT2_FLAG_RW) {
5586 sb->s_feature_ro_compat &=
5587 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5588 ext2fs_mark_super_dirty(fs);
5594 #define MAX_DEPTH 32000
5595 static int htree_depth(struct dx_dir_info *dx_dir,
5596 struct dx_dirblock_info *dx_db)
5600 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5601 dx_db = &dx_dir->dx_block[dx_db->parent];
5607 static int dict_de_cmp(const void *a, const void *b)
5609 const struct ext2_dir_entry *de_a, *de_b;
5612 de_a = (const struct ext2_dir_entry *) a;
5613 a_len = de_a->name_len & 0xFF;
5614 de_b = (const struct ext2_dir_entry *) b;
5615 b_len = de_b->name_len & 0xFF;
5618 return (a_len - b_len);
5620 return strncmp(de_a->name, de_b->name, a_len);
5624 * This is special sort function that makes sure that directory blocks
5625 * with a dirblock of zero are sorted to the beginning of the list.
5626 * This guarantees that the root node of the htree directories are
5627 * processed first, so we know what hash version to use.
5629 static int special_dir_block_cmp(const void *a, const void *b)
5631 const struct ext2_db_entry *db_a =
5632 (const struct ext2_db_entry *) a;
5633 const struct ext2_db_entry *db_b =
5634 (const struct ext2_db_entry *) b;
5636 if (db_a->blockcnt && !db_b->blockcnt)
5639 if (!db_a->blockcnt && db_b->blockcnt)
5642 if (db_a->blk != db_b->blk)
5643 return (int) (db_a->blk - db_b->blk);
5645 if (db_a->ino != db_b->ino)
5646 return (int) (db_a->ino - db_b->ino);
5648 return (int) (db_a->blockcnt - db_b->blockcnt);
5653 * Make sure the first entry in the directory is '.', and that the
5654 * directory entry is sane.
5656 static int check_dot(e2fsck_t ctx,
5657 struct ext2_dir_entry *dirent,
5658 ext2_ino_t ino, struct problem_context *pctx)
5660 struct ext2_dir_entry *nextdir;
5667 problem = PR_2_MISSING_DOT;
5668 else if (((dirent->name_len & 0xFF) != 1) ||
5669 (dirent->name[0] != '.'))
5670 problem = PR_2_1ST_NOT_DOT;
5671 else if (dirent->name[1] != '\0')
5672 problem = PR_2_DOT_NULL_TERM;
5675 if (fix_problem(ctx, problem, pctx)) {
5676 if (dirent->rec_len < 12)
5677 dirent->rec_len = 12;
5678 dirent->inode = ino;
5679 dirent->name_len = 1;
5680 dirent->name[0] = '.';
5681 dirent->name[1] = '\0';
5686 if (dirent->inode != ino) {
5687 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5688 dirent->inode = ino;
5692 if (dirent->rec_len > 12) {
5693 new_len = dirent->rec_len - 12;
5696 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5697 nextdir = (struct ext2_dir_entry *)
5698 ((char *) dirent + 12);
5699 dirent->rec_len = 12;
5700 nextdir->rec_len = new_len;
5702 nextdir->name_len = 0;
5711 * Make sure the second entry in the directory is '..', and that the
5712 * directory entry is sane. We do not check the inode number of '..'
5713 * here; this gets done in pass 3.
5715 static int check_dotdot(e2fsck_t ctx,
5716 struct ext2_dir_entry *dirent,
5717 struct dir_info *dir, struct problem_context *pctx)
5722 problem = PR_2_MISSING_DOT_DOT;
5723 else if (((dirent->name_len & 0xFF) != 2) ||
5724 (dirent->name[0] != '.') ||
5725 (dirent->name[1] != '.'))
5726 problem = PR_2_2ND_NOT_DOT_DOT;
5727 else if (dirent->name[2] != '\0')
5728 problem = PR_2_DOT_DOT_NULL_TERM;
5731 if (fix_problem(ctx, problem, pctx)) {
5732 if (dirent->rec_len < 12)
5733 dirent->rec_len = 12;
5735 * Note: we don't have the parent inode just
5736 * yet, so we will fill it in with the root
5737 * inode. This will get fixed in pass 3.
5739 dirent->inode = EXT2_ROOT_INO;
5740 dirent->name_len = 2;
5741 dirent->name[0] = '.';
5742 dirent->name[1] = '.';
5743 dirent->name[2] = '\0';
5748 dir->dotdot = dirent->inode;
5753 * Check to make sure a directory entry doesn't contain any illegal
5756 static int check_name(e2fsck_t ctx,
5757 struct ext2_dir_entry *dirent,
5758 struct problem_context *pctx)
5764 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5765 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5767 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5770 dirent->name[i] = '.';
5779 * Check the directory filetype (if present)
5783 * Given a mode, return the ext2 file type
5785 static int ext2_file_type(unsigned int mode)
5787 if (LINUX_S_ISREG(mode))
5788 return EXT2_FT_REG_FILE;
5790 if (LINUX_S_ISDIR(mode))
5793 if (LINUX_S_ISCHR(mode))
5794 return EXT2_FT_CHRDEV;
5796 if (LINUX_S_ISBLK(mode))
5797 return EXT2_FT_BLKDEV;
5799 if (LINUX_S_ISLNK(mode))
5800 return EXT2_FT_SYMLINK;
5802 if (LINUX_S_ISFIFO(mode))
5803 return EXT2_FT_FIFO;
5805 if (LINUX_S_ISSOCK(mode))
5806 return EXT2_FT_SOCK;
5811 static int check_filetype(e2fsck_t ctx,
5812 struct ext2_dir_entry *dirent,
5813 struct problem_context *pctx)
5815 int filetype = dirent->name_len >> 8;
5816 int should_be = EXT2_FT_UNKNOWN;
5817 struct ext2_inode inode;
5819 if (!(ctx->fs->super->s_feature_incompat &
5820 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5821 if (filetype == 0 ||
5822 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5824 dirent->name_len = dirent->name_len & 0xFF;
5828 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5829 should_be = EXT2_FT_DIR;
5830 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5832 should_be = EXT2_FT_REG_FILE;
5833 } else if (ctx->inode_bad_map &&
5834 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5838 e2fsck_read_inode(ctx, dirent->inode, &inode,
5840 should_be = ext2_file_type(inode.i_mode);
5842 if (filetype == should_be)
5844 pctx->num = should_be;
5846 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5850 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5855 static void parse_int_node(ext2_filsys fs,
5856 struct ext2_db_entry *db,
5857 struct check_dir_struct *cd,
5858 struct dx_dir_info *dx_dir,
5861 struct ext2_dx_root_info *root;
5862 struct ext2_dx_entry *ent;
5863 struct ext2_dx_countlimit *limit;
5864 struct dx_dirblock_info *dx_db;
5865 int i, expect_limit, count;
5867 ext2_dirhash_t min_hash = 0xffffffff;
5868 ext2_dirhash_t max_hash = 0;
5869 ext2_dirhash_t hash = 0, prev_hash;
5871 if (db->blockcnt == 0) {
5872 root = (struct ext2_dx_root_info *) (block_buf + 24);
5873 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5875 ent = (struct ext2_dx_entry *) (block_buf+8);
5877 limit = (struct ext2_dx_countlimit *) ent;
5879 count = ext2fs_le16_to_cpu(limit->count);
5880 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5881 sizeof(struct ext2_dx_entry);
5882 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5883 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5884 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5885 goto clear_and_exit;
5887 if (count > expect_limit) {
5888 cd->pctx.num = count;
5889 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5890 goto clear_and_exit;
5891 count = expect_limit;
5894 for (i=0; i < count; i++) {
5896 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5897 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5898 /* Check to make sure the block is valid */
5899 if (blk > (blk_t) dx_dir->numblocks) {
5901 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5903 goto clear_and_exit;
5905 if (hash < prev_hash &&
5906 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5907 goto clear_and_exit;
5908 dx_db = &dx_dir->dx_block[blk];
5909 if (dx_db->flags & DX_FLAG_REFERENCED) {
5910 dx_db->flags |= DX_FLAG_DUP_REF;
5912 dx_db->flags |= DX_FLAG_REFERENCED;
5913 dx_db->parent = db->blockcnt;
5915 if (hash < min_hash)
5917 if (hash > max_hash)
5919 dx_db->node_min_hash = hash;
5921 dx_db->node_max_hash =
5922 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5924 dx_db->node_max_hash = 0xfffffffe;
5925 dx_db->flags |= DX_FLAG_LAST;
5928 dx_db->flags |= DX_FLAG_FIRST;
5930 dx_db = &dx_dir->dx_block[db->blockcnt];
5931 dx_db->min_hash = min_hash;
5932 dx_db->max_hash = max_hash;
5936 clear_htree(cd->ctx, cd->pctx.ino);
5937 dx_dir->numblocks = 0;
5939 #endif /* ENABLE_HTREE */
5942 * Given a busted directory, try to salvage it somehow.
5945 static void salvage_directory(ext2_filsys fs,
5946 struct ext2_dir_entry *dirent,
5947 struct ext2_dir_entry *prev,
5948 unsigned int *offset)
5950 char *cp = (char *) dirent;
5951 int left = fs->blocksize - *offset - dirent->rec_len;
5952 int name_len = dirent->name_len & 0xFF;
5955 * Special case of directory entry of size 8: copy what's left
5956 * of the directory block up to cover up the invalid hole.
5958 if ((left >= 12) && (dirent->rec_len == 8)) {
5959 memmove(cp, cp+8, left);
5960 memset(cp + left, 0, 8);
5964 * If the directory entry overruns the end of the directory
5965 * block, and the name is small enough to fit, then adjust the
5969 (name_len + 8 <= dirent->rec_len + left) &&
5970 dirent->inode <= fs->super->s_inodes_count &&
5971 strnlen(dirent->name, name_len) == name_len) {
5972 dirent->rec_len += left;
5976 * If the directory entry is a multiple of four, so it is
5977 * valid, let the previous directory entry absorb the invalid
5980 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
5981 prev->rec_len += dirent->rec_len;
5982 *offset += dirent->rec_len;
5986 * Default salvage method --- kill all of the directory
5987 * entries for the rest of the block. We will either try to
5988 * absorb it into the previous directory entry, or create a
5989 * new empty directory entry the rest of the directory block.
5992 prev->rec_len += fs->blocksize - *offset;
5993 *offset = fs->blocksize;
5995 dirent->rec_len = fs->blocksize - *offset;
5996 dirent->name_len = 0;
6001 static int check_dir_block(ext2_filsys fs,
6002 struct ext2_db_entry *db,
6005 struct dir_info *subdir, *dir;
6006 struct dx_dir_info *dx_dir;
6008 struct dx_dirblock_info *dx_db = NULL;
6009 #endif /* ENABLE_HTREE */
6010 struct ext2_dir_entry *dirent, *prev;
6011 ext2_dirhash_t hash;
6012 unsigned int offset = 0;
6013 int dir_modified = 0;
6015 blk_t block_nr = db->blk;
6016 ext2_ino_t ino = db->ino;
6018 struct check_dir_struct *cd;
6022 struct ext2_dx_root_info *root;
6023 struct ext2_dx_countlimit *limit;
6024 static dict_t de_dict;
6025 struct problem_context pctx;
6028 cd = (struct check_dir_struct *) priv_data;
6032 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6033 return DIRENT_ABORT;
6035 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6036 return DIRENT_ABORT;
6039 * Make sure the inode is still in use (could have been
6040 * deleted in the duplicate/bad blocks pass.
6042 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6046 cd->pctx.blk = block_nr;
6047 cd->pctx.blkcount = db->blockcnt;
6049 cd->pctx.dirent = 0;
6053 if (allocate_dir_block(ctx, db, &cd->pctx))
6063 if (ctx->dirs_to_hash &&
6064 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6067 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6068 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6069 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6070 if (cd->pctx.errcode) {
6071 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6072 ctx->flags |= E2F_FLAG_ABORT;
6073 return DIRENT_ABORT;
6075 memset(buf, 0, fs->blocksize);
6078 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6079 if (dx_dir && dx_dir->numblocks) {
6080 if (db->blockcnt >= dx_dir->numblocks) {
6081 printf("XXX should never happen!!!\n");
6084 dx_db = &dx_dir->dx_block[db->blockcnt];
6085 dx_db->type = DX_DIRBLOCK_LEAF;
6086 dx_db->phys = block_nr;
6087 dx_db->min_hash = ~0;
6088 dx_db->max_hash = 0;
6090 dirent = (struct ext2_dir_entry *) buf;
6091 limit = (struct ext2_dx_countlimit *) (buf+8);
6092 if (db->blockcnt == 0) {
6093 root = (struct ext2_dx_root_info *) (buf + 24);
6094 dx_db->type = DX_DIRBLOCK_ROOT;
6095 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6096 if ((root->reserved_zero ||
6097 root->info_length < 8 ||
6098 root->indirect_levels > 1) &&
6099 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6100 clear_htree(ctx, ino);
6101 dx_dir->numblocks = 0;
6104 dx_dir->hashversion = root->hash_version;
6105 dx_dir->depth = root->indirect_levels + 1;
6106 } else if ((dirent->inode == 0) &&
6107 (dirent->rec_len == fs->blocksize) &&
6108 (dirent->name_len == 0) &&
6109 (ext2fs_le16_to_cpu(limit->limit) ==
6110 ((fs->blocksize-8) /
6111 sizeof(struct ext2_dx_entry))))
6112 dx_db->type = DX_DIRBLOCK_NODE;
6114 #endif /* ENABLE_HTREE */
6116 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6120 dirent = (struct ext2_dir_entry *) (buf + offset);
6121 cd->pctx.dirent = dirent;
6122 cd->pctx.num = offset;
6123 if (((offset + dirent->rec_len) > fs->blocksize) ||
6124 (dirent->rec_len < 12) ||
6125 ((dirent->rec_len % 4) != 0) ||
6126 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6127 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6128 salvage_directory(fs, dirent, prev, &offset);
6132 goto abort_free_dict;
6134 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6135 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6136 dirent->name_len = EXT2_NAME_LEN;
6141 if (dot_state == 0) {
6142 if (check_dot(ctx, dirent, ino, &cd->pctx))
6144 } else if (dot_state == 1) {
6145 dir = e2fsck_get_dir_info(ctx, ino);
6147 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6148 goto abort_free_dict;
6150 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6152 } else if (dirent->inode == ino) {
6153 problem = PR_2_LINK_DOT;
6154 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6164 * Make sure the inode listed is a legal one.
6166 if (((dirent->inode != EXT2_ROOT_INO) &&
6167 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6168 (dirent->inode > fs->super->s_inodes_count)) {
6169 problem = PR_2_BAD_INO;
6170 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6173 * If the inode is unused, offer to clear it.
6175 problem = PR_2_UNUSED_INODE;
6176 } else if ((dot_state > 1) &&
6177 ((dirent->name_len & 0xFF) == 1) &&
6178 (dirent->name[0] == '.')) {
6180 * If there's a '.' entry in anything other
6181 * than the first directory entry, it's a
6182 * duplicate entry that should be removed.
6184 problem = PR_2_DUP_DOT;
6185 } else if ((dot_state > 1) &&
6186 ((dirent->name_len & 0xFF) == 2) &&
6187 (dirent->name[0] == '.') &&
6188 (dirent->name[1] == '.')) {
6190 * If there's a '..' entry in anything other
6191 * than the second directory entry, it's a
6192 * duplicate entry that should be removed.
6194 problem = PR_2_DUP_DOT_DOT;
6195 } else if ((dot_state > 1) &&
6196 (dirent->inode == EXT2_ROOT_INO)) {
6198 * Don't allow links to the root directory.
6199 * We check this specially to make sure we
6200 * catch this error case even if the root
6201 * directory hasn't been created yet.
6203 problem = PR_2_LINK_ROOT;
6204 } else if ((dot_state > 1) &&
6205 (dirent->name_len & 0xFF) == 0) {
6207 * Don't allow zero-length directory names.
6209 problem = PR_2_NULL_NAME;
6213 if (fix_problem(ctx, problem, &cd->pctx)) {
6218 ext2fs_unmark_valid(fs);
6219 if (problem == PR_2_BAD_INO)
6225 * If the inode was marked as having bad fields in
6226 * pass1, process it and offer to fix/clear it.
6227 * (We wait until now so that we can display the
6228 * pathname to the user.)
6230 if (ctx->inode_bad_map &&
6231 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6233 if (e2fsck_process_bad_inode(ctx, ino,
6235 buf + fs->blocksize)) {
6240 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6241 return DIRENT_ABORT;
6244 if (check_name(ctx, dirent, &cd->pctx))
6247 if (check_filetype(ctx, dirent, &cd->pctx))
6252 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6253 (dirent->name_len & 0xFF),
6254 fs->super->s_hash_seed, &hash, 0);
6255 if (hash < dx_db->min_hash)
6256 dx_db->min_hash = hash;
6257 if (hash > dx_db->max_hash)
6258 dx_db->max_hash = hash;
6263 * If this is a directory, then mark its parent in its
6264 * dir_info structure. If the parent field is already
6265 * filled in, then this directory has more than one
6266 * hard link. We assume the first link is correct,
6267 * and ask the user if he/she wants to clear this one.
6269 if ((dot_state > 1) &&
6270 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6272 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6274 cd->pctx.ino = dirent->inode;
6275 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6276 goto abort_free_dict;
6278 if (subdir->parent) {
6279 cd->pctx.ino2 = subdir->parent;
6280 if (fix_problem(ctx, PR_2_LINK_DIR,
6288 subdir->parent = ino;
6293 } else if (dict_lookup(&de_dict, dirent)) {
6294 clear_problem_context(&pctx);
6296 pctx.dirent = dirent;
6297 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6298 if (!ctx->dirs_to_hash)
6299 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6300 if (ctx->dirs_to_hash)
6301 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6304 dict_alloc_insert(&de_dict, dirent, dirent);
6306 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6309 ctx->fs_links_count++;
6310 ctx->fs_total_count++;
6313 offset += dirent->rec_len;
6315 } while (offset < fs->blocksize);
6318 cd->pctx.dir = cd->pctx.ino;
6319 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6320 (dx_db->type == DX_DIRBLOCK_NODE))
6321 parse_int_node(fs, db, cd, dx_dir, buf);
6323 #endif /* ENABLE_HTREE */
6324 if (offset != fs->blocksize) {
6325 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6326 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6327 dirent->rec_len = cd->pctx.num;
6332 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6333 if (cd->pctx.errcode) {
6334 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6336 goto abort_free_dict;
6338 ext2fs_mark_changed(fs);
6340 dict_free_nodes(&de_dict);
6343 dict_free_nodes(&de_dict);
6344 ctx->flags |= E2F_FLAG_ABORT;
6345 return DIRENT_ABORT;
6349 * This function is called to deallocate a block, and is an interator
6350 * functioned called by deallocate inode via ext2fs_iterate_block().
6352 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6353 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6354 blk_t ref_block FSCK_ATTR((unused)),
6355 int ref_offset FSCK_ATTR((unused)),
6358 e2fsck_t ctx = (e2fsck_t) priv_data;
6360 if (HOLE_BLKADDR(*block_nr))
6362 if ((*block_nr < fs->super->s_first_data_block) ||
6363 (*block_nr >= fs->super->s_blocks_count))
6365 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6366 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6371 * This fuction deallocates an inode
6373 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6375 ext2_filsys fs = ctx->fs;
6376 struct ext2_inode inode;
6377 struct problem_context pctx;
6380 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6381 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6382 inode.i_links_count = 0;
6383 inode.i_dtime = time(NULL);
6384 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6385 clear_problem_context(&pctx);
6389 * Fix up the bitmaps...
6391 e2fsck_read_bitmaps(ctx);
6392 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6393 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6394 if (ctx->inode_bad_map)
6395 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6396 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6398 if (inode.i_file_acl &&
6399 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6400 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6401 block_buf, -1, &count);
6402 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6407 pctx.blk = inode.i_file_acl;
6408 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6409 ctx->flags |= E2F_FLAG_ABORT;
6413 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6415 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6417 inode.i_file_acl = 0;
6420 if (!ext2fs_inode_has_valid_blocks(&inode))
6423 if (LINUX_S_ISREG(inode.i_mode) &&
6424 (inode.i_size_high || inode.i_size & 0x80000000UL))
6427 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6428 deallocate_inode_block, ctx);
6430 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6431 ctx->flags |= E2F_FLAG_ABORT;
6437 * This fuction clears the htree flag on an inode
6439 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6441 struct ext2_inode inode;
6443 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6444 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6445 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6446 if (ctx->dirs_to_hash)
6447 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6451 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6452 ext2_ino_t ino, char *buf)
6454 ext2_filsys fs = ctx->fs;
6455 struct ext2_inode inode;
6456 int inode_modified = 0;
6458 unsigned char *frag, *fsize;
6459 struct problem_context pctx;
6462 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6464 clear_problem_context(&pctx);
6467 pctx.inode = &inode;
6469 if (inode.i_file_acl &&
6470 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6471 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6472 inode.i_file_acl = 0;
6475 * This is a special kludge to deal with long symlinks
6476 * on big endian systems. i_blocks had already been
6477 * decremented earlier in pass 1, but since i_file_acl
6478 * hadn't yet been cleared, ext2fs_read_inode()
6479 * assumed that the file was short symlink and would
6480 * not have byte swapped i_block[0]. Hence, we have
6481 * to byte-swap it here.
6483 if (LINUX_S_ISLNK(inode.i_mode) &&
6484 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6485 (inode.i_blocks == fs->blocksize >> 9))
6486 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6492 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6493 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6494 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6495 !(LINUX_S_ISSOCK(inode.i_mode)))
6496 problem = PR_2_BAD_MODE;
6497 else if (LINUX_S_ISCHR(inode.i_mode)
6498 && !e2fsck_pass1_check_device_inode(fs, &inode))
6499 problem = PR_2_BAD_CHAR_DEV;
6500 else if (LINUX_S_ISBLK(inode.i_mode)
6501 && !e2fsck_pass1_check_device_inode(fs, &inode))
6502 problem = PR_2_BAD_BLOCK_DEV;
6503 else if (LINUX_S_ISFIFO(inode.i_mode)
6504 && !e2fsck_pass1_check_device_inode(fs, &inode))
6505 problem = PR_2_BAD_FIFO;
6506 else if (LINUX_S_ISSOCK(inode.i_mode)
6507 && !e2fsck_pass1_check_device_inode(fs, &inode))
6508 problem = PR_2_BAD_SOCKET;
6509 else if (LINUX_S_ISLNK(inode.i_mode)
6510 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6511 problem = PR_2_INVALID_SYMLINK;
6515 if (fix_problem(ctx, problem, &pctx)) {
6516 deallocate_inode(ctx, ino, 0);
6517 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6525 if (inode.i_faddr) {
6526 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6533 switch (fs->super->s_creator_os) {
6535 frag = &inode.osd2.linux2.l_i_frag;
6536 fsize = &inode.osd2.linux2.l_i_fsize;
6539 frag = &inode.osd2.hurd2.h_i_frag;
6540 fsize = &inode.osd2.hurd2.h_i_fsize;
6543 frag = &inode.osd2.masix2.m_i_frag;
6544 fsize = &inode.osd2.masix2.m_i_fsize;
6549 if (frag && *frag) {
6551 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6558 if (fsize && *fsize) {
6560 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6568 if (inode.i_file_acl &&
6569 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6570 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6571 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6572 inode.i_file_acl = 0;
6577 if (inode.i_dir_acl &&
6578 LINUX_S_ISDIR(inode.i_mode)) {
6579 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6580 inode.i_dir_acl = 0;
6587 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6589 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6595 * allocate_dir_block --- this function allocates a new directory
6596 * block for a particular inode; this is done if a directory has
6597 * a "hole" in it, or if a directory has a illegal block number
6598 * that was zeroed out and now needs to be replaced.
6600 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6601 struct problem_context *pctx)
6603 ext2_filsys fs = ctx->fs;
6606 struct ext2_inode inode;
6608 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6612 * Read the inode and block bitmaps in; we'll be messing with
6615 e2fsck_read_bitmaps(ctx);
6618 * First, find a free block
6620 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6621 if (pctx->errcode) {
6622 pctx->str = "ext2fs_new_block";
6623 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6626 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6627 ext2fs_mark_block_bitmap(fs->block_map, blk);
6628 ext2fs_mark_bb_dirty(fs);
6631 * Now let's create the actual data block for the inode
6634 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6636 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6637 EXT2_ROOT_INO, &block);
6639 if (pctx->errcode) {
6640 pctx->str = "ext2fs_new_dir_block";
6641 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6645 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6646 ext2fs_free_mem(&block);
6647 if (pctx->errcode) {
6648 pctx->str = "ext2fs_write_dir_block";
6649 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6654 * Update the inode block count
6656 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6657 inode.i_blocks += fs->blocksize / 512;
6658 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6659 inode.i_size = (db->blockcnt+1) * fs->blocksize;
6660 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6663 * Finally, update the block pointers for the inode
6666 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6667 0, update_dir_block, db);
6668 if (pctx->errcode) {
6669 pctx->str = "ext2fs_block_iterate";
6670 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6678 * This is a helper function for allocate_dir_block().
6680 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6682 e2_blkcnt_t blockcnt,
6683 blk_t ref_block FSCK_ATTR((unused)),
6684 int ref_offset FSCK_ATTR((unused)),
6687 struct ext2_db_entry *db;
6689 db = (struct ext2_db_entry *) priv_data;
6690 if (db->blockcnt == (int) blockcnt) {
6691 *block_nr = db->blk;
6692 return BLOCK_CHANGED;
6698 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6700 * Pass #3 assures that all directories are connected to the
6701 * filesystem tree, using the following algorithm:
6703 * First, the root directory is checked to make sure it exists; if
6704 * not, e2fsck will offer to create a new one. It is then marked as
6707 * Then, pass3 interates over all directory inodes; for each directory
6708 * it attempts to trace up the filesystem tree, using dirinfo.parent
6709 * until it reaches a directory which has been marked "done". If it
6710 * cannot do so, then the directory must be disconnected, and e2fsck
6711 * will offer to reconnect it to /lost+found. While it is chasing
6712 * parent pointers up the filesystem tree, if pass3 sees a directory
6713 * twice, then it has detected a filesystem loop, and it will again
6714 * offer to reconnect the directory to /lost+found in to break the
6717 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6718 * reconnect inodes to /lost+found; this subroutine is also used by
6719 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6720 * is responsible for creating /lost+found if it does not exist.
6722 * Pass 3 frees the following data structures:
6723 * - The dirinfo directory information cache.
6726 static void check_root(e2fsck_t ctx);
6727 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6728 struct problem_context *pctx);
6729 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6731 static ext2fs_inode_bitmap inode_loop_detect;
6732 static ext2fs_inode_bitmap inode_done_map;
6734 static void e2fsck_pass3(e2fsck_t ctx)
6736 ext2_filsys fs = ctx->fs;
6738 struct problem_context pctx;
6739 struct dir_info *dir;
6740 unsigned long maxdirs, count;
6742 clear_problem_context(&pctx);
6746 if (!(ctx->options & E2F_OPT_PREEN))
6747 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6750 * Allocate some bitmaps to do loop detection.
6752 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6756 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6757 ctx->flags |= E2F_FLAG_ABORT;
6761 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6764 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6766 maxdirs = e2fsck_get_num_dirinfo(ctx);
6770 if ((ctx->progress)(ctx, 3, 0, maxdirs))
6773 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6774 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6776 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6778 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6779 if (check_directory(ctx, dir, &pctx))
6784 * Force the creation of /lost+found if not present
6786 if ((ctx->flags & E2F_OPT_READONLY) == 0)
6787 e2fsck_get_lost_and_found(ctx, 1);
6790 * If there are any directories that need to be indexed or
6791 * optimized, do it here.
6793 e2fsck_rehash_directories(ctx);
6796 e2fsck_free_dir_info(ctx);
6797 ext2fs_free_inode_bitmap(inode_loop_detect);
6798 inode_loop_detect = 0;
6799 ext2fs_free_inode_bitmap(inode_done_map);
6804 * This makes sure the root inode is present; if not, we ask if the
6805 * user wants us to create it. Not creating it is a fatal error.
6807 static void check_root(e2fsck_t ctx)
6809 ext2_filsys fs = ctx->fs;
6811 struct ext2_inode inode;
6813 struct problem_context pctx;
6815 clear_problem_context(&pctx);
6817 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6819 * If the root inode is not a directory, die here. The
6820 * user must have answered 'no' in pass1 when we
6821 * offered to clear it.
6823 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6825 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6826 ctx->flags |= E2F_FLAG_ABORT;
6831 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6832 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6833 ctx->flags |= E2F_FLAG_ABORT;
6837 e2fsck_read_bitmaps(ctx);
6840 * First, find a free block
6842 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6844 pctx.str = "ext2fs_new_block";
6845 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6846 ctx->flags |= E2F_FLAG_ABORT;
6849 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6850 ext2fs_mark_block_bitmap(fs->block_map, blk);
6851 ext2fs_mark_bb_dirty(fs);
6854 * Now let's create the actual data block for the inode
6856 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6859 pctx.str = "ext2fs_new_dir_block";
6860 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6861 ctx->flags |= E2F_FLAG_ABORT;
6865 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6867 pctx.str = "ext2fs_write_dir_block";
6868 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6869 ctx->flags |= E2F_FLAG_ABORT;
6872 ext2fs_free_mem(&block);
6875 * Set up the inode structure
6877 memset(&inode, 0, sizeof(inode));
6878 inode.i_mode = 040755;
6879 inode.i_size = fs->blocksize;
6880 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
6881 inode.i_links_count = 2;
6882 inode.i_blocks = fs->blocksize / 512;
6883 inode.i_block[0] = blk;
6886 * Write out the inode.
6888 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6890 pctx.str = "ext2fs_write_inode";
6891 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6892 ctx->flags |= E2F_FLAG_ABORT;
6897 * Miscellaneous bookkeeping...
6899 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6900 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6901 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6903 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6904 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6905 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6906 ext2fs_mark_ib_dirty(fs);
6910 * This subroutine is responsible for making sure that a particular
6911 * directory is connected to the root; if it isn't we trace it up as
6912 * far as we can go, and then offer to connect the resulting parent to
6913 * the lost+found. We have to do loop detection; if we ever discover
6914 * a loop, we treat that as a disconnected directory and offer to
6915 * reparent it to lost+found.
6917 * However, loop detection is expensive, because for very large
6918 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6919 * is non-trivial. Loops in filesystems are also a rare error case,
6920 * and we shouldn't optimize for error cases. So we try two passes of
6921 * the algorithm. The first time, we ignore loop detection and merely
6922 * increment a counter; if the counter exceeds some extreme threshold,
6923 * then we try again with the loop detection bitmap enabled.
6925 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6926 struct problem_context *pctx)
6928 ext2_filsys fs = ctx->fs;
6929 struct dir_info *p = dir;
6930 int loop_pass = 0, parent_count = 0;
6937 * Mark this inode as being "done"; by the time we
6938 * return from this function, the inode we either be
6939 * verified as being connected to the directory tree,
6940 * or we will have offered to reconnect this to
6943 * If it was marked done already, then we've reached a
6944 * parent we've already checked.
6946 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6950 * If this directory doesn't have a parent, or we've
6951 * seen the parent once already, then offer to
6952 * reparent it to lost+found
6956 (ext2fs_test_inode_bitmap(inode_loop_detect,
6959 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6960 if (e2fsck_reconnect_file(ctx, pctx->ino))
6961 ext2fs_unmark_valid(fs);
6963 p = e2fsck_get_dir_info(ctx, pctx->ino);
6964 p->parent = ctx->lost_and_found;
6965 fix_dotdot(ctx, p, ctx->lost_and_found);
6970 p = e2fsck_get_dir_info(ctx, p->parent);
6972 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
6976 ext2fs_mark_inode_bitmap(inode_loop_detect,
6978 } else if (parent_count++ > 2048) {
6980 * If we've run into a path depth that's
6981 * greater than 2048, try again with the inode
6982 * loop bitmap turned on and start from the
6986 if (inode_loop_detect)
6987 ext2fs_clear_inode_bitmap(inode_loop_detect);
6989 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
6990 if (pctx->errcode) {
6993 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
6994 ctx->flags |= E2F_FLAG_ABORT;
7003 * Make sure that .. and the parent directory are the same;
7004 * offer to fix it if not.
7006 if (dir->parent != dir->dotdot) {
7007 pctx->ino = dir->ino;
7008 pctx->ino2 = dir->dotdot;
7009 pctx->dir = dir->parent;
7010 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7011 fix_dotdot(ctx, dir, dir->parent);
7017 * This routine gets the lost_and_found inode, making it a directory
7020 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7022 ext2_filsys fs = ctx->fs;
7026 struct ext2_inode inode;
7028 static const char name[] = "lost+found";
7029 struct problem_context pctx;
7030 struct dir_info *dirinfo;
7032 if (ctx->lost_and_found)
7033 return ctx->lost_and_found;
7035 clear_problem_context(&pctx);
7037 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7038 sizeof(name)-1, 0, &ino);
7042 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7043 ctx->lost_and_found = ino;
7047 /* Lost+found isn't a directory! */
7051 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7054 /* OK, unlink the old /lost+found file. */
7055 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7057 pctx.str = "ext2fs_unlink";
7058 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7061 dirinfo = e2fsck_get_dir_info(ctx, ino);
7063 dirinfo->parent = 0;
7064 e2fsck_adjust_inode_count(ctx, ino, -1);
7065 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7066 pctx.errcode = retval;
7067 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7069 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7073 * Read the inode and block bitmaps in; we'll be messing with
7076 e2fsck_read_bitmaps(ctx);
7079 * First, find a free block
7081 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7083 pctx.errcode = retval;
7084 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7087 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7088 ext2fs_block_alloc_stats(fs, blk, +1);
7091 * Next find a free inode.
7093 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7094 ctx->inode_used_map, &ino);
7096 pctx.errcode = retval;
7097 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7100 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7101 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7102 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7105 * Now let's create the actual data block for the inode
7107 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7109 pctx.errcode = retval;
7110 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7114 retval = ext2fs_write_dir_block(fs, blk, block);
7115 ext2fs_free_mem(&block);
7117 pctx.errcode = retval;
7118 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7123 * Set up the inode structure
7125 memset(&inode, 0, sizeof(inode));
7126 inode.i_mode = 040700;
7127 inode.i_size = fs->blocksize;
7128 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
7129 inode.i_links_count = 2;
7130 inode.i_blocks = fs->blocksize / 512;
7131 inode.i_block[0] = blk;
7134 * Next, write out the inode.
7136 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7138 pctx.str = "ext2fs_write_inode";
7139 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7143 * Finally, create the directory link
7145 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7147 pctx.str = "ext2fs_link";
7148 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7153 * Miscellaneous bookkeeping that needs to be kept straight.
7155 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7156 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7157 ext2fs_icount_store(ctx->inode_count, ino, 2);
7158 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7159 ctx->lost_and_found = ino;
7164 * This routine will connect a file to lost+found
7166 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7168 ext2_filsys fs = ctx->fs;
7171 struct problem_context pctx;
7172 struct ext2_inode inode;
7175 clear_problem_context(&pctx);
7178 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7179 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7180 ctx->bad_lost_and_found++;
7182 if (ctx->bad_lost_and_found) {
7183 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7187 sprintf(name, "#%u", ino);
7188 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7189 file_type = ext2_file_type(inode.i_mode);
7190 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7191 if (retval == EXT2_ET_DIR_NO_SPACE) {
7192 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7194 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7197 pctx.errcode = retval;
7198 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7201 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7205 pctx.errcode = retval;
7206 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7209 e2fsck_adjust_inode_count(ctx, ino, 1);
7215 * Utility routine to adjust the inode counts on an inode.
7217 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7219 ext2_filsys fs = ctx->fs;
7221 struct ext2_inode inode;
7226 retval = ext2fs_read_inode(fs, ino, &inode);
7231 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7232 if (inode.i_links_count == (__u16) ~0)
7234 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7235 inode.i_links_count++;
7236 } else if (adj == -1) {
7237 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7238 if (inode.i_links_count == 0)
7240 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7241 inode.i_links_count--;
7244 retval = ext2fs_write_inode(fs, ino, &inode);
7252 * Fix parent --- this routine fixes up the parent of a directory.
7254 struct fix_dotdot_struct {
7261 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7262 int offset FSCK_ATTR((unused)),
7263 int blocksize FSCK_ATTR((unused)),
7264 char *buf FSCK_ATTR((unused)),
7267 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7269 struct problem_context pctx;
7271 if ((dirent->name_len & 0xFF) != 2)
7273 if (strncmp(dirent->name, "..", 2))
7276 clear_problem_context(&pctx);
7278 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7280 pctx.errcode = retval;
7281 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7283 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7285 pctx.errcode = retval;
7286 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7288 dirent->inode = fp->parent;
7291 return DIRENT_ABORT | DIRENT_CHANGED;
7294 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7296 ext2_filsys fs = ctx->fs;
7298 struct fix_dotdot_struct fp;
7299 struct problem_context pctx;
7306 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7307 0, fix_dotdot_proc, &fp);
7308 if (retval || !fp.done) {
7309 clear_problem_context(&pctx);
7310 pctx.ino = dir->ino;
7311 pctx.errcode = retval;
7312 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7313 PR_3_FIX_PARENT_NOFIND, &pctx);
7314 ext2fs_unmark_valid(fs);
7316 dir->dotdot = parent;
7320 * These routines are responsible for expanding a /lost+found if it is
7324 struct expand_dir_struct {
7326 int guaranteed_size;
7333 static int expand_dir_proc(ext2_filsys fs,
7335 e2_blkcnt_t blockcnt,
7336 blk_t ref_block FSCK_ATTR((unused)),
7337 int ref_offset FSCK_ATTR((unused)),
7340 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7342 static blk_t last_blk = 0;
7349 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7353 es->last_block = blockcnt;
7355 last_blk = *blocknr;
7358 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7365 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7371 retval = ext2fs_write_dir_block(fs, new_blk, block);
7373 retval = ext2fs_get_mem(fs->blocksize, &block);
7378 memset(block, 0, fs->blocksize);
7379 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7385 ext2fs_free_mem(&block);
7387 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7388 ext2fs_block_alloc_stats(fs, new_blk, +1);
7392 return (BLOCK_CHANGED | BLOCK_ABORT);
7394 return BLOCK_CHANGED;
7397 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7398 int num, int guaranteed_size)
7400 ext2_filsys fs = ctx->fs;
7402 struct expand_dir_struct es;
7403 struct ext2_inode inode;
7405 if (!(fs->flags & EXT2_FLAG_RW))
7406 return EXT2_ET_RO_FILSYS;
7409 * Read the inode and block bitmaps in; we'll be messing with
7412 e2fsck_read_bitmaps(ctx);
7414 retval = ext2fs_check_directory(fs, dir);
7419 es.guaranteed_size = guaranteed_size;
7425 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7426 0, expand_dir_proc, &es);
7432 * Update the size and block count fields in the inode.
7434 retval = ext2fs_read_inode(fs, dir, &inode);
7438 inode.i_size = (es.last_block + 1) * fs->blocksize;
7439 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7441 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7447 * pass4.c -- pass #4 of e2fsck: Check reference counts
7449 * Pass 4 frees the following data structures:
7450 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7454 * This routine is called when an inode is not connected to the
7457 * This subroutine returns 1 then the caller shouldn't bother with the
7458 * rest of the pass 4 tests.
7460 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7462 ext2_filsys fs = ctx->fs;
7463 struct ext2_inode inode;
7464 struct problem_context pctx;
7466 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7467 clear_problem_context(&pctx);
7469 pctx.inode = &inode;
7472 * Offer to delete any zero-length files that does not have
7473 * blocks. If there is an EA block, it might have useful
7474 * information, so we won't prompt to delete it, but let it be
7475 * reconnected to lost+found.
7477 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7478 LINUX_S_ISDIR(inode.i_mode))) {
7479 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7480 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7481 inode.i_links_count = 0;
7482 inode.i_dtime = time(NULL);
7483 e2fsck_write_inode(ctx, i, &inode,
7484 "disconnect_inode");
7486 * Fix up the bitmaps...
7488 e2fsck_read_bitmaps(ctx);
7489 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7490 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7491 ext2fs_inode_alloc_stats2(fs, i, -1,
7492 LINUX_S_ISDIR(inode.i_mode));
7498 * Prompt to reconnect.
7500 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7501 if (e2fsck_reconnect_file(ctx, i))
7502 ext2fs_unmark_valid(fs);
7505 * If we don't attach the inode, then skip the
7506 * i_links_test since there's no point in trying to
7507 * force i_links_count to zero.
7509 ext2fs_unmark_valid(fs);
7516 static void e2fsck_pass4(e2fsck_t ctx)
7518 ext2_filsys fs = ctx->fs;
7520 struct ext2_inode inode;
7521 struct problem_context pctx;
7522 __u16 link_count, link_counted;
7524 int group, maxgroup;
7528 clear_problem_context(&pctx);
7530 if (!(ctx->options & E2F_OPT_PREEN))
7531 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7534 maxgroup = fs->group_desc_count;
7536 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7539 for (i=1; i <= fs->super->s_inodes_count; i++) {
7540 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7542 if ((i % fs->super->s_inodes_per_group) == 0) {
7545 if ((ctx->progress)(ctx, 4, group, maxgroup))
7548 if (i == EXT2_BAD_INO ||
7549 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7551 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7552 (ctx->inode_imagic_map &&
7553 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7555 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7556 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7557 if (link_counted == 0) {
7559 buf = e2fsck_allocate_memory(ctx,
7560 fs->blocksize, "bad_inode buffer");
7561 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7563 if (disconnect_inode(ctx, i))
7565 ext2fs_icount_fetch(ctx->inode_link_info, i,
7567 ext2fs_icount_fetch(ctx->inode_count, i,
7570 if (link_counted != link_count) {
7571 e2fsck_read_inode(ctx, i, &inode, "pass4");
7573 pctx.inode = &inode;
7574 if (link_count != inode.i_links_count) {
7575 pctx.num = link_count;
7577 PR_4_INCONSISTENT_COUNT, &pctx);
7579 pctx.num = link_counted;
7580 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7581 inode.i_links_count = link_counted;
7582 e2fsck_write_inode(ctx, i, &inode, "pass4");
7586 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7587 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7588 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7589 ctx->inode_imagic_map = 0;
7590 ext2fs_free_mem(&buf);
7594 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7597 #define NO_BLK ((blk_t) -1)
7599 static void print_bitmap_problem(e2fsck_t ctx, int problem,
7600 struct problem_context *pctx)
7603 case PR_5_BLOCK_UNUSED:
7604 if (pctx->blk == pctx->blk2)
7607 problem = PR_5_BLOCK_RANGE_UNUSED;
7609 case PR_5_BLOCK_USED:
7610 if (pctx->blk == pctx->blk2)
7613 problem = PR_5_BLOCK_RANGE_USED;
7615 case PR_5_INODE_UNUSED:
7616 if (pctx->ino == pctx->ino2)
7619 problem = PR_5_INODE_RANGE_UNUSED;
7621 case PR_5_INODE_USED:
7622 if (pctx->ino == pctx->ino2)
7625 problem = PR_5_INODE_RANGE_USED;
7628 fix_problem(ctx, problem, pctx);
7629 pctx->blk = pctx->blk2 = NO_BLK;
7630 pctx->ino = pctx->ino2 = 0;
7633 static void check_block_bitmaps(e2fsck_t ctx)
7635 ext2_filsys fs = ctx->fs;
7639 unsigned int blocks = 0;
7640 unsigned int free_blocks = 0;
7643 struct problem_context pctx;
7644 int problem, save_problem, fixit, had_problem;
7647 clear_problem_context(&pctx);
7648 free_array = (int *) e2fsck_allocate_memory(ctx,
7649 fs->group_desc_count * sizeof(int), "free block count array");
7651 if ((fs->super->s_first_data_block <
7652 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7653 (fs->super->s_blocks_count-1 >
7654 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7656 pctx.blk = fs->super->s_first_data_block;
7657 pctx.blk2 = fs->super->s_blocks_count -1;
7658 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7659 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7660 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7662 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7666 if ((fs->super->s_first_data_block <
7667 ext2fs_get_block_bitmap_start(fs->block_map)) ||
7668 (fs->super->s_blocks_count-1 >
7669 ext2fs_get_block_bitmap_end(fs->block_map))) {
7671 pctx.blk = fs->super->s_first_data_block;
7672 pctx.blk2 = fs->super->s_blocks_count -1;
7673 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7674 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7675 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7677 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7684 pctx.blk = pctx.blk2 = NO_BLK;
7685 for (i = fs->super->s_first_data_block;
7686 i < fs->super->s_blocks_count;
7688 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7689 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7691 if (actual == bitmap)
7694 if (!actual && bitmap) {
7696 * Block not used, but marked in use in the bitmap.
7698 problem = PR_5_BLOCK_UNUSED;
7701 * Block used, but not marked in use in the bitmap.
7703 problem = PR_5_BLOCK_USED;
7705 if (pctx.blk == NO_BLK) {
7706 pctx.blk = pctx.blk2 = i;
7707 save_problem = problem;
7709 if ((problem == save_problem) &&
7713 print_bitmap_problem(ctx, save_problem, &pctx);
7714 pctx.blk = pctx.blk2 = i;
7715 save_problem = problem;
7718 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7727 if ((blocks == fs->super->s_blocks_per_group) ||
7728 (i == fs->super->s_blocks_count-1)) {
7729 free_array[group] = group_free;
7734 if ((ctx->progress)(ctx, 5, group,
7735 fs->group_desc_count*2))
7739 if (pctx.blk != NO_BLK)
7740 print_bitmap_problem(ctx, save_problem, &pctx);
7742 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7745 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7748 ext2fs_free_block_bitmap(fs->block_map);
7749 retval = ext2fs_copy_bitmap(ctx->block_found_map,
7752 clear_problem_context(&pctx);
7753 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7754 ctx->flags |= E2F_FLAG_ABORT;
7757 ext2fs_set_bitmap_padding(fs->block_map);
7758 ext2fs_mark_bb_dirty(fs);
7760 /* Redo the counts */
7761 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7762 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7764 } else if (fixit == 0)
7765 ext2fs_unmark_valid(fs);
7767 for (i = 0; i < fs->group_desc_count; i++) {
7768 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7770 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7771 pctx.blk2 = free_array[i];
7773 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7775 fs->group_desc[i].bg_free_blocks_count =
7777 ext2fs_mark_super_dirty(fs);
7779 ext2fs_unmark_valid(fs);
7782 if (free_blocks != fs->super->s_free_blocks_count) {
7784 pctx.blk = fs->super->s_free_blocks_count;
7785 pctx.blk2 = free_blocks;
7787 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7788 fs->super->s_free_blocks_count = free_blocks;
7789 ext2fs_mark_super_dirty(fs);
7791 ext2fs_unmark_valid(fs);
7793 ext2fs_free_mem(&free_array);
7796 static void check_inode_bitmaps(e2fsck_t ctx)
7798 ext2_filsys fs = ctx->fs;
7800 unsigned int free_inodes = 0;
7804 unsigned int inodes = 0;
7809 struct problem_context pctx;
7810 int problem, save_problem, fixit, had_problem;
7812 clear_problem_context(&pctx);
7813 free_array = (int *) e2fsck_allocate_memory(ctx,
7814 fs->group_desc_count * sizeof(int), "free inode count array");
7816 dir_array = (int *) e2fsck_allocate_memory(ctx,
7817 fs->group_desc_count * sizeof(int), "directory count array");
7819 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7820 (fs->super->s_inodes_count >
7821 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7824 pctx.blk2 = fs->super->s_inodes_count;
7825 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7826 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7827 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7829 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7832 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7833 (fs->super->s_inodes_count >
7834 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7837 pctx.blk2 = fs->super->s_inodes_count;
7838 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7839 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7840 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7842 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7849 pctx.ino = pctx.ino2 = 0;
7850 for (i = 1; i <= fs->super->s_inodes_count; i++) {
7851 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7852 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7854 if (actual == bitmap)
7857 if (!actual && bitmap) {
7859 * Inode wasn't used, but marked in bitmap
7861 problem = PR_5_INODE_UNUSED;
7862 } else /* if (actual && !bitmap) */ {
7864 * Inode used, but not in bitmap
7866 problem = PR_5_INODE_USED;
7868 if (pctx.ino == 0) {
7869 pctx.ino = pctx.ino2 = i;
7870 save_problem = problem;
7872 if ((problem == save_problem) &&
7876 print_bitmap_problem(ctx, save_problem, &pctx);
7877 pctx.ino = pctx.ino2 = i;
7878 save_problem = problem;
7881 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7889 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7893 if ((inodes == fs->super->s_inodes_per_group) ||
7894 (i == fs->super->s_inodes_count)) {
7895 free_array[group] = group_free;
7896 dir_array[group] = dirs_count;
7902 if ((ctx->progress)(ctx, 5,
7903 group + fs->group_desc_count,
7904 fs->group_desc_count*2))
7909 print_bitmap_problem(ctx, save_problem, &pctx);
7912 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7915 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7918 ext2fs_free_inode_bitmap(fs->inode_map);
7919 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7922 clear_problem_context(&pctx);
7923 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7924 ctx->flags |= E2F_FLAG_ABORT;
7927 ext2fs_set_bitmap_padding(fs->inode_map);
7928 ext2fs_mark_ib_dirty(fs);
7931 inodes = 0; free_inodes = 0; group_free = 0;
7932 dirs_count = 0; group = 0;
7933 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7934 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7936 } else if (fixit == 0)
7937 ext2fs_unmark_valid(fs);
7939 for (i = 0; i < fs->group_desc_count; i++) {
7940 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7942 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7943 pctx.ino2 = free_array[i];
7944 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7946 fs->group_desc[i].bg_free_inodes_count =
7948 ext2fs_mark_super_dirty(fs);
7950 ext2fs_unmark_valid(fs);
7952 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7954 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7955 pctx.ino2 = dir_array[i];
7957 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7959 fs->group_desc[i].bg_used_dirs_count =
7961 ext2fs_mark_super_dirty(fs);
7963 ext2fs_unmark_valid(fs);
7966 if (free_inodes != fs->super->s_free_inodes_count) {
7968 pctx.ino = fs->super->s_free_inodes_count;
7969 pctx.ino2 = free_inodes;
7971 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
7972 fs->super->s_free_inodes_count = free_inodes;
7973 ext2fs_mark_super_dirty(fs);
7975 ext2fs_unmark_valid(fs);
7977 ext2fs_free_mem(&free_array);
7978 ext2fs_free_mem(&dir_array);
7981 static void check_inode_end(e2fsck_t ctx)
7983 ext2_filsys fs = ctx->fs;
7984 ext2_ino_t end, save_inodes_count, i;
7985 struct problem_context pctx;
7987 clear_problem_context(&pctx);
7989 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
7990 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
7991 &save_inodes_count);
7994 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
7995 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7998 if (save_inodes_count == end)
8001 for (i = save_inodes_count + 1; i <= end; i++) {
8002 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8003 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8004 for (i = save_inodes_count + 1; i <= end; i++)
8005 ext2fs_mark_inode_bitmap(fs->inode_map,
8007 ext2fs_mark_ib_dirty(fs);
8009 ext2fs_unmark_valid(fs);
8014 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8015 save_inodes_count, 0);
8018 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8019 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8024 static void check_block_end(e2fsck_t ctx)
8026 ext2_filsys fs = ctx->fs;
8027 blk_t end, save_blocks_count, i;
8028 struct problem_context pctx;
8030 clear_problem_context(&pctx);
8032 end = fs->block_map->start +
8033 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8034 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8035 &save_blocks_count);
8038 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8039 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8042 if (save_blocks_count == end)
8045 for (i = save_blocks_count + 1; i <= end; i++) {
8046 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8047 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8048 for (i = save_blocks_count + 1; i <= end; i++)
8049 ext2fs_mark_block_bitmap(fs->block_map,
8051 ext2fs_mark_bb_dirty(fs);
8053 ext2fs_unmark_valid(fs);
8058 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8059 save_blocks_count, 0);
8062 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8063 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8068 static void e2fsck_pass5(e2fsck_t ctx)
8070 struct problem_context pctx;
8074 clear_problem_context(&pctx);
8076 if (!(ctx->options & E2F_OPT_PREEN))
8077 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8080 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8083 e2fsck_read_bitmaps(ctx);
8085 check_block_bitmaps(ctx);
8086 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8088 check_inode_bitmaps(ctx);
8089 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8091 check_inode_end(ctx);
8092 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8094 check_block_end(ctx);
8095 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8098 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8099 ctx->inode_used_map = 0;
8100 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8101 ctx->inode_dir_map = 0;
8102 ext2fs_free_block_bitmap(ctx->block_found_map);
8103 ctx->block_found_map = 0;
8107 * problem.c --- report filesystem problems to the user
8110 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8111 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8112 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8113 #define PR_MSG_ONLY 0x000008 /* Print message only */
8115 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8117 #define PR_FATAL 0x001000 /* Fatal error */
8118 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8120 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8121 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8122 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8123 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8124 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8127 #define PROMPT_NONE 0
8128 #define PROMPT_FIX 1
8129 #define PROMPT_CLEAR 2
8130 #define PROMPT_RELOCATE 3
8131 #define PROMPT_ALLOCATE 4
8132 #define PROMPT_EXPAND 5
8133 #define PROMPT_CONNECT 6
8134 #define PROMPT_CREATE 7
8135 #define PROMPT_SALVAGE 8
8136 #define PROMPT_TRUNCATE 9
8137 #define PROMPT_CLEAR_INODE 10
8138 #define PROMPT_ABORT 11
8139 #define PROMPT_SPLIT 12
8140 #define PROMPT_CONTINUE 13
8141 #define PROMPT_CLONE 14
8142 #define PROMPT_DELETE 15
8143 #define PROMPT_SUPPRESS 16
8144 #define PROMPT_UNLINK 17
8145 #define PROMPT_CLEAR_HTREE 18
8146 #define PROMPT_RECREATE 19
8147 #define PROMPT_NULL 20
8149 struct e2fsck_problem {
8151 const char * e2p_description;
8154 problem_t second_code;
8157 struct latch_descr {
8160 problem_t end_message;
8165 * These are the prompts which are used to ask the user if they want
8168 static const char *const prompt[] = {
8169 N_("(no prompt)"), /* 0 */
8171 N_("Clear"), /* 2 */
8172 N_("Relocate"), /* 3 */
8173 N_("Allocate"), /* 4 */
8174 N_("Expand"), /* 5 */
8175 N_("Connect to /lost+found"), /* 6 */
8176 N_("Create"), /* 7 */
8177 N_("Salvage"), /* 8 */
8178 N_("Truncate"), /* 9 */
8179 N_("Clear inode"), /* 10 */
8180 N_("Abort"), /* 11 */
8181 N_("Split"), /* 12 */
8182 N_("Continue"), /* 13 */
8183 N_("Clone multiply-claimed blocks"), /* 14 */
8184 N_("Delete file"), /* 15 */
8185 N_("Suppress messages"),/* 16 */
8186 N_("Unlink"), /* 17 */
8187 N_("Clear HTree index"),/* 18 */
8188 N_("Recreate"), /* 19 */
8193 * These messages are printed when we are preen mode and we will be
8194 * automatically fixing the problem.
8196 static const char *const preen_msg[] = {
8197 N_("(NONE)"), /* 0 */
8198 N_("FIXED"), /* 1 */
8199 N_("CLEARED"), /* 2 */
8200 N_("RELOCATED"), /* 3 */
8201 N_("ALLOCATED"), /* 4 */
8202 N_("EXPANDED"), /* 5 */
8203 N_("RECONNECTED"), /* 6 */
8204 N_("CREATED"), /* 7 */
8205 N_("SALVAGED"), /* 8 */
8206 N_("TRUNCATED"), /* 9 */
8207 N_("INODE CLEARED"), /* 10 */
8208 N_("ABORTED"), /* 11 */
8209 N_("SPLIT"), /* 12 */
8210 N_("CONTINUING"), /* 13 */
8211 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8212 N_("FILE DELETED"), /* 15 */
8213 N_("SUPPRESSED"), /* 16 */
8214 N_("UNLINKED"), /* 17 */
8215 N_("HTREE INDEX CLEARED"),/* 18 */
8216 N_("WILL RECREATE"), /* 19 */
8220 static const struct e2fsck_problem problem_table[] = {
8222 /* Pre-Pass 1 errors */
8224 /* Block bitmap not in group */
8225 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8226 PROMPT_RELOCATE, PR_LATCH_RELOC },
8228 /* Inode bitmap not in group */
8229 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8230 PROMPT_RELOCATE, PR_LATCH_RELOC },
8232 /* Inode table not in group */
8233 { PR_0_ITABLE_NOT_GROUP,
8234 N_("@i table for @g %g is not in @g. (@b %b)\n"
8235 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8236 PROMPT_RELOCATE, PR_LATCH_RELOC },
8238 /* Superblock corrupt */
8240 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8241 "@f. If the @v is valid and it really contains an ext2\n"
8242 "@f (and not swap or ufs or something else), then the @S\n"
8243 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8244 " e2fsck -b %S <@v>\n\n"),
8245 PROMPT_NONE, PR_FATAL },
8247 /* Filesystem size is wrong */
8248 { PR_0_FS_SIZE_WRONG,
8249 N_("The @f size (according to the @S) is %b @bs\n"
8250 "The physical size of the @v is %c @bs\n"
8251 "Either the @S or the partition table is likely to be corrupt!\n"),
8254 /* Fragments not supported */
8255 { PR_0_NO_FRAGMENTS,
8256 N_("@S @b_size = %b, fragsize = %c.\n"
8257 "This version of e2fsck does not support fragment sizes different\n"
8258 "from the @b size.\n"),
8259 PROMPT_NONE, PR_FATAL },
8261 /* Bad blocks_per_group */
8262 { PR_0_BLOCKS_PER_GROUP,
8263 N_("@S @bs_per_group = %b, should have been %c\n"),
8264 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8266 /* Bad first_data_block */
8267 { PR_0_FIRST_DATA_BLOCK,
8268 N_("@S first_data_@b = %b, should have been %c\n"),
8269 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8271 /* Adding UUID to filesystem */
8273 N_("@f did not have a UUID; generating one.\n\n"),
8277 { PR_0_RELOCATE_HINT,
8278 N_("Note: if several inode or block bitmap blocks or part\n"
8279 "of the inode table require relocation, you may wish to try\n"
8280 "running e2fsck with the '-b %S' option first. The problem\n"
8281 "may lie only with the primary block group descriptors, and\n"
8282 "the backup block group descriptors may be OK.\n\n"),
8283 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8285 /* Miscellaneous superblock corruption */
8286 { PR_0_MISC_CORRUPT_SUPER,
8287 N_("Corruption found in @S. (%s = %N).\n"),
8288 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8290 /* Error determing physical device size of filesystem */
8291 { PR_0_GETSIZE_ERROR,
8292 N_("Error determining size of the physical @v: %m\n"),
8293 PROMPT_NONE, PR_FATAL },
8295 /* Inode count in superblock is incorrect */
8296 { PR_0_INODE_COUNT_WRONG,
8297 N_("@i count in @S is %i, @s %j.\n"),
8300 { PR_0_HURD_CLEAR_FILETYPE,
8301 N_("The Hurd does not support the filetype feature.\n"),
8304 /* Journal inode is invalid */
8305 { PR_0_JOURNAL_BAD_INODE,
8306 N_("@S has an @n ext3 @j (@i %i).\n"),
8307 PROMPT_CLEAR, PR_PREEN_OK },
8309 /* The external journal has (unsupported) multiple filesystems */
8310 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8311 N_("External @j has multiple @f users (unsupported).\n"),
8312 PROMPT_NONE, PR_FATAL },
8314 /* Can't find external journal */
8315 { PR_0_CANT_FIND_JOURNAL,
8316 N_("Can't find external @j\n"),
8317 PROMPT_NONE, PR_FATAL },
8319 /* External journal has bad superblock */
8320 { PR_0_EXT_JOURNAL_BAD_SUPER,
8321 N_("External @j has bad @S\n"),
8322 PROMPT_NONE, PR_FATAL },
8324 /* Superblock has a bad journal UUID */
8325 { PR_0_JOURNAL_BAD_UUID,
8326 N_("External @j does not support this @f\n"),
8327 PROMPT_NONE, PR_FATAL },
8329 /* Journal has an unknown superblock type */
8330 { PR_0_JOURNAL_UNSUPP_SUPER,
8331 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8332 "It is likely that your copy of e2fsck is old and/or doesn't "
8333 "support this @j format.\n"
8334 "It is also possible the @j @S is corrupt.\n"),
8335 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8337 /* Journal superblock is corrupt */
8338 { PR_0_JOURNAL_BAD_SUPER,
8339 N_("Ext3 @j @S is corrupt.\n"),
8340 PROMPT_FIX, PR_PREEN_OK },
8342 /* Superblock flag should be cleared */
8343 { PR_0_JOURNAL_HAS_JOURNAL,
8344 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8345 PROMPT_CLEAR, PR_PREEN_OK },
8347 /* Superblock flag is incorrect */
8348 { PR_0_JOURNAL_RECOVER_SET,
8349 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8350 PROMPT_CLEAR, PR_PREEN_OK },
8352 /* Journal has data, but recovery flag is clear */
8353 { PR_0_JOURNAL_RECOVERY_CLEAR,
8354 N_("ext3 recovery flag is clear, but @j has data.\n"),
8357 /* Ask if we should clear the journal */
8358 { PR_0_JOURNAL_RESET_JOURNAL,
8360 PROMPT_NULL, PR_PREEN_NOMSG },
8362 /* Ask if we should run the journal anyway */
8364 N_("Run @j anyway"),
8367 /* Run the journal by default */
8368 { PR_0_JOURNAL_RUN_DEFAULT,
8369 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8372 /* Clearing orphan inode */
8373 { PR_0_ORPHAN_CLEAR_INODE,
8374 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8377 /* Illegal block found in orphaned inode */
8378 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8379 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8382 /* Already cleared block found in orphaned inode */
8383 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8384 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8387 /* Illegal orphan inode in superblock */
8388 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8389 N_("@I @o @i %i in @S.\n"),
8392 /* Illegal inode in orphaned inode list */
8393 { PR_0_ORPHAN_ILLEGAL_INODE,
8394 N_("@I @i %i in @o @i list.\n"),
8397 /* Filesystem revision is 0, but feature flags are set */
8398 { PR_0_FS_REV_LEVEL,
8399 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8400 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8402 /* Journal superblock has an unknown read-only feature flag set */
8403 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8404 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8407 /* Journal superblock has an unknown incompatible feature flag set */
8408 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8409 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8412 /* Journal has unsupported version number */
8413 { PR_0_JOURNAL_UNSUPP_VERSION,
8414 N_("@j version not supported by this e2fsck.\n"),
8417 /* Moving journal to hidden file */
8418 { PR_0_MOVE_JOURNAL,
8419 N_("Moving @j from /%s to hidden @i.\n\n"),
8422 /* Error moving journal to hidden file */
8423 { PR_0_ERR_MOVE_JOURNAL,
8424 N_("Error moving @j: %m\n\n"),
8427 /* Clearing V2 journal superblock */
8428 { PR_0_CLEAR_V2_JOURNAL,
8429 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8430 "Clearing fields beyond the V1 @j @S...\n\n"),
8433 /* Backup journal inode blocks */
8435 N_("Backing up @j @i @b information.\n\n"),
8438 /* Reserved blocks w/o resize_inode */
8439 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8440 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8441 "is %N; @s zero. "),
8444 /* Resize_inode not enabled, but resize inode is non-zero */
8445 { PR_0_CLEAR_RESIZE_INODE,
8446 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8449 /* Resize inode invalid */
8450 { PR_0_RESIZE_INODE_INVALID,
8451 N_("Resize @i not valid. "),
8452 PROMPT_RECREATE, 0 },
8456 /* Pass 1: Checking inodes, blocks, and sizes */
8458 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8461 /* Root directory is not an inode */
8462 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8465 /* Root directory has dtime set */
8467 N_("@r has dtime set (probably due to old mke2fs). "),
8468 PROMPT_FIX, PR_PREEN_OK },
8470 /* Reserved inode has bad mode */
8471 { PR_1_RESERVED_BAD_MODE,
8472 N_("Reserved @i %i (%Q) has @n mode. "),
8473 PROMPT_CLEAR, PR_PREEN_OK },
8475 /* Deleted inode has zero dtime */
8477 N_("@D @i %i has zero dtime. "),
8478 PROMPT_FIX, PR_PREEN_OK },
8480 /* Inode in use, but dtime set */
8482 N_("@i %i is in use, but has dtime set. "),
8483 PROMPT_FIX, PR_PREEN_OK },
8485 /* Zero-length directory */
8486 { PR_1_ZERO_LENGTH_DIR,
8487 N_("@i %i is a @z @d. "),
8488 PROMPT_CLEAR, PR_PREEN_OK },
8490 /* Block bitmap conflicts with some other fs block */
8492 N_("@g %g's @b @B at %b @C.\n"),
8493 PROMPT_RELOCATE, 0 },
8495 /* Inode bitmap conflicts with some other fs block */
8497 N_("@g %g's @i @B at %b @C.\n"),
8498 PROMPT_RELOCATE, 0 },
8500 /* Inode table conflicts with some other fs block */
8501 { PR_1_ITABLE_CONFLICT,
8502 N_("@g %g's @i table at %b @C.\n"),
8503 PROMPT_RELOCATE, 0 },
8505 /* Block bitmap is on a bad block */
8506 { PR_1_BB_BAD_BLOCK,
8507 N_("@g %g's @b @B (%b) is bad. "),
8508 PROMPT_RELOCATE, 0 },
8510 /* Inode bitmap is on a bad block */
8511 { PR_1_IB_BAD_BLOCK,
8512 N_("@g %g's @i @B (%b) is bad. "),
8513 PROMPT_RELOCATE, 0 },
8515 /* Inode has incorrect i_size */
8517 N_("@i %i, i_size is %Is, @s %N. "),
8518 PROMPT_FIX, PR_PREEN_OK },
8520 /* Inode has incorrect i_blocks */
8521 { PR_1_BAD_I_BLOCKS,
8522 N_("@i %i, i_@bs is %Ib, @s %N. "),
8523 PROMPT_FIX, PR_PREEN_OK },
8525 /* Illegal blocknumber in inode */
8526 { PR_1_ILLEGAL_BLOCK_NUM,
8527 N_("@I @b #%B (%b) in @i %i. "),
8528 PROMPT_CLEAR, PR_LATCH_BLOCK },
8530 /* Block number overlaps fs metadata */
8531 { PR_1_BLOCK_OVERLAPS_METADATA,
8532 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8533 PROMPT_CLEAR, PR_LATCH_BLOCK },
8535 /* Inode has illegal blocks (latch question) */
8536 { PR_1_INODE_BLOCK_LATCH,
8537 N_("@i %i has illegal @b(s). "),
8540 /* Too many bad blocks in inode */
8541 { PR_1_TOO_MANY_BAD_BLOCKS,
8542 N_("Too many illegal @bs in @i %i.\n"),
8543 PROMPT_CLEAR_INODE, PR_NO_OK },
8545 /* Illegal block number in bad block inode */
8546 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8547 N_("@I @b #%B (%b) in bad @b @i. "),
8548 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8550 /* Bad block inode has illegal blocks (latch question) */
8551 { PR_1_INODE_BBLOCK_LATCH,
8552 N_("Bad @b @i has illegal @b(s). "),
8555 /* Duplicate or bad blocks in use! */
8556 { PR_1_DUP_BLOCKS_PREENSTOP,
8557 N_("Duplicate or bad @b in use!\n"),
8560 /* Bad block used as bad block indirect block */
8561 { PR_1_BBINODE_BAD_METABLOCK,
8562 N_("Bad @b %b used as bad @b @i indirect @b. "),
8563 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8565 /* Inconsistency can't be fixed prompt */
8566 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8567 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8568 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8570 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8572 /* Bad primary block */
8573 { PR_1_BAD_PRIMARY_BLOCK,
8574 N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
8575 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8577 /* Bad primary block prompt */
8578 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8579 N_("You can remove this @b from the bad @b list and hope\n"
8580 "that the @b is really OK. But there are no guarantees.\n\n"),
8581 PROMPT_CLEAR, PR_PREEN_NOMSG },
8583 /* Bad primary superblock */
8584 { PR_1_BAD_PRIMARY_SUPERBLOCK,
8585 N_("The primary @S (%b) is on the bad @b list.\n"),
8586 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8588 /* Bad primary block group descriptors */
8589 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8590 N_("Block %b in the primary @g descriptors "
8591 "is on the bad @b list\n"),
8592 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8594 /* Bad superblock in group */
8595 { PR_1_BAD_SUPERBLOCK,
8596 N_("Warning: Group %g's @S (%b) is bad.\n"),
8597 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8599 /* Bad block group descriptors in group */
8600 { PR_1_BAD_GROUP_DESCRIPTORS,
8601 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8603 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8605 /* Block claimed for no reason */
8606 { PR_1_PROGERR_CLAIMED_BLOCK,
8607 N_("Programming error? @b #%b claimed for no reason in "
8608 "process_bad_@b.\n"),
8609 PROMPT_NONE, PR_PREEN_OK },
8611 /* Error allocating blocks for relocating metadata */
8612 { PR_1_RELOC_BLOCK_ALLOCATE,
8613 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8614 PROMPT_NONE, PR_PREEN_OK },
8616 /* Error allocating block buffer during relocation process */
8617 { PR_1_RELOC_MEMORY_ALLOCATE,
8618 N_("@A @b buffer for relocating %s\n"),
8619 PROMPT_NONE, PR_PREEN_OK },
8621 /* Relocating metadata group information from X to Y */
8622 { PR_1_RELOC_FROM_TO,
8623 N_("Relocating @g %g's %s from %b to %c...\n"),
8624 PROMPT_NONE, PR_PREEN_OK },
8626 /* Relocating metatdata group information to X */
8628 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8629 PROMPT_NONE, PR_PREEN_OK },
8631 /* Block read error during relocation process */
8632 { PR_1_RELOC_READ_ERR,
8633 N_("Warning: could not read @b %b of %s: %m\n"),
8634 PROMPT_NONE, PR_PREEN_OK },
8636 /* Block write error during relocation process */
8637 { PR_1_RELOC_WRITE_ERR,
8638 N_("Warning: could not write @b %b for %s: %m\n"),
8639 PROMPT_NONE, PR_PREEN_OK },
8641 /* Error allocating inode bitmap */
8642 { PR_1_ALLOCATE_IBITMAP_ERROR,
8643 N_("@A @i @B (%N): %m\n"),
8644 PROMPT_NONE, PR_FATAL },
8646 /* Error allocating block bitmap */
8647 { PR_1_ALLOCATE_BBITMAP_ERROR,
8648 N_("@A @b @B (%N): %m\n"),
8649 PROMPT_NONE, PR_FATAL },
8651 /* Error allocating icount structure */
8652 { PR_1_ALLOCATE_ICOUNT,
8653 N_("@A icount link information: %m\n"),
8654 PROMPT_NONE, PR_FATAL },
8656 /* Error allocating dbcount */
8657 { PR_1_ALLOCATE_DBCOUNT,
8658 N_("@A @d @b array: %m\n"),
8659 PROMPT_NONE, PR_FATAL },
8661 /* Error while scanning inodes */
8663 N_("Error while scanning @is (%i): %m\n"),
8664 PROMPT_NONE, PR_FATAL },
8666 /* Error while iterating over blocks */
8667 { PR_1_BLOCK_ITERATE,
8668 N_("Error while iterating over @bs in @i %i: %m\n"),
8669 PROMPT_NONE, PR_FATAL },
8671 /* Error while storing inode count information */
8672 { PR_1_ICOUNT_STORE,
8673 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8674 PROMPT_NONE, PR_FATAL },
8676 /* Error while storing directory block information */
8678 N_("Error storing @d @b information "
8679 "(@i=%i, @b=%b, num=%N): %m\n"),
8680 PROMPT_NONE, PR_FATAL },
8682 /* Error while reading inode (for clearing) */
8684 N_("Error reading @i %i: %m\n"),
8685 PROMPT_NONE, PR_FATAL },
8687 /* Suppress messages prompt */
8688 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8690 /* Imagic flag set on an inode when filesystem doesn't support it */
8692 N_("@i %i has imagic flag set. "),
8695 /* Immutable flag set on a device or socket inode */
8696 { PR_1_SET_IMMUTABLE,
8697 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8698 "or append-only flag set. "),
8699 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8701 /* Compression flag set on an inode when filesystem doesn't support it */
8703 N_("@i %i has @cion flag set on @f without @cion support. "),
8706 /* Non-zero size for device, fifo or socket inode */
8707 { PR_1_SET_NONZSIZE,
8708 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8709 PROMPT_FIX, PR_PREEN_OK },
8711 /* Filesystem revision is 0, but feature flags are set */
8712 { PR_1_FS_REV_LEVEL,
8713 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8714 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8716 /* Journal inode is not in use, but contains data */
8717 { PR_1_JOURNAL_INODE_NOT_CLEAR,
8718 N_("@j @i is not in use, but contains data. "),
8719 PROMPT_CLEAR, PR_PREEN_OK },
8721 /* Journal has bad mode */
8722 { PR_1_JOURNAL_BAD_MODE,
8723 N_("@j is not regular file. "),
8724 PROMPT_FIX, PR_PREEN_OK },
8726 /* Deal with inodes that were part of orphan linked list */
8728 N_("@i %i was part of the @o @i list. "),
8729 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8731 /* Deal with inodes that were part of corrupted orphan linked
8732 list (latch question) */
8733 { PR_1_ORPHAN_LIST_REFUGEES,
8734 N_("@is that were part of a corrupted orphan linked list found. "),
8737 /* Error allocating refcount structure */
8738 { PR_1_ALLOCATE_REFCOUNT,
8739 N_("@A refcount structure (%N): %m\n"),
8740 PROMPT_NONE, PR_FATAL },
8742 /* Error reading extended attribute block */
8743 { PR_1_READ_EA_BLOCK,
8744 N_("Error reading @a @b %b for @i %i. "),
8747 /* Invalid extended attribute block */
8748 { PR_1_BAD_EA_BLOCK,
8749 N_("@i %i has a bad @a @b %b. "),
8752 /* Error reading Extended Attribute block while fixing refcount */
8753 { PR_1_EXTATTR_READ_ABORT,
8754 N_("Error reading @a @b %b (%m). "),
8757 /* Extended attribute reference count incorrect */
8758 { PR_1_EXTATTR_REFCOUNT,
8759 N_("@a @b %b has reference count %B, @s %N. "),
8762 /* Error writing Extended Attribute block while fixing refcount */
8763 { PR_1_EXTATTR_WRITE,
8764 N_("Error writing @a @b %b (%m). "),
8767 /* Multiple EA blocks not supported */
8768 { PR_1_EA_MULTI_BLOCK,
8769 N_("@a @b %b has h_@bs > 1. "),
8772 /* Error allocating EA region allocation structure */
8773 { PR_1_EA_ALLOC_REGION,
8774 N_("@A @a @b %b. "),
8777 /* Error EA allocation collision */
8778 { PR_1_EA_ALLOC_COLLISION,
8779 N_("@a @b %b is corrupt (allocation collision). "),
8782 /* Bad extended attribute name */
8784 N_("@a @b %b is corrupt (@n name). "),
8787 /* Bad extended attribute value */
8788 { PR_1_EA_BAD_VALUE,
8789 N_("@a @b %b is corrupt (@n value). "),
8792 /* Inode too big (latch question) */
8793 { PR_1_INODE_TOOBIG,
8794 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
8796 /* Directory too big */
8798 N_("@b #%B (%b) causes @d to be too big. "),
8799 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8801 /* Regular file too big */
8803 N_("@b #%B (%b) causes file to be too big. "),
8804 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8806 /* Symlink too big */
8807 { PR_1_TOOBIG_SYMLINK,
8808 N_("@b #%B (%b) causes symlink to be too big. "),
8809 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8811 /* INDEX_FL flag set on a non-HTREE filesystem */
8813 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8814 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8816 /* INDEX_FL flag set on a non-directory */
8818 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8819 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8821 /* Invalid root node in HTREE directory */
8822 { PR_1_HTREE_BADROOT,
8823 N_("@h %i has an @n root node.\n"),
8824 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8826 /* Unsupported hash version in HTREE directory */
8828 N_("@h %i has an unsupported hash version (%N)\n"),
8829 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8831 /* Incompatible flag in HTREE root node */
8832 { PR_1_HTREE_INCOMPAT,
8833 N_("@h %i uses an incompatible htree root node flag.\n"),
8834 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8836 /* HTREE too deep */
8838 N_("@h %i has a tree depth (%N) which is too big\n"),
8839 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8841 /* Bad block has indirect block that conflicts with filesystem block */
8843 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8845 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8847 /* Resize inode failed */
8848 { PR_1_RESIZE_INODE_CREATE,
8849 N_("Resize @i (re)creation failed: %m."),
8852 /* invalid inode->i_extra_isize */
8854 N_("@i %i has a extra size (%IS) which is @n\n"),
8855 PROMPT_FIX, PR_PREEN_OK },
8857 /* invalid ea entry->e_name_len */
8858 { PR_1_ATTR_NAME_LEN,
8859 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8860 PROMPT_CLEAR, PR_PREEN_OK },
8862 /* invalid ea entry->e_value_size */
8863 { PR_1_ATTR_VALUE_SIZE,
8864 N_("@a in @i %i has a value size (%N) which is @n\n"),
8865 PROMPT_CLEAR, PR_PREEN_OK },
8867 /* invalid ea entry->e_value_offs */
8868 { PR_1_ATTR_VALUE_OFFSET,
8869 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8870 PROMPT_CLEAR, PR_PREEN_OK },
8872 /* invalid ea entry->e_value_block */
8873 { PR_1_ATTR_VALUE_BLOCK,
8874 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8875 PROMPT_CLEAR, PR_PREEN_OK },
8877 /* invalid ea entry->e_hash */
8879 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8880 PROMPT_CLEAR, PR_PREEN_OK },
8882 /* Pass 1b errors */
8884 /* Pass 1B: Rescan for duplicate/bad blocks */
8885 { PR_1B_PASS_HEADER,
8886 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8887 "Pass 1B: Rescanning for @m @bs\n"),
8890 /* Duplicate/bad block(s) header */
8891 { PR_1B_DUP_BLOCK_HEADER,
8892 N_("@m @b(s) in @i %i:"),
8895 /* Duplicate/bad block(s) in inode */
8898 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8900 /* Duplicate/bad block(s) end */
8901 { PR_1B_DUP_BLOCK_END,
8903 PROMPT_NONE, PR_PREEN_NOHDR },
8905 /* Error while scanning inodes */
8906 { PR_1B_ISCAN_ERROR,
8907 N_("Error while scanning inodes (%i): %m\n"),
8908 PROMPT_NONE, PR_FATAL },
8910 /* Error allocating inode bitmap */
8911 { PR_1B_ALLOCATE_IBITMAP_ERROR,
8912 N_("@A @i @B (@i_dup_map): %m\n"),
8913 PROMPT_NONE, PR_FATAL },
8915 /* Error while iterating over blocks */
8916 { PR_1B_BLOCK_ITERATE,
8917 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8920 /* Error adjusting EA refcount */
8921 { PR_1B_ADJ_EA_REFCOUNT,
8922 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8926 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8927 { PR_1C_PASS_HEADER,
8928 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8932 /* Pass 1D: Reconciling multiply-claimed blocks */
8933 { PR_1D_PASS_HEADER,
8934 N_("Pass 1D: Reconciling @m @bs\n"),
8937 /* File has duplicate blocks */
8939 N_("File %Q (@i #%i, mod time %IM)\n"
8940 " has %B @m @b(s), shared with %N file(s):\n"),
8943 /* List of files sharing duplicate blocks */
8944 { PR_1D_DUP_FILE_LIST,
8945 N_("\t%Q (@i #%i, mod time %IM)\n"),
8948 /* File sharing blocks with filesystem metadata */
8949 { PR_1D_SHARE_METADATA,
8950 N_("\t<@f metadata>\n"),
8953 /* Report of how many duplicate/bad inodes */
8954 { PR_1D_NUM_DUP_INODES,
8955 N_("(There are %N @is containing @m @bs.)\n\n"),
8958 /* Duplicated blocks already reassigned or cloned. */
8959 { PR_1D_DUP_BLOCKS_DEALT,
8960 N_("@m @bs already reassigned or cloned.\n\n"),
8963 /* Clone duplicate/bad blocks? */
8964 { PR_1D_CLONE_QUESTION,
8965 "", PROMPT_CLONE, PR_NO_OK },
8968 { PR_1D_DELETE_QUESTION,
8969 "", PROMPT_DELETE, 0 },
8971 /* Couldn't clone file (error) */
8972 { PR_1D_CLONE_ERROR,
8973 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
8977 /* Pass 2: Checking directory structure */
8979 N_("Pass 2: Checking @d structure\n"),
8982 /* Bad inode number for '.' */
8983 { PR_2_BAD_INODE_DOT,
8984 N_("@n @i number for '.' in @d @i %i.\n"),
8987 /* Directory entry has bad inode number */
8989 N_("@E has @n @i #: %Di.\n"),
8992 /* Directory entry has deleted or unused inode */
8993 { PR_2_UNUSED_INODE,
8994 N_("@E has @D/unused @i %Di. "),
8995 PROMPT_CLEAR, PR_PREEN_OK },
8997 /* Directry entry is link to '.' */
8999 N_("@E @L to '.' "),
9002 /* Directory entry points to inode now located in a bad block */
9004 N_("@E points to @i (%Di) located in a bad @b.\n"),
9007 /* Directory entry contains a link to a directory */
9009 N_("@E @L to @d %P (%Di).\n"),
9012 /* Directory entry contains a link to the root directry */
9014 N_("@E @L to the @r.\n"),
9017 /* Directory entry has illegal characters in its name */
9019 N_("@E has illegal characters in its name.\n"),
9022 /* Missing '.' in directory inode */
9024 N_("Missing '.' in @d @i %i.\n"),
9027 /* Missing '..' in directory inode */
9028 { PR_2_MISSING_DOT_DOT,
9029 N_("Missing '..' in @d @i %i.\n"),
9032 /* First entry in directory inode doesn't contain '.' */
9034 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9037 /* Second entry in directory inode doesn't contain '..' */
9038 { PR_2_2ND_NOT_DOT_DOT,
9039 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9042 /* i_faddr should be zero */
9044 N_("i_faddr @F %IF, @s zero.\n"),
9047 /* i_file_acl should be zero */
9048 { PR_2_FILE_ACL_ZERO,
9049 N_("i_file_acl @F %If, @s zero.\n"),
9052 /* i_dir_acl should be zero */
9053 { PR_2_DIR_ACL_ZERO,
9054 N_("i_dir_acl @F %Id, @s zero.\n"),
9057 /* i_frag should be zero */
9059 N_("i_frag @F %N, @s zero.\n"),
9062 /* i_fsize should be zero */
9064 N_("i_fsize @F %N, @s zero.\n"),
9067 /* inode has bad mode */
9069 N_("@i %i (%Q) has @n mode (%Im).\n"),
9072 /* directory corrupted */
9073 { PR_2_DIR_CORRUPTED,
9074 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9075 PROMPT_SALVAGE, 0 },
9077 /* filename too long */
9078 { PR_2_FILENAME_LONG,
9079 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9080 PROMPT_TRUNCATE, 0 },
9082 /* Directory inode has a missing block (hole) */
9083 { PR_2_DIRECTORY_HOLE,
9084 N_("@d @i %i has an unallocated @b #%B. "),
9085 PROMPT_ALLOCATE, 0 },
9087 /* '.' is not NULL terminated */
9088 { PR_2_DOT_NULL_TERM,
9089 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9092 /* '..' is not NULL terminated */
9093 { PR_2_DOT_DOT_NULL_TERM,
9094 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9097 /* Illegal character device inode */
9098 { PR_2_BAD_CHAR_DEV,
9099 N_("@i %i (%Q) is an @I character @v.\n"),
9102 /* Illegal block device inode */
9103 { PR_2_BAD_BLOCK_DEV,
9104 N_("@i %i (%Q) is an @I @b @v.\n"),
9107 /* Duplicate '.' entry */
9109 N_("@E is duplicate '.' @e.\n"),
9112 /* Duplicate '..' entry */
9114 N_("@E is duplicate '..' @e.\n"),
9117 /* Internal error: couldn't find dir_info */
9119 N_("Internal error: cannot find dir_info for %i.\n"),
9120 PROMPT_NONE, PR_FATAL },
9122 /* Final rec_len is wrong */
9123 { PR_2_FINAL_RECLEN,
9124 N_("@E has rec_len of %Dr, @s %N.\n"),
9127 /* Error allocating icount structure */
9128 { PR_2_ALLOCATE_ICOUNT,
9129 N_("@A icount structure: %m\n"),
9130 PROMPT_NONE, PR_FATAL },
9132 /* Error iterating over directory blocks */
9133 { PR_2_DBLIST_ITERATE,
9134 N_("Error iterating over @d @bs: %m\n"),
9135 PROMPT_NONE, PR_FATAL },
9137 /* Error reading directory block */
9138 { PR_2_READ_DIRBLOCK,
9139 N_("Error reading @d @b %b (@i %i): %m\n"),
9140 PROMPT_CONTINUE, 0 },
9142 /* Error writing directory block */
9143 { PR_2_WRITE_DIRBLOCK,
9144 N_("Error writing @d @b %b (@i %i): %m\n"),
9145 PROMPT_CONTINUE, 0 },
9147 /* Error allocating new directory block */
9148 { PR_2_ALLOC_DIRBOCK,
9149 N_("@A new @d @b for @i %i (%s): %m\n"),
9152 /* Error deallocating inode */
9153 { PR_2_DEALLOC_INODE,
9154 N_("Error deallocating @i %i: %m\n"),
9155 PROMPT_NONE, PR_FATAL },
9157 /* Directory entry for '.' is big. Split? */
9159 N_("@d @e for '.' is big. "),
9160 PROMPT_SPLIT, PR_NO_OK },
9162 /* Illegal FIFO inode */
9164 N_("@i %i (%Q) is an @I FIFO.\n"),
9167 /* Illegal socket inode */
9169 N_("@i %i (%Q) is an @I socket.\n"),
9172 /* Directory filetype not set */
9173 { PR_2_SET_FILETYPE,
9174 N_("Setting filetype for @E to %N.\n"),
9175 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9177 /* Directory filetype incorrect */
9178 { PR_2_BAD_FILETYPE,
9179 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9182 /* Directory filetype set on filesystem */
9183 { PR_2_CLEAR_FILETYPE,
9184 N_("@E has filetype set.\n"),
9185 PROMPT_CLEAR, PR_PREEN_OK },
9187 /* Directory filename is null */
9189 N_("@E has a @z name.\n"),
9192 /* Invalid symlink */
9193 { PR_2_INVALID_SYMLINK,
9194 N_("Symlink %Q (@i #%i) is @n.\n"),
9197 /* i_file_acl (extended attribute block) is bad */
9198 { PR_2_FILE_ACL_BAD,
9199 N_("@a @b @F @n (%If).\n"),
9202 /* Filesystem contains large files, but has no such flag in sb */
9203 { PR_2_FEATURE_LARGE_FILES,
9204 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9207 /* Node in HTREE directory not referenced */
9208 { PR_2_HTREE_NOTREF,
9209 N_("@p @h %d: node (%B) not referenced\n"),
9212 /* Node in HTREE directory referenced twice */
9213 { PR_2_HTREE_DUPREF,
9214 N_("@p @h %d: node (%B) referenced twice\n"),
9217 /* Node in HTREE directory has bad min hash */
9218 { PR_2_HTREE_MIN_HASH,
9219 N_("@p @h %d: node (%B) has bad min hash\n"),
9222 /* Node in HTREE directory has bad max hash */
9223 { PR_2_HTREE_MAX_HASH,
9224 N_("@p @h %d: node (%B) has bad max hash\n"),
9227 /* Clear invalid HTREE directory */
9229 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9231 /* Bad block in htree interior node */
9232 { PR_2_HTREE_BADBLK,
9233 N_("@p @h %d (%q): bad @b number %b.\n"),
9234 PROMPT_CLEAR_HTREE, 0 },
9236 /* Error adjusting EA refcount */
9237 { PR_2_ADJ_EA_REFCOUNT,
9238 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9239 PROMPT_NONE, PR_FATAL },
9241 /* Invalid HTREE root node */
9242 { PR_2_HTREE_BAD_ROOT,
9243 N_("@p @h %d: root node is @n\n"),
9244 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9246 /* Invalid HTREE limit */
9247 { PR_2_HTREE_BAD_LIMIT,
9248 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9249 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9251 /* Invalid HTREE count */
9252 { PR_2_HTREE_BAD_COUNT,
9253 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9254 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9256 /* HTREE interior node has out-of-order hashes in table */
9257 { PR_2_HTREE_HASH_ORDER,
9258 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9259 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9261 /* Node in HTREE directory has invalid depth */
9262 { PR_2_HTREE_BAD_DEPTH,
9263 N_("@p @h %d: node (%B) has @n depth\n"),
9266 /* Duplicate directory entry found */
9267 { PR_2_DUPLICATE_DIRENT,
9268 N_("Duplicate @E found. "),
9271 /* Non-unique filename found */
9272 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9273 N_("@E has a non-unique filename.\nRename to %s"),
9276 /* Duplicate directory entry found */
9277 { PR_2_REPORT_DUP_DIRENT,
9278 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9283 /* Pass 3: Checking directory connectivity */
9285 N_("Pass 3: Checking @d connectivity\n"),
9288 /* Root inode not allocated */
9289 { PR_3_NO_ROOT_INODE,
9290 N_("@r not allocated. "),
9291 PROMPT_ALLOCATE, 0 },
9293 /* No room in lost+found */
9294 { PR_3_EXPAND_LF_DIR,
9295 N_("No room in @l @d. "),
9298 /* Unconnected directory inode */
9299 { PR_3_UNCONNECTED_DIR,
9300 N_("Unconnected @d @i %i (%p)\n"),
9301 PROMPT_CONNECT, 0 },
9303 /* /lost+found not found */
9305 N_("/@l not found. "),
9306 PROMPT_CREATE, PR_PREEN_OK },
9308 /* .. entry is incorrect */
9310 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9313 /* Bad or non-existent /lost+found. Cannot reconnect */
9315 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9318 /* Could not expand /lost+found */
9319 { PR_3_CANT_EXPAND_LPF,
9320 N_("Could not expand /@l: %m\n"),
9323 /* Could not reconnect inode */
9324 { PR_3_CANT_RECONNECT,
9325 N_("Could not reconnect %i: %m\n"),
9328 /* Error while trying to find /lost+found */
9329 { PR_3_ERR_FIND_LPF,
9330 N_("Error while trying to find /@l: %m\n"),
9333 /* Error in ext2fs_new_block while creating /lost+found */
9334 { PR_3_ERR_LPF_NEW_BLOCK,
9335 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9338 /* Error in ext2fs_new_inode while creating /lost+found */
9339 { PR_3_ERR_LPF_NEW_INODE,
9340 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9343 /* Error in ext2fs_new_dir_block while creating /lost+found */
9344 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9345 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9348 /* Error while writing directory block for /lost+found */
9349 { PR_3_ERR_LPF_WRITE_BLOCK,
9350 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9353 /* Error while adjusting inode count */
9354 { PR_3_ADJUST_INODE,
9355 N_("Error while adjusting @i count on @i %i\n"),
9358 /* Couldn't fix parent directory -- error */
9359 { PR_3_FIX_PARENT_ERR,
9360 N_("Couldn't fix parent of @i %i: %m\n\n"),
9363 /* Couldn't fix parent directory -- couldn't find it */
9364 { PR_3_FIX_PARENT_NOFIND,
9365 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9368 /* Error allocating inode bitmap */
9369 { PR_3_ALLOCATE_IBITMAP_ERROR,
9370 N_("@A @i @B (%N): %m\n"),
9371 PROMPT_NONE, PR_FATAL },
9373 /* Error creating root directory */
9374 { PR_3_CREATE_ROOT_ERROR,
9375 N_("Error creating root @d (%s): %m\n"),
9376 PROMPT_NONE, PR_FATAL },
9378 /* Error creating lost and found directory */
9379 { PR_3_CREATE_LPF_ERROR,
9380 N_("Error creating /@l @d (%s): %m\n"),
9381 PROMPT_NONE, PR_FATAL },
9383 /* Root inode is not directory; aborting */
9384 { PR_3_ROOT_NOT_DIR_ABORT,
9385 N_("@r is not a @d; aborting.\n"),
9386 PROMPT_NONE, PR_FATAL },
9388 /* Cannot proceed without a root inode. */
9389 { PR_3_NO_ROOT_INODE_ABORT,
9390 N_("can't proceed without a @r.\n"),
9391 PROMPT_NONE, PR_FATAL },
9393 /* Internal error: couldn't find dir_info */
9395 N_("Internal error: cannot find dir_info for %i.\n"),
9396 PROMPT_NONE, PR_FATAL },
9398 /* Lost+found not a directory */
9400 N_("/@l is not a @d (ino=%i)\n"),
9403 /* Pass 3A Directory Optimization */
9405 /* Pass 3A: Optimizing directories */
9406 { PR_3A_PASS_HEADER,
9407 N_("Pass 3A: Optimizing directories\n"),
9408 PROMPT_NONE, PR_PREEN_NOMSG },
9410 /* Error iterating over directories */
9411 { PR_3A_OPTIMIZE_ITER,
9412 N_("Failed to create dirs_to_hash iterator: %m"),
9415 /* Error rehash directory */
9416 { PR_3A_OPTIMIZE_DIR_ERR,
9417 N_("Failed to optimize directory %q (%d): %m"),
9420 /* Rehashing dir header */
9421 { PR_3A_OPTIMIZE_DIR_HEADER,
9422 N_("Optimizing directories: "),
9423 PROMPT_NONE, PR_MSG_ONLY },
9425 /* Rehashing directory %d */
9426 { PR_3A_OPTIMIZE_DIR,
9428 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9430 /* Rehashing dir end */
9431 { PR_3A_OPTIMIZE_DIR_END,
9433 PROMPT_NONE, PR_PREEN_NOHDR },
9437 /* Pass 4: Checking reference counts */
9439 N_("Pass 4: Checking reference counts\n"),
9442 /* Unattached zero-length inode */
9443 { PR_4_ZERO_LEN_INODE,
9444 N_("@u @z @i %i. "),
9445 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9447 /* Unattached inode */
9448 { PR_4_UNATTACHED_INODE,
9450 PROMPT_CONNECT, 0 },
9452 /* Inode ref count wrong */
9453 { PR_4_BAD_REF_COUNT,
9454 N_("@i %i ref count is %Il, @s %N. "),
9455 PROMPT_FIX, PR_PREEN_OK },
9457 { PR_4_INCONSISTENT_COUNT,
9458 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9459 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9460 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9461 "They @s the same!\n"),
9466 /* Pass 5: Checking group summary information */
9468 N_("Pass 5: Checking @g summary information\n"),
9471 /* Padding at end of inode bitmap is not set. */
9472 { PR_5_INODE_BMAP_PADDING,
9473 N_("Padding at end of @i @B is not set. "),
9474 PROMPT_FIX, PR_PREEN_OK },
9476 /* Padding at end of block bitmap is not set. */
9477 { PR_5_BLOCK_BMAP_PADDING,
9478 N_("Padding at end of @b @B is not set. "),
9479 PROMPT_FIX, PR_PREEN_OK },
9481 /* Block bitmap differences header */
9482 { PR_5_BLOCK_BITMAP_HEADER,
9483 N_("@b @B differences: "),
9484 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9486 /* Block not used, but marked in bitmap */
9487 { PR_5_BLOCK_UNUSED,
9489 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9491 /* Block used, but not marked used in bitmap */
9494 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9496 /* Block bitmap differences end */
9497 { PR_5_BLOCK_BITMAP_END,
9499 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9501 /* Inode bitmap differences header */
9502 { PR_5_INODE_BITMAP_HEADER,
9503 N_("@i @B differences: "),
9504 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9506 /* Inode not used, but marked in bitmap */
9507 { PR_5_INODE_UNUSED,
9509 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9511 /* Inode used, but not marked used in bitmap */
9514 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9516 /* Inode bitmap differences end */
9517 { PR_5_INODE_BITMAP_END,
9519 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9521 /* Free inodes count for group wrong */
9522 { PR_5_FREE_INODE_COUNT_GROUP,
9523 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9524 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9526 /* Directories count for group wrong */
9527 { PR_5_FREE_DIR_COUNT_GROUP,
9528 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9529 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9531 /* Free inodes count wrong */
9532 { PR_5_FREE_INODE_COUNT,
9533 N_("Free @is count wrong (%i, counted=%j).\n"),
9534 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9536 /* Free blocks count for group wrong */
9537 { PR_5_FREE_BLOCK_COUNT_GROUP,
9538 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9539 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9541 /* Free blocks count wrong */
9542 { PR_5_FREE_BLOCK_COUNT,
9543 N_("Free @bs count wrong (%b, counted=%c).\n"),
9544 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9546 /* Programming error: bitmap endpoints don't match */
9547 { PR_5_BMAP_ENDPOINTS,
9548 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9549 "match calculated @B endpoints (%i, %j)\n"),
9550 PROMPT_NONE, PR_FATAL },
9552 /* Internal error: fudging end of bitmap */
9553 { PR_5_FUDGE_BITMAP_ERROR,
9554 N_("Internal error: fudging end of bitmap (%N)\n"),
9555 PROMPT_NONE, PR_FATAL },
9557 /* Error copying in replacement inode bitmap */
9558 { PR_5_COPY_IBITMAP_ERROR,
9559 N_("Error copying in replacement @i @B: %m\n"),
9560 PROMPT_NONE, PR_FATAL },
9562 /* Error copying in replacement block bitmap */
9563 { PR_5_COPY_BBITMAP_ERROR,
9564 N_("Error copying in replacement @b @B: %m\n"),
9565 PROMPT_NONE, PR_FATAL },
9567 /* Block range not used, but marked in bitmap */
9568 { PR_5_BLOCK_RANGE_UNUSED,
9570 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9572 /* Block range used, but not marked used in bitmap */
9573 { PR_5_BLOCK_RANGE_USED,
9575 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9577 /* Inode range not used, but marked in bitmap */
9578 { PR_5_INODE_RANGE_UNUSED,
9580 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9582 /* Inode range used, but not marked used in bitmap */
9583 { PR_5_INODE_RANGE_USED,
9585 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9591 * This is the latch flags register. It allows several problems to be
9592 * "latched" together. This means that the user has to answer but one
9593 * question for the set of problems, and all of the associated
9594 * problems will be either fixed or not fixed.
9596 static struct latch_descr pr_latch_info[] = {
9597 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9598 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9599 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9600 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9601 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9602 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9603 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9604 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9605 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9609 static const struct e2fsck_problem *find_problem(problem_t code)
9613 for (i=0; problem_table[i].e2p_code; i++) {
9614 if (problem_table[i].e2p_code == code)
9615 return &problem_table[i];
9620 static struct latch_descr *find_latch(int code)
9624 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9625 if (pr_latch_info[i].latch_code == code)
9626 return &pr_latch_info[i];
9631 int end_problem_latch(e2fsck_t ctx, int mask)
9633 struct latch_descr *ldesc;
9634 struct problem_context pctx;
9637 ldesc = find_latch(mask);
9638 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9639 clear_problem_context(&pctx);
9640 answer = fix_problem(ctx, ldesc->end_message, &pctx);
9642 ldesc->flags &= ~(PRL_VARIABLE);
9646 int set_latch_flags(int mask, int setflags, int clearflags)
9648 struct latch_descr *ldesc;
9650 ldesc = find_latch(mask);
9653 ldesc->flags |= setflags;
9654 ldesc->flags &= ~clearflags;
9658 void clear_problem_context(struct problem_context *ctx)
9660 memset(ctx, 0, sizeof(struct problem_context));
9665 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9667 ext2_filsys fs = ctx->fs;
9668 const struct e2fsck_problem *ptr;
9669 struct latch_descr *ldesc = NULL;
9670 const char *message;
9671 int def_yn, answer, ans;
9672 int print_answer = 0;
9675 ptr = find_problem(code);
9677 printf(_("Unhandled error code (0x%x)!\n"), code);
9681 if ((ptr->flags & PR_NO_DEFAULT) ||
9682 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9683 (ctx->options & E2F_OPT_NO))
9687 * Do special latch processing. This is where we ask the
9688 * latch question, if it exists
9690 if (ptr->flags & PR_LATCH_MASK) {
9691 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9692 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9693 ans = fix_problem(ctx, ldesc->question, pctx);
9695 ldesc->flags |= PRL_YES;
9697 ldesc->flags |= PRL_NO;
9698 ldesc->flags |= PRL_LATCHED;
9700 if (ldesc->flags & PRL_SUPPRESS)
9703 if ((ptr->flags & PR_PREEN_NOMSG) &&
9704 (ctx->options & E2F_OPT_PREEN))
9706 if ((ptr->flags & PR_NO_NOMSG) &&
9707 (ctx->options & E2F_OPT_NO))
9710 message = ptr->e2p_description;
9711 if ((ctx->options & E2F_OPT_PREEN) &&
9712 !(ptr->flags & PR_PREEN_NOHDR)) {
9713 printf("%s: ", ctx->device_name ?
9714 ctx->device_name : ctx->filesystem_name);
9717 print_e2fsck_message(ctx, _(message), pctx, 1);
9719 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9722 if (ptr->flags & PR_FATAL)
9723 bb_error_msg_and_die(0);
9725 if (ptr->prompt == PROMPT_NONE) {
9726 if (ptr->flags & PR_NOCOLLATE)
9731 if (ctx->options & E2F_OPT_PREEN) {
9733 if (!(ptr->flags & PR_PREEN_NOMSG))
9735 } else if ((ptr->flags & PR_LATCH_MASK) &&
9736 (ldesc->flags & (PRL_YES | PRL_NO))) {
9739 if (ldesc->flags & PRL_YES)
9744 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9745 if (!answer && !(ptr->flags & PR_NO_OK))
9746 ext2fs_unmark_valid(fs);
9749 printf("%s.\n", answer ?
9750 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9754 if ((ptr->prompt == PROMPT_ABORT) && answer)
9755 bb_error_msg_and_die(0);
9757 if (ptr->flags & PR_AFTER_CODE)
9758 answer = fix_problem(ctx, ptr->second_code, pctx);
9764 * linux/fs/recovery.c
9766 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9770 * Maintain information about the progress of the recovery job, so that
9771 * the different passes can carry information between them.
9773 struct recovery_info
9775 tid_t start_transaction;
9776 tid_t end_transaction;
9783 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9784 static int do_one_pass(journal_t *journal,
9785 struct recovery_info *info, enum passtype pass);
9786 static int scan_revoke_records(journal_t *, struct buffer_head *,
9787 tid_t, struct recovery_info *);
9790 * Read a block from the journal
9793 static int jread(struct buffer_head **bhp, journal_t *journal,
9794 unsigned int offset)
9797 unsigned long blocknr;
9798 struct buffer_head *bh;
9802 err = journal_bmap(journal, offset, &blocknr);
9805 printf("JBD: bad block at offset %u\n", offset);
9809 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9813 if (!buffer_uptodate(bh)) {
9814 /* If this is a brand new buffer, start readahead.
9815 Otherwise, we assume we are already reading it. */
9816 if (!buffer_req(bh))
9817 do_readahead(journal, offset);
9821 if (!buffer_uptodate(bh)) {
9822 printf("JBD: Failed to read block at offset %u\n", offset);
9833 * Count the number of in-use tags in a journal descriptor block.
9836 static int count_tags(struct buffer_head *bh, int size)
9839 journal_block_tag_t * tag;
9842 tagp = &bh->b_data[sizeof(journal_header_t)];
9844 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9845 tag = (journal_block_tag_t *) tagp;
9848 tagp += sizeof(journal_block_tag_t);
9849 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9852 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9860 /* Make sure we wrap around the log correctly! */
9861 #define wrap(journal, var) \
9863 if (var >= (journal)->j_last) \
9864 var -= ((journal)->j_last - (journal)->j_first); \
9868 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9869 * @journal: the journal to recover
9871 * The primary function for recovering the log contents when mounting a
9874 * Recovery is done in three passes. In the first pass, we look for the
9875 * end of the log. In the second, we assemble the list of revoke
9876 * blocks. In the third and final pass, we replay any un-revoked blocks
9879 int journal_recover(journal_t *journal)
9882 journal_superblock_t * sb;
9884 struct recovery_info info;
9886 memset(&info, 0, sizeof(info));
9887 sb = journal->j_superblock;
9890 * The journal superblock's s_start field (the current log head)
9891 * is always zero if, and only if, the journal was cleanly
9896 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9900 err = do_one_pass(journal, &info, PASS_SCAN);
9902 err = do_one_pass(journal, &info, PASS_REVOKE);
9904 err = do_one_pass(journal, &info, PASS_REPLAY);
9906 /* Restart the log at the next transaction ID, thus invalidating
9907 * any existing commit records in the log. */
9908 journal->j_transaction_sequence = ++info.end_transaction;
9910 journal_clear_revoke(journal);
9911 sync_blockdev(journal->j_fs_dev);
9915 static int do_one_pass(journal_t *journal,
9916 struct recovery_info *info, enum passtype pass)
9918 unsigned int first_commit_ID, next_commit_ID;
9919 unsigned long next_log_block;
9920 int err, success = 0;
9921 journal_superblock_t * sb;
9922 journal_header_t * tmp;
9923 struct buffer_head * bh;
9924 unsigned int sequence;
9927 /* Precompute the maximum metadata descriptors in a descriptor block */
9928 int MAX_BLOCKS_PER_DESC;
9929 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9930 / sizeof(journal_block_tag_t));
9933 * First thing is to establish what we expect to find in the log
9934 * (in terms of transaction IDs), and where (in terms of log
9935 * block offsets): query the superblock.
9938 sb = journal->j_superblock;
9939 next_commit_ID = ntohl(sb->s_sequence);
9940 next_log_block = ntohl(sb->s_start);
9942 first_commit_ID = next_commit_ID;
9943 if (pass == PASS_SCAN)
9944 info->start_transaction = first_commit_ID;
9947 * Now we walk through the log, transaction by transaction,
9948 * making sure that each transaction has a commit block in the
9949 * expected place. Each complete transaction gets replayed back
9950 * into the main filesystem.
9956 journal_block_tag_t * tag;
9957 struct buffer_head * obh;
9958 struct buffer_head * nbh;
9960 /* If we already know where to stop the log traversal,
9961 * check right now that we haven't gone past the end of
9964 if (pass != PASS_SCAN)
9965 if (tid_geq(next_commit_ID, info->end_transaction))
9968 /* Skip over each chunk of the transaction looking
9969 * either the next descriptor block or the final commit
9972 err = jread(&bh, journal, next_log_block);
9977 wrap(journal, next_log_block);
9979 /* What kind of buffer is it?
9981 * If it is a descriptor block, check that it has the
9982 * expected sequence number. Otherwise, we're all done
9985 tmp = (journal_header_t *)bh->b_data;
9987 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
9992 blocktype = ntohl(tmp->h_blocktype);
9993 sequence = ntohl(tmp->h_sequence);
9995 if (sequence != next_commit_ID) {
10000 /* OK, we have a valid descriptor block which matches
10001 * all of the sequence number checks. What are we going
10002 * to do with it? That depends on the pass... */
10004 switch (blocktype) {
10005 case JFS_DESCRIPTOR_BLOCK:
10006 /* If it is a valid descriptor block, replay it
10007 * in pass REPLAY; otherwise, just skip over the
10008 * blocks it describes. */
10009 if (pass != PASS_REPLAY) {
10011 count_tags(bh, journal->j_blocksize);
10012 wrap(journal, next_log_block);
10017 /* A descriptor block: we can now write all of
10018 * the data blocks. Yay, useful work is finally
10019 * getting done here! */
10021 tagp = &bh->b_data[sizeof(journal_header_t)];
10022 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10023 <= journal->j_blocksize) {
10024 unsigned long io_block;
10026 tag = (journal_block_tag_t *) tagp;
10027 flags = ntohl(tag->t_flags);
10029 io_block = next_log_block++;
10030 wrap(journal, next_log_block);
10031 err = jread(&obh, journal, io_block);
10033 /* Recover what we can, but
10034 * report failure at the end. */
10036 printf("JBD: IO error %d recovering "
10037 "block %ld in log\n",
10040 unsigned long blocknr;
10042 blocknr = ntohl(tag->t_blocknr);
10044 /* If the block has been
10045 * revoked, then we're all done
10047 if (journal_test_revoke
10051 ++info->nr_revoke_hits;
10055 /* Find a buffer for the new
10056 * data being restored */
10057 nbh = getblk(journal->j_fs_dev,
10059 journal->j_blocksize);
10061 printf("JBD: Out of memory "
10062 "during recovery.\n");
10070 memcpy(nbh->b_data, obh->b_data,
10071 journal->j_blocksize);
10072 if (flags & JFS_FLAG_ESCAPE) {
10073 *((unsigned int *)bh->b_data) =
10074 htonl(JFS_MAGIC_NUMBER);
10077 mark_buffer_uptodate(nbh, 1);
10078 mark_buffer_dirty(nbh);
10079 ++info->nr_replays;
10080 /* ll_rw_block(WRITE, 1, &nbh); */
10081 unlock_buffer(nbh);
10087 tagp += sizeof(journal_block_tag_t);
10088 if (!(flags & JFS_FLAG_SAME_UUID))
10091 if (flags & JFS_FLAG_LAST_TAG)
10098 case JFS_COMMIT_BLOCK:
10099 /* Found an expected commit block: not much to
10100 * do other than move on to the next sequence
10106 case JFS_REVOKE_BLOCK:
10107 /* If we aren't in the REVOKE pass, then we can
10108 * just skip over this block. */
10109 if (pass != PASS_REVOKE) {
10114 err = scan_revoke_records(journal, bh,
10115 next_commit_ID, info);
10128 * We broke out of the log scan loop: either we came to the
10129 * known end of the log or we found an unexpected block in the
10130 * log. If the latter happened, then we know that the "current"
10131 * transaction marks the end of the valid log.
10134 if (pass == PASS_SCAN)
10135 info->end_transaction = next_commit_ID;
10137 /* It's really bad news if different passes end up at
10138 * different places (but possible due to IO errors). */
10139 if (info->end_transaction != next_commit_ID) {
10140 printf("JBD: recovery pass %d ended at "
10141 "transaction %u, expected %u\n",
10142 pass, next_commit_ID, info->end_transaction);
10155 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10157 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10158 tid_t sequence, struct recovery_info *info)
10160 journal_revoke_header_t *header;
10163 header = (journal_revoke_header_t *) bh->b_data;
10164 offset = sizeof(journal_revoke_header_t);
10165 max = ntohl(header->r_count);
10167 while (offset < max) {
10168 unsigned long blocknr;
10171 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10173 err = journal_set_revoke(journal, blocknr, sequence);
10176 ++info->nr_revokes;
10183 * rehash.c --- rebuild hash tree directories
10185 * This algorithm is designed for simplicity of implementation and to
10186 * pack the directory as much as possible. It however requires twice
10187 * as much memory as the size of the directory. The maximum size
10188 * directory supported using a 4k blocksize is roughly a gigabyte, and
10189 * so there may very well be problems with machines that don't have
10190 * virtual memory, and obscenely large directories.
10192 * An alternate algorithm which is much more disk intensive could be
10193 * written, and probably will need to be written in the future. The
10194 * design goals of such an algorithm are: (a) use (roughly) constant
10195 * amounts of memory, no matter how large the directory, (b) the
10196 * directory must be safe at all times, even if e2fsck is interrupted
10197 * in the middle, (c) we must use minimal amounts of extra disk
10198 * blocks. This pretty much requires an incremental approach, where
10199 * we are reading from one part of the directory, and inserting into
10200 * the front half. So the algorithm will have to keep track of a
10201 * moving block boundary between the new tree and the old tree, and
10202 * files will need to be moved from the old directory and inserted
10203 * into the new tree. If the new directory requires space which isn't
10204 * yet available, blocks from the beginning part of the old directory
10205 * may need to be moved to the end of the directory to make room for
10208 * --------------------------------------------------------
10209 * | new tree | | old tree |
10210 * --------------------------------------------------------
10212 * tail new head old
10214 * This is going to be a pain in the tuckus to implement, and will
10215 * require a lot more disk accesses. So I'm going to skip it for now;
10216 * it's only really going to be an issue for really, really big
10217 * filesystems (when we reach the level of tens of millions of files
10218 * in a single directory). It will probably be easier to simply
10219 * require that e2fsck use VM first.
10222 struct fill_dir_struct {
10224 struct ext2_inode *inode;
10227 struct hash_entry *harray;
10228 int max_array, num_array;
10234 struct hash_entry {
10235 ext2_dirhash_t hash;
10236 ext2_dirhash_t minor_hash;
10237 struct ext2_dir_entry *dir;
10244 ext2_dirhash_t *hashes;
10247 static int fill_dir_block(ext2_filsys fs,
10249 e2_blkcnt_t blockcnt,
10250 blk_t ref_block FSCK_ATTR((unused)),
10251 int ref_offset FSCK_ATTR((unused)),
10254 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10255 struct hash_entry *new_array, *ent;
10256 struct ext2_dir_entry *dirent;
10258 unsigned int offset, dir_offset;
10263 offset = blockcnt * fs->blocksize;
10264 if (offset + fs->blocksize > fd->inode->i_size) {
10265 fd->err = EXT2_ET_DIR_CORRUPTED;
10266 return BLOCK_ABORT;
10268 dir = (fd->buf+offset);
10269 if (HOLE_BLKADDR(*block_nr)) {
10270 memset(dir, 0, fs->blocksize);
10271 dirent = (struct ext2_dir_entry *) dir;
10272 dirent->rec_len = fs->blocksize;
10274 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10276 return BLOCK_ABORT;
10278 /* While the directory block is "hot", index it. */
10280 while (dir_offset < fs->blocksize) {
10281 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10282 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10283 (dirent->rec_len < 8) ||
10284 ((dirent->rec_len % 4) != 0) ||
10285 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10286 fd->err = EXT2_ET_DIR_CORRUPTED;
10287 return BLOCK_ABORT;
10289 dir_offset += dirent->rec_len;
10290 if (dirent->inode == 0)
10292 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10293 (dirent->name[0] == '.'))
10295 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10296 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10297 fd->parent = dirent->inode;
10300 if (fd->num_array >= fd->max_array) {
10301 new_array = xrealloc(fd->harray,
10302 sizeof(struct hash_entry) * (fd->max_array+500));
10303 fd->harray = new_array;
10304 fd->max_array += 500;
10306 ent = fd->harray + fd->num_array++;
10308 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10310 ent->hash = ent->minor_hash = 0;
10312 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10314 dirent->name_len & 0xFF,
10315 fs->super->s_hash_seed,
10316 &ent->hash, &ent->minor_hash);
10318 return BLOCK_ABORT;
10325 /* Used for sorting the hash entry */
10326 static int name_cmp(const void *a, const void *b)
10328 const struct hash_entry *he_a = (const struct hash_entry *) a;
10329 const struct hash_entry *he_b = (const struct hash_entry *) b;
10333 min_len = he_a->dir->name_len;
10334 if (min_len > he_b->dir->name_len)
10335 min_len = he_b->dir->name_len;
10337 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10339 if (he_a->dir->name_len > he_b->dir->name_len)
10341 else if (he_a->dir->name_len < he_b->dir->name_len)
10344 ret = he_b->dir->inode - he_a->dir->inode;
10349 /* Used for sorting the hash entry */
10350 static int hash_cmp(const void *a, const void *b)
10352 const struct hash_entry *he_a = (const struct hash_entry *) a;
10353 const struct hash_entry *he_b = (const struct hash_entry *) b;
10356 if (he_a->hash > he_b->hash)
10358 else if (he_a->hash < he_b->hash)
10361 if (he_a->minor_hash > he_b->minor_hash)
10363 else if (he_a->minor_hash < he_b->minor_hash)
10366 ret = name_cmp(a, b);
10371 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10377 new_mem = xrealloc(outdir->buf, blocks * fs->blocksize);
10378 outdir->buf = new_mem;
10379 new_mem = xrealloc(outdir->hashes,
10380 blocks * sizeof(ext2_dirhash_t));
10381 outdir->hashes = new_mem;
10383 outdir->buf = xmalloc(blocks * fs->blocksize);
10384 outdir->hashes = xmalloc(blocks * sizeof(ext2_dirhash_t));
10387 outdir->max = blocks;
10391 static void free_out_dir(struct out_dir *outdir)
10394 free(outdir->hashes);
10399 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10404 if (outdir->num >= outdir->max) {
10405 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10409 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10410 memset(*ret, 0, fs->blocksize);
10415 * This function is used to make a unique filename. We do this by
10416 * appending ~0, and then incrementing the number. However, we cannot
10417 * expand the length of the filename beyond the padding available in
10418 * the directory entry.
10420 static void mutate_name(char *str, __u16 *len)
10423 __u16 l = *len & 0xFF, h = *len & 0xff00;
10426 * First check to see if it looks the name has been mutated
10429 for (i = l-1; i > 0; i--) {
10430 if (!isdigit(str[i]))
10433 if ((i == l-1) || (str[i] != '~')) {
10434 if (((l-1) & 3) < 2)
10443 for (i = l-1; i >= 0; i--) {
10444 if (isdigit(str[i])) {
10456 else if (str[0] == 'Z') {
10461 } else if (i > 0) {
10474 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10476 struct fill_dir_struct *fd)
10478 struct problem_context pctx;
10479 struct hash_entry *ent, *prev;
10482 char new_name[256];
10485 clear_problem_context(&pctx);
10488 for (i=1; i < fd->num_array; i++) {
10489 ent = fd->harray + i;
10491 if (!ent->dir->inode ||
10492 ((ent->dir->name_len & 0xFF) !=
10493 (prev->dir->name_len & 0xFF)) ||
10494 (strncmp(ent->dir->name, prev->dir->name,
10495 ent->dir->name_len & 0xFF)))
10497 pctx.dirent = ent->dir;
10498 if ((ent->dir->inode == prev->dir->inode) &&
10499 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10500 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10501 ent->dir->inode = 0;
10505 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10506 new_len = ent->dir->name_len;
10507 mutate_name(new_name, &new_len);
10508 for (j=0; j < fd->num_array; j++) {
10510 ((ent->dir->name_len & 0xFF) !=
10511 (fd->harray[j].dir->name_len & 0xFF)) ||
10512 (strncmp(new_name, fd->harray[j].dir->name,
10515 mutate_name(new_name, &new_len);
10519 new_name[new_len & 0xFF] = 0;
10520 pctx.str = new_name;
10521 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10522 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10523 ent->dir->name_len = new_len;
10524 ext2fs_dirhash(fs->super->s_def_hash_version,
10526 ent->dir->name_len & 0xFF,
10527 fs->super->s_hash_seed,
10528 &ent->hash, &ent->minor_hash);
10536 static errcode_t copy_dir_entries(ext2_filsys fs,
10537 struct fill_dir_struct *fd,
10538 struct out_dir *outdir)
10542 struct hash_entry *ent;
10543 struct ext2_dir_entry *dirent;
10544 int i, rec_len, left;
10545 ext2_dirhash_t prev_hash;
10549 retval = alloc_size_dir(fs, outdir,
10550 (fd->dir_size / fs->blocksize) + 2);
10553 outdir->num = fd->compress ? 0 : 1;
10555 outdir->hashes[0] = 0;
10557 if ((retval = get_next_block(fs, outdir, &block_start)))
10559 dirent = (struct ext2_dir_entry *) block_start;
10560 left = fs->blocksize;
10561 for (i=0; i < fd->num_array; i++) {
10562 ent = fd->harray + i;
10563 if (ent->dir->inode == 0)
10565 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10566 if (rec_len > left) {
10568 dirent->rec_len += left;
10569 if ((retval = get_next_block(fs, outdir,
10574 left = fs->blocksize - offset;
10575 dirent = (struct ext2_dir_entry *) (block_start + offset);
10577 if (ent->hash == prev_hash)
10578 outdir->hashes[outdir->num-1] = ent->hash | 1;
10580 outdir->hashes[outdir->num-1] = ent->hash;
10582 dirent->inode = ent->dir->inode;
10583 dirent->name_len = ent->dir->name_len;
10584 dirent->rec_len = rec_len;
10585 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10589 dirent->rec_len += left;
10593 prev_hash = ent->hash;
10596 dirent->rec_len += left;
10602 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10603 ext2_ino_t ino, ext2_ino_t parent)
10605 struct ext2_dir_entry *dir;
10606 struct ext2_dx_root_info *root;
10607 struct ext2_dx_countlimit *limits;
10610 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10611 filetype = EXT2_FT_DIR << 8;
10613 memset(buf, 0, fs->blocksize);
10614 dir = (struct ext2_dir_entry *) buf;
10616 dir->name[0] = '.';
10617 dir->name_len = 1 | filetype;
10619 dir = (struct ext2_dir_entry *) (buf + 12);
10620 dir->inode = parent;
10621 dir->name[0] = '.';
10622 dir->name[1] = '.';
10623 dir->name_len = 2 | filetype;
10624 dir->rec_len = fs->blocksize - 12;
10626 root = (struct ext2_dx_root_info *) (buf+24);
10627 root->reserved_zero = 0;
10628 root->hash_version = fs->super->s_def_hash_version;
10629 root->info_length = 8;
10630 root->indirect_levels = 0;
10631 root->unused_flags = 0;
10633 limits = (struct ext2_dx_countlimit *) (buf+32);
10634 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10641 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10643 struct ext2_dir_entry *dir;
10644 struct ext2_dx_countlimit *limits;
10646 memset(buf, 0, fs->blocksize);
10647 dir = (struct ext2_dir_entry *) buf;
10649 dir->rec_len = fs->blocksize;
10651 limits = (struct ext2_dx_countlimit *) (buf+8);
10652 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10655 return (struct ext2_dx_entry *) limits;
10659 * This function takes the leaf nodes which have been written in
10660 * outdir, and populates the root node and any necessary interior nodes.
10662 static errcode_t calculate_tree(ext2_filsys fs,
10663 struct out_dir *outdir,
10667 struct ext2_dx_root_info *root_info;
10668 struct ext2_dx_entry *root, *dx_ent = NULL;
10669 struct ext2_dx_countlimit *root_limit, *limit;
10671 char * block_start;
10672 int i, c1, c2, nblks;
10673 int limit_offset, root_offset;
10675 root_info = set_root_node(fs, outdir->buf, ino, parent);
10676 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10677 root_info->info_length;
10678 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10679 c1 = root_limit->limit;
10680 nblks = outdir->num;
10682 /* Write out the pointer blocks */
10683 if (nblks-1 <= c1) {
10684 /* Just write out the root block, and we're done */
10685 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10686 for (i=1; i < nblks; i++) {
10687 root->block = ext2fs_cpu_to_le32(i);
10690 ext2fs_cpu_to_le32(outdir->hashes[i]);
10697 root_info->indirect_levels = 1;
10698 for (i=1; i < nblks; i++) {
10703 limit->limit = limit->count =
10704 ext2fs_cpu_to_le16(limit->limit);
10705 root = (struct ext2_dx_entry *)
10706 (outdir->buf + root_offset);
10707 root->block = ext2fs_cpu_to_le32(outdir->num);
10710 ext2fs_cpu_to_le32(outdir->hashes[i]);
10711 if ((retval = get_next_block(fs, outdir,
10714 dx_ent = set_int_node(fs, block_start);
10715 limit = (struct ext2_dx_countlimit *) dx_ent;
10717 root_offset += sizeof(struct ext2_dx_entry);
10720 dx_ent->block = ext2fs_cpu_to_le32(i);
10721 if (c2 != limit->limit)
10723 ext2fs_cpu_to_le32(outdir->hashes[i]);
10727 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10728 limit->limit = ext2fs_cpu_to_le16(limit->limit);
10730 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10731 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10732 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10737 struct write_dir_struct {
10738 struct out_dir *outdir;
10745 * Helper function which writes out a directory block.
10747 static int write_dir_block(ext2_filsys fs,
10749 e2_blkcnt_t blockcnt,
10750 blk_t ref_block FSCK_ATTR((unused)),
10751 int ref_offset FSCK_ATTR((unused)),
10754 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10758 if (*block_nr == 0)
10760 if (blockcnt >= wd->outdir->num) {
10761 e2fsck_read_bitmaps(wd->ctx);
10763 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10764 ext2fs_block_alloc_stats(fs, blk, -1);
10767 return BLOCK_CHANGED;
10772 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10773 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10775 return BLOCK_ABORT;
10779 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10780 struct out_dir *outdir,
10781 ext2_ino_t ino, int compress)
10783 struct write_dir_struct wd;
10785 struct ext2_inode inode;
10787 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10791 wd.outdir = outdir;
10796 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10797 write_dir_block, &wd);
10803 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10805 inode.i_flags &= ~EXT2_INDEX_FL;
10807 inode.i_flags |= EXT2_INDEX_FL;
10808 inode.i_size = outdir->num * fs->blocksize;
10809 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10810 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10815 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10817 ext2_filsys fs = ctx->fs;
10819 struct ext2_inode inode;
10820 char *dir_buf = NULL;
10821 struct fill_dir_struct fd;
10822 struct out_dir outdir;
10824 outdir.max = outdir.num = 0;
10827 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10831 dir_buf = xmalloc(inode.i_size);
10833 fd.max_array = inode.i_size / 32;
10835 fd.harray = xmalloc(fd.max_array * sizeof(struct hash_entry));
10843 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10844 (inode.i_size / fs->blocksize) < 2)
10848 /* Read in the entire directory into memory */
10849 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10850 fill_dir_block, &fd);
10856 /* Sort the list */
10859 qsort(fd.harray+2, fd.num_array-2,
10860 sizeof(struct hash_entry), name_cmp);
10862 qsort(fd.harray, fd.num_array,
10863 sizeof(struct hash_entry), hash_cmp);
10866 * Look for duplicates
10868 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10871 if (ctx->options & E2F_OPT_NO) {
10877 * Copy the directory entries. In a htree directory these
10878 * will become the leaf nodes.
10880 retval = copy_dir_entries(fs, &fd, &outdir);
10884 free(dir_buf); dir_buf = 0;
10886 if (!fd.compress) {
10887 /* Calculate the interior nodes */
10888 retval = calculate_tree(fs, &outdir, ino, fd.parent);
10893 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10899 free_out_dir(&outdir);
10903 void e2fsck_rehash_directories(e2fsck_t ctx)
10905 struct problem_context pctx;
10906 struct dir_info *dir;
10907 ext2_u32_iterate iter;
10910 int i, cur, max, all_dirs, dir_index, first = 1;
10912 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10914 if (!ctx->dirs_to_hash && !all_dirs)
10917 e2fsck_get_lost_and_found(ctx, 0);
10919 clear_problem_context(&pctx);
10921 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10925 max = e2fsck_get_num_dirinfo(ctx);
10927 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10930 pctx.errcode = retval;
10931 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10934 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10938 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10942 if (!ext2fs_u32_list_iterate(iter, &ino))
10945 if (ino == ctx->lost_and_found)
10949 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
10952 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
10953 if (pctx.errcode) {
10954 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10955 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
10957 if (ctx->progress && !ctx->progress_fd)
10958 e2fsck_simple_progress(ctx, "Rebuilding directory",
10959 100.0 * (float) (++cur) / (float) max, ino);
10961 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10963 ext2fs_u32_list_iterate_end(iter);
10965 ext2fs_u32_list_free(ctx->dirs_to_hash);
10966 ctx->dirs_to_hash = 0;
10970 * linux/fs/revoke.c
10972 * Journal revoke routines for the generic filesystem journaling code;
10973 * part of the ext2fs journaling system.
10975 * Revoke is the mechanism used to prevent old log records for deleted
10976 * metadata from being replayed on top of newer data using the same
10977 * blocks. The revoke mechanism is used in two separate places:
10979 * + Commit: during commit we write the entire list of the current
10980 * transaction's revoked blocks to the journal
10982 * + Recovery: during recovery we record the transaction ID of all
10983 * revoked blocks. If there are multiple revoke records in the log
10984 * for a single block, only the last one counts, and if there is a log
10985 * entry for a block beyond the last revoke, then that log entry still
10988 * We can get interactions between revokes and new log data within a
10989 * single transaction:
10991 * Block is revoked and then journaled:
10992 * The desired end result is the journaling of the new block, so we
10993 * cancel the revoke before the transaction commits.
10995 * Block is journaled and then revoked:
10996 * The revoke must take precedence over the write of the block, so we
10997 * need either to cancel the journal entry or to write the revoke
10998 * later in the log than the log block. In this case, we choose the
10999 * latter: journaling a block cancels any revoke record for that block
11000 * in the current transaction, so any revoke for that block in the
11001 * transaction must have happened after the block was journaled and so
11002 * the revoke must take precedence.
11004 * Block is revoked and then written as data:
11005 * The data write is allowed to succeed, but the revoke is _not_
11006 * cancelled. We still need to prevent old log records from
11007 * overwriting the new data. We don't even need to clear the revoke
11010 * Revoke information on buffers is a tri-state value:
11012 * RevokeValid clear: no cached revoke status, need to look it up
11013 * RevokeValid set, Revoked clear:
11014 * buffer has not been revoked, and cancel_revoke
11016 * RevokeValid set, Revoked set:
11017 * buffer has been revoked.
11020 static kmem_cache_t *revoke_record_cache;
11021 static kmem_cache_t *revoke_table_cache;
11023 /* Each revoke record represents one single revoked block. During
11024 journal replay, this involves recording the transaction ID of the
11025 last transaction to revoke this block. */
11027 struct jbd_revoke_record_s
11029 struct list_head hash;
11030 tid_t sequence; /* Used for recovery only */
11031 unsigned long blocknr;
11035 /* The revoke table is just a simple hash table of revoke records. */
11036 struct jbd_revoke_table_s
11038 /* It is conceivable that we might want a larger hash table
11039 * for recovery. Must be a power of two. */
11042 struct list_head *hash_table;
11046 /* Utility functions to maintain the revoke table */
11048 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11049 static int hash(journal_t *journal, unsigned long block)
11051 struct jbd_revoke_table_s *table = journal->j_revoke;
11052 int hash_shift = table->hash_shift;
11054 return ((block << (hash_shift - 6)) ^
11056 (block << (hash_shift - 12))) & (table->hash_size - 1);
11059 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11062 struct list_head *hash_list;
11063 struct jbd_revoke_record_s *record;
11065 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11069 record->sequence = seq;
11070 record->blocknr = blocknr;
11071 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11072 list_add(&record->hash, hash_list);
11079 /* Find a revoke record in the journal's hash table. */
11081 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11082 unsigned long blocknr)
11084 struct list_head *hash_list;
11085 struct jbd_revoke_record_s *record;
11087 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11089 record = (struct jbd_revoke_record_s *) hash_list->next;
11090 while (&(record->hash) != hash_list) {
11091 if (record->blocknr == blocknr)
11093 record = (struct jbd_revoke_record_s *) record->hash.next;
11098 int journal_init_revoke_caches(void)
11100 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11101 if (revoke_record_cache == 0)
11104 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11105 if (revoke_table_cache == 0) {
11106 do_cache_destroy(revoke_record_cache);
11107 revoke_record_cache = NULL;
11113 void journal_destroy_revoke_caches(void)
11115 do_cache_destroy(revoke_record_cache);
11116 revoke_record_cache = 0;
11117 do_cache_destroy(revoke_table_cache);
11118 revoke_table_cache = 0;
11121 /* Initialise the revoke table for a given journal to a given size. */
11123 int journal_init_revoke(journal_t *journal, int hash_size)
11127 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11128 if (!journal->j_revoke)
11131 /* Check that the hash_size is a power of two */
11132 journal->j_revoke->hash_size = hash_size;
11136 while ((tmp >>= 1UL) != 0UL)
11138 journal->j_revoke->hash_shift = shift;
11140 journal->j_revoke->hash_table = xmalloc(hash_size * sizeof(struct list_head));
11142 for (tmp = 0; tmp < hash_size; tmp++)
11143 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11148 /* Destoy a journal's revoke table. The table must already be empty! */
11150 void journal_destroy_revoke(journal_t *journal)
11152 struct jbd_revoke_table_s *table;
11153 struct list_head *hash_list;
11156 table = journal->j_revoke;
11160 for (i=0; i<table->hash_size; i++) {
11161 hash_list = &table->hash_table[i];
11164 free(table->hash_table);
11166 journal->j_revoke = NULL;
11170 * Revoke support for recovery.
11172 * Recovery needs to be able to:
11174 * record all revoke records, including the tid of the latest instance
11175 * of each revoke in the journal
11177 * check whether a given block in a given transaction should be replayed
11178 * (ie. has not been revoked by a revoke record in that or a subsequent
11181 * empty the revoke table after recovery.
11185 * First, setting revoke records. We create a new revoke record for
11186 * every block ever revoked in the log as we scan it for recovery, and
11187 * we update the existing records if we find multiple revokes for a
11191 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11194 struct jbd_revoke_record_s *record;
11196 record = find_revoke_record(journal, blocknr);
11198 /* If we have multiple occurences, only record the
11199 * latest sequence number in the hashed record */
11200 if (tid_gt(sequence, record->sequence))
11201 record->sequence = sequence;
11204 return insert_revoke_hash(journal, blocknr, sequence);
11208 * Test revoke records. For a given block referenced in the log, has
11209 * that block been revoked? A revoke record with a given transaction
11210 * sequence number revokes all blocks in that transaction and earlier
11211 * ones, but later transactions still need replayed.
11214 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11217 struct jbd_revoke_record_s *record;
11219 record = find_revoke_record(journal, blocknr);
11222 if (tid_gt(sequence, record->sequence))
11228 * Finally, once recovery is over, we need to clear the revoke table so
11229 * that it can be reused by the running filesystem.
11232 void journal_clear_revoke(journal_t *journal)
11235 struct list_head *hash_list;
11236 struct jbd_revoke_record_s *record;
11237 struct jbd_revoke_table_s *revoke_var;
11239 revoke_var = journal->j_revoke;
11241 for (i = 0; i < revoke_var->hash_size; i++) {
11242 hash_list = &revoke_var->hash_table[i];
11243 while (!list_empty(hash_list)) {
11244 record = (struct jbd_revoke_record_s*) hash_list->next;
11245 list_del(&record->hash);
11252 * e2fsck.c - superblock checks
11255 #define MIN_CHECK 1
11256 #define MAX_CHECK 2
11258 static void check_super_value(e2fsck_t ctx, const char *descr,
11259 unsigned long value, int flags,
11260 unsigned long min_val, unsigned long max_val)
11262 struct problem_context pctx;
11264 if (((flags & MIN_CHECK) && (value < min_val)) ||
11265 ((flags & MAX_CHECK) && (value > max_val))) {
11266 clear_problem_context(&pctx);
11269 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11270 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11275 * This routine may get stubbed out in special compilations of the
11278 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11279 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11281 return (ext2fs_get_device_size(ctx->filesystem_name,
11282 EXT2_BLOCK_SIZE(ctx->fs->super),
11283 &ctx->num_blocks));
11288 * helper function to release an inode
11290 struct process_block_struct {
11293 struct problem_context *pctx;
11295 int truncate_offset;
11296 e2_blkcnt_t truncate_block;
11297 int truncated_blocks;
11302 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11303 e2_blkcnt_t blockcnt,
11304 blk_t ref_blk FSCK_ATTR((unused)),
11305 int ref_offset FSCK_ATTR((unused)),
11308 struct process_block_struct *pb;
11310 struct problem_context *pctx;
11311 blk_t blk = *block_nr;
11314 pb = (struct process_block_struct *) priv_data;
11319 pctx->blkcount = blockcnt;
11321 if (HOLE_BLKADDR(blk))
11324 if ((blk < fs->super->s_first_data_block) ||
11325 (blk >= fs->super->s_blocks_count)) {
11326 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11329 return BLOCK_ABORT;
11332 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11333 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11338 * If we are deleting an orphan, then we leave the fields alone.
11339 * If we are truncating an orphan, then update the inode fields
11340 * and clean up any partial block data.
11342 if (pb->truncating) {
11344 * We only remove indirect blocks if they are
11345 * completely empty.
11347 if (blockcnt < 0) {
11351 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11356 limit = fs->blocksize >> 2;
11357 for (i = 0, bp = (blk_t *) pb->buf;
11358 i < limit; i++, bp++)
11363 * We don't remove direct blocks until we've reached
11364 * the truncation block.
11366 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11369 * If part of the last block needs truncating, we do
11372 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11373 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11377 memset(pb->buf + pb->truncate_offset, 0,
11378 fs->blocksize - pb->truncate_offset);
11379 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11384 pb->truncated_blocks++;
11386 retval |= BLOCK_CHANGED;
11389 ext2fs_block_alloc_stats(fs, blk, -1);
11394 * This function releases an inode. Returns 1 if an inconsistency was
11395 * found. If the inode has a link count, then it is being truncated and
11398 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11399 struct ext2_inode *inode, char *block_buf,
11400 struct problem_context *pctx)
11402 struct process_block_struct pb;
11403 ext2_filsys fs = ctx->fs;
11407 if (!ext2fs_inode_has_valid_blocks(inode))
11410 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11415 if (inode->i_links_count) {
11417 pb.truncate_block = (e2_blkcnt_t)
11418 ((((long long)inode->i_size_high << 32) +
11419 inode->i_size + fs->blocksize - 1) /
11421 pb.truncate_offset = inode->i_size % fs->blocksize;
11424 pb.truncate_block = 0;
11425 pb.truncate_offset = 0;
11427 pb.truncated_blocks = 0;
11428 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11429 block_buf, release_inode_block, &pb);
11431 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11438 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11439 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11441 if (pb.truncated_blocks)
11442 inode->i_blocks -= pb.truncated_blocks *
11443 (fs->blocksize / 512);
11445 if (inode->i_file_acl) {
11446 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11447 block_buf, -1, &count);
11448 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11453 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11458 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11459 inode->i_file_acl = 0;
11465 * This function releases all of the orphan inodes. It returns 1 if
11466 * it hit some error, and 0 on success.
11468 static int release_orphan_inodes(e2fsck_t ctx)
11470 ext2_filsys fs = ctx->fs;
11471 ext2_ino_t ino, next_ino;
11472 struct ext2_inode inode;
11473 struct problem_context pctx;
11476 if ((ino = fs->super->s_last_orphan) == 0)
11480 * Win or lose, we won't be using the head of the orphan inode
11483 fs->super->s_last_orphan = 0;
11484 ext2fs_mark_super_dirty(fs);
11487 * If the filesystem contains errors, don't run the orphan
11488 * list, since the orphan list can't be trusted; and we're
11489 * going to be running a full e2fsck run anyway...
11491 if (fs->super->s_state & EXT2_ERROR_FS)
11494 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11495 (ino > fs->super->s_inodes_count)) {
11496 clear_problem_context(&pctx);
11498 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11502 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11503 "block iterate buffer");
11504 e2fsck_read_bitmaps(ctx);
11507 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11508 clear_problem_context(&pctx);
11510 pctx.inode = &inode;
11511 pctx.str = inode.i_links_count ? _("Truncating") :
11514 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11516 next_ino = inode.i_dtime;
11518 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11519 (next_ino > fs->super->s_inodes_count))) {
11520 pctx.ino = next_ino;
11521 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11525 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11528 if (!inode.i_links_count) {
11529 ext2fs_inode_alloc_stats2(fs, ino, -1,
11530 LINUX_S_ISDIR(inode.i_mode));
11531 inode.i_dtime = time(NULL);
11535 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11538 ext2fs_free_mem(&block_buf);
11541 ext2fs_free_mem(&block_buf);
11546 * Check the resize inode to make sure it is sane. We check both for
11547 * the case where on-line resizing is not enabled (in which case the
11548 * resize inode should be cleared) as well as the case where on-line
11549 * resizing is enabled.
11551 static void check_resize_inode(e2fsck_t ctx)
11553 ext2_filsys fs = ctx->fs;
11554 struct ext2_inode inode;
11555 struct problem_context pctx;
11556 int i, j, gdt_off, ind_off;
11557 blk_t blk, pblk, expect;
11558 __u32 *dind_buf = NULL, *ind_buf;
11561 clear_problem_context(&pctx);
11564 * If the resize inode feature isn't set, then
11565 * s_reserved_gdt_blocks must be zero.
11567 if (!(fs->super->s_feature_compat &
11568 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11569 if (fs->super->s_reserved_gdt_blocks) {
11570 pctx.num = fs->super->s_reserved_gdt_blocks;
11571 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11573 fs->super->s_reserved_gdt_blocks = 0;
11574 ext2fs_mark_super_dirty(fs);
11579 /* Read the resize inode */
11580 pctx.ino = EXT2_RESIZE_INO;
11581 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11583 if (fs->super->s_feature_compat &
11584 EXT2_FEATURE_COMPAT_RESIZE_INODE)
11585 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11590 * If the resize inode feature isn't set, check to make sure
11591 * the resize inode is cleared; then we're done.
11593 if (!(fs->super->s_feature_compat &
11594 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11595 for (i=0; i < EXT2_N_BLOCKS; i++) {
11596 if (inode.i_block[i])
11599 if ((i < EXT2_N_BLOCKS) &&
11600 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11601 memset(&inode, 0, sizeof(inode));
11602 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11609 * The resize inode feature is enabled; check to make sure the
11610 * only block in use is the double indirect block
11612 blk = inode.i_block[EXT2_DIND_BLOCK];
11613 for (i=0; i < EXT2_N_BLOCKS; i++) {
11614 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11617 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11618 !(inode.i_mode & LINUX_S_IFREG) ||
11619 (blk < fs->super->s_first_data_block ||
11620 blk >= fs->super->s_blocks_count)) {
11621 resize_inode_invalid:
11622 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11623 memset(&inode, 0, sizeof(inode));
11624 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11626 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11628 if (!(ctx->options & E2F_OPT_READONLY)) {
11629 fs->super->s_state &= ~EXT2_VALID_FS;
11630 ext2fs_mark_super_dirty(fs);
11634 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11635 "resize dind buffer");
11636 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11638 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11640 goto resize_inode_invalid;
11642 gdt_off = fs->desc_blocks;
11643 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11644 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11645 i++, gdt_off++, pblk++) {
11646 gdt_off %= fs->blocksize/4;
11647 if (dind_buf[gdt_off] != pblk)
11648 goto resize_inode_invalid;
11649 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11651 goto resize_inode_invalid;
11653 for (j = 1; j < fs->group_desc_count; j++) {
11654 if (!ext2fs_bg_has_super(fs, j))
11656 expect = pblk + (j * fs->super->s_blocks_per_group);
11657 if (ind_buf[ind_off] != expect)
11658 goto resize_inode_invalid;
11664 ext2fs_free_mem(&dind_buf);
11668 static void check_super_block(e2fsck_t ctx)
11670 ext2_filsys fs = ctx->fs;
11671 blk_t first_block, last_block;
11672 struct ext2_super_block *sb = fs->super;
11673 struct ext2_group_desc *gd;
11674 blk_t blocks_per_group = fs->super->s_blocks_per_group;
11676 int inodes_per_block;
11681 struct problem_context pctx;
11682 __u32 free_blocks = 0, free_inodes = 0;
11684 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11685 ipg_max = inodes_per_block * (blocks_per_group - 4);
11686 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11687 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11688 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11689 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11690 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11692 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11693 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11694 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11695 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11696 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11697 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11699 clear_problem_context(&pctx);
11702 * Verify the super block constants...
11704 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11706 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11708 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11709 MAX_CHECK, 0, sb->s_blocks_count);
11710 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11711 MIN_CHECK | MAX_CHECK, 0,
11712 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11713 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11714 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11715 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11716 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11718 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11719 MIN_CHECK | MAX_CHECK, 8, bpg_max);
11720 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11721 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11722 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11723 MAX_CHECK, 0, sb->s_blocks_count / 2);
11724 check_super_value(ctx, "reserved_gdt_blocks",
11725 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11727 inode_size = EXT2_INODE_SIZE(sb);
11728 check_super_value(ctx, "inode_size",
11729 inode_size, MIN_CHECK | MAX_CHECK,
11730 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11731 if (inode_size & (inode_size - 1)) {
11732 pctx.num = inode_size;
11733 pctx.str = "inode_size";
11734 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11735 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11739 if (!ctx->num_blocks) {
11740 pctx.errcode = e2fsck_get_device_size(ctx);
11741 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11742 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11743 ctx->flags |= E2F_FLAG_ABORT;
11746 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11747 (ctx->num_blocks < sb->s_blocks_count)) {
11748 pctx.blk = sb->s_blocks_count;
11749 pctx.blk2 = ctx->num_blocks;
11750 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11751 ctx->flags |= E2F_FLAG_ABORT;
11757 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11758 pctx.blk = EXT2_BLOCK_SIZE(sb);
11759 pctx.blk2 = EXT2_FRAG_SIZE(sb);
11760 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11761 ctx->flags |= E2F_FLAG_ABORT;
11765 should_be = sb->s_frags_per_group >>
11766 (sb->s_log_block_size - sb->s_log_frag_size);
11767 if (sb->s_blocks_per_group != should_be) {
11768 pctx.blk = sb->s_blocks_per_group;
11769 pctx.blk2 = should_be;
11770 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11771 ctx->flags |= E2F_FLAG_ABORT;
11775 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11776 if (sb->s_first_data_block != should_be) {
11777 pctx.blk = sb->s_first_data_block;
11778 pctx.blk2 = should_be;
11779 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11780 ctx->flags |= E2F_FLAG_ABORT;
11784 should_be = sb->s_inodes_per_group * fs->group_desc_count;
11785 if (sb->s_inodes_count != should_be) {
11786 pctx.ino = sb->s_inodes_count;
11787 pctx.ino2 = should_be;
11788 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11789 sb->s_inodes_count = should_be;
11790 ext2fs_mark_super_dirty(fs);
11795 * Verify the group descriptors....
11797 first_block = sb->s_first_data_block;
11798 last_block = first_block + blocks_per_group;
11800 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11803 if (i == fs->group_desc_count - 1)
11804 last_block = sb->s_blocks_count;
11805 if ((gd->bg_block_bitmap < first_block) ||
11806 (gd->bg_block_bitmap >= last_block)) {
11807 pctx.blk = gd->bg_block_bitmap;
11808 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11809 gd->bg_block_bitmap = 0;
11811 if (gd->bg_block_bitmap == 0) {
11812 ctx->invalid_block_bitmap_flag[i]++;
11813 ctx->invalid_bitmaps++;
11815 if ((gd->bg_inode_bitmap < first_block) ||
11816 (gd->bg_inode_bitmap >= last_block)) {
11817 pctx.blk = gd->bg_inode_bitmap;
11818 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11819 gd->bg_inode_bitmap = 0;
11821 if (gd->bg_inode_bitmap == 0) {
11822 ctx->invalid_inode_bitmap_flag[i]++;
11823 ctx->invalid_bitmaps++;
11825 if ((gd->bg_inode_table < first_block) ||
11826 ((gd->bg_inode_table +
11827 fs->inode_blocks_per_group - 1) >= last_block)) {
11828 pctx.blk = gd->bg_inode_table;
11829 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11830 gd->bg_inode_table = 0;
11832 if (gd->bg_inode_table == 0) {
11833 ctx->invalid_inode_table_flag[i]++;
11834 ctx->invalid_bitmaps++;
11836 free_blocks += gd->bg_free_blocks_count;
11837 free_inodes += gd->bg_free_inodes_count;
11838 first_block += sb->s_blocks_per_group;
11839 last_block += sb->s_blocks_per_group;
11841 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11842 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11843 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11844 ext2fs_unmark_valid(fs);
11849 * Update the global counts from the block group counts. This
11850 * is needed for an experimental patch which eliminates
11851 * locking the entire filesystem when allocating blocks or
11852 * inodes; if the filesystem is not unmounted cleanly, the
11853 * global counts may not be accurate.
11855 if ((free_blocks != sb->s_free_blocks_count) ||
11856 (free_inodes != sb->s_free_inodes_count)) {
11857 if (ctx->options & E2F_OPT_READONLY)
11858 ext2fs_unmark_valid(fs);
11860 sb->s_free_blocks_count = free_blocks;
11861 sb->s_free_inodes_count = free_inodes;
11862 ext2fs_mark_super_dirty(fs);
11866 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11867 (sb->s_free_inodes_count > sb->s_inodes_count))
11868 ext2fs_unmark_valid(fs);
11872 * If we have invalid bitmaps, set the error state of the
11875 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11876 sb->s_state &= ~EXT2_VALID_FS;
11877 ext2fs_mark_super_dirty(fs);
11880 clear_problem_context(&pctx);
11883 * If the UUID field isn't assigned, assign it.
11885 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11886 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11887 uuid_generate(sb->s_uuid);
11888 ext2fs_mark_super_dirty(fs);
11889 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11893 /* FIXME - HURD support?
11894 * For the Hurd, check to see if the filetype option is set,
11895 * since it doesn't support it.
11897 if (!(ctx->options & E2F_OPT_READONLY) &&
11898 fs->super->s_creator_os == EXT2_OS_HURD &&
11899 (fs->super->s_feature_incompat &
11900 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11901 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11902 fs->super->s_feature_incompat &=
11903 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11904 ext2fs_mark_super_dirty(fs);
11910 * If we have any of the compatibility flags set, we need to have a
11911 * revision 1 filesystem. Most kernels will not check the flags on
11912 * a rev 0 filesystem and we may have corruption issues because of
11913 * the incompatible changes to the filesystem.
11915 if (!(ctx->options & E2F_OPT_READONLY) &&
11916 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11917 (fs->super->s_feature_compat ||
11918 fs->super->s_feature_ro_compat ||
11919 fs->super->s_feature_incompat) &&
11920 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11921 ext2fs_update_dynamic_rev(fs);
11922 ext2fs_mark_super_dirty(fs);
11925 check_resize_inode(ctx);
11928 * Clean up any orphan inodes, if present.
11930 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11931 fs->super->s_state &= ~EXT2_VALID_FS;
11932 ext2fs_mark_super_dirty(fs);
11936 * Move the ext3 journal file, if necessary.
11938 e2fsck_move_ext3_journal(ctx);
11942 * swapfs.c --- byte-swap an ext2 filesystem
11945 #ifdef ENABLE_SWAPFS
11947 struct swap_block_struct {
11952 struct ext2_inode *inode;
11956 * This is a helper function for block_iterate. We mark all of the
11957 * indirect and direct blocks as changed, so that block_iterate will
11960 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
11965 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
11967 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
11968 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
11970 sb->errcode = retval;
11971 return BLOCK_ABORT;
11973 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
11975 sb->errcode = retval;
11976 return BLOCK_ABORT;
11979 if (blockcnt >= 0) {
11980 if (blockcnt < EXT2_NDIR_BLOCKS)
11982 return BLOCK_CHANGED;
11984 if (blockcnt == BLOCK_COUNT_IND) {
11985 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
11987 return BLOCK_CHANGED;
11989 if (blockcnt == BLOCK_COUNT_DIND) {
11990 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
11992 return BLOCK_CHANGED;
11994 if (blockcnt == BLOCK_COUNT_TIND) {
11995 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
11997 return BLOCK_CHANGED;
11999 return BLOCK_CHANGED;
12003 * This function is responsible for byte-swapping all of the indirect,
12004 * block pointers. It is also responsible for byte-swapping directories.
12006 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12007 struct ext2_inode *inode)
12010 struct swap_block_struct sb;
12014 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12017 if (LINUX_S_ISDIR(inode->i_mode))
12020 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12023 bb_error_msg(_("while calling ext2fs_block_iterate"));
12024 ctx->flags |= E2F_FLAG_ABORT;
12028 bb_error_msg(_("while calling iterator function"));
12029 ctx->flags |= E2F_FLAG_ABORT;
12034 static void swap_inodes(e2fsck_t ctx)
12036 ext2_filsys fs = ctx->fs;
12039 ext2_ino_t ino = 1;
12040 char *buf, *block_buf;
12042 struct ext2_inode * inode;
12044 e2fsck_use_inode_shortcuts(ctx, 1);
12046 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12049 bb_error_msg(_("while allocating inode buffer"));
12050 ctx->flags |= E2F_FLAG_ABORT;
12053 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12054 "block interate buffer");
12055 for (group = 0; group < fs->group_desc_count; group++) {
12056 retval = io_channel_read_blk(fs->io,
12057 fs->group_desc[group].bg_inode_table,
12058 fs->inode_blocks_per_group, buf);
12060 bb_error_msg(_("while reading inode table (group %d)"),
12062 ctx->flags |= E2F_FLAG_ABORT;
12065 inode = (struct ext2_inode *) buf;
12066 for (i=0; i < fs->super->s_inodes_per_group;
12067 i++, ino++, inode++) {
12068 ctx->stashed_ino = ino;
12069 ctx->stashed_inode = inode;
12071 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12072 ext2fs_swap_inode(fs, inode, inode, 0);
12075 * Skip deleted files.
12077 if (inode->i_links_count == 0)
12080 if (LINUX_S_ISDIR(inode->i_mode) ||
12081 ((inode->i_block[EXT2_IND_BLOCK] ||
12082 inode->i_block[EXT2_DIND_BLOCK] ||
12083 inode->i_block[EXT2_TIND_BLOCK]) &&
12084 ext2fs_inode_has_valid_blocks(inode)))
12085 swap_inode_blocks(ctx, ino, block_buf, inode);
12087 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12090 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12091 ext2fs_swap_inode(fs, inode, inode, 1);
12093 retval = io_channel_write_blk(fs->io,
12094 fs->group_desc[group].bg_inode_table,
12095 fs->inode_blocks_per_group, buf);
12097 bb_error_msg(_("while writing inode table (group %d)"),
12099 ctx->flags |= E2F_FLAG_ABORT;
12103 ext2fs_free_mem(&buf);
12104 ext2fs_free_mem(&block_buf);
12105 e2fsck_use_inode_shortcuts(ctx, 0);
12106 ext2fs_flush_icache(fs);
12109 #if defined(__powerpc__) && BB_BIG_ENDIAN
12111 * On the PowerPC, the big-endian variant of the ext2 filesystem
12112 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12113 * of each word. Thus a bitmap with only bit 0 set would be, as
12114 * a string of bytes, 00 00 00 01 00 ...
12115 * To cope with this, we byte-reverse each word of a bitmap if
12116 * we have a big-endian filesystem, that is, if we are *not*
12117 * byte-swapping other word-sized numbers.
12119 #define EXT2_BIG_ENDIAN_BITMAPS
12122 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12123 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12125 __u32 *p = (__u32 *) bmap->bitmap;
12126 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12128 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12129 *p = ext2fs_swab32(*p);
12134 #ifdef ENABLE_SWAPFS
12135 static void swap_filesys(e2fsck_t ctx)
12137 ext2_filsys fs = ctx->fs;
12138 if (!(ctx->options & E2F_OPT_PREEN))
12139 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12143 if (fs->super->s_mnt_count) {
12144 fprintf(stderr, _("%s: the filesystem must be freshly "
12145 "checked using fsck\n"
12146 "and not mounted before trying to "
12147 "byte-swap it.\n"), ctx->device_name);
12148 ctx->flags |= E2F_FLAG_ABORT;
12151 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12152 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12153 EXT2_FLAG_SWAP_BYTES_WRITE);
12154 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12156 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12157 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12160 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12162 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12163 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12164 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12165 EXT2_FLAG_SWAP_BYTES_WRITE);
12167 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12168 e2fsck_read_bitmaps(ctx);
12169 ext2fs_swap_bitmap(fs->inode_map);
12170 ext2fs_swap_bitmap(fs->block_map);
12171 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12173 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12175 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12177 #endif /* ENABLE_SWAPFS */
12182 * util.c --- miscellaneous utilities
12186 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12187 const char *description)
12192 ret = xzalloc(size);
12196 static char *string_copy(const char *str, int len)
12204 ret = xmalloc(len+1);
12205 strncpy(ret, str, len);
12210 #ifndef HAVE_CONIO_H
12211 static int read_a_char(void)
12218 if (e2fsck_global_ctx &&
12219 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12222 r = read(0, &c, 1);
12232 static int ask_yn(const char * string, int def)
12235 const char *defstr;
12236 static const char short_yes[] = "yY";
12237 static const char short_no[] = "nN";
12239 #ifdef HAVE_TERMIOS_H
12240 struct termios termios, tmp;
12242 tcgetattr (0, &termios);
12244 tmp.c_lflag &= ~(ICANON | ECHO);
12245 tmp.c_cc[VMIN] = 1;
12246 tmp.c_cc[VTIME] = 0;
12247 tcsetattr_stdin_TCSANOW(&tmp);
12256 printf("%s%s? ", string, defstr);
12259 if ((c = read_a_char()) == EOF)
12262 #ifdef HAVE_TERMIOS_H
12263 tcsetattr_stdin_TCSANOW(&termios);
12265 if (e2fsck_global_ctx &&
12266 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12268 longjmp(e2fsck_global_ctx->abort_loc, 1);
12270 puts(_("cancelled!\n"));
12273 if (strchr(short_yes, (char) c)) {
12277 else if (strchr(short_no, (char) c)) {
12281 else if ((c == ' ' || c == '\n') && (def != -1))
12288 #ifdef HAVE_TERMIOS_H
12289 tcsetattr_stdin_TCSANOW(&termios);
12294 int ask (e2fsck_t ctx, const char * string, int def)
12296 if (ctx->options & E2F_OPT_NO) {
12297 printf(_("%s? no\n\n"), string);
12300 if (ctx->options & E2F_OPT_YES) {
12301 printf(_("%s? yes\n\n"), string);
12304 if (ctx->options & E2F_OPT_PREEN) {
12305 printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
12308 return ask_yn(string, def);
12311 void e2fsck_read_bitmaps(e2fsck_t ctx)
12313 ext2_filsys fs = ctx->fs;
12316 if (ctx->invalid_bitmaps) {
12317 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12319 bb_error_msg_and_die(0);
12322 ehandler_operation(_("reading inode and block bitmaps"));
12323 retval = ext2fs_read_bitmaps(fs);
12324 ehandler_operation(0);
12326 bb_error_msg(_("while retrying to read bitmaps for %s"),
12328 bb_error_msg_and_die(0);
12332 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12334 ext2_filsys fs = ctx->fs;
12337 if (ext2fs_test_bb_dirty(fs)) {
12338 ehandler_operation(_("writing block bitmaps"));
12339 retval = ext2fs_write_block_bitmap(fs);
12340 ehandler_operation(0);
12342 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12344 bb_error_msg_and_die(0);
12348 if (ext2fs_test_ib_dirty(fs)) {
12349 ehandler_operation(_("writing inode bitmaps"));
12350 retval = ext2fs_write_inode_bitmap(fs);
12351 ehandler_operation(0);
12353 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12355 bb_error_msg_and_die(0);
12360 void preenhalt(e2fsck_t ctx)
12362 ext2_filsys fs = ctx->fs;
12364 if (!(ctx->options & E2F_OPT_PREEN))
12366 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12367 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12370 fs->super->s_state |= EXT2_ERROR_FS;
12371 ext2fs_mark_super_dirty(fs);
12374 exit(EXIT_UNCORRECTED);
12377 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12378 struct ext2_inode * inode, const char *proc)
12382 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12384 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12385 bb_error_msg_and_die(0);
12389 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12390 struct ext2_inode * inode, int bufsize,
12395 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12397 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12398 bb_error_msg_and_die(0);
12402 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12403 struct ext2_inode * inode, const char *proc)
12407 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12409 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12410 bb_error_msg_and_die(0);
12414 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12415 io_manager manager)
12417 struct ext2_super_block *sb;
12418 io_channel io = NULL;
12421 blk_t superblock, ret_sb = 8193;
12423 if (fs && fs->super) {
12424 ret_sb = (fs->super->s_blocks_per_group +
12425 fs->super->s_first_data_block);
12427 ctx->superblock = ret_sb;
12428 ctx->blocksize = fs->blocksize;
12434 if (ctx->blocksize) {
12435 ret_sb = ctx->blocksize * 8;
12436 if (ctx->blocksize == 1024)
12438 ctx->superblock = ret_sb;
12441 ctx->superblock = ret_sb;
12442 ctx->blocksize = 1024;
12445 if (!name || !manager)
12448 if (manager->open(name, 0, &io) != 0)
12451 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12453 sb = (struct ext2_super_block *) buf;
12455 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12456 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
12457 superblock = blocksize*8;
12458 if (blocksize == 1024)
12460 io_channel_set_blksize(io, blocksize);
12461 if (io_channel_read_blk(io, superblock,
12462 -SUPERBLOCK_SIZE, buf))
12465 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12466 ext2fs_swap_super(sb);
12468 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12469 ret_sb = superblock;
12471 ctx->superblock = superblock;
12472 ctx->blocksize = blocksize;
12480 io_channel_close(io);
12481 ext2fs_free_mem(&buf);
12487 * This function runs through the e2fsck passes and calls them all,
12488 * returning restart, abort, or cancel as necessary...
12490 typedef void (*pass_t)(e2fsck_t ctx);
12492 static const pass_t e2fsck_passes[] = {
12493 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12496 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12498 static int e2fsck_run(e2fsck_t ctx)
12501 pass_t e2fsck_pass;
12503 if (setjmp(ctx->abort_loc)) {
12504 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12505 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12507 ctx->flags |= E2F_FLAG_SETJMP_OK;
12509 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12510 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12514 (void) (ctx->progress)(ctx, 0, 0, 0);
12516 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12518 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12519 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12525 * unix.c - The unix-specific code for e2fsck
12529 /* Command line options */
12531 #ifdef ENABLE_SWAPFS
12532 static int normalize_swapfs;
12534 static int cflag; /* check disk */
12535 static int show_version_only;
12536 static int verbose;
12538 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12540 static void show_stats(e2fsck_t ctx)
12542 ext2_filsys fs = ctx->fs;
12543 int inodes, inodes_used, blocks, blocks_used;
12545 int num_files, num_links;
12548 dir_links = 2 * ctx->fs_directory_count - 1;
12549 num_files = ctx->fs_total_count - dir_links;
12550 num_links = ctx->fs_links_count - dir_links;
12551 inodes = fs->super->s_inodes_count;
12552 inodes_used = (fs->super->s_inodes_count -
12553 fs->super->s_free_inodes_count);
12554 blocks = fs->super->s_blocks_count;
12555 blocks_used = (fs->super->s_blocks_count -
12556 fs->super->s_free_blocks_count);
12558 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12559 frag_percent = (frag_percent + 5) / 10;
12562 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12563 ctx->device_name, inodes_used, inodes,
12564 frag_percent / 10, frag_percent % 10,
12565 blocks_used, blocks);
12568 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12569 100 * inodes_used / inodes);
12570 printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12571 P_E2("", "s", ctx->fs_fragmented),
12572 frag_percent / 10, frag_percent % 10);
12573 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12574 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12575 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12576 (int) ((long long) 100 * blocks_used / blocks));
12577 printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12578 printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12579 printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12580 printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12581 printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12582 printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12583 printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12584 printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12585 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12586 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12587 printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12590 static void check_mount(e2fsck_t ctx)
12595 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12596 &ctx->mount_flags);
12598 bb_error_msg(_("while determining whether %s is mounted"),
12599 ctx->filesystem_name);
12604 * If the filesystem isn't mounted, or it's the root filesystem
12605 * and it's mounted read-only, then everything's fine.
12607 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12608 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12609 (ctx->mount_flags & EXT2_MF_READONLY)))
12612 if (ctx->options & E2F_OPT_READONLY) {
12613 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
12617 printf(_("%s is mounted. "), ctx->filesystem_name);
12618 if (!ctx->interactive)
12619 bb_error_msg_and_die(_("can't continue, aborting"));
12620 printf(_("\n\n\007\007\007\007WARNING!!! "
12621 "Running e2fsck on a mounted filesystem may cause\n"
12622 "SEVERE filesystem damage.\007\007\007\n\n"));
12623 cont = ask_yn(_("Do you really want to continue"), -1);
12625 printf(_("check aborted.\n"));
12630 static int is_on_batt(void)
12634 char tmp[80], tmp2[80], fname[80];
12635 unsigned int acflag;
12638 f = fopen_for_read("/proc/apm");
12640 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12643 return (acflag != 1);
12645 d = opendir("/proc/acpi/ac_adapter");
12647 while ((de=readdir(d)) != NULL) {
12648 if (!strncmp(".", de->d_name, 1))
12650 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12652 f = fopen_for_read(fname);
12655 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12658 if (strncmp(tmp, "off-line", 8) == 0) {
12669 * This routine checks to see if a filesystem can be skipped; if so,
12670 * it will exit with EXIT_OK. Under some conditions it will print a
12671 * message explaining why a check is being forced.
12673 static void check_if_skip(e2fsck_t ctx)
12675 ext2_filsys fs = ctx->fs;
12676 const char *reason = NULL;
12677 unsigned int reason_arg = 0;
12679 int batt = is_on_batt();
12680 time_t now = time(NULL);
12682 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12685 if ((fs->super->s_state & EXT2_ERROR_FS) ||
12686 !ext2fs_test_valid(fs))
12687 reason = _(" contains a file system with errors");
12688 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12689 reason = _(" was not cleanly unmounted");
12690 else if ((fs->super->s_max_mnt_count > 0) &&
12691 (fs->super->s_mnt_count >=
12692 (unsigned) fs->super->s_max_mnt_count)) {
12693 reason = _(" has been mounted %u times without being checked");
12694 reason_arg = fs->super->s_mnt_count;
12695 if (batt && (fs->super->s_mnt_count <
12696 (unsigned) fs->super->s_max_mnt_count*2))
12698 } else if (fs->super->s_checkinterval &&
12699 ((now - fs->super->s_lastcheck) >=
12700 fs->super->s_checkinterval)) {
12701 reason = _(" has gone %u days without being checked");
12702 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12703 if (batt && ((now - fs->super->s_lastcheck) <
12704 fs->super->s_checkinterval*2))
12708 fputs(ctx->device_name, stdout);
12709 printf(reason, reason_arg);
12710 fputs(_(", check forced.\n"), stdout);
12713 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12714 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12715 fs->super->s_inodes_count,
12716 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12717 fs->super->s_blocks_count);
12718 next_check = 100000;
12719 if (fs->super->s_max_mnt_count > 0) {
12720 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12721 if (next_check <= 0)
12724 if (fs->super->s_checkinterval &&
12725 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12727 if (next_check <= 5) {
12728 if (next_check == 1)
12729 fputs(_(" (check after next mount)"), stdout);
12731 printf(_(" (check in %ld mounts)"), next_check);
12736 e2fsck_free_context(ctx);
12741 * For completion notice
12743 struct percent_tbl {
12747 static const struct percent_tbl e2fsck_tbl = {
12748 5, { 0, 70, 90, 92, 95, 100 }
12751 static char bar[128], spaces[128];
12753 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12760 if (pass > tbl->max_pass || max == 0)
12762 percent = ((float) curr) / ((float) max);
12763 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12764 + tbl->table[pass-1]);
12767 void e2fsck_clear_progbar(e2fsck_t ctx)
12769 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12772 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12775 ctx->flags &= ~E2F_FLAG_PROG_BAR;
12778 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12779 unsigned int dpynum)
12781 static const char spinner[] = "\\|/-";
12788 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12792 * Calculate the new progress position. If the
12793 * percentage hasn't changed, then we skip out right
12796 fixed_percent = (int) ((10 * percent) + 0.5);
12797 if (ctx->progress_last_percent == fixed_percent)
12799 ctx->progress_last_percent = fixed_percent;
12802 * If we've already updated the spinner once within
12803 * the last 1/8th of a second, no point doing it
12806 gettimeofday(&tv, NULL);
12807 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12808 if ((tick == ctx->progress_last_time) &&
12809 (fixed_percent != 0) && (fixed_percent != 1000))
12811 ctx->progress_last_time = tick;
12814 * Advance the spinner, and note that the progress bar
12815 * will be on the screen
12817 ctx->progress_pos = (ctx->progress_pos+1) & 3;
12818 ctx->flags |= E2F_FLAG_PROG_BAR;
12820 dpywidth = 66 - strlen(label);
12821 dpywidth = 8 * (dpywidth / 8);
12825 i = ((percent * dpywidth) + 50) / 100;
12826 printf("%s%s: |%s%s", ctx->start_meta, label,
12827 bar + (sizeof(bar) - (i+1)),
12828 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12829 if (fixed_percent == 1000)
12832 bb_putchar(spinner[ctx->progress_pos & 3]);
12833 printf(" %4.1f%% ", percent);
12835 printf("%u\r", dpynum);
12837 fputs(" \r", stdout);
12838 fputs(ctx->stop_meta, stdout);
12840 if (fixed_percent == 1000)
12841 e2fsck_clear_progbar(ctx);
12847 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12848 unsigned long cur, unsigned long max)
12856 if (ctx->progress_fd) {
12857 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12858 xwrite_str(ctx->progress_fd, buf);
12860 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12861 e2fsck_simple_progress(ctx, ctx->device_name,
12867 static void reserve_stdio_fds(void)
12872 fd = open(bb_dev_null, O_RDWR);
12876 fprintf(stderr, _("ERROR: Cannot open "
12877 "/dev/null (%s)\n"),
12885 static void signal_progress_on(int sig FSCK_ATTR((unused)))
12887 e2fsck_t ctx = e2fsck_global_ctx;
12892 ctx->progress = e2fsck_update_progress;
12893 ctx->progress_fd = 0;
12896 static void signal_progress_off(int sig FSCK_ATTR((unused)))
12898 e2fsck_t ctx = e2fsck_global_ctx;
12903 e2fsck_clear_progbar(ctx);
12907 static void signal_cancel(int sig FSCK_ATTR((unused)))
12909 e2fsck_t ctx = e2fsck_global_ctx;
12912 exit(FSCK_CANCELED);
12914 ctx->flags |= E2F_FLAG_CANCEL;
12917 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12919 char *buf, *token, *next, *p, *arg;
12921 int extended_usage = 0;
12923 buf = string_copy(opts, 0);
12924 for (token = buf; token && *token; token = next) {
12925 p = strchr(token, ',');
12931 arg = strchr(token, '=');
12936 if (strcmp(token, "ea_ver") == 0) {
12941 ea_ver = strtoul(arg, &p, 0);
12943 ((ea_ver != 1) && (ea_ver != 2))) {
12945 _("Invalid EA version.\n"));
12949 ctx->ext_attr_ver = ea_ver;
12951 fprintf(stderr, _("Unknown extended option: %s\n"),
12956 if (extended_usage) {
12957 bb_error_msg_and_die(
12958 "Extended options are separated by commas, "
12959 "and may take an argument which\n"
12960 "is set off by an equals ('=') sign. "
12961 "Valid extended options are:\n"
12962 "\tea_ver=<ea_version (1 or 2)>\n\n");
12967 static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx)
12973 struct sigaction sa;
12974 char *extended_opts = NULL;
12976 retval = e2fsck_allocate_context(&ctx);
12982 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
12983 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
12984 if (isatty(0) && isatty(1)) {
12985 ctx->interactive = 1;
12987 ctx->start_meta[0] = '\001';
12988 ctx->stop_meta[0] = '\002';
12990 memset(bar, '=', sizeof(bar)-1);
12991 memset(spaces, ' ', sizeof(spaces)-1);
12992 blkid_get_cache(&ctx->blkid, NULL);
12995 ctx->program_name = *argv;
12997 ctx->program_name = "e2fsck";
12998 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13001 ctx->progress = e2fsck_update_progress;
13002 ctx->progress_fd = atoi(optarg);
13003 if (!ctx->progress_fd)
13005 /* Validate the file descriptor to avoid disasters */
13006 fd = dup(ctx->progress_fd);
13009 _("Error validating file descriptor %d: %s\n"),
13011 error_message(errno));
13012 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13017 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13020 extended_opts = optarg;
13024 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13026 bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
13028 ctx->options |= E2F_OPT_PREEN;
13031 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13033 ctx->options |= E2F_OPT_NO;
13036 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13038 ctx->options |= E2F_OPT_YES;
13041 /* FIXME - This needs to go away in a future path - will change binary */
13042 fprintf(stderr, _("The -t option is not "
13043 "supported on this version of e2fsck.\n"));
13047 ctx->options |= E2F_OPT_WRITECHECK;
13048 ctx->options |= E2F_OPT_CHECKBLOCKS;
13051 /* What we do by default, anyway! */
13054 ctx->use_superblock = atoi(optarg);
13055 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13058 ctx->blocksize = atoi(optarg);
13061 ctx->inode_buffer_blocks = atoi(optarg);
13064 ctx->journal_name = string_copy(optarg, 0);
13067 ctx->process_inode_size = atoi(optarg);
13070 ctx->options |= E2F_OPT_DEBUG;
13073 ctx->options |= E2F_OPT_FORCE;
13082 show_version_only = 1;
13085 ctx->device_name = optarg;
13087 #ifdef ENABLE_SWAPFS
13089 normalize_swapfs = 1;
13096 fprintf(stderr, _("Byte-swapping filesystems "
13097 "not compiled in this version "
13104 if (show_version_only)
13106 if (optind != argc - 1)
13108 if ((ctx->options & E2F_OPT_NO) &&
13109 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13110 ctx->options |= E2F_OPT_READONLY;
13111 ctx->io_options = strchr(argv[optind], '?');
13112 if (ctx->io_options)
13113 *ctx->io_options++ = 0;
13114 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13115 if (!ctx->filesystem_name) {
13116 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13117 bb_error_msg_and_die(0);
13120 parse_extended_opts(ctx, extended_opts);
13123 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13125 bb_error_msg(_("while opening %s for flushing"),
13126 ctx->filesystem_name);
13127 bb_error_msg_and_die(0);
13129 if ((retval = ext2fs_sync_device(fd, 1))) {
13130 bb_error_msg(_("while trying to flush %s"),
13131 ctx->filesystem_name);
13132 bb_error_msg_and_die(0);
13136 #ifdef ENABLE_SWAPFS
13137 if (swapfs && cflag) {
13138 fprintf(stderr, _("Incompatible options not "
13139 "allowed when byte-swapping.\n"));
13144 * Set up signal action
13146 memset(&sa, 0, sizeof(struct sigaction));
13147 sa.sa_handler = signal_cancel;
13148 sigaction(SIGINT, &sa, 0);
13149 sigaction(SIGTERM, &sa, 0);
13151 sa.sa_flags = SA_RESTART;
13153 e2fsck_global_ctx = ctx;
13154 sa.sa_handler = signal_progress_on;
13155 sigaction(SIGUSR1, &sa, 0);
13156 sa.sa_handler = signal_progress_off;
13157 sigaction(SIGUSR2, &sa, 0);
13159 /* Update our PATH to include /sbin if we need to run badblocks */
13161 e2fs_set_sbin_path();
13165 static const char my_ver_string[] = E2FSPROGS_VERSION;
13166 static const char my_ver_date[] = E2FSPROGS_DATE;
13168 int e2fsck_main (int argc, char **argv);
13169 int e2fsck_main (int argc, char **argv)
13172 int exit_value = EXIT_OK;
13173 ext2_filsys fs = 0;
13175 struct ext2_super_block *sb;
13176 const char *lib_ver_date;
13177 int my_ver, lib_ver;
13179 struct problem_context pctx;
13180 int flags, run_result;
13182 clear_problem_context(&pctx);
13184 my_ver = ext2fs_parse_version_string(my_ver_string);
13185 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13186 if (my_ver > lib_ver) {
13187 fprintf( stderr, _("Error: ext2fs library version "
13188 "out of date!\n"));
13189 show_version_only++;
13192 retval = PRS(argc, argv, &ctx);
13194 bb_error_msg(_("while trying to initialize program"));
13197 reserve_stdio_fds();
13199 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13200 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13203 if (show_version_only) {
13204 fprintf(stderr, _("\tUsing %s, %s\n"),
13205 error_message(EXT2_ET_BASE), lib_ver_date);
13211 if (!(ctx->options & E2F_OPT_PREEN) &&
13212 !(ctx->options & E2F_OPT_NO) &&
13213 !(ctx->options & E2F_OPT_YES)) {
13214 if (!ctx->interactive)
13215 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13217 ctx->superblock = ctx->use_superblock;
13219 #ifdef CONFIG_TESTIO_DEBUG
13220 io_ptr = test_io_manager;
13221 test_io_backing_manager = unix_io_manager;
13223 io_ptr = unix_io_manager;
13226 if ((ctx->options & E2F_OPT_READONLY) == 0)
13227 flags |= EXT2_FLAG_RW;
13229 if (ctx->superblock && ctx->blocksize) {
13230 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13231 flags, ctx->superblock, ctx->blocksize,
13233 } else if (ctx->superblock) {
13235 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13236 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13237 retval = ext2fs_open2(ctx->filesystem_name,
13238 ctx->io_options, flags,
13239 ctx->superblock, blocksize,
13245 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13246 flags, 0, 0, io_ptr, &fs);
13247 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13248 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13249 ((retval == EXT2_ET_BAD_MAGIC) ||
13250 ((retval == 0) && ext2fs_check_desc(fs)))) {
13251 if (!fs || (fs->group_desc_count > 1)) {
13252 printf(_("%s trying backup blocks...\n"),
13253 retval ? _("Couldn't find ext2 superblock,") :
13254 _("Group descriptors look bad..."));
13255 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13262 bb_error_msg(_("while trying to open %s"),
13263 ctx->filesystem_name);
13264 if (retval == EXT2_ET_REV_TOO_HIGH) {
13265 printf(_("The filesystem revision is apparently "
13266 "too high for this version of e2fsck.\n"
13267 "(Or the filesystem superblock "
13268 "is corrupt)\n\n"));
13269 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13270 } else if (retval == EXT2_ET_SHORT_READ)
13271 printf(_("Could this be a zero-length partition?\n"));
13272 else if ((retval == EPERM) || (retval == EACCES))
13273 printf(_("You must have %s access to the "
13274 "filesystem or be root\n"),
13275 (ctx->options & E2F_OPT_READONLY) ?
13277 else if (retval == ENXIO)
13278 printf(_("Possibly non-existent or swap device?\n"));
13280 else if (retval == EROFS)
13281 printf(_("Disk write-protected; use the -n option "
13282 "to do a read-only\n"
13283 "check of the device.\n"));
13286 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13287 bb_error_msg_and_die(0);
13290 fs->priv_data = ctx;
13292 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13293 bb_error_msg(_("while trying to open %s"),
13294 ctx->filesystem_name);
13296 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13300 * Set the device name, which is used whenever we print error
13301 * or informational messages to the user.
13303 if (ctx->device_name == 0 &&
13304 (sb->s_volume_name[0] != 0)) {
13305 ctx->device_name = string_copy(sb->s_volume_name,
13306 sizeof(sb->s_volume_name));
13308 if (ctx->device_name == 0)
13309 ctx->device_name = ctx->filesystem_name;
13312 * Make sure the ext3 superblock fields are consistent.
13314 retval = e2fsck_check_ext3_journal(ctx);
13316 bb_error_msg(_("while checking ext3 journal for %s"),
13318 bb_error_msg_and_die(0);
13322 * Check to see if we need to do ext3-style recovery. If so,
13323 * do it, and then restart the fsck.
13325 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13326 if (ctx->options & E2F_OPT_READONLY) {
13327 printf(_("Warning: skipping journal recovery "
13328 "because doing a read-only filesystem "
13330 io_channel_flush(ctx->fs->io);
13332 if (ctx->flags & E2F_FLAG_RESTARTED) {
13334 * Whoops, we attempted to run the
13335 * journal twice. This should never
13336 * happen, unless the hardware or
13337 * device driver is being bogus.
13339 bb_error_msg(_("can't set superblock flags on %s"), ctx->device_name);
13340 bb_error_msg_and_die(0);
13342 retval = e2fsck_run_ext3_journal(ctx);
13344 bb_error_msg(_("while recovering ext3 journal of %s"),
13346 bb_error_msg_and_die(0);
13348 ext2fs_close(ctx->fs);
13350 ctx->flags |= E2F_FLAG_RESTARTED;
13356 * Check for compatibility with the feature sets. We need to
13357 * be more stringent than ext2fs_open().
13359 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13360 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13361 bb_error_msg("(%s)", ctx->device_name);
13364 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13365 bb_error_msg("(%s)", ctx->device_name);
13368 #ifdef ENABLE_COMPRESSION
13369 /* FIXME - do we support this at all? */
13370 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13371 bb_error_msg(_("warning: compression support is experimental"));
13373 #ifndef ENABLE_HTREE
13374 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13375 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13376 "but filesystem %s has HTREE directories."),
13383 * If the user specified a specific superblock, presumably the
13384 * master superblock has been trashed. So we mark the
13385 * superblock as dirty, so it can be written out.
13387 if (ctx->superblock &&
13388 !(ctx->options & E2F_OPT_READONLY))
13389 ext2fs_mark_super_dirty(fs);
13392 * We only update the master superblock because (a) paranoia;
13393 * we don't want to corrupt the backup superblocks, and (b) we
13394 * don't need to update the mount count and last checked
13395 * fields in the backup superblock (the kernel doesn't
13396 * update the backup superblocks anyway).
13398 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13400 ehandler_init(fs->io);
13402 if (ctx->superblock)
13403 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13404 ext2fs_mark_valid(fs);
13405 check_super_block(ctx);
13406 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13407 bb_error_msg_and_die(0);
13408 check_if_skip(ctx);
13409 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13410 bb_error_msg_and_die(0);
13411 #ifdef ENABLE_SWAPFS
13413 #ifdef WORDS_BIGENDIAN
13414 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13416 #define NATIVE_FLAG 0
13420 if (normalize_swapfs) {
13421 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13422 fprintf(stderr, _("%s: Filesystem byte order "
13423 "already normalized.\n"), ctx->device_name);
13424 bb_error_msg_and_die(0);
13429 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13430 bb_error_msg_and_die(0);
13435 * Mark the system as valid, 'til proven otherwise
13437 ext2fs_mark_valid(fs);
13439 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13441 bb_error_msg(_("while reading bad blocks inode"));
13443 printf(_("This doesn't bode well,"
13444 " but we'll try to go on...\n"));
13447 run_result = e2fsck_run(ctx);
13448 e2fsck_clear_progbar(ctx);
13449 if (run_result == E2F_FLAG_RESTART) {
13450 printf(_("Restarting e2fsck from the beginning...\n"));
13451 retval = e2fsck_reset_context(ctx);
13453 bb_error_msg(_("while resetting context"));
13454 bb_error_msg_and_die(0);
13459 if (run_result & E2F_FLAG_CANCEL) {
13460 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13461 ctx->device_name : ctx->filesystem_name);
13462 exit_value |= FSCK_CANCELED;
13464 if (run_result & E2F_FLAG_ABORT)
13465 bb_error_msg_and_die(_("aborted"));
13468 if (ext2fs_test_changed(fs)) {
13469 exit_value |= EXIT_NONDESTRUCT;
13470 if (!(ctx->options & E2F_OPT_PREEN))
13471 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13473 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13474 printf(_("%s: ***** REBOOT LINUX *****\n"),
13476 exit_value |= EXIT_DESTRUCT;
13479 if (!ext2fs_test_valid(fs)) {
13480 printf(_("\n%s: ********** WARNING: Filesystem still has "
13481 "errors **********\n\n"), ctx->device_name);
13482 exit_value |= EXIT_UNCORRECTED;
13483 exit_value &= ~EXIT_NONDESTRUCT;
13485 if (exit_value & FSCK_CANCELED)
13486 exit_value &= ~EXIT_NONDESTRUCT;
13489 if (!(ctx->options & E2F_OPT_READONLY)) {
13490 if (ext2fs_test_valid(fs)) {
13491 if (!(sb->s_state & EXT2_VALID_FS))
13492 exit_value |= EXIT_NONDESTRUCT;
13493 sb->s_state = EXT2_VALID_FS;
13495 sb->s_state &= ~EXT2_VALID_FS;
13496 sb->s_mnt_count = 0;
13497 sb->s_lastcheck = time(NULL);
13498 ext2fs_mark_super_dirty(fs);
13502 e2fsck_write_bitmaps(ctx);
13506 free(ctx->filesystem_name);
13507 free(ctx->journal_name);
13508 e2fsck_free_context(ctx);