4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
5 * Copyright (C) 2006 Garrett Kajmowicz
7 * redistributed under the terms of the GNU Public License.
10 * Dictionary Abstract Data Type
11 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
12 * Free Software License:
13 * All rights are reserved by the author, with the following exceptions:
14 * Permission is granted to freely reproduce and distribute this software,
15 * possibly in exchange for a fee, provided that this copyright notice appears
16 * intact. Permission is also granted to adapt this software to produce
17 * derivative works, as long as the modified versions carry this copyright
18 * notice and additional notices stating that the work has been modified.
19 * This source code may be translated into executable form and incorporated
20 * into proprietary software; there is no requirement for such software to
21 * contain a copyright notice related to this source.
23 * linux/fs/recovery and linux/fs/revoke
24 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
26 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
28 * This file is part of the Linux kernel and is made available under
29 * the terms of the GNU General Public License, version 2, or at your
30 * option, any later version, incorporated herein by reference.
32 * Journal recovery routines for the generic filesystem journaling code;
33 * part of the ext2fs journaling system.
37 #define _GNU_SOURCE 1 /* get strnlen() */
40 #include "e2fsck.h" /*Put all of our defines here to clean things up*/
43 * Procedure declarations
46 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
49 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
52 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
53 ext2_ino_t ino, char *buf);
56 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
57 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
58 int num, int gauranteed_size);
59 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
60 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
64 static void e2fsck_rehash_directories(e2fsck_t ctx);
67 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
68 const char *description);
69 static int ask(e2fsck_t ctx, const char * string, int def);
70 static void e2fsck_read_bitmaps(e2fsck_t ctx);
71 static void preenhalt(e2fsck_t ctx);
72 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
73 struct ext2_inode * inode, const char * proc);
74 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
75 struct ext2_inode * inode, const char * proc);
76 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
77 const char *name, io_manager manager);
80 static void e2fsck_clear_progbar(e2fsck_t ctx);
81 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
82 float percent, unsigned int dpynum);
86 * problem.h --- e2fsck problem error codes
89 typedef __u32 problem_t;
91 struct problem_context {
93 ext2_ino_t ino, ino2, dir;
94 struct ext2_inode *inode;
95 struct ext2_dir_entry *dirent;
106 * Function declarations
108 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
109 static int end_problem_latch(e2fsck_t ctx, int mask);
110 static int set_latch_flags(int mask, int setflags, int clearflags);
111 static void clear_problem_context(struct problem_context *ctx);
114 * Dictionary Abstract Data Type
115 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
117 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
125 * Blurb for inclusion into C++ translation units
128 typedef unsigned long dictcount_t;
129 #define DICTCOUNT_T_MAX ULONG_MAX
132 * The dictionary is implemented as a red-black tree
135 typedef enum { dnode_red, dnode_black } dnode_color_t;
137 typedef struct dnode_t {
138 struct dnode_t *dict_left;
139 struct dnode_t *dict_right;
140 struct dnode_t *dict_parent;
141 dnode_color_t dict_color;
142 const void *dict_key;
146 typedef int (*dict_comp_t)(const void *, const void *);
147 typedef void (*dnode_free_t)(dnode_t *);
149 typedef struct dict_t {
150 dnode_t dict_nilnode;
151 dictcount_t dict_nodecount;
152 dictcount_t dict_maxcount;
153 dict_comp_t dict_compare;
154 dnode_free_t dict_freenode;
158 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
160 typedef struct dict_load_t {
161 dict_t *dict_dictptr;
162 dnode_t dict_nilnode;
165 #define dict_count(D) ((D)->dict_nodecount)
166 #define dnode_get(N) ((N)->dict_data)
167 #define dnode_getkey(N) ((N)->dict_key)
172 * Compatibility header file for e2fsck which should be included
173 * instead of linux/jfs.h
175 * Copyright (C) 2000 Stephen C. Tweedie
179 * Pull in the definition of the e2fsck context structure
195 #define K_DEV_JOURNAL 2
197 #define lock_buffer(bh) do {} while(0)
198 #define unlock_buffer(bh) do {} while(0)
199 #define buffer_req(bh) 1
200 #define do_readahead(journal, start) do {} while(0)
202 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
208 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
211 * We use the standard libext2fs portability tricks for inline
215 static kmem_cache_t * do_cache_create(int len)
217 kmem_cache_t *new_cache;
219 new_cache = malloc(sizeof(*new_cache));
221 new_cache->object_length = len;
225 static void do_cache_destroy(kmem_cache_t *cache)
231 * badblocks.c --- replace/append bad blocks to the bad block inode
234 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
238 static void invalid_block(ext2_filsys fs FSCK_ATTR((unused)), blk_t blk)
240 printf(_("Bad block %u out of range; ignored.\n"), blk);
244 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
245 int replace_bad_blocks)
247 ext2_filsys fs = ctx->fs;
249 badblocks_list bb_list = 0;
253 e2fsck_read_bitmaps(ctx);
256 * Make sure the bad block inode is sane. If there are any
257 * illegal blocks, clear them.
259 retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
260 check_bb_inode_blocks, 0);
262 bb_error_msg(_("while sanity checking the bad blocks inode"));
267 * If we're appending to the bad blocks inode, read in the
268 * current bad blocks.
270 if (!replace_bad_blocks) {
271 retval = ext2fs_read_bb_inode(fs, &bb_list);
273 bb_error_msg(_("while reading the bad blocks inode"));
279 * Now read in the bad blocks from the file; if
280 * bad_blocks_file is null, then try to run the badblocks
283 if (bad_blocks_file) {
284 f = fopen(bad_blocks_file, "r");
286 bb_error_msg(_("while trying to open %s"), bad_blocks_file);
290 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
291 (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
292 (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
293 fs->device_name, fs->super->s_blocks_count);
296 bb_error_msg(_("while trying popen '%s'"), buf);
300 retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
306 bb_error_msg(_("while reading in list of bad blocks from file"));
311 * Finally, update the bad blocks from the bad_block_map
313 retval = ext2fs_update_bb_inode(fs, bb_list);
315 bb_error_msg(_("while updating bad block inode"));
319 ext2fs_badblocks_list_free(bb_list);
323 ctx->flags |= E2F_FLAG_ABORT;
328 static int check_bb_inode_blocks(ext2_filsys fs,
330 int blockcnt FSCK_ATTR((unused)),
331 void *priv_data FSCK_ATTR((unused)))
337 * If the block number is outrageous, clear it and ignore it.
339 if (*block_nr >= fs->super->s_blocks_count ||
340 *block_nr < fs->super->s_first_data_block) {
341 printf(_("Warning illegal block %u found in bad block inode. Cleared.\n"), *block_nr);
343 return BLOCK_CHANGED;
350 * Dictionary Abstract Data Type
355 * These macros provide short convenient names for structure members,
356 * which are embellished with dict_ prefixes so that they are
357 * properly confined to the documented namespace. It's legal for a
358 * program which uses dict to define, for instance, a macro called ``parent''.
359 * Such a macro would interfere with the dnode_t struct definition.
360 * In general, highly portable and reusable C modules which expose their
361 * structures need to confine structure member names to well-defined spaces.
362 * The resulting identifiers aren't necessarily convenient to use, nor
363 * readable, in the implementation, however!
366 #define left dict_left
367 #define right dict_right
368 #define parent dict_parent
369 #define color dict_color
371 #define data dict_data
373 #define nilnode dict_nilnode
374 #define maxcount dict_maxcount
375 #define compare dict_compare
376 #define dupes dict_dupes
378 #define dict_root(D) ((D)->nilnode.left)
379 #define dict_nil(D) (&(D)->nilnode)
381 static void dnode_free(dnode_t *node);
384 * Perform a ``left rotation'' adjustment on the tree. The given node P and
385 * its right child C are rearranged so that the P instead becomes the left
386 * child of C. The left subtree of C is inherited as the new right subtree
387 * for P. The ordering of the keys within the tree is thus preserved.
390 static void rotate_left(dnode_t *upper)
392 dnode_t *lower, *lowleft, *upparent;
394 lower = upper->right;
395 upper->right = lowleft = lower->left;
396 lowleft->parent = upper;
398 lower->parent = upparent = upper->parent;
400 /* don't need to check for root node here because root->parent is
401 the sentinel nil node, and root->parent->left points back to root */
403 if (upper == upparent->left) {
404 upparent->left = lower;
406 assert (upper == upparent->right);
407 upparent->right = lower;
411 upper->parent = lower;
415 * This operation is the ``mirror'' image of rotate_left. It is
416 * the same procedure, but with left and right interchanged.
419 static void rotate_right(dnode_t *upper)
421 dnode_t *lower, *lowright, *upparent;
424 upper->left = lowright = lower->right;
425 lowright->parent = upper;
427 lower->parent = upparent = upper->parent;
429 if (upper == upparent->right) {
430 upparent->right = lower;
432 assert (upper == upparent->left);
433 upparent->left = lower;
436 lower->right = upper;
437 upper->parent = lower;
441 * Do a postorder traversal of the tree rooted at the specified
442 * node and free everything under it. Used by dict_free().
445 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
449 free_nodes(dict, node->left, nil);
450 free_nodes(dict, node->right, nil);
451 dict->dict_freenode(node);
455 * Verify that the tree contains the given node. This is done by
456 * traversing all of the nodes and comparing their pointers to the
457 * given pointer. Returns 1 if the node is found, otherwise
458 * returns zero. It is intended for debugging purposes.
461 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
465 || verify_dict_has_node(nil, root->left, node)
466 || verify_dict_has_node(nil, root->right, node);
473 * Select a different set of node allocator routines.
476 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
478 assert (dict_count(dict) == 0);
479 dict->dict_freenode = fr;
483 * Free all the nodes in the dictionary by using the dictionary's
484 * installed free routine. The dictionary is emptied.
487 static void dict_free_nodes(dict_t *dict)
489 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
490 free_nodes(dict, root, nil);
491 dict->dict_nodecount = 0;
492 dict->nilnode.left = &dict->nilnode;
493 dict->nilnode.right = &dict->nilnode;
497 * Initialize a user-supplied dictionary object.
500 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
502 dict->compare = comp;
503 dict->dict_freenode = dnode_free;
504 dict->dict_nodecount = 0;
505 dict->maxcount = maxcount;
506 dict->nilnode.left = &dict->nilnode;
507 dict->nilnode.right = &dict->nilnode;
508 dict->nilnode.parent = &dict->nilnode;
509 dict->nilnode.color = dnode_black;
515 * Locate a node in the dictionary having the given key.
516 * If the node is not found, a null a pointer is returned (rather than
517 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
518 * located node is returned.
521 static dnode_t *dict_lookup(dict_t *dict, const void *key)
523 dnode_t *root = dict_root(dict);
524 dnode_t *nil = dict_nil(dict);
528 /* simple binary search adapted for trees that contain duplicate keys */
530 while (root != nil) {
531 result = dict->compare(key, root->key);
537 if (!dict->dupes) { /* no duplicates, return match */
539 } else { /* could be dupes, find leftmost one */
543 while (root != nil && dict->compare(key, root->key))
545 } while (root != nil);
555 * Insert a node into the dictionary. The node should have been
556 * initialized with a data field. All other fields are ignored.
557 * The behavior is undefined if the user attempts to insert into
558 * a dictionary that is already full (for which the dict_isfull()
559 * function returns true).
562 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
564 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
565 dnode_t *parent = nil, *uncle, *grandpa;
570 /* basic binary tree insert */
572 while (where != nil) {
574 result = dict->compare(key, where->key);
575 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
576 assert (dict->dupes || result != 0);
580 where = where->right;
583 assert (where == nil);
588 parent->right = node;
590 node->parent = parent;
594 dict->dict_nodecount++;
596 /* red black adjustments */
598 node->color = dnode_red;
600 while (parent->color == dnode_red) {
601 grandpa = parent->parent;
602 if (parent == grandpa->left) {
603 uncle = grandpa->right;
604 if (uncle->color == dnode_red) { /* red parent, red uncle */
605 parent->color = dnode_black;
606 uncle->color = dnode_black;
607 grandpa->color = dnode_red;
609 parent = grandpa->parent;
610 } else { /* red parent, black uncle */
611 if (node == parent->right) {
614 assert (grandpa == parent->parent);
615 /* rotation between parent and child preserves grandpa */
617 parent->color = dnode_black;
618 grandpa->color = dnode_red;
619 rotate_right(grandpa);
622 } else { /* symmetric cases: parent == parent->parent->right */
623 uncle = grandpa->left;
624 if (uncle->color == dnode_red) {
625 parent->color = dnode_black;
626 uncle->color = dnode_black;
627 grandpa->color = dnode_red;
629 parent = grandpa->parent;
631 if (node == parent->left) {
632 rotate_right(parent);
634 assert (grandpa == parent->parent);
636 parent->color = dnode_black;
637 grandpa->color = dnode_red;
638 rotate_left(grandpa);
644 dict_root(dict)->color = dnode_black;
649 * Allocate a node using the dictionary's allocator routine, give it
653 static dnode_t *dnode_init(dnode_t *dnode, void *data)
656 dnode->parent = NULL;
662 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
664 dnode_t *node = malloc(sizeof(dnode_t));
667 dnode_init(node, data);
668 dict_insert(dict, node, key);
675 * Return the node with the lowest (leftmost) key. If the dictionary is empty
676 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
679 static dnode_t *dict_first(dict_t *dict)
681 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
684 while ((left = root->left) != nil)
687 return (root == nil) ? NULL : root;
691 * Return the given node's successor node---the node which has the
692 * next key in the the left to right ordering. If the node has
693 * no successor, a null pointer is returned rather than a pointer to
697 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
699 dnode_t *nil = dict_nil(dict), *parent, *left;
701 if (curr->right != nil) {
703 while ((left = curr->left) != nil)
708 parent = curr->parent;
710 while (parent != nil && curr == parent->right) {
712 parent = curr->parent;
715 return (parent == nil) ? NULL : parent;
719 static void dnode_free(dnode_t *node)
739 * dirinfo.c --- maintains the directory information table for e2fsck.
743 * This subroutine is called during pass1 to create a directory info
744 * entry. During pass1, the passed-in parent is 0; it will get filled
747 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
749 struct dir_info *dir;
753 unsigned long old_size;
755 if (!ctx->dir_info) {
756 ctx->dir_info_count = 0;
757 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
759 num_dirs = 1024; /* Guess */
760 ctx->dir_info_size = num_dirs + 10;
761 ctx->dir_info = (struct dir_info *)
762 e2fsck_allocate_memory(ctx, ctx->dir_info_size
763 * sizeof (struct dir_info),
767 if (ctx->dir_info_count >= ctx->dir_info_size) {
768 old_size = ctx->dir_info_size * sizeof(struct dir_info);
769 ctx->dir_info_size += 10;
770 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
771 sizeof(struct dir_info),
774 ctx->dir_info_size -= 10;
780 * Normally, add_dir_info is called with each inode in
781 * sequential order; but once in a while (like when pass 3
782 * needs to recreate the root directory or lost+found
783 * directory) it is called out of order. In those cases, we
784 * need to move the dir_info entries down to make room, since
785 * the dir_info array needs to be sorted by inode number for
786 * get_dir_info()'s sake.
788 if (ctx->dir_info_count &&
789 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
790 for (i = ctx->dir_info_count-1; i > 0; i--)
791 if (ctx->dir_info[i-1].ino < ino)
793 dir = &ctx->dir_info[i];
795 for (j = ctx->dir_info_count++; j > i; j--)
796 ctx->dir_info[j] = ctx->dir_info[j-1];
798 dir = &ctx->dir_info[ctx->dir_info_count++];
801 dir->dotdot = parent;
802 dir->parent = parent;
806 * get_dir_info() --- given an inode number, try to find the directory
807 * information entry for it.
809 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
814 high = ctx->dir_info_count-1;
817 if (ino == ctx->dir_info[low].ino)
818 return &ctx->dir_info[low];
819 if (ino == ctx->dir_info[high].ino)
820 return &ctx->dir_info[high];
824 if (mid == low || mid == high)
826 if (ino == ctx->dir_info[mid].ino)
827 return &ctx->dir_info[mid];
828 if (ino < ctx->dir_info[mid].ino)
837 * Free the dir_info structure when it isn't needed any more.
839 static void e2fsck_free_dir_info(e2fsck_t ctx)
841 ext2fs_free_mem(&ctx->dir_info);
842 ctx->dir_info_size = 0;
843 ctx->dir_info_count = 0;
847 * Return the count of number of directories in the dir_info structure
849 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
851 return ctx->dir_info_count;
855 * A simple interator function
857 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
859 if (*control >= ctx->dir_info_count)
862 return(ctx->dir_info + (*control)++);
866 * dirinfo.c --- maintains the directory information table for e2fsck.
873 * This subroutine is called during pass1 to create a directory info
874 * entry. During pass1, the passed-in parent is 0; it will get filled
877 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
879 struct dx_dir_info *dir;
882 unsigned long old_size;
884 if (!ctx->dx_dir_info) {
885 ctx->dx_dir_info_count = 0;
886 ctx->dx_dir_info_size = 100; /* Guess */
887 ctx->dx_dir_info = (struct dx_dir_info *)
888 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
889 * sizeof (struct dx_dir_info),
893 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
894 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
895 ctx->dx_dir_info_size += 10;
896 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
897 sizeof(struct dx_dir_info),
900 ctx->dx_dir_info_size -= 10;
906 * Normally, add_dx_dir_info is called with each inode in
907 * sequential order; but once in a while (like when pass 3
908 * needs to recreate the root directory or lost+found
909 * directory) it is called out of order. In those cases, we
910 * need to move the dx_dir_info entries down to make room, since
911 * the dx_dir_info array needs to be sorted by inode number for
912 * get_dx_dir_info()'s sake.
914 if (ctx->dx_dir_info_count &&
915 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
916 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
917 if (ctx->dx_dir_info[i-1].ino < ino)
919 dir = &ctx->dx_dir_info[i];
921 for (j = ctx->dx_dir_info_count++; j > i; j--)
922 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
924 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
927 dir->numblocks = num_blocks;
928 dir->hashversion = 0;
929 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
930 * sizeof (struct dx_dirblock_info),
931 "dx_block info array");
936 * get_dx_dir_info() --- given an inode number, try to find the directory
937 * information entry for it.
939 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
944 high = ctx->dx_dir_info_count-1;
945 if (!ctx->dx_dir_info)
947 if (ino == ctx->dx_dir_info[low].ino)
948 return &ctx->dx_dir_info[low];
949 if (ino == ctx->dx_dir_info[high].ino)
950 return &ctx->dx_dir_info[high];
954 if (mid == low || mid == high)
956 if (ino == ctx->dx_dir_info[mid].ino)
957 return &ctx->dx_dir_info[mid];
958 if (ino < ctx->dx_dir_info[mid].ino)
967 * Free the dx_dir_info structure when it isn't needed any more.
969 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
972 struct dx_dir_info *dir;
974 if (ctx->dx_dir_info) {
975 dir = ctx->dx_dir_info;
976 for (i=0; i < ctx->dx_dir_info_count; i++) {
977 ext2fs_free_mem(&dir->dx_block);
979 ext2fs_free_mem(&ctx->dx_dir_info);
981 ctx->dx_dir_info_size = 0;
982 ctx->dx_dir_info_count = 0;
986 * A simple interator function
988 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
990 if (*control >= ctx->dx_dir_info_count)
993 return(ctx->dx_dir_info + (*control)++);
996 #endif /* ENABLE_HTREE */
998 * e2fsck.c - a consistency checker for the new extended file system.
1003 * This function allocates an e2fsck context
1005 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
1010 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
1014 memset(context, 0, sizeof(struct e2fsck_struct));
1016 context->process_inode_size = 256;
1017 context->ext_attr_ver = 2;
1023 struct ea_refcount_el {
1028 struct ea_refcount {
1032 struct ea_refcount_el *list;
1035 static void ea_refcount_free(ext2_refcount_t refcount)
1040 ext2fs_free_mem(&refcount->list);
1041 ext2fs_free_mem(&refcount);
1045 * This function resets an e2fsck context; it is called when e2fsck
1046 * needs to be restarted.
1048 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
1051 ctx->lost_and_found = 0;
1052 ctx->bad_lost_and_found = 0;
1053 ext2fs_free_inode_bitmap(ctx->inode_used_map);
1054 ctx->inode_used_map = 0;
1055 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
1056 ctx->inode_dir_map = 0;
1057 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
1058 ctx->inode_reg_map = 0;
1059 ext2fs_free_block_bitmap(ctx->block_found_map);
1060 ctx->block_found_map = 0;
1061 ext2fs_free_icount(ctx->inode_link_info);
1062 ctx->inode_link_info = 0;
1063 if (ctx->journal_io) {
1064 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1065 io_channel_close(ctx->journal_io);
1066 ctx->journal_io = 0;
1069 ext2fs_free_dblist(ctx->fs->dblist);
1070 ctx->fs->dblist = 0;
1072 e2fsck_free_dir_info(ctx);
1074 e2fsck_free_dx_dir_info(ctx);
1076 ea_refcount_free(ctx->refcount);
1078 ea_refcount_free(ctx->refcount_extra);
1079 ctx->refcount_extra = 0;
1080 ext2fs_free_block_bitmap(ctx->block_dup_map);
1081 ctx->block_dup_map = 0;
1082 ext2fs_free_block_bitmap(ctx->block_ea_map);
1083 ctx->block_ea_map = 0;
1084 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
1085 ctx->inode_bb_map = 0;
1086 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
1087 ctx->inode_bad_map = 0;
1088 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
1089 ctx->inode_imagic_map = 0;
1090 ext2fs_u32_list_free(ctx->dirs_to_hash);
1091 ctx->dirs_to_hash = 0;
1094 * Clear the array of invalid meta-data flags
1096 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
1097 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
1098 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
1100 /* Clear statistic counters */
1101 ctx->fs_directory_count = 0;
1102 ctx->fs_regular_count = 0;
1103 ctx->fs_blockdev_count = 0;
1104 ctx->fs_chardev_count = 0;
1105 ctx->fs_links_count = 0;
1106 ctx->fs_symlinks_count = 0;
1107 ctx->fs_fast_symlinks_count = 0;
1108 ctx->fs_fifo_count = 0;
1109 ctx->fs_total_count = 0;
1110 ctx->fs_badblocks_count = 0;
1111 ctx->fs_sockets_count = 0;
1112 ctx->fs_ind_count = 0;
1113 ctx->fs_dind_count = 0;
1114 ctx->fs_tind_count = 0;
1115 ctx->fs_fragmented = 0;
1116 ctx->large_files = 0;
1118 /* Reset the superblock to the user's requested value */
1119 ctx->superblock = ctx->use_superblock;
1124 static void e2fsck_free_context(e2fsck_t ctx)
1129 e2fsck_reset_context(ctx);
1131 blkid_put_cache(ctx->blkid);
1133 ext2fs_free_mem(&ctx);
1141 * The strategy we use for keeping track of EA refcounts is as
1142 * follows. We keep a sorted array of first EA blocks and its
1143 * reference counts. Once the refcount has dropped to zero, it is
1144 * removed from the array to save memory space. Once the EA block is
1145 * checked, its bit is set in the block_ea_map bitmap.
1149 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1151 ext2_refcount_t refcount;
1155 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1158 memset(refcount, 0, sizeof(struct ea_refcount));
1162 refcount->size = size;
1163 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1165 printf("Refcount allocated %d entries, %d bytes.\n",
1166 refcount->size, bytes);
1168 retval = ext2fs_get_mem(bytes, &refcount->list);
1171 memset(refcount->list, 0, bytes);
1173 refcount->count = 0;
1174 refcount->cursor = 0;
1180 ea_refcount_free(refcount);
1185 * collapse_refcount() --- go through the refcount array, and get rid
1186 * of any count == zero entries
1188 static void refcount_collapse(ext2_refcount_t refcount)
1191 struct ea_refcount_el *list;
1193 list = refcount->list;
1194 for (i = 0, j = 0; i < refcount->count; i++) {
1195 if (list[i].ea_count) {
1201 #if defined(DEBUG) || defined(TEST_PROGRAM)
1202 printf("Refcount_collapse: size was %d, now %d\n",
1203 refcount->count, j);
1205 refcount->count = j;
1210 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1211 * specified position.
1213 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1216 struct ea_refcount_el *el;
1221 if (refcount->count >= refcount->size) {
1222 new_size = refcount->size + 100;
1224 printf("Reallocating refcount %d entries...\n", new_size);
1226 retval = ext2fs_resize_mem((size_t) refcount->size *
1227 sizeof(struct ea_refcount_el),
1229 sizeof(struct ea_refcount_el),
1233 refcount->size = new_size;
1235 num = (int) refcount->count - pos;
1237 return 0; /* should never happen */
1239 memmove(&refcount->list[pos+1], &refcount->list[pos],
1240 sizeof(struct ea_refcount_el) * num);
1243 el = &refcount->list[pos];
1251 * get_refcount_el() --- given an block number, try to find refcount
1252 * information in the sorted list. If the create flag is set,
1253 * and we can't find an entry, create one in the sorted list.
1255 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1256 blk_t blk, int create)
1260 blk_t lowval, highval;
1262 if (!refcount || !refcount->list)
1266 high = (int) refcount->count-1;
1267 if (create && ((refcount->count == 0) ||
1268 (blk > refcount->list[high].ea_blk))) {
1269 if (refcount->count >= refcount->size)
1270 refcount_collapse(refcount);
1272 return insert_refcount_el(refcount, blk,
1273 (unsigned) refcount->count);
1275 if (refcount->count == 0)
1278 if (refcount->cursor >= refcount->count)
1279 refcount->cursor = 0;
1280 if (blk == refcount->list[refcount->cursor].ea_blk)
1281 return &refcount->list[refcount->cursor++];
1283 printf("Non-cursor get_refcount_el: %u\n", blk);
1285 while (low <= high) {
1289 /* Interpolate for efficiency */
1290 lowval = refcount->list[low].ea_blk;
1291 highval = refcount->list[high].ea_blk;
1295 else if (blk > highval)
1298 range = ((float) (blk - lowval)) /
1300 mid = low + ((int) (range * (high-low)));
1303 if (blk == refcount->list[mid].ea_blk) {
1304 refcount->cursor = mid+1;
1305 return &refcount->list[mid];
1307 if (blk < refcount->list[mid].ea_blk)
1313 * If we need to create a new entry, it should be right at
1314 * low (where high will be left at low-1).
1317 if (refcount->count >= refcount->size) {
1318 refcount_collapse(refcount);
1319 if (refcount->count < refcount->size)
1322 return insert_refcount_el(refcount, blk, low);
1328 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1330 struct ea_refcount_el *el;
1332 el = get_refcount_el(refcount, blk, 1);
1334 return EXT2_ET_NO_MEMORY;
1338 *ret = el->ea_count;
1343 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1345 struct ea_refcount_el *el;
1347 el = get_refcount_el(refcount, blk, 0);
1348 if (!el || el->ea_count == 0)
1349 return EXT2_ET_INVALID_ARGUMENT;
1354 *ret = el->ea_count;
1359 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1361 struct ea_refcount_el *el;
1364 * Get the refcount element
1366 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1368 return count ? EXT2_ET_NO_MEMORY : 0;
1369 el->ea_count = count;
1373 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1375 refcount->cursor = 0;
1379 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1381 struct ea_refcount_el *list;
1384 if (refcount->cursor >= refcount->count)
1386 list = refcount->list;
1387 if (list[refcount->cursor].ea_count) {
1389 *ret = list[refcount->cursor].ea_count;
1390 return list[refcount->cursor++].ea_blk;
1398 * ehandler.c --- handle bad block errors which come up during the
1399 * course of an e2fsck session.
1403 static const char *operation;
1406 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1407 void *data, size_t size FSCK_ATTR((unused)),
1408 int actual FSCK_ATTR((unused)), errcode_t error)
1412 ext2_filsys fs = (ext2_filsys) channel->app_data;
1415 ctx = (e2fsck_t) fs->priv_data;
1418 * If more than one block was read, try reading each block
1419 * separately. We could use the actual bytes read to figure
1420 * out where to start, but we don't bother.
1424 for (i=0; i < count; i++, p += channel->block_size, block++) {
1425 error = io_channel_read_blk(channel, block,
1433 printf(_("Error reading block %lu (%s) while %s. "), block,
1434 error_message(error), operation);
1436 printf(_("Error reading block %lu (%s). "), block,
1437 error_message(error));
1439 if (ask(ctx, _("Ignore error"), 1)) {
1440 if (ask(ctx, _("Force rewrite"), 1))
1441 io_channel_write_blk(channel, block, 1, data);
1449 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1450 const void *data, size_t size FSCK_ATTR((unused)),
1451 int actual FSCK_ATTR((unused)), errcode_t error)
1455 ext2_filsys fs = (ext2_filsys) channel->app_data;
1458 ctx = (e2fsck_t) fs->priv_data;
1461 * If more than one block was written, try writing each block
1462 * separately. We could use the actual bytes read to figure
1463 * out where to start, but we don't bother.
1466 p = (const char *) data;
1467 for (i=0; i < count; i++, p += channel->block_size, block++) {
1468 error = io_channel_write_blk(channel, block,
1477 printf(_("Error writing block %lu (%s) while %s. "), block,
1478 error_message(error), operation);
1480 printf(_("Error writing block %lu (%s). "), block,
1481 error_message(error));
1483 if (ask(ctx, _("Ignore error"), 1))
1489 static inline const char *ehandler_operation(const char *op)
1491 const char *ret = operation;
1497 static void ehandler_init(io_channel channel)
1499 channel->read_error = e2fsck_handle_read_error;
1500 channel->write_error = e2fsck_handle_write_error;
1504 * journal.c --- code for handling the "ext3" journal
1506 * Copyright (C) 2000 Andreas Dilger
1507 * Copyright (C) 2000 Theodore Ts'o
1509 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1510 * Copyright (C) 1999 Red Hat Software
1512 * This file may be redistributed under the terms of the
1513 * GNU General Public License version 2 or at your discretion
1514 * any later version.
1518 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1519 * This creates a larger static binary, and a smaller binary using
1520 * shared libraries. It's also probably slightly less CPU-efficient,
1521 * which is why it's not on by default. But, it's a good way of
1522 * testing the functions in inode_io.c and fileio.c.
1526 /* Kernel compatibility functions for handling the journal. These allow us
1527 * to use the recovery.c file virtually unchanged from the kernel, so we
1528 * don't have to do much to keep kernel and user recovery in sync.
1530 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1536 struct inode *inode = journal->j_inode;
1545 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1546 &inode->i_ext2, NULL, 0, block, &pblk);
1552 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1554 struct buffer_head *bh;
1556 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1560 bh->b_ctx = kdev->k_ctx;
1561 if (kdev->k_dev == K_DEV_FS)
1562 bh->b_io = kdev->k_ctx->fs->io;
1564 bh->b_io = kdev->k_ctx->journal_io;
1565 bh->b_size = blocksize;
1566 bh->b_blocknr = blocknr;
1571 static void sync_blockdev(kdev_t kdev)
1575 if (kdev->k_dev == K_DEV_FS)
1576 io = kdev->k_ctx->fs->io;
1578 io = kdev->k_ctx->journal_io;
1580 io_channel_flush(io);
1583 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1586 struct buffer_head *bh;
1588 for (; nr > 0; --nr) {
1590 if (rw == READ && !bh->b_uptodate) {
1591 retval = io_channel_read_blk(bh->b_io,
1595 bb_error_msg("while reading block %lu\n",
1596 (unsigned long) bh->b_blocknr);
1601 } else if (rw == WRITE && bh->b_dirty) {
1602 retval = io_channel_write_blk(bh->b_io,
1606 bb_error_msg("while writing block %lu\n",
1607 (unsigned long) bh->b_blocknr);
1617 static inline void mark_buffer_dirty(struct buffer_head *bh)
1622 static inline void mark_buffer_clean(struct buffer_head * bh)
1627 static void brelse(struct buffer_head *bh)
1630 ll_rw_block(WRITE, 1, &bh);
1631 ext2fs_free_mem(&bh);
1634 static inline int buffer_uptodate(struct buffer_head *bh)
1636 return bh->b_uptodate;
1639 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1641 bh->b_uptodate = val;
1644 static void wait_on_buffer(struct buffer_head *bh)
1646 if (!bh->b_uptodate)
1647 ll_rw_block(READ, 1, &bh);
1651 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1653 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1655 /* if we had an error doing journal recovery, we need a full fsck */
1657 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1658 ext2fs_mark_super_dirty(ctx->fs);
1661 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1663 struct ext2_super_block *sb = ctx->fs->super;
1664 struct ext2_super_block jsuper;
1665 struct problem_context pctx;
1666 struct buffer_head *bh;
1667 struct inode *j_inode = NULL;
1668 struct kdev_s *dev_fs = NULL, *dev_journal;
1669 const char *journal_name = 0;
1670 journal_t *journal = NULL;
1671 errcode_t retval = 0;
1672 io_manager io_ptr = 0;
1673 unsigned long start = 0;
1675 int ext_journal = 0;
1676 int tried_backup_jnl = 0;
1679 clear_problem_context(&pctx);
1681 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1683 return EXT2_ET_NO_MEMORY;
1686 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1688 retval = EXT2_ET_NO_MEMORY;
1691 dev_journal = dev_fs+1;
1693 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1694 dev_fs->k_dev = K_DEV_FS;
1695 dev_journal->k_dev = K_DEV_JOURNAL;
1697 journal->j_dev = dev_journal;
1698 journal->j_fs_dev = dev_fs;
1699 journal->j_inode = NULL;
1700 journal->j_blocksize = ctx->fs->blocksize;
1702 if (uuid_is_null(sb->s_journal_uuid)) {
1703 if (!sb->s_journal_inum)
1704 return EXT2_ET_BAD_INODE_NUM;
1705 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1708 retval = EXT2_ET_NO_MEMORY;
1712 j_inode->i_ctx = ctx;
1713 j_inode->i_ino = sb->s_journal_inum;
1715 if ((retval = ext2fs_read_inode(ctx->fs,
1717 &j_inode->i_ext2))) {
1719 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1722 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1723 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1725 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1726 j_inode->i_ext2.i_links_count = 1;
1727 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1730 if (!j_inode->i_ext2.i_links_count ||
1731 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1732 retval = EXT2_ET_NO_JOURNAL;
1733 goto try_backup_journal;
1735 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1736 JFS_MIN_JOURNAL_BLOCKS) {
1737 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1738 goto try_backup_journal;
1740 for (i=0; i < EXT2_N_BLOCKS; i++) {
1741 blk = j_inode->i_ext2.i_block[i];
1743 if (i < EXT2_NDIR_BLOCKS) {
1744 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1745 goto try_backup_journal;
1749 if (blk < sb->s_first_data_block ||
1750 blk >= sb->s_blocks_count) {
1751 retval = EXT2_ET_BAD_BLOCK_NUM;
1752 goto try_backup_journal;
1755 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1758 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1764 io_ptr = inode_io_manager;
1766 journal->j_inode = j_inode;
1767 ctx->journal_io = ctx->fs->io;
1768 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1773 if (!ctx->journal_name) {
1776 uuid_unparse(sb->s_journal_uuid, uuid);
1777 ctx->journal_name = blkid_get_devname(ctx->blkid,
1779 if (!ctx->journal_name)
1780 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1782 journal_name = ctx->journal_name;
1784 if (!journal_name) {
1785 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1786 return EXT2_ET_LOAD_EXT_JOURNAL;
1789 io_ptr = unix_io_manager;
1792 #ifndef USE_INODE_IO
1795 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1800 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1803 if (ctx->fs->blocksize == 1024)
1805 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1807 retval = EXT2_ET_NO_MEMORY;
1810 ll_rw_block(READ, 1, &bh);
1811 if ((retval = bh->b_err) != 0)
1813 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1817 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1818 ext2fs_swap_super(&jsuper);
1820 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1821 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1822 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1823 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1826 /* Make sure the journal UUID is correct */
1827 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1828 sizeof(jsuper.s_uuid))) {
1829 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1830 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1834 journal->j_maxlen = jsuper.s_blocks_count;
1838 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1839 retval = EXT2_ET_NO_MEMORY;
1843 journal->j_sb_buffer = bh;
1844 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1847 ext2fs_free_mem(&j_inode);
1850 *ret_journal = journal;
1854 ext2fs_free_mem(&dev_fs);
1855 ext2fs_free_mem(&j_inode);
1856 ext2fs_free_mem(&journal);
1861 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1862 struct problem_context *pctx)
1864 struct ext2_super_block *sb = ctx->fs->super;
1865 int recover = ctx->fs->super->s_feature_incompat &
1866 EXT3_FEATURE_INCOMPAT_RECOVER;
1867 int has_journal = ctx->fs->super->s_feature_compat &
1868 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1870 if (has_journal || sb->s_journal_inum) {
1871 /* The journal inode is bogus, remove and force full fsck */
1872 pctx->ino = sb->s_journal_inum;
1873 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1874 if (has_journal && sb->s_journal_inum)
1875 printf("*** ext3 journal has been deleted - "
1876 "filesystem is now ext2 only ***\n\n");
1877 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1878 sb->s_journal_inum = 0;
1879 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1880 e2fsck_clear_recover(ctx, 1);
1883 return EXT2_ET_BAD_INODE_NUM;
1884 } else if (recover) {
1885 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1886 e2fsck_clear_recover(ctx, 1);
1889 return EXT2_ET_UNSUPP_FEATURE;
1894 #define V1_SB_SIZE 0x0024
1895 static void clear_v2_journal_fields(journal_t *journal)
1897 e2fsck_t ctx = journal->j_dev->k_ctx;
1898 struct problem_context pctx;
1900 clear_problem_context(&pctx);
1902 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1905 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1906 ctx->fs->blocksize-V1_SB_SIZE);
1907 mark_buffer_dirty(journal->j_sb_buffer);
1911 static errcode_t e2fsck_journal_load(journal_t *journal)
1913 e2fsck_t ctx = journal->j_dev->k_ctx;
1914 journal_superblock_t *jsb;
1915 struct buffer_head *jbh = journal->j_sb_buffer;
1916 struct problem_context pctx;
1918 clear_problem_context(&pctx);
1920 ll_rw_block(READ, 1, &jbh);
1922 bb_error_msg(_("reading journal superblock\n"));
1926 jsb = journal->j_superblock;
1927 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1928 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1929 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1931 switch (ntohl(jsb->s_header.h_blocktype)) {
1932 case JFS_SUPERBLOCK_V1:
1933 journal->j_format_version = 1;
1934 if (jsb->s_feature_compat ||
1935 jsb->s_feature_incompat ||
1936 jsb->s_feature_ro_compat ||
1938 clear_v2_journal_fields(journal);
1941 case JFS_SUPERBLOCK_V2:
1942 journal->j_format_version = 2;
1943 if (ntohl(jsb->s_nr_users) > 1 &&
1944 uuid_is_null(ctx->fs->super->s_journal_uuid))
1945 clear_v2_journal_fields(journal);
1946 if (ntohl(jsb->s_nr_users) > 1) {
1947 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1948 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1953 * These should never appear in a journal super block, so if
1954 * they do, the journal is badly corrupted.
1956 case JFS_DESCRIPTOR_BLOCK:
1957 case JFS_COMMIT_BLOCK:
1958 case JFS_REVOKE_BLOCK:
1959 return EXT2_ET_CORRUPT_SUPERBLOCK;
1961 /* If we don't understand the superblock major type, but there
1962 * is a magic number, then it is likely to be a new format we
1963 * just don't understand, so leave it alone. */
1965 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1968 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1969 return EXT2_ET_UNSUPP_FEATURE;
1971 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1972 return EXT2_ET_RO_UNSUPP_FEATURE;
1974 /* We have now checked whether we know enough about the journal
1975 * format to be able to proceed safely, so any other checks that
1976 * fail we should attempt to recover from. */
1977 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1978 bb_error_msg(_("%s: no valid journal superblock found\n"),
1980 return EXT2_ET_CORRUPT_SUPERBLOCK;
1983 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1984 journal->j_maxlen = ntohl(jsb->s_maxlen);
1985 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1986 bb_error_msg(_("%s: journal too short\n"),
1988 return EXT2_ET_CORRUPT_SUPERBLOCK;
1991 journal->j_tail_sequence = ntohl(jsb->s_sequence);
1992 journal->j_transaction_sequence = journal->j_tail_sequence;
1993 journal->j_tail = ntohl(jsb->s_start);
1994 journal->j_first = ntohl(jsb->s_first);
1995 journal->j_last = ntohl(jsb->s_maxlen);
2000 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
2011 /* Leave a valid existing V1 superblock signature alone.
2012 * Anything unrecognisable we overwrite with a new V2
2015 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
2016 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
2017 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
2018 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
2021 /* Zero out everything else beyond the superblock header */
2023 p = ((char *) jsb) + sizeof(journal_header_t);
2024 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
2026 jsb->s_blocksize = htonl(ctx->fs->blocksize);
2027 jsb->s_maxlen = htonl(journal->j_maxlen);
2028 jsb->s_first = htonl(1);
2030 /* Initialize the journal sequence number so that there is "no"
2031 * chance we will find old "valid" transactions in the journal.
2032 * This avoids the need to zero the whole journal (slow to do,
2033 * and risky when we are just recovering the filesystem).
2035 uuid_generate(u.uuid);
2036 for (i = 0; i < 4; i ++)
2037 new_seq ^= u.val[i];
2038 jsb->s_sequence = htonl(new_seq);
2040 mark_buffer_dirty(journal->j_sb_buffer);
2041 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
2044 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
2046 struct problem_context *pctx)
2048 struct ext2_super_block *sb = ctx->fs->super;
2049 int recover = ctx->fs->super->s_feature_incompat &
2050 EXT3_FEATURE_INCOMPAT_RECOVER;
2052 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
2053 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
2054 e2fsck_journal_reset_super(ctx, journal->j_superblock,
2056 journal->j_transaction_sequence = 1;
2057 e2fsck_clear_recover(ctx, recover);
2060 return EXT2_ET_CORRUPT_SUPERBLOCK;
2061 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
2062 return EXT2_ET_CORRUPT_SUPERBLOCK;
2067 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
2068 int reset, int drop)
2070 journal_superblock_t *jsb;
2073 mark_buffer_clean(journal->j_sb_buffer);
2074 else if (!(ctx->options & E2F_OPT_READONLY)) {
2075 jsb = journal->j_superblock;
2076 jsb->s_sequence = htonl(journal->j_transaction_sequence);
2078 jsb->s_start = 0; /* this marks the journal as empty */
2079 mark_buffer_dirty(journal->j_sb_buffer);
2081 brelse(journal->j_sb_buffer);
2083 if (ctx->journal_io) {
2084 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2085 io_channel_close(ctx->journal_io);
2086 ctx->journal_io = 0;
2089 #ifndef USE_INODE_IO
2090 ext2fs_free_mem(&journal->j_inode);
2092 ext2fs_free_mem(&journal->j_fs_dev);
2093 ext2fs_free_mem(&journal);
2097 * This function makes sure that the superblock fields regarding the
2098 * journal are consistent.
2100 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
2102 struct ext2_super_block *sb = ctx->fs->super;
2104 int recover = ctx->fs->super->s_feature_incompat &
2105 EXT3_FEATURE_INCOMPAT_RECOVER;
2106 struct problem_context pctx;
2108 int reset = 0, force_fsck = 0;
2111 /* If we don't have any journal features, don't do anything more */
2112 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
2113 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
2114 uuid_is_null(sb->s_journal_uuid))
2117 clear_problem_context(&pctx);
2118 pctx.num = sb->s_journal_inum;
2120 retval = e2fsck_get_journal(ctx, &journal);
2122 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2123 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2124 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2125 (retval == EXT2_ET_NO_JOURNAL))
2126 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2130 retval = e2fsck_journal_load(journal);
2132 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2133 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2134 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2136 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2137 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2139 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2140 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2141 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2143 e2fsck_journal_release(ctx, journal, 0, 1);
2148 * We want to make the flags consistent here. We will not leave with
2149 * needs_recovery set but has_journal clear. We can't get in a loop
2150 * with -y, -n, or -p, only if a user isn't making up their mind.
2153 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2154 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2156 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2158 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2159 goto no_has_journal;
2161 * Need a full fsck if we are releasing a
2162 * journal stored on a reserved inode.
2164 force_fsck = recover ||
2165 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2166 /* Clear all of the journal fields */
2167 sb->s_journal_inum = 0;
2168 sb->s_journal_dev = 0;
2169 memset(sb->s_journal_uuid, 0,
2170 sizeof(sb->s_journal_uuid));
2171 e2fsck_clear_recover(ctx, force_fsck);
2172 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2173 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2174 ext2fs_mark_super_dirty(ctx->fs);
2178 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2179 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2180 journal->j_superblock->s_start != 0) {
2181 /* Print status information */
2182 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2183 if (ctx->superblock)
2184 problem = PR_0_JOURNAL_RUN_DEFAULT;
2186 problem = PR_0_JOURNAL_RUN;
2187 if (fix_problem(ctx, problem, &pctx)) {
2188 ctx->options |= E2F_OPT_FORCE;
2189 sb->s_feature_incompat |=
2190 EXT3_FEATURE_INCOMPAT_RECOVER;
2191 ext2fs_mark_super_dirty(ctx->fs);
2192 } else if (fix_problem(ctx,
2193 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2195 sb->s_state &= ~EXT2_VALID_FS;
2196 ext2fs_mark_super_dirty(ctx->fs);
2199 * If the user answers no to the above question, we
2200 * ignore the fact that journal apparently has data;
2201 * accidentally replaying over valid data would be far
2202 * worse than skipping a questionable recovery.
2204 * XXX should we abort with a fatal error here? What
2205 * will the ext3 kernel code do if a filesystem with
2206 * !NEEDS_RECOVERY but with a non-zero
2207 * journal->j_superblock->s_start is mounted?
2211 e2fsck_journal_release(ctx, journal, reset, 0);
2215 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2220 journal_init_revoke_caches();
2221 retval = e2fsck_get_journal(ctx, &journal);
2225 retval = e2fsck_journal_load(journal);
2229 retval = journal_init_revoke(journal, 1024);
2233 retval = -journal_recover(journal);
2237 if (journal->j_superblock->s_errno) {
2238 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2239 ext2fs_mark_super_dirty(ctx->fs);
2240 journal->j_superblock->s_errno = 0;
2241 mark_buffer_dirty(journal->j_sb_buffer);
2245 journal_destroy_revoke(journal);
2246 journal_destroy_revoke_caches();
2247 e2fsck_journal_release(ctx, journal, 1, 0);
2251 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2253 io_manager io_ptr = ctx->fs->io->manager;
2254 int blocksize = ctx->fs->blocksize;
2255 errcode_t retval, recover_retval;
2257 printf(_("%s: recovering journal\n"), ctx->device_name);
2258 if (ctx->options & E2F_OPT_READONLY) {
2259 printf(_("%s: won't do journal recovery while read-only\n"),
2261 return EXT2_ET_FILE_RO;
2264 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2265 ext2fs_flush(ctx->fs); /* Force out any modifications */
2267 recover_retval = recover_ext3_journal(ctx);
2270 * Reload the filesystem context to get up-to-date data from disk
2271 * because journal recovery will change the filesystem under us.
2273 ext2fs_close(ctx->fs);
2274 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2275 ctx->superblock, blocksize, io_ptr,
2279 bb_error_msg(_("while trying to re-open %s"),
2281 bb_error_msg_and_die(0);
2283 ctx->fs->priv_data = ctx;
2285 /* Set the superblock flags */
2286 e2fsck_clear_recover(ctx, recover_retval);
2287 return recover_retval;
2291 * This function will move the journal inode from a visible file in
2292 * the filesystem directory hierarchy to the reserved inode if necessary.
2294 static const char * const journal_names[] = {
2295 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2297 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2299 struct ext2_super_block *sb = ctx->fs->super;
2300 struct problem_context pctx;
2301 struct ext2_inode inode;
2302 ext2_filsys fs = ctx->fs;
2305 const char * const * cpp;
2306 int group, mount_flags;
2308 clear_problem_context(&pctx);
2311 * If the filesystem is opened read-only, or there is no
2312 * journal, then do nothing.
2314 if ((ctx->options & E2F_OPT_READONLY) ||
2315 (sb->s_journal_inum == 0) ||
2316 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2320 * Read in the journal inode
2322 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2326 * If it's necessary to backup the journal inode, do so.
2328 if ((sb->s_jnl_backup_type == 0) ||
2329 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2330 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2331 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2332 memcpy(sb->s_jnl_blocks, inode.i_block,
2334 sb->s_jnl_blocks[16] = inode.i_size;
2335 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2336 ext2fs_mark_super_dirty(fs);
2337 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2342 * If the journal is already the hidden inode, then do nothing
2344 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2348 * The journal inode had better have only one link and not be readable.
2350 if (inode.i_links_count != 1)
2354 * If the filesystem is mounted, or we can't tell whether
2355 * or not it's mounted, do nothing.
2357 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2358 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2362 * If we can't find the name of the journal inode, then do
2365 for (cpp = journal_names; *cpp; cpp++) {
2366 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2367 strlen(*cpp), 0, &ino);
2368 if ((retval == 0) && (ino == sb->s_journal_inum))
2374 /* We need the inode bitmap to be loaded */
2375 retval = ext2fs_read_bitmaps(fs);
2380 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2384 * OK, we've done all the checks, let's actually move the
2385 * journal inode. Errors at this point mean we need to force
2386 * an ext2 filesystem check.
2388 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2390 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2392 sb->s_journal_inum = EXT2_JOURNAL_INO;
2393 ext2fs_mark_super_dirty(fs);
2394 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2395 inode.i_links_count = 0;
2396 inode.i_dtime = time(0);
2397 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2400 group = ext2fs_group_of_ino(fs, ino);
2401 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2402 ext2fs_mark_ib_dirty(fs);
2403 fs->group_desc[group].bg_free_inodes_count++;
2404 fs->super->s_free_inodes_count++;
2408 pctx.errcode = retval;
2409 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2410 fs->super->s_state &= ~EXT2_VALID_FS;
2411 ext2fs_mark_super_dirty(fs);
2416 * message.c --- print e2fsck messages (with compression)
2418 * print_e2fsck_message() prints a message to the user, using
2419 * compression techniques and expansions of abbreviations.
2421 * The following % expansions are supported:
2423 * %b <blk> block number
2424 * %B <blkcount> integer
2425 * %c <blk2> block number
2426 * %Di <dirent>->ino inode number
2427 * %Dn <dirent>->name string
2428 * %Dr <dirent>->rec_len
2429 * %Dl <dirent>->name_len
2430 * %Dt <dirent>->filetype
2431 * %d <dir> inode number
2432 * %g <group> integer
2433 * %i <ino> inode number
2434 * %Is <inode> -> i_size
2435 * %IS <inode> -> i_extra_isize
2436 * %Ib <inode> -> i_blocks
2437 * %Il <inode> -> i_links_count
2438 * %Im <inode> -> i_mode
2439 * %IM <inode> -> i_mtime
2440 * %IF <inode> -> i_faddr
2441 * %If <inode> -> i_file_acl
2442 * %Id <inode> -> i_dir_acl
2443 * %Iu <inode> -> i_uid
2444 * %Ig <inode> -> i_gid
2445 * %j <ino2> inode number
2446 * %m <com_err error message>
2448 * %p ext2fs_get_pathname of directory <ino>
2449 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2450 * the containing directory. (If dirent is NULL
2451 * then return the pathname of directory <ino2>)
2452 * %q ext2fs_get_pathname of directory <dir>
2453 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2454 * the containing directory.
2455 * %s <str> miscellaneous string
2456 * %S backup superblock
2457 * %X <num> hexadecimal format
2459 * The following '@' expansions are supported:
2461 * @a extended attribute
2462 * @A error allocating
2466 * @C conflicts with some other fs block
2470 * @E Entry '%Dn' in %p (%i)
2472 * @F for @i %i (%Q) is
2474 * @h HTREE directory inode
2480 * @m multiply-claimed
2494 * This structure defines the abbreviations used by the text strings
2495 * below. The first character in the string is the index letter. An
2496 * abbreviation of the form '@<i>' is expanded by looking up the index
2497 * letter <i> in the table below.
2499 static const char * const abbrevs[] = {
2500 N_("aextended attribute"),
2501 N_("Aerror allocating"),
2505 N_("Cconflicts with some other fs @b"),
2512 N_("E@e '%Dn' in %p (%i)"),
2514 N_("Ffor @i %i (%Q) is"),
2519 N_("mmultiply-claimed"),
2534 * Give more user friendly names to the "special" inodes.
2536 #define num_special_inodes 11
2537 static const char * const special_inode_name[] =
2539 N_("<The NULL inode>"), /* 0 */
2540 N_("<The bad blocks inode>"), /* 1 */
2542 N_("<The ACL index inode>"), /* 3 */
2543 N_("<The ACL data inode>"), /* 4 */
2544 N_("<The boot loader inode>"), /* 5 */
2545 N_("<The undelete directory inode>"), /* 6 */
2546 N_("<The group descriptor inode>"), /* 7 */
2547 N_("<The journal inode>"), /* 8 */
2548 N_("<Reserved inode 9>"), /* 9 */
2549 N_("<Reserved inode 10>"), /* 10 */
2553 * This function does "safe" printing. It will convert non-printable
2554 * ASCII characters using '^' and M- notation.
2556 static void safe_print(const char *cp, int len)
2566 fputs("M-", stdout);
2569 if ((ch < 32) || (ch == 0x7f)) {
2571 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2579 * This function prints a pathname, using the ext2fs_get_pathname
2582 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2587 if (!dir && (ino < num_special_inodes)) {
2588 fputs(_(special_inode_name[ino]), stdout);
2592 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2594 fputs("???", stdout);
2596 safe_print(path, -1);
2597 ext2fs_free_mem(&path);
2601 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2602 struct problem_context *pctx, int first);
2604 * This function handles the '@' expansion. We allow recursive
2605 * expansion; an @ expression can contain further '@' and '%'
2608 static void expand_at_expression(e2fsck_t ctx, char ch,
2609 struct problem_context *pctx,
2612 const char * const *cpp;
2615 /* Search for the abbreviation */
2616 for (cpp = abbrevs; *cpp; cpp++) {
2622 if (*first && islower(*str)) {
2624 fputc(toupper(*str++), stdout);
2626 print_e2fsck_message(ctx, str, pctx, *first);
2632 * This function expands '%IX' expressions
2634 static void expand_inode_expression(char ch,
2635 struct problem_context *ctx)
2637 struct ext2_inode *inode;
2638 struct ext2_inode_large *large_inode;
2643 if (!ctx || !ctx->inode)
2647 large_inode = (struct ext2_inode_large *) inode;
2651 if (LINUX_S_ISDIR(inode->i_mode))
2652 printf("%u", inode->i_size);
2654 #ifdef EXT2_NO_64_TYPE
2655 if (inode->i_size_high)
2656 printf("0x%x%08x", inode->i_size_high,
2659 printf("%u", inode->i_size);
2661 printf("%llu", (inode->i_size |
2662 ((__u64) inode->i_size_high << 32)));
2667 printf("%u", large_inode->i_extra_isize);
2670 printf("%u", inode->i_blocks);
2673 printf("%d", inode->i_links_count);
2676 printf("0%o", inode->i_mode);
2679 /* The diet libc doesn't respect the TZ environemnt variable */
2681 time_str = getenv("TZ");
2684 do_gmt = !strcmp(time_str, "GMT");
2687 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2688 printf("%.24s", time_str);
2691 printf("%u", inode->i_faddr);
2694 printf("%u", inode->i_file_acl);
2697 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2698 inode->i_dir_acl : 0));
2701 printf("%d", (inode->i_uid |
2702 (inode->osd2.linux2.l_i_uid_high << 16)));
2705 printf("%d", (inode->i_gid |
2706 (inode->osd2.linux2.l_i_gid_high << 16)));
2710 printf("%%I%c", ch);
2716 * This function expands '%dX' expressions
2718 static void expand_dirent_expression(char ch,
2719 struct problem_context *ctx)
2721 struct ext2_dir_entry *dirent;
2724 if (!ctx || !ctx->dirent)
2727 dirent = ctx->dirent;
2731 printf("%u", dirent->inode);
2734 len = dirent->name_len & 0xFF;
2735 if (len > EXT2_NAME_LEN)
2736 len = EXT2_NAME_LEN;
2737 if (len > dirent->rec_len)
2738 len = dirent->rec_len;
2739 safe_print(dirent->name, len);
2742 printf("%u", dirent->rec_len);
2745 printf("%u", dirent->name_len & 0xFF);
2748 printf("%u", dirent->name_len >> 8);
2752 printf("%%D%c", ch);
2757 static void expand_percent_expression(ext2_filsys fs, char ch,
2758 struct problem_context *ctx)
2768 printf("%u", ctx->blk);
2771 #ifdef EXT2_NO_64_TYPE
2772 printf("%d", ctx->blkcount);
2774 printf("%lld", ctx->blkcount);
2778 printf("%u", ctx->blk2);
2781 printf("%u", ctx->dir);
2784 printf("%d", ctx->group);
2787 printf("%u", ctx->ino);
2790 printf("%u", ctx->ino2);
2793 printf("%s", error_message(ctx->errcode));
2796 #ifdef EXT2_NO_64_TYPE
2797 printf("%u", ctx->num);
2799 printf("%llu", ctx->num);
2803 print_pathname(fs, ctx->ino, 0);
2806 print_pathname(fs, ctx->ino2,
2807 ctx->dirent ? ctx->dirent->inode : 0);
2810 print_pathname(fs, ctx->dir, 0);
2813 print_pathname(fs, ctx->dir, ctx->ino);
2816 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2819 printf("%s", ctx->str ? ctx->str : "NULL");
2822 #ifdef EXT2_NO_64_TYPE
2823 printf("0x%x", ctx->num);
2825 printf("0x%llx", ctx->num);
2836 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2837 struct problem_context *pctx, int first)
2839 ext2_filsys fs = ctx->fs;
2843 e2fsck_clear_progbar(ctx);
2844 for (cp = msg; *cp; cp++) {
2847 expand_at_expression(ctx, *cp, pctx, &first);
2848 } else if (cp[0] == '%' && cp[1] == 'I') {
2850 expand_inode_expression(*cp, pctx);
2851 } else if (cp[0] == '%' && cp[1] == 'D') {
2853 expand_dirent_expression(*cp, pctx);
2854 } else if ((cp[0] == '%')) {
2856 expand_percent_expression(fs, *cp, pctx);
2858 for (i=0; cp[i]; i++)
2859 if ((cp[i] == '@') || cp[i] == '%')
2861 printf("%.*s", i, cp);
2870 * region.c --- code which manages allocations within a region.
2874 region_addr_t start;
2876 struct region_el *next;
2879 struct region_struct {
2882 struct region_el *allocated;
2885 static region_t region_create(region_addr_t min, region_addr_t max)
2889 region = malloc(sizeof(struct region_struct));
2892 memset(region, 0, sizeof(struct region_struct));
2898 static void region_free(region_t region)
2900 struct region_el *r, *next;
2902 for (r = region->allocated; r; r = next) {
2906 memset(region, 0, sizeof(struct region_struct));
2910 static int region_allocate(region_t region, region_addr_t start, int n)
2912 struct region_el *r, *new_region, *prev, *next;
2916 if ((start < region->min) || (end > region->max))
2922 * Search through the linked list. If we find that it
2923 * conflicts witih something that's already allocated, return
2924 * 1; if we can find an existing region which we can grow, do
2925 * so. Otherwise, stop when we find the appropriate place
2926 * insert a new region element into the linked list.
2928 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2929 if (((start >= r->start) && (start < r->end)) ||
2930 ((end > r->start) && (end <= r->end)) ||
2931 ((start <= r->start) && (end >= r->end)))
2933 if (end == r->start) {
2937 if (start == r->end) {
2938 if ((next = r->next)) {
2939 if (end > next->start)
2941 if (end == next->start) {
2943 r->next = next->next;
2951 if (start < r->start)
2955 * Insert a new region element structure into the linked list
2957 new_region = malloc(sizeof(struct region_el));
2960 new_region->start = start;
2961 new_region->end = start + n;
2962 new_region->next = r;
2964 prev->next = new_region;
2966 region->allocated = new_region;
2971 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2973 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2974 * and applies the following tests to each inode:
2976 * - The mode field of the inode must be legal.
2977 * - The size and block count fields of the inode are correct.
2978 * - A data block must not be used by another inode
2980 * Pass 1 also gathers the collects the following information:
2982 * - A bitmap of which inodes are in use. (inode_used_map)
2983 * - A bitmap of which inodes are directories. (inode_dir_map)
2984 * - A bitmap of which inodes are regular files. (inode_reg_map)
2985 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2986 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
2987 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2988 * - A bitmap of which blocks are in use. (block_found_map)
2989 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2990 * - The data blocks of the directory inodes. (dir_map)
2992 * Pass 1 is designed to stash away enough information so that the
2993 * other passes should not need to read in the inode information
2994 * during the normal course of a filesystem check. (Althogh if an
2995 * inconsistency is detected, other passes may need to read in an
2998 * Note that pass 1B will be invoked if there are any duplicate blocks
3003 static int process_block(ext2_filsys fs, blk_t *blocknr,
3004 e2_blkcnt_t blockcnt, blk_t ref_blk,
3005 int ref_offset, void *priv_data);
3006 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
3007 e2_blkcnt_t blockcnt, blk_t ref_blk,
3008 int ref_offset, void *priv_data);
3009 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3011 static void mark_table_blocks(e2fsck_t ctx);
3012 static void alloc_bb_map(e2fsck_t ctx);
3013 static void alloc_imagic_map(e2fsck_t ctx);
3014 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
3015 static void handle_fs_bad_blocks(e2fsck_t ctx);
3016 static void process_inodes(e2fsck_t ctx, char *block_buf);
3017 static int process_inode_cmp(const void *a, const void *b);
3018 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
3019 dgrp_t group, void * priv_data);
3020 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3021 char *block_buf, int adjust_sign);
3022 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
3024 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
3025 struct ext2_inode * inode, int bufsize,
3028 struct process_block_struct_1 {
3030 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
3031 fragmented:1, compressed:1, bbcheck:1;
3034 e2_blkcnt_t last_block;
3035 int num_illegal_blocks;
3036 blk_t previous_block;
3037 struct ext2_inode *inode;
3038 struct problem_context *pctx;
3039 ext2fs_block_bitmap fs_meta_blocks;
3043 struct process_inode_block {
3045 struct ext2_inode inode;
3048 struct scan_callback_struct {
3054 * For the inodes to process list.
3056 static struct process_inode_block *inodes_to_process;
3057 static int process_inode_count;
3059 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
3060 EXT2_MIN_BLOCK_LOG_SIZE + 1];
3063 * Free all memory allocated by pass1 in preparation for restarting
3066 static void unwind_pass1(void)
3068 ext2fs_free_mem(&inodes_to_process);
3072 * Check to make sure a device inode is real. Returns 1 if the device
3073 * checks out, 0 if not.
3075 * Note: this routine is now also used to check FIFO's and Sockets,
3076 * since they have the same requirement; the i_block fields should be
3080 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
3085 * If i_blocks is non-zero, or the index flag is set, then
3086 * this is a bogus device/fifo/socket
3088 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
3089 (inode->i_flags & EXT2_INDEX_FL))
3093 * We should be able to do the test below all the time, but
3094 * because the kernel doesn't forcibly clear the device
3095 * inode's additional i_block fields, there are some rare
3096 * occasions when a legitimate device inode will have non-zero
3097 * additional i_block fields. So for now, we only complain
3098 * when the immutable flag is set, which should never happen
3099 * for devices. (And that's when the problem is caused, since
3100 * you can't set or clear immutable flags for devices.) Once
3101 * the kernel has been fixed we can change this...
3103 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
3104 for (i=4; i < EXT2_N_BLOCKS; i++)
3105 if (inode->i_block[i])
3112 * Check to make sure a symlink inode is real. Returns 1 if the symlink
3113 * checks out, 0 if not.
3116 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
3122 if ((inode->i_size_high || inode->i_size == 0) ||
3123 (inode->i_flags & EXT2_INDEX_FL))
3126 blocks = ext2fs_inode_data_blocks(fs, inode);
3128 if ((inode->i_size >= fs->blocksize) ||
3129 (blocks != fs->blocksize >> 9) ||
3130 (inode->i_block[0] < fs->super->s_first_data_block) ||
3131 (inode->i_block[0] >= fs->super->s_blocks_count))
3134 for (i = 1; i < EXT2_N_BLOCKS; i++)
3135 if (inode->i_block[i])
3138 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
3141 len = strnlen(buf, fs->blocksize);
3142 if (len == fs->blocksize)
3145 if (inode->i_size >= sizeof(inode->i_block))
3148 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3149 if (len == sizeof(inode->i_block))
3152 if (len != inode->i_size)
3158 * If the immutable (or append-only) flag is set on the inode, offer
3161 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3162 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3164 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3167 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3170 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3171 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3175 * If device, fifo or socket, check size is zero -- if not offer to
3178 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3180 struct ext2_inode *inode = pctx->inode;
3182 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3185 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3189 inode->i_size_high = 0;
3190 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3193 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3195 struct ext2_super_block *sb = ctx->fs->super;
3196 struct ext2_inode_large *inode;
3197 struct ext2_ext_attr_entry *entry;
3199 int storage_size, remain, offs;
3202 inode = (struct ext2_inode_large *) pctx->inode;
3203 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3204 inode->i_extra_isize;
3205 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3206 inode->i_extra_isize + sizeof(__u32);
3207 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3208 entry = (struct ext2_ext_attr_entry *) start;
3210 /* scan all entry's headers first */
3212 /* take finish entry 0UL into account */
3213 remain = storage_size - sizeof(__u32);
3216 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3218 /* header eats this space */
3219 remain -= sizeof(struct ext2_ext_attr_entry);
3221 /* is attribute name valid? */
3222 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3223 pctx->num = entry->e_name_len;
3224 problem = PR_1_ATTR_NAME_LEN;
3228 /* attribute len eats this space */
3229 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3231 /* check value size */
3232 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3233 pctx->num = entry->e_value_size;
3234 problem = PR_1_ATTR_VALUE_SIZE;
3238 /* check value placement */
3239 if (entry->e_value_offs +
3240 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3241 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3242 pctx->num = entry->e_value_offs;
3243 problem = PR_1_ATTR_VALUE_OFFSET;
3247 /* e_value_block must be 0 in inode's ea */
3248 if (entry->e_value_block != 0) {
3249 pctx->num = entry->e_value_block;
3250 problem = PR_1_ATTR_VALUE_BLOCK;
3254 /* e_hash must be 0 in inode's ea */
3255 if (entry->e_hash != 0) {
3256 pctx->num = entry->e_hash;
3257 problem = PR_1_ATTR_HASH;
3261 remain -= entry->e_value_size;
3262 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3264 entry = EXT2_EXT_ATTR_NEXT(entry);
3268 * it seems like a corruption. it's very unlikely we could repair
3269 * EA(s) in automatic fashion -bzzz
3271 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3274 /* simple remove all possible EA(s) */
3275 *((__u32 *)start) = 0UL;
3276 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3277 EXT2_INODE_SIZE(sb), "pass1");
3280 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3282 struct ext2_super_block *sb = ctx->fs->super;
3283 struct ext2_inode_large *inode;
3287 inode = (struct ext2_inode_large *) pctx->inode;
3288 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3289 /* this isn't large inode. so, nothing to check */
3293 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3294 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3295 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3297 * For now we will allow i_extra_isize to be 0, but really
3298 * implementations should never allow i_extra_isize to be 0
3300 if (inode->i_extra_isize &&
3301 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3302 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3304 inode->i_extra_isize = min;
3305 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3306 EXT2_INODE_SIZE(sb), "pass1");
3310 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3311 inode->i_extra_isize);
3312 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3313 /* it seems inode has an extended attribute(s) in body */
3314 check_ea_in_inode(ctx, pctx);
3318 static void e2fsck_pass1(e2fsck_t ctx)
3322 ext2_filsys fs = ctx->fs;
3324 struct ext2_inode *inode;
3325 ext2_inode_scan scan;
3327 unsigned char frag, fsize;
3328 struct problem_context pctx;
3329 struct scan_callback_struct scan_struct;
3330 struct ext2_super_block *sb = ctx->fs->super;
3332 int busted_fs_time = 0;
3335 clear_problem_context(&pctx);
3337 if (!(ctx->options & E2F_OPT_PREEN))
3338 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3340 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3341 !(ctx->options & E2F_OPT_NO)) {
3342 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3343 ctx->dirs_to_hash = 0;
3348 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3350 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3351 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3352 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3353 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3354 max_sizes = (max_sizes * (1UL << i)) - 1;
3355 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3359 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3362 * Allocate bitmaps structures
3364 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3365 &ctx->inode_used_map);
3368 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3369 ctx->flags |= E2F_FLAG_ABORT;
3372 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3373 _("directory inode map"), &ctx->inode_dir_map);
3376 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3377 ctx->flags |= E2F_FLAG_ABORT;
3380 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3381 _("regular file inode map"), &ctx->inode_reg_map);
3384 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3385 ctx->flags |= E2F_FLAG_ABORT;
3388 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3389 &ctx->block_found_map);
3392 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3393 ctx->flags |= E2F_FLAG_ABORT;
3396 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3397 &ctx->inode_link_info);
3399 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3400 ctx->flags |= E2F_FLAG_ABORT;
3403 inode_size = EXT2_INODE_SIZE(fs->super);
3404 inode = (struct ext2_inode *)
3405 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3407 inodes_to_process = (struct process_inode_block *)
3408 e2fsck_allocate_memory(ctx,
3409 (ctx->process_inode_size *
3410 sizeof(struct process_inode_block)),
3411 "array of inodes to process");
3412 process_inode_count = 0;
3414 pctx.errcode = ext2fs_init_dblist(fs, 0);
3416 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3417 ctx->flags |= E2F_FLAG_ABORT;
3422 * If the last orphan field is set, clear it, since the pass1
3423 * processing will automatically find and clear the orphans.
3424 * In the future, we may want to try using the last_orphan
3425 * linked list ourselves, but for now, we clear it so that the
3426 * ext3 mount code won't get confused.
3428 if (!(ctx->options & E2F_OPT_READONLY)) {
3429 if (fs->super->s_last_orphan) {
3430 fs->super->s_last_orphan = 0;
3431 ext2fs_mark_super_dirty(fs);
3435 mark_table_blocks(ctx);
3436 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3437 "block interate buffer");
3438 e2fsck_use_inode_shortcuts(ctx, 1);
3439 ehandler_operation(_("doing inode scan"));
3440 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3443 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3444 ctx->flags |= E2F_FLAG_ABORT;
3447 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3448 ctx->stashed_inode = inode;
3449 scan_struct.ctx = ctx;
3450 scan_struct.block_buf = block_buf;
3451 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3453 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3455 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3456 (fs->super->s_mtime < fs->super->s_inodes_count))
3460 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3462 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3464 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3465 if (!ctx->inode_bb_map)
3467 ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
3468 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3472 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3473 ctx->flags |= E2F_FLAG_ABORT;
3480 ctx->stashed_ino = ino;
3481 if (inode->i_links_count) {
3482 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3483 ino, inode->i_links_count);
3485 pctx.num = inode->i_links_count;
3486 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3487 ctx->flags |= E2F_FLAG_ABORT;
3491 if (ino == EXT2_BAD_INO) {
3492 struct process_block_struct_1 pb;
3494 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3495 &pb.fs_meta_blocks);
3498 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3499 ctx->flags |= E2F_FLAG_ABORT;
3502 pb.ino = EXT2_BAD_INO;
3503 pb.num_blocks = pb.last_block = 0;
3504 pb.num_illegal_blocks = 0;
3505 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3506 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3510 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3511 block_buf, process_bad_block, &pb);
3512 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3514 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3515 ctx->flags |= E2F_FLAG_ABORT;
3519 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3520 ctx->flags |= E2F_FLAG_ABORT;
3523 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3524 clear_problem_context(&pctx);
3526 } else if (ino == EXT2_ROOT_INO) {
3528 * Make sure the root inode is a directory; if
3529 * not, offer to clear it. It will be
3530 * regnerated in pass #3.
3532 if (!LINUX_S_ISDIR(inode->i_mode)) {
3533 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3534 inode->i_dtime = time(0);
3535 inode->i_links_count = 0;
3536 ext2fs_icount_store(ctx->inode_link_info,
3538 e2fsck_write_inode(ctx, ino, inode,
3544 * If dtime is set, offer to clear it. mke2fs
3545 * version 0.2b created filesystems with the
3546 * dtime field set for the root and lost+found
3547 * directories. We won't worry about
3548 * /lost+found, since that can be regenerated
3549 * easily. But we will fix the root directory
3550 * as a special case.
3552 if (inode->i_dtime && inode->i_links_count) {
3553 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3555 e2fsck_write_inode(ctx, ino, inode,
3559 } else if (ino == EXT2_JOURNAL_INO) {
3560 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3561 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3562 if (!LINUX_S_ISREG(inode->i_mode) &&
3563 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3565 inode->i_mode = LINUX_S_IFREG;
3566 e2fsck_write_inode(ctx, ino, inode,
3569 check_blocks(ctx, &pctx, block_buf);
3572 if ((inode->i_links_count || inode->i_blocks ||
3573 inode->i_blocks || inode->i_block[0]) &&
3574 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3576 memset(inode, 0, inode_size);
3577 ext2fs_icount_store(ctx->inode_link_info,
3579 e2fsck_write_inode_full(ctx, ino, inode,
3580 inode_size, "pass1");
3582 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3585 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3586 if (ino == EXT2_BOOT_LOADER_INO) {
3587 if (LINUX_S_ISDIR(inode->i_mode))
3588 problem = PR_1_RESERVED_BAD_MODE;
3589 } else if (ino == EXT2_RESIZE_INO) {
3590 if (inode->i_mode &&
3591 !LINUX_S_ISREG(inode->i_mode))
3592 problem = PR_1_RESERVED_BAD_MODE;
3594 if (inode->i_mode != 0)
3595 problem = PR_1_RESERVED_BAD_MODE;
3598 if (fix_problem(ctx, problem, &pctx)) {
3600 e2fsck_write_inode(ctx, ino, inode,
3604 check_blocks(ctx, &pctx, block_buf);
3608 * Check for inodes who might have been part of the
3609 * orphaned list linked list. They should have gotten
3610 * dealt with by now, unless the list had somehow been
3613 * FIXME: In the future, inodes which are still in use
3614 * (and which are therefore) pending truncation should
3615 * be handled specially. Right now we just clear the
3616 * dtime field, and the normal e2fsck handling of
3617 * inodes where i_size and the inode blocks are
3618 * inconsistent is to fix i_size, instead of releasing
3619 * the extra blocks. This won't catch the inodes that
3620 * was at the end of the orphan list, but it's better
3621 * than nothing. The right answer is that there
3622 * shouldn't be any bugs in the orphan list handling. :-)
3624 if (inode->i_dtime && !busted_fs_time &&
3625 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3626 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3627 inode->i_dtime = inode->i_links_count ?
3629 e2fsck_write_inode(ctx, ino, inode,
3635 * This code assumes that deleted inodes have
3636 * i_links_count set to 0.
3638 if (!inode->i_links_count) {
3639 if (!inode->i_dtime && inode->i_mode) {
3640 if (fix_problem(ctx,
3641 PR_1_ZERO_DTIME, &pctx)) {
3642 inode->i_dtime = time(0);
3643 e2fsck_write_inode(ctx, ino, inode,
3650 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3651 * deleted files. Oops.
3653 * Since all new ext2 implementations get this right,
3654 * we now assume that the case of non-zero
3655 * i_links_count and non-zero dtime means that we
3656 * should keep the file, not delete it.
3659 if (inode->i_dtime) {
3660 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3662 e2fsck_write_inode(ctx, ino, inode, "pass1");
3666 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3667 switch (fs->super->s_creator_os) {
3669 frag = inode->osd2.linux2.l_i_frag;
3670 fsize = inode->osd2.linux2.l_i_fsize;
3673 frag = inode->osd2.hurd2.h_i_frag;
3674 fsize = inode->osd2.hurd2.h_i_fsize;
3677 frag = inode->osd2.masix2.m_i_frag;
3678 fsize = inode->osd2.masix2.m_i_fsize;
3684 if (inode->i_faddr || frag || fsize ||
3685 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3686 mark_inode_bad(ctx, ino);
3687 if (inode->i_flags & EXT2_IMAGIC_FL) {
3689 if (!ctx->inode_imagic_map)
3690 alloc_imagic_map(ctx);
3691 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3694 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3695 inode->i_flags &= ~EXT2_IMAGIC_FL;
3696 e2fsck_write_inode(ctx, ino,
3702 check_inode_extra_space(ctx, &pctx);
3704 if (LINUX_S_ISDIR(inode->i_mode)) {
3705 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3706 e2fsck_add_dir_info(ctx, ino, 0);
3707 ctx->fs_directory_count++;
3708 } else if (LINUX_S_ISREG (inode->i_mode)) {
3709 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3710 ctx->fs_regular_count++;
3711 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3712 e2fsck_pass1_check_device_inode(fs, inode)) {
3713 check_immutable(ctx, &pctx);
3714 check_size(ctx, &pctx);
3715 ctx->fs_chardev_count++;
3716 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3717 e2fsck_pass1_check_device_inode(fs, inode)) {
3718 check_immutable(ctx, &pctx);
3719 check_size(ctx, &pctx);
3720 ctx->fs_blockdev_count++;
3721 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3722 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3723 check_immutable(ctx, &pctx);
3724 ctx->fs_symlinks_count++;
3725 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3726 ctx->fs_fast_symlinks_count++;
3727 check_blocks(ctx, &pctx, block_buf);
3731 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3732 e2fsck_pass1_check_device_inode(fs, inode)) {
3733 check_immutable(ctx, &pctx);
3734 check_size(ctx, &pctx);
3735 ctx->fs_fifo_count++;
3736 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3737 e2fsck_pass1_check_device_inode(fs, inode)) {
3738 check_immutable(ctx, &pctx);
3739 check_size(ctx, &pctx);
3740 ctx->fs_sockets_count++;
3742 mark_inode_bad(ctx, ino);
3743 if (inode->i_block[EXT2_IND_BLOCK])
3744 ctx->fs_ind_count++;
3745 if (inode->i_block[EXT2_DIND_BLOCK])
3746 ctx->fs_dind_count++;
3747 if (inode->i_block[EXT2_TIND_BLOCK])
3748 ctx->fs_tind_count++;
3749 if (inode->i_block[EXT2_IND_BLOCK] ||
3750 inode->i_block[EXT2_DIND_BLOCK] ||
3751 inode->i_block[EXT2_TIND_BLOCK] ||
3752 inode->i_file_acl) {
3753 inodes_to_process[process_inode_count].ino = ino;
3754 inodes_to_process[process_inode_count].inode = *inode;
3755 process_inode_count++;
3757 check_blocks(ctx, &pctx, block_buf);
3759 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3762 if (process_inode_count >= ctx->process_inode_size) {
3763 process_inodes(ctx, block_buf);
3765 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3769 process_inodes(ctx, block_buf);
3770 ext2fs_close_inode_scan(scan);
3771 ehandler_operation(0);
3774 * If any extended attribute blocks' reference counts need to
3775 * be adjusted, either up (ctx->refcount_extra), or down
3776 * (ctx->refcount), then fix them.
3778 if (ctx->refcount) {
3779 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3780 ea_refcount_free(ctx->refcount);
3783 if (ctx->refcount_extra) {
3784 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3786 ea_refcount_free(ctx->refcount_extra);
3787 ctx->refcount_extra = 0;
3790 if (ctx->invalid_bitmaps)
3791 handle_fs_bad_blocks(ctx);
3793 /* We don't need the block_ea_map any more */
3794 ext2fs_free_block_bitmap(ctx->block_ea_map);
3795 ctx->block_ea_map = 0;
3797 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3798 ext2fs_block_bitmap save_bmap;
3800 save_bmap = fs->block_map;
3801 fs->block_map = ctx->block_found_map;
3802 clear_problem_context(&pctx);
3803 pctx.errcode = ext2fs_create_resize_inode(fs);
3805 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3806 /* Should never get here */
3807 ctx->flags |= E2F_FLAG_ABORT;
3810 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3812 inode->i_mtime = time(0);
3813 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3815 fs->block_map = save_bmap;
3816 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3819 if (ctx->flags & E2F_FLAG_RESTART) {
3821 * Only the master copy of the superblock and block
3822 * group descriptors are going to be written during a
3823 * restart, so set the superblock to be used to be the
3824 * master superblock.
3826 ctx->use_superblock = 0;
3831 if (ctx->block_dup_map) {
3832 if (ctx->options & E2F_OPT_PREEN) {
3833 clear_problem_context(&pctx);
3834 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3836 e2fsck_pass1_dupblocks(ctx, block_buf);
3838 ext2fs_free_mem(&inodes_to_process);
3840 e2fsck_use_inode_shortcuts(ctx, 0);
3842 ext2fs_free_mem(&block_buf);
3843 ext2fs_free_mem(&inode);
3848 * When the inode_scan routines call this callback at the end of the
3849 * glock group, call process_inodes.
3851 static errcode_t scan_callback(ext2_filsys fs,
3852 ext2_inode_scan scan FSCK_ATTR((unused)),
3853 dgrp_t group, void * priv_data)
3855 struct scan_callback_struct *scan_struct;
3858 scan_struct = (struct scan_callback_struct *) priv_data;
3859 ctx = scan_struct->ctx;
3861 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3864 if ((ctx->progress)(ctx, 1, group+1,
3865 ctx->fs->group_desc_count))
3866 return EXT2_ET_CANCEL_REQUESTED;
3872 * Process the inodes in the "inodes to process" list.
3874 static void process_inodes(e2fsck_t ctx, char *block_buf)
3877 struct ext2_inode *old_stashed_inode;
3878 ext2_ino_t old_stashed_ino;
3879 const char *old_operation;
3881 struct problem_context pctx;
3883 /* begin process_inodes */
3884 if (process_inode_count == 0)
3886 old_operation = ehandler_operation(0);
3887 old_stashed_inode = ctx->stashed_inode;
3888 old_stashed_ino = ctx->stashed_ino;
3889 qsort(inodes_to_process, process_inode_count,
3890 sizeof(struct process_inode_block), process_inode_cmp);
3891 clear_problem_context(&pctx);
3892 for (i=0; i < process_inode_count; i++) {
3893 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3894 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3895 sprintf(buf, _("reading indirect blocks of inode %u"),
3897 ehandler_operation(buf);
3898 check_blocks(ctx, &pctx, block_buf);
3899 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3902 ctx->stashed_inode = old_stashed_inode;
3903 ctx->stashed_ino = old_stashed_ino;
3904 process_inode_count = 0;
3905 /* end process inodes */
3907 ehandler_operation(old_operation);
3910 static int process_inode_cmp(const void *a, const void *b)
3912 const struct process_inode_block *ib_a =
3913 (const struct process_inode_block *) a;
3914 const struct process_inode_block *ib_b =
3915 (const struct process_inode_block *) b;
3918 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3919 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3921 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3926 * Mark an inode as being bad in some what
3928 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3930 struct problem_context pctx;
3932 if (!ctx->inode_bad_map) {
3933 clear_problem_context(&pctx);
3935 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3936 _("bad inode map"), &ctx->inode_bad_map);
3939 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3940 /* Should never get here */
3941 ctx->flags |= E2F_FLAG_ABORT;
3945 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3950 * This procedure will allocate the inode "bb" (badblock) map table
3952 static void alloc_bb_map(e2fsck_t ctx)
3954 struct problem_context pctx;
3956 clear_problem_context(&pctx);
3957 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3958 _("inode in bad block map"),
3959 &ctx->inode_bb_map);
3962 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3963 /* Should never get here */
3964 ctx->flags |= E2F_FLAG_ABORT;
3970 * This procedure will allocate the inode imagic table
3972 static void alloc_imagic_map(e2fsck_t ctx)
3974 struct problem_context pctx;
3976 clear_problem_context(&pctx);
3977 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3978 _("imagic inode map"),
3979 &ctx->inode_imagic_map);
3982 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3983 /* Should never get here */
3984 ctx->flags |= E2F_FLAG_ABORT;
3990 * Marks a block as in use, setting the dup_map if it's been set
3991 * already. Called by process_block and process_bad_block.
3993 * WARNING: Assumes checks have already been done to make sure block
3994 * is valid. This is true in both process_block and process_bad_block.
3996 static void mark_block_used(e2fsck_t ctx, blk_t block)
3998 struct problem_context pctx;
4000 clear_problem_context(&pctx);
4002 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
4003 if (!ctx->block_dup_map) {
4004 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
4005 _("multiply claimed block map"),
4006 &ctx->block_dup_map);
4009 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
4011 /* Should never get here */
4012 ctx->flags |= E2F_FLAG_ABORT;
4016 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
4018 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
4023 * Adjust the extended attribute block's reference counts at the end
4024 * of pass 1, either by subtracting out references for EA blocks that
4025 * are still referenced in ctx->refcount, or by adding references for
4026 * EA blocks that had extra references as accounted for in
4027 * ctx->refcount_extra.
4029 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4030 char *block_buf, int adjust_sign)
4032 struct ext2_ext_attr_header *header;
4033 struct problem_context pctx;
4034 ext2_filsys fs = ctx->fs;
4039 clear_problem_context(&pctx);
4041 ea_refcount_intr_begin(refcount);
4043 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
4046 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4048 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
4051 header = (struct ext2_ext_attr_header *) block_buf;
4052 pctx.blkcount = header->h_refcount;
4053 should_be = header->h_refcount + adjust_sign * count;
4054 pctx.num = should_be;
4055 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
4056 header->h_refcount = should_be;
4057 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
4060 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
4068 * Handle processing the extended attribute blocks
4070 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
4073 ext2_filsys fs = ctx->fs;
4074 ext2_ino_t ino = pctx->ino;
4075 struct ext2_inode *inode = pctx->inode;
4078 struct ext2_ext_attr_header *header;
4079 struct ext2_ext_attr_entry *entry;
4083 blk = inode->i_file_acl;
4088 * If the Extended attribute flag isn't set, then a non-zero
4089 * file acl means that the inode is corrupted.
4091 * Or if the extended attribute block is an invalid block,
4092 * then the inode is also corrupted.
4094 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
4095 (blk < fs->super->s_first_data_block) ||
4096 (blk >= fs->super->s_blocks_count)) {
4097 mark_inode_bad(ctx, ino);
4101 /* If ea bitmap hasn't been allocated, create it */
4102 if (!ctx->block_ea_map) {
4103 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
4104 _("ext attr block map"),
4105 &ctx->block_ea_map);
4106 if (pctx->errcode) {
4108 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
4109 ctx->flags |= E2F_FLAG_ABORT;
4114 /* Create the EA refcount structure if necessary */
4115 if (!ctx->refcount) {
4116 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
4117 if (pctx->errcode) {
4119 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4120 ctx->flags |= E2F_FLAG_ABORT;
4125 /* Have we seen this EA block before? */
4126 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
4127 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
4129 /* Ooops, this EA was referenced more than it stated */
4130 if (!ctx->refcount_extra) {
4131 pctx->errcode = ea_refcount_create(0,
4132 &ctx->refcount_extra);
4133 if (pctx->errcode) {
4135 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4136 ctx->flags |= E2F_FLAG_ABORT;
4140 ea_refcount_increment(ctx->refcount_extra, blk, 0);
4145 * OK, we haven't seen this EA block yet. So we need to
4149 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4150 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
4152 header = (struct ext2_ext_attr_header *) block_buf;
4153 pctx->blk = inode->i_file_acl;
4154 if (((ctx->ext_attr_ver == 1) &&
4155 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
4156 ((ctx->ext_attr_ver == 2) &&
4157 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
4158 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
4162 if (header->h_blocks != 1) {
4163 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
4167 region = region_create(0, fs->blocksize);
4169 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
4170 ctx->flags |= E2F_FLAG_ABORT;
4173 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4174 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4178 entry = (struct ext2_ext_attr_entry *)(header+1);
4179 end = block_buf + fs->blocksize;
4180 while ((char *)entry < end && *(__u32 *)entry) {
4181 if (region_allocate(region, (char *)entry - (char *)header,
4182 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4183 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4186 if ((ctx->ext_attr_ver == 1 &&
4187 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4188 (ctx->ext_attr_ver == 2 &&
4189 entry->e_name_index == 0)) {
4190 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4193 if (entry->e_value_block != 0) {
4194 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4197 if (entry->e_value_size &&
4198 region_allocate(region, entry->e_value_offs,
4199 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4200 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4203 entry = EXT2_EXT_ATTR_NEXT(entry);
4205 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4206 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4209 region_free(region);
4211 count = header->h_refcount - 1;
4213 ea_refcount_store(ctx->refcount, blk, count);
4214 mark_block_used(ctx, blk);
4215 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4220 inode->i_file_acl = 0;
4221 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4225 /* Returns 1 if bad htree, 0 if OK */
4226 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4227 ext2_ino_t ino FSCK_ATTR((unused)),
4228 struct ext2_inode *inode,
4231 struct ext2_dx_root_info *root;
4232 ext2_filsys fs = ctx->fs;
4236 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4237 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4238 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4239 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4242 blk = inode->i_block[0];
4244 (blk < fs->super->s_first_data_block) ||
4245 (blk >= fs->super->s_blocks_count)) &&
4246 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4249 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4250 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4253 /* XXX should check that beginning matches a directory */
4254 root = (struct ext2_dx_root_info *) (block_buf + 24);
4256 if ((root->reserved_zero || root->info_length < 8) &&
4257 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4260 pctx->num = root->hash_version;
4261 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4262 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4263 (root->hash_version != EXT2_HASH_TEA) &&
4264 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4267 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4268 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4271 pctx->num = root->indirect_levels;
4272 if ((root->indirect_levels > 1) &&
4273 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4280 * This subroutine is called on each inode to account for all of the
4281 * blocks used by that inode.
4283 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4286 ext2_filsys fs = ctx->fs;
4287 struct process_block_struct_1 pb;
4288 ext2_ino_t ino = pctx->ino;
4289 struct ext2_inode *inode = pctx->inode;
4291 int dirty_inode = 0;
4297 pb.num_illegal_blocks = 0;
4298 pb.suppress = 0; pb.clear = 0;
4301 pb.previous_block = 0;
4302 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4303 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4304 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4311 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4312 if (fs->super->s_feature_incompat &
4313 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4316 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4317 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4323 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4326 if (ext2fs_inode_has_valid_blocks(inode))
4327 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4328 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4329 block_buf, process_block, &pb);
4330 end_problem_latch(ctx, PR_LATCH_BLOCK);
4331 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4332 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4335 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4337 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4338 ctx->fs_fragmented++;
4341 inode->i_links_count = 0;
4342 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4343 inode->i_dtime = time(0);
4345 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4346 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4347 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4349 * The inode was probably partially accounted for
4350 * before processing was aborted, so we need to
4351 * restart the pass 1 scan.
4353 ctx->flags |= E2F_FLAG_RESTART;
4357 if (inode->i_flags & EXT2_INDEX_FL) {
4358 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4359 inode->i_flags &= ~EXT2_INDEX_FL;
4363 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4367 if (ctx->dirs_to_hash && pb.is_dir &&
4368 !(inode->i_flags & EXT2_INDEX_FL) &&
4369 ((inode->i_size / fs->blocksize) >= 3))
4370 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4372 if (!pb.num_blocks && pb.is_dir) {
4373 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4374 inode->i_links_count = 0;
4375 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4376 inode->i_dtime = time(0);
4378 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4379 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4380 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4381 ctx->fs_directory_count--;
4386 pb.num_blocks *= (fs->blocksize / 512);
4389 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4390 if (nblock > (pb.last_block + 1))
4392 else if (nblock < (pb.last_block + 1)) {
4393 if (((pb.last_block + 1) - nblock) >
4394 fs->super->s_prealloc_dir_blocks)
4398 size = EXT2_I_SIZE(inode);
4399 if ((pb.last_block >= 0) &&
4400 (size < (__u64) pb.last_block * fs->blocksize))
4402 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4405 /* i_size for symlinks is checked elsewhere */
4406 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4407 pctx->num = (pb.last_block+1) * fs->blocksize;
4408 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4409 inode->i_size = pctx->num;
4410 if (!LINUX_S_ISDIR(inode->i_mode))
4411 inode->i_size_high = pctx->num >> 32;
4416 if (LINUX_S_ISREG(inode->i_mode) &&
4417 (inode->i_size_high || inode->i_size & 0x80000000UL))
4419 if (pb.num_blocks != inode->i_blocks) {
4420 pctx->num = pb.num_blocks;
4421 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4422 inode->i_blocks = pb.num_blocks;
4429 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4434 * This is a helper function for check_blocks().
4436 static int process_block(ext2_filsys fs,
4438 e2_blkcnt_t blockcnt,
4439 blk_t ref_block FSCK_ATTR((unused)),
4440 int ref_offset FSCK_ATTR((unused)),
4443 struct process_block_struct_1 *p;
4444 struct problem_context *pctx;
4445 blk_t blk = *block_nr;
4450 p = (struct process_block_struct_1 *) priv_data;
4454 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4455 /* todo: Check that the comprblk_fl is high, that the
4456 blkaddr pattern looks right (all non-holes up to
4457 first EXT2FS_COMPRESSED_BLKADDR, then all
4458 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4459 that the feature_incompat bit is high, and that the
4460 inode is a regular file. If we're doing a "full
4461 check" (a concept introduced to e2fsck by e2compr,
4462 meaning that we look at data blocks as well as
4463 metadata) then call some library routine that
4464 checks the compressed data. I'll have to think
4465 about this, because one particularly important
4466 problem to be able to fix is to recalculate the
4467 cluster size if necessary. I think that perhaps
4468 we'd better do most/all e2compr-specific checks
4469 separately, after the non-e2compr checks. If not
4470 doing a full check, it may be useful to test that
4471 the personality is linux; e.g. if it isn't then
4472 perhaps this really is just an illegal block. */
4477 if (p->is_dir == 0) {
4479 * Should never happen, since only directories
4480 * get called with BLOCK_FLAG_HOLE
4483 printf("process_block() called with blk == 0, "
4484 "blockcnt=%d, inode %lu???\n",
4491 if (blockcnt * fs->blocksize < p->inode->i_size) {
4498 * Simplistic fragmentation check. We merely require that the
4499 * file be contiguous. (Which can never be true for really
4500 * big files that are greater than a block group.)
4502 if (!HOLE_BLKADDR(p->previous_block)) {
4503 if (p->previous_block+1 != blk)
4506 p->previous_block = blk;
4508 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4509 problem = PR_1_TOOBIG_DIR;
4510 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4511 problem = PR_1_TOOBIG_REG;
4512 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4513 problem = PR_1_TOOBIG_SYMLINK;
4515 if (blk < fs->super->s_first_data_block ||
4516 blk >= fs->super->s_blocks_count)
4517 problem = PR_1_ILLEGAL_BLOCK_NUM;
4520 p->num_illegal_blocks++;
4521 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4522 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4526 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4528 set_latch_flags(PR_LATCH_BLOCK,
4533 pctx->blkcount = blockcnt;
4534 if (fix_problem(ctx, problem, pctx)) {
4535 blk = *block_nr = 0;
4536 ret_code = BLOCK_CHANGED;
4542 if (p->ino == EXT2_RESIZE_INO) {
4544 * The resize inode has already be sanity checked
4545 * during pass #0 (the superblock checks). All we
4546 * have to do is mark the double indirect block as
4547 * being in use; all of the other blocks are handled
4548 * by mark_table_blocks()).
4550 if (blockcnt == BLOCK_COUNT_DIND)
4551 mark_block_used(ctx, blk);
4553 mark_block_used(ctx, blk);
4556 p->last_block = blockcnt;
4558 if (p->is_dir && (blockcnt >= 0)) {
4559 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4561 if (pctx->errcode) {
4563 pctx->num = blockcnt;
4564 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4565 /* Should never get here */
4566 ctx->flags |= E2F_FLAG_ABORT;
4573 static int process_bad_block(ext2_filsys fs,
4575 e2_blkcnt_t blockcnt,
4576 blk_t ref_block FSCK_ATTR((unused)),
4577 int ref_offset FSCK_ATTR((unused)),
4580 struct process_block_struct_1 *p;
4581 blk_t blk = *block_nr;
4584 struct problem_context *pctx;
4588 * Note: This function processes blocks for the bad blocks
4589 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4595 p = (struct process_block_struct_1 *) priv_data;
4599 pctx->ino = EXT2_BAD_INO;
4601 pctx->blkcount = blockcnt;
4603 if ((blk < fs->super->s_first_data_block) ||
4604 (blk >= fs->super->s_blocks_count)) {
4605 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
4607 return BLOCK_CHANGED;
4613 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
4615 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
4617 return BLOCK_CHANGED;
4619 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
4622 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
4625 return BLOCK_CHANGED;
4627 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4630 mark_block_used(ctx, blk);
4634 ctx->fs_badblocks_count++;
4636 * If the block is not used, then mark it as used and return.
4637 * If it is already marked as found, this must mean that
4638 * there's an overlap between the filesystem table blocks
4639 * (bitmaps and inode table) and the bad block list.
4641 if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
4642 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
4646 * Try to find the where the filesystem block was used...
4648 first_block = fs->super->s_first_data_block;
4650 for (i = 0; i < fs->group_desc_count; i++ ) {
4653 if (!ext2fs_bg_has_super(fs, i))
4655 if (blk == first_block) {
4657 if (fix_problem(ctx,
4658 PR_1_BAD_PRIMARY_SUPERBLOCK,
4661 return BLOCK_CHANGED;
4665 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
4668 if ((blk > first_block) &&
4669 (blk <= first_block + fs->desc_blocks)) {
4671 pctx->blk = *block_nr;
4672 if (fix_problem(ctx,
4673 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
4675 return BLOCK_CHANGED;
4679 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
4683 if (blk == fs->group_desc[i].bg_block_bitmap) {
4684 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
4685 ctx->invalid_block_bitmap_flag[i]++;
4686 ctx->invalid_bitmaps++;
4690 if (blk == fs->group_desc[i].bg_inode_bitmap) {
4691 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
4692 ctx->invalid_inode_bitmap_flag[i]++;
4693 ctx->invalid_bitmaps++;
4697 if ((blk >= fs->group_desc[i].bg_inode_table) &&
4698 (blk < (fs->group_desc[i].bg_inode_table +
4699 fs->inode_blocks_per_group))) {
4701 * If there are bad blocks in the inode table,
4702 * the inode scan code will try to do
4703 * something reasonable automatically.
4707 first_block += fs->super->s_blocks_per_group;
4710 * If we've gotten to this point, then the only
4711 * possibility is that the bad block inode meta data
4712 * is using a bad block.
4714 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
4715 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
4716 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
4718 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
4720 return BLOCK_CHANGED;
4722 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4729 /* Warn user that the block wasn't claimed */
4730 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
4735 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
4736 const char *name, int num, blk_t *new_block)
4738 ext2_filsys fs = ctx->fs;
4739 blk_t old_block = *new_block;
4742 struct problem_context pctx;
4744 clear_problem_context(&pctx);
4747 pctx.blk = old_block;
4750 pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
4751 first_block + fs->super->s_blocks_per_group,
4752 num, ctx->block_found_map, new_block);
4755 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
4756 ext2fs_unmark_valid(fs);
4759 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
4761 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
4762 ext2fs_unmark_valid(fs);
4765 ext2fs_mark_super_dirty(fs);
4766 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
4767 pctx.blk2 = *new_block;
4768 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
4769 PR_1_RELOC_TO), &pctx);
4771 for (i = 0; i < num; i++) {
4773 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
4775 pctx.errcode = io_channel_read_blk(fs->io,
4776 old_block + i, 1, buf);
4778 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
4780 memset(buf, 0, fs->blocksize);
4782 pctx.blk = (*new_block) + i;
4783 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
4786 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
4788 ext2fs_free_mem(&buf);
4792 * This routine gets called at the end of pass 1 if bad blocks are
4793 * detected in the superblock, group descriptors, inode_bitmaps, or
4794 * block bitmaps. At this point, all of the blocks have been mapped
4795 * out, so we can try to allocate new block(s) to replace the bad
4798 static void handle_fs_bad_blocks(e2fsck_t ctx)
4800 ext2_filsys fs = ctx->fs;
4802 int first_block = fs->super->s_first_data_block;
4804 for (i = 0; i < fs->group_desc_count; i++) {
4805 if (ctx->invalid_block_bitmap_flag[i]) {
4806 new_table_block(ctx, first_block, i, _("block bitmap"),
4807 1, &fs->group_desc[i].bg_block_bitmap);
4809 if (ctx->invalid_inode_bitmap_flag[i]) {
4810 new_table_block(ctx, first_block, i, _("inode bitmap"),
4811 1, &fs->group_desc[i].bg_inode_bitmap);
4813 if (ctx->invalid_inode_table_flag[i]) {
4814 new_table_block(ctx, first_block, i, _("inode table"),
4815 fs->inode_blocks_per_group,
4816 &fs->group_desc[i].bg_inode_table);
4817 ctx->flags |= E2F_FLAG_RESTART;
4819 first_block += fs->super->s_blocks_per_group;
4821 ctx->invalid_bitmaps = 0;
4825 * This routine marks all blocks which are used by the superblock,
4826 * group descriptors, inode bitmaps, and block bitmaps.
4828 static void mark_table_blocks(e2fsck_t ctx)
4830 ext2_filsys fs = ctx->fs;
4834 struct problem_context pctx;
4836 clear_problem_context(&pctx);
4838 block = fs->super->s_first_data_block;
4839 for (i = 0; i < fs->group_desc_count; i++) {
4842 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4845 * Mark the blocks used for the inode table
4847 if (fs->group_desc[i].bg_inode_table) {
4848 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4849 j < fs->inode_blocks_per_group;
4851 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4854 if (fix_problem(ctx,
4855 PR_1_ITABLE_CONFLICT, &pctx)) {
4856 ctx->invalid_inode_table_flag[i]++;
4857 ctx->invalid_bitmaps++;
4860 ext2fs_mark_block_bitmap(ctx->block_found_map,
4867 * Mark block used for the block bitmap
4869 if (fs->group_desc[i].bg_block_bitmap) {
4870 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4871 fs->group_desc[i].bg_block_bitmap)) {
4872 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4873 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4874 ctx->invalid_block_bitmap_flag[i]++;
4875 ctx->invalid_bitmaps++;
4878 ext2fs_mark_block_bitmap(ctx->block_found_map,
4879 fs->group_desc[i].bg_block_bitmap);
4884 * Mark block used for the inode bitmap
4886 if (fs->group_desc[i].bg_inode_bitmap) {
4887 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4888 fs->group_desc[i].bg_inode_bitmap)) {
4889 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4890 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4891 ctx->invalid_inode_bitmap_flag[i]++;
4892 ctx->invalid_bitmaps++;
4895 ext2fs_mark_block_bitmap(ctx->block_found_map,
4896 fs->group_desc[i].bg_inode_bitmap);
4899 block += fs->super->s_blocks_per_group;
4904 * Thes subroutines short circuits ext2fs_get_blocks and
4905 * ext2fs_check_directory; we use them since we already have the inode
4906 * structure, so there's no point in letting the ext2fs library read
4909 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4912 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4915 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4916 return EXT2_ET_CALLBACK_NOTHANDLED;
4918 for (i=0; i < EXT2_N_BLOCKS; i++)
4919 blocks[i] = ctx->stashed_inode->i_block[i];
4923 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4924 struct ext2_inode *inode)
4926 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4928 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4929 return EXT2_ET_CALLBACK_NOTHANDLED;
4930 *inode = *ctx->stashed_inode;
4934 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4935 struct ext2_inode *inode)
4937 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4939 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4940 *ctx->stashed_inode = *inode;
4941 return EXT2_ET_CALLBACK_NOTHANDLED;
4944 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4946 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4948 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4949 return EXT2_ET_CALLBACK_NOTHANDLED;
4951 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4952 return EXT2_ET_NO_DIRECTORY;
4956 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4958 ext2_filsys fs = ctx->fs;
4961 fs->get_blocks = pass1_get_blocks;
4962 fs->check_directory = pass1_check_directory;
4963 fs->read_inode = pass1_read_inode;
4964 fs->write_inode = pass1_write_inode;
4965 ctx->stashed_ino = 0;
4968 fs->check_directory = 0;
4970 fs->write_inode = 0;
4975 * pass1b.c --- Pass #1b of e2fsck
4977 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4978 * only invoked if pass 1 discovered blocks which are in use by more
4981 * Pass1B scans the data blocks of all the inodes again, generating a
4982 * complete list of duplicate blocks and which inodes have claimed
4985 * Pass1C does a tree-traversal of the filesystem, to determine the
4986 * parent directories of these inodes. This step is necessary so that
4987 * e2fsck can print out the pathnames of affected inodes.
4989 * Pass1D is a reconciliation pass. For each inode with duplicate
4990 * blocks, the user is prompted if s/he would like to clone the file
4991 * (so that the file gets a fresh copy of the duplicated blocks) or
4992 * simply to delete the file.
4997 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4998 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4999 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
5001 /* Define an extension to the ext2 library's block count information */
5002 #define BLOCK_COUNT_EXTATTR (-5)
5006 struct block_el *next;
5011 struct inode_el *next;
5016 struct inode_el *inode_list;
5020 * This structure stores information about a particular inode which
5021 * is sharing blocks with other inodes. This information is collected
5022 * to display to the user, so that the user knows what files he or she
5023 * is dealing with, when trying to decide how to resolve the conflict
5024 * of multiply-claimed blocks.
5029 struct ext2_inode inode;
5030 struct block_el *block_list;
5033 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
5034 e2_blkcnt_t blockcnt, blk_t ref_blk,
5035 int ref_offset, void *priv_data);
5036 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5037 struct dup_inode *dp, char *block_buf);
5038 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5039 struct dup_inode *dp, char* block_buf);
5040 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
5042 static void pass1b(e2fsck_t ctx, char *block_buf);
5043 static void pass1c(e2fsck_t ctx, char *block_buf);
5044 static void pass1d(e2fsck_t ctx, char *block_buf);
5046 static int dup_inode_count = 0;
5048 static dict_t blk_dict, ino_dict;
5050 static ext2fs_inode_bitmap inode_dup_map;
5052 static int dict_int_cmp(const void *a, const void *b)
5063 * Add a duplicate block record
5065 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
5066 struct ext2_inode *inode)
5069 struct dup_block *db;
5070 struct dup_inode *di;
5071 struct block_el *blk_el;
5072 struct inode_el *ino_el;
5074 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5076 db = (struct dup_block *) dnode_get(n);
5078 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
5079 sizeof(struct dup_block), "duplicate block header");
5082 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
5084 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
5085 sizeof(struct inode_el), "inode element");
5086 ino_el->inode = ino;
5087 ino_el->next = db->inode_list;
5088 db->inode_list = ino_el;
5091 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
5093 di = (struct dup_inode *) dnode_get(n);
5095 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
5096 sizeof(struct dup_inode), "duplicate inode header");
5097 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
5098 di->num_dupblocks = 0;
5101 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
5103 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
5104 sizeof(struct block_el), "block element");
5105 blk_el->block = blk;
5106 blk_el->next = di->block_list;
5107 di->block_list = blk_el;
5108 di->num_dupblocks++;
5112 * Free a duplicate inode record
5114 static void inode_dnode_free(dnode_t *node)
5116 struct dup_inode *di;
5117 struct block_el *p, *next;
5119 di = (struct dup_inode *) dnode_get(node);
5120 for (p = di->block_list; p; p = next) {
5128 * Free a duplicate block record
5130 static void block_dnode_free(dnode_t *node)
5132 struct dup_block *db;
5133 struct inode_el *p, *next;
5135 db = (struct dup_block *) dnode_get(node);
5136 for (p = db->inode_list; p; p = next) {
5145 * Main procedure for handling duplicate blocks
5147 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
5149 ext2_filsys fs = ctx->fs;
5150 struct problem_context pctx;
5152 clear_problem_context(&pctx);
5154 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
5155 _("multiply claimed inode map"), &inode_dup_map);
5157 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
5158 ctx->flags |= E2F_FLAG_ABORT;
5162 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
5163 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
5164 dict_set_allocator(&ino_dict, inode_dnode_free);
5165 dict_set_allocator(&blk_dict, block_dnode_free);
5167 pass1b(ctx, block_buf);
5168 pass1c(ctx, block_buf);
5169 pass1d(ctx, block_buf);
5172 * Time to free all of the accumulated data structures that we
5173 * don't need anymore.
5175 dict_free_nodes(&ino_dict);
5176 dict_free_nodes(&blk_dict);
5180 * Scan the inodes looking for inodes that contain duplicate blocks.
5182 struct process_block_struct_1b {
5186 struct ext2_inode *inode;
5187 struct problem_context *pctx;
5190 static void pass1b(e2fsck_t ctx, char *block_buf)
5192 ext2_filsys fs = ctx->fs;
5194 struct ext2_inode inode;
5195 ext2_inode_scan scan;
5196 struct process_block_struct_1b pb;
5197 struct problem_context pctx;
5199 clear_problem_context(&pctx);
5201 if (!(ctx->options & E2F_OPT_PREEN))
5202 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
5203 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
5206 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
5207 ctx->flags |= E2F_FLAG_ABORT;
5210 ctx->stashed_inode = &inode;
5213 pctx.str = "pass1b";
5215 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
5216 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
5219 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
5220 ctx->flags |= E2F_FLAG_ABORT;
5225 pctx.ino = ctx->stashed_ino = ino;
5226 if ((ino != EXT2_BAD_INO) &&
5227 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
5234 if (ext2fs_inode_has_valid_blocks(&inode) ||
5235 (ino == EXT2_BAD_INO))
5236 pctx.errcode = ext2fs_block_iterate2(fs, ino,
5237 0, block_buf, process_pass1b_block, &pb);
5238 if (inode.i_file_acl)
5239 process_pass1b_block(fs, &inode.i_file_acl,
5240 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5241 if (pb.dup_blocks) {
5242 end_problem_latch(ctx, PR_LATCH_DBLOCK);
5243 if (ino >= EXT2_FIRST_INODE(fs->super) ||
5244 ino == EXT2_ROOT_INO)
5248 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5250 ext2fs_close_inode_scan(scan);
5251 e2fsck_use_inode_shortcuts(ctx, 0);
5254 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
5256 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5257 blk_t ref_blk FSCK_ATTR((unused)),
5258 int ref_offset FSCK_ATTR((unused)),
5261 struct process_block_struct_1b *p;
5264 if (HOLE_BLKADDR(*block_nr))
5266 p = (struct process_block_struct_1b *) priv_data;
5269 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
5272 /* OK, this is a duplicate block */
5273 if (p->ino != EXT2_BAD_INO) {
5274 p->pctx->blk = *block_nr;
5275 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
5278 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
5280 add_dupe(ctx, p->ino, *block_nr, p->inode);
5286 * Pass 1c: Scan directories for inodes with duplicate blocks. This
5287 * is used so that we can print pathnames when prompting the user for
5290 struct search_dir_struct {
5292 ext2_ino_t first_inode;
5293 ext2_ino_t max_inode;
5296 static int search_dirent_proc(ext2_ino_t dir, int entry,
5297 struct ext2_dir_entry *dirent,
5298 int offset FSCK_ATTR((unused)),
5299 int blocksize FSCK_ATTR((unused)),
5300 char *buf FSCK_ATTR((unused)),
5303 struct search_dir_struct *sd;
5304 struct dup_inode *p;
5307 sd = (struct search_dir_struct *) priv_data;
5309 if (dirent->inode > sd->max_inode)
5310 /* Should abort this inode, but not everything */
5313 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
5314 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
5317 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
5320 p = (struct dup_inode *) dnode_get(n);
5324 return(sd->count ? 0 : DIRENT_ABORT);
5328 static void pass1c(e2fsck_t ctx, char *block_buf)
5330 ext2_filsys fs = ctx->fs;
5331 struct search_dir_struct sd;
5332 struct problem_context pctx;
5334 clear_problem_context(&pctx);
5336 if (!(ctx->options & E2F_OPT_PREEN))
5337 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
5340 * Search through all directories to translate inodes to names
5341 * (by searching for the containing directory for that inode.)
5343 sd.count = dup_inode_count;
5344 sd.first_inode = EXT2_FIRST_INODE(fs->super);
5345 sd.max_inode = fs->super->s_inodes_count;
5346 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
5347 search_dirent_proc, &sd);
5350 static void pass1d(e2fsck_t ctx, char *block_buf)
5352 ext2_filsys fs = ctx->fs;
5353 struct dup_inode *p, *t;
5354 struct dup_block *q;
5355 ext2_ino_t *shared, ino;
5360 struct problem_context pctx;
5365 clear_problem_context(&pctx);
5367 if (!(ctx->options & E2F_OPT_PREEN))
5368 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
5369 e2fsck_read_bitmaps(ctx);
5371 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
5372 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
5373 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
5374 sizeof(ext2_ino_t) * dict_count(&ino_dict),
5375 "Shared inode list");
5376 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
5377 p = (struct dup_inode *) dnode_get(n);
5380 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
5381 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
5385 * Find all of the inodes which share blocks with this
5386 * one. First we find all of the duplicate blocks
5387 * belonging to this inode, and then search each block
5388 * get the list of inodes, and merge them together.
5390 for (s = p->block_list; s; s = s->next) {
5391 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5393 continue; /* Should never happen... */
5394 q = (struct dup_block *) dnode_get(m);
5397 if (check_if_fs_block(ctx, s->block)) {
5403 * Add all inodes used by this block to the
5404 * shared[] --- which is a unique list, so
5405 * if an inode is already in shared[], don't
5408 for (r = q->inode_list; r; r = r->next) {
5409 if (r->inode == ino)
5411 for (i = 0; i < shared_len; i++)
5412 if (shared[i] == r->inode)
5414 if (i == shared_len) {
5415 shared[shared_len++] = r->inode;
5421 * Report the inode that we are working on
5423 pctx.inode = &p->inode;
5426 pctx.blkcount = p->num_dupblocks;
5427 pctx.num = meta_data ? shared_len+1 : shared_len;
5428 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5433 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5435 for (i = 0; i < shared_len; i++) {
5436 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5438 continue; /* should never happen */
5439 t = (struct dup_inode *) dnode_get(m);
5441 * Report the inode that we are sharing with
5443 pctx.inode = &t->inode;
5444 pctx.ino = shared[i];
5446 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5449 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5452 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5453 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5455 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5459 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5460 delete_file(ctx, ino, p, block_buf);
5462 ext2fs_unmark_valid(fs);
5464 ext2fs_free_mem(&shared);
5468 * Drop the refcount on the dup_block structure, and clear the entry
5469 * in the block_dup_map if appropriate.
5471 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5474 if (p->num_bad <= 0 ||
5475 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5476 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5479 static int delete_file_block(ext2_filsys fs,
5481 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5482 blk_t ref_block FSCK_ATTR((unused)),
5483 int ref_offset FSCK_ATTR((unused)),
5486 struct process_block_struct_1b *pb;
5487 struct dup_block *p;
5491 pb = (struct process_block_struct_1b *) priv_data;
5494 if (HOLE_BLKADDR(*block_nr))
5497 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5498 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5500 p = (struct dup_block *) dnode_get(n);
5501 decrement_badcount(ctx, *block_nr, p);
5503 bb_error_msg(_("internal error; can't find dup_blk for %d\n"),
5506 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5507 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5513 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5514 struct dup_inode *dp, char* block_buf)
5516 ext2_filsys fs = ctx->fs;
5517 struct process_block_struct_1b pb;
5518 struct ext2_inode inode;
5519 struct problem_context pctx;
5522 clear_problem_context(&pctx);
5523 pctx.ino = pb.ino = ino;
5524 pb.dup_blocks = dp->num_dupblocks;
5526 pctx.str = "delete_file";
5528 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5529 if (ext2fs_inode_has_valid_blocks(&inode))
5530 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5531 delete_file_block, &pb);
5533 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5534 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5535 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5536 if (ctx->inode_bad_map)
5537 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5538 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5540 /* Inode may have changed by block_iterate, so reread it */
5541 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5542 inode.i_links_count = 0;
5543 inode.i_dtime = time(0);
5544 if (inode.i_file_acl &&
5545 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5547 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5548 block_buf, -1, &count);
5549 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5554 pctx.blk = inode.i_file_acl;
5555 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5558 * If the count is zero, then arrange to have the
5559 * block deleted. If the block is in the block_dup_map,
5560 * also call delete_file_block since it will take care
5561 * of keeping the accounting straight.
5564 ext2fs_test_block_bitmap(ctx->block_dup_map,
5566 delete_file_block(fs, &inode.i_file_acl,
5567 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5569 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5572 struct clone_struct {
5579 static int clone_file_block(ext2_filsys fs,
5581 e2_blkcnt_t blockcnt,
5582 blk_t ref_block FSCK_ATTR((unused)),
5583 int ref_offset FSCK_ATTR((unused)),
5586 struct dup_block *p;
5589 struct clone_struct *cs = (struct clone_struct *) priv_data;
5595 if (HOLE_BLKADDR(*block_nr))
5598 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5599 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5601 p = (struct dup_block *) dnode_get(n);
5602 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5605 cs->errcode = retval;
5608 if (cs->dir && (blockcnt >= 0)) {
5609 retval = ext2fs_set_dir_block(fs->dblist,
5610 cs->dir, new_block, blockcnt);
5612 cs->errcode = retval;
5617 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5620 cs->errcode = retval;
5623 retval = io_channel_write_blk(fs->io, new_block, 1,
5626 cs->errcode = retval;
5629 decrement_badcount(ctx, *block_nr, p);
5630 *block_nr = new_block;
5631 ext2fs_mark_block_bitmap(ctx->block_found_map,
5633 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5634 return BLOCK_CHANGED;
5636 bb_error_msg(_("internal error; can't find dup_blk for %d\n"),
5642 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5643 struct dup_inode *dp, char* block_buf)
5645 ext2_filsys fs = ctx->fs;
5647 struct clone_struct cs;
5648 struct problem_context pctx;
5651 struct inode_el *ino_el;
5652 struct dup_block *db;
5653 struct dup_inode *di;
5655 clear_problem_context(&pctx);
5659 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5663 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5667 pctx.str = "clone_file";
5668 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5669 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5670 clone_file_block, &cs);
5671 ext2fs_mark_bb_dirty(fs);
5673 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5674 retval = pctx.errcode;
5678 bb_error_msg(_("returned from clone_file_block"));
5679 retval = cs.errcode;
5682 /* The inode may have changed on disk, so we have to re-read it */
5683 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5684 blk = dp->inode.i_file_acl;
5685 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5686 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5688 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5690 * If we cloned the EA block, find all other inodes
5691 * which refered to that EA block, and modify
5692 * them to point to the new EA block.
5694 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5695 db = (struct dup_block *) dnode_get(n);
5696 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5697 if (ino_el->inode == ino)
5699 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5700 di = (struct dup_inode *) dnode_get(n);
5701 if (di->inode.i_file_acl == blk) {
5702 di->inode.i_file_acl = dp->inode.i_file_acl;
5703 e2fsck_write_inode(ctx, ino_el->inode,
5704 &di->inode, "clone file EA");
5705 decrement_badcount(ctx, blk, db);
5711 ext2fs_free_mem(&cs.buf);
5716 * This routine returns 1 if a block overlaps with one of the superblocks,
5717 * group descriptors, inode bitmaps, or block bitmaps.
5719 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5721 ext2_filsys fs = ctx->fs;
5725 block = fs->super->s_first_data_block;
5726 for (i = 0; i < fs->group_desc_count; i++) {
5728 /* Check superblocks/block group descriptros */
5729 if (ext2fs_bg_has_super(fs, i)) {
5730 if (test_block >= block &&
5731 (test_block <= block + fs->desc_blocks))
5735 /* Check the inode table */
5736 if ((fs->group_desc[i].bg_inode_table) &&
5737 (test_block >= fs->group_desc[i].bg_inode_table) &&
5738 (test_block < (fs->group_desc[i].bg_inode_table +
5739 fs->inode_blocks_per_group)))
5742 /* Check the bitmap blocks */
5743 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5744 (test_block == fs->group_desc[i].bg_inode_bitmap))
5747 block += fs->super->s_blocks_per_group;
5752 * pass2.c --- check directory structure
5754 * Pass 2 of e2fsck iterates through all active directory inodes, and
5755 * applies to following tests to each directory entry in the directory
5756 * blocks in the inodes:
5758 * - The length of the directory entry (rec_len) should be at
5759 * least 8 bytes, and no more than the remaining space
5760 * left in the directory block.
5761 * - The length of the name in the directory entry (name_len)
5762 * should be less than (rec_len - 8).
5763 * - The inode number in the directory entry should be within
5765 * - The inode number should refer to a in-use inode.
5766 * - The first entry should be '.', and its inode should be
5767 * the inode of the directory.
5768 * - The second entry should be '..'.
5770 * To minimize disk seek time, the directory blocks are processed in
5771 * sorted order of block numbers.
5773 * Pass 2 also collects the following information:
5774 * - The inode numbers of the subdirectories for each directory.
5776 * Pass 2 relies on the following information from previous passes:
5777 * - The directory information collected in pass 1.
5778 * - The inode_used_map bitmap
5779 * - The inode_bad_map bitmap
5780 * - The inode_dir_map bitmap
5782 * Pass 2 frees the following data structures
5783 * - The inode_bad_map bitmap
5784 * - The inode_reg_map bitmap
5788 * Keeps track of how many times an inode is referenced.
5790 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5791 static int check_dir_block(ext2_filsys fs,
5792 struct ext2_db_entry *dir_blocks_info,
5794 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5795 struct problem_context *pctx);
5796 static int update_dir_block(ext2_filsys fs,
5798 e2_blkcnt_t blockcnt,
5802 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5803 static int htree_depth(struct dx_dir_info *dx_dir,
5804 struct dx_dirblock_info *dx_db);
5805 static int special_dir_block_cmp(const void *a, const void *b);
5807 struct check_dir_struct {
5809 struct problem_context pctx;
5814 static void e2fsck_pass2(e2fsck_t ctx)
5816 struct ext2_super_block *sb = ctx->fs->super;
5817 struct problem_context pctx;
5818 ext2_filsys fs = ctx->fs;
5820 struct dir_info *dir;
5821 struct check_dir_struct cd;
5822 struct dx_dir_info *dx_dir;
5823 struct dx_dirblock_info *dx_db, *dx_parent;
5829 clear_problem_context(&cd.pctx);
5833 if (!(ctx->options & E2F_OPT_PREEN))
5834 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5836 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5837 0, ctx->inode_link_info,
5839 if (cd.pctx.errcode) {
5840 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5841 ctx->flags |= E2F_FLAG_ABORT;
5844 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5845 "directory scan buffer");
5848 * Set up the parent pointer for the root directory, if
5849 * present. (If the root directory is not present, we will
5850 * create it in pass 3.)
5852 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5854 dir->parent = EXT2_ROOT_INO;
5859 cd.max = ext2fs_dblist_count(fs->dblist);
5862 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5864 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5865 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5867 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5869 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5871 if (cd.pctx.errcode) {
5872 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5873 ctx->flags |= E2F_FLAG_ABORT;
5878 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5879 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5881 if (dx_dir->numblocks == 0)
5883 clear_problem_context(&pctx);
5885 pctx.dir = dx_dir->ino;
5886 dx_db = dx_dir->dx_block;
5887 if (dx_db->flags & DX_FLAG_REFERENCED)
5888 dx_db->flags |= DX_FLAG_DUP_REF;
5890 dx_db->flags |= DX_FLAG_REFERENCED;
5892 * Find all of the first and last leaf blocks, and
5893 * update their parent's min and max hash values
5895 for (b=0, dx_db = dx_dir->dx_block;
5896 b < dx_dir->numblocks;
5898 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5899 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5901 dx_parent = &dx_dir->dx_block[dx_db->parent];
5903 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5905 if (dx_db->flags & DX_FLAG_FIRST)
5906 dx_parent->min_hash = dx_db->min_hash;
5908 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5910 if (dx_db->flags & DX_FLAG_LAST)
5911 dx_parent->max_hash = dx_db->max_hash;
5914 for (b=0, dx_db = dx_dir->dx_block;
5915 b < dx_dir->numblocks;
5918 pctx.group = dx_db->parent;
5920 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5921 (dx_db->min_hash < dx_db->node_min_hash)) {
5922 pctx.blk = dx_db->min_hash;
5923 pctx.blk2 = dx_db->node_min_hash;
5924 code = PR_2_HTREE_MIN_HASH;
5925 fix_problem(ctx, code, &pctx);
5928 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5929 depth = htree_depth(dx_dir, dx_db);
5930 if (depth != dx_dir->depth) {
5931 code = PR_2_HTREE_BAD_DEPTH;
5932 fix_problem(ctx, code, &pctx);
5937 * This test doesn't apply for the root block
5941 (dx_db->max_hash > dx_db->node_max_hash)) {
5942 pctx.blk = dx_db->max_hash;
5943 pctx.blk2 = dx_db->node_max_hash;
5944 code = PR_2_HTREE_MAX_HASH;
5945 fix_problem(ctx, code, &pctx);
5948 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5949 code = PR_2_HTREE_NOTREF;
5950 fix_problem(ctx, code, &pctx);
5952 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5953 code = PR_2_HTREE_DUPREF;
5954 fix_problem(ctx, code, &pctx);
5960 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5961 clear_htree(ctx, dx_dir->ino);
5962 dx_dir->numblocks = 0;
5966 ext2fs_free_mem(&buf);
5967 ext2fs_free_dblist(fs->dblist);
5969 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5970 ctx->inode_bad_map = 0;
5971 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5972 ctx->inode_reg_map = 0;
5974 clear_problem_context(&pctx);
5975 if (ctx->large_files) {
5976 if (!(sb->s_feature_ro_compat &
5977 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5978 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5979 sb->s_feature_ro_compat |=
5980 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5981 ext2fs_mark_super_dirty(fs);
5983 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5984 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5985 ext2fs_update_dynamic_rev(fs);
5986 ext2fs_mark_super_dirty(fs);
5988 } else if (!ctx->large_files &&
5989 (sb->s_feature_ro_compat &
5990 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5991 if (fs->flags & EXT2_FLAG_RW) {
5992 sb->s_feature_ro_compat &=
5993 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5994 ext2fs_mark_super_dirty(fs);
6000 #define MAX_DEPTH 32000
6001 static int htree_depth(struct dx_dir_info *dx_dir,
6002 struct dx_dirblock_info *dx_db)
6006 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
6007 dx_db = &dx_dir->dx_block[dx_db->parent];
6013 static int dict_de_cmp(const void *a, const void *b)
6015 const struct ext2_dir_entry *de_a, *de_b;
6018 de_a = (const struct ext2_dir_entry *) a;
6019 a_len = de_a->name_len & 0xFF;
6020 de_b = (const struct ext2_dir_entry *) b;
6021 b_len = de_b->name_len & 0xFF;
6024 return (a_len - b_len);
6026 return strncmp(de_a->name, de_b->name, a_len);
6030 * This is special sort function that makes sure that directory blocks
6031 * with a dirblock of zero are sorted to the beginning of the list.
6032 * This guarantees that the root node of the htree directories are
6033 * processed first, so we know what hash version to use.
6035 static int special_dir_block_cmp(const void *a, const void *b)
6037 const struct ext2_db_entry *db_a =
6038 (const struct ext2_db_entry *) a;
6039 const struct ext2_db_entry *db_b =
6040 (const struct ext2_db_entry *) b;
6042 if (db_a->blockcnt && !db_b->blockcnt)
6045 if (!db_a->blockcnt && db_b->blockcnt)
6048 if (db_a->blk != db_b->blk)
6049 return (int) (db_a->blk - db_b->blk);
6051 if (db_a->ino != db_b->ino)
6052 return (int) (db_a->ino - db_b->ino);
6054 return (int) (db_a->blockcnt - db_b->blockcnt);
6059 * Make sure the first entry in the directory is '.', and that the
6060 * directory entry is sane.
6062 static int check_dot(e2fsck_t ctx,
6063 struct ext2_dir_entry *dirent,
6064 ext2_ino_t ino, struct problem_context *pctx)
6066 struct ext2_dir_entry *nextdir;
6073 problem = PR_2_MISSING_DOT;
6074 else if (((dirent->name_len & 0xFF) != 1) ||
6075 (dirent->name[0] != '.'))
6076 problem = PR_2_1ST_NOT_DOT;
6077 else if (dirent->name[1] != '\0')
6078 problem = PR_2_DOT_NULL_TERM;
6081 if (fix_problem(ctx, problem, pctx)) {
6082 if (dirent->rec_len < 12)
6083 dirent->rec_len = 12;
6084 dirent->inode = ino;
6085 dirent->name_len = 1;
6086 dirent->name[0] = '.';
6087 dirent->name[1] = '\0';
6092 if (dirent->inode != ino) {
6093 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
6094 dirent->inode = ino;
6098 if (dirent->rec_len > 12) {
6099 new_len = dirent->rec_len - 12;
6102 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
6103 nextdir = (struct ext2_dir_entry *)
6104 ((char *) dirent + 12);
6105 dirent->rec_len = 12;
6106 nextdir->rec_len = new_len;
6108 nextdir->name_len = 0;
6117 * Make sure the second entry in the directory is '..', and that the
6118 * directory entry is sane. We do not check the inode number of '..'
6119 * here; this gets done in pass 3.
6121 static int check_dotdot(e2fsck_t ctx,
6122 struct ext2_dir_entry *dirent,
6123 struct dir_info *dir, struct problem_context *pctx)
6128 problem = PR_2_MISSING_DOT_DOT;
6129 else if (((dirent->name_len & 0xFF) != 2) ||
6130 (dirent->name[0] != '.') ||
6131 (dirent->name[1] != '.'))
6132 problem = PR_2_2ND_NOT_DOT_DOT;
6133 else if (dirent->name[2] != '\0')
6134 problem = PR_2_DOT_DOT_NULL_TERM;
6137 if (fix_problem(ctx, problem, pctx)) {
6138 if (dirent->rec_len < 12)
6139 dirent->rec_len = 12;
6141 * Note: we don't have the parent inode just
6142 * yet, so we will fill it in with the root
6143 * inode. This will get fixed in pass 3.
6145 dirent->inode = EXT2_ROOT_INO;
6146 dirent->name_len = 2;
6147 dirent->name[0] = '.';
6148 dirent->name[1] = '.';
6149 dirent->name[2] = '\0';
6154 dir->dotdot = dirent->inode;
6159 * Check to make sure a directory entry doesn't contain any illegal
6162 static int check_name(e2fsck_t ctx,
6163 struct ext2_dir_entry *dirent,
6164 struct problem_context *pctx)
6170 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
6171 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
6173 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
6176 dirent->name[i] = '.';
6185 * Check the directory filetype (if present)
6189 * Given a mode, return the ext2 file type
6191 static int ext2_file_type(unsigned int mode)
6193 if (LINUX_S_ISREG(mode))
6194 return EXT2_FT_REG_FILE;
6196 if (LINUX_S_ISDIR(mode))
6199 if (LINUX_S_ISCHR(mode))
6200 return EXT2_FT_CHRDEV;
6202 if (LINUX_S_ISBLK(mode))
6203 return EXT2_FT_BLKDEV;
6205 if (LINUX_S_ISLNK(mode))
6206 return EXT2_FT_SYMLINK;
6208 if (LINUX_S_ISFIFO(mode))
6209 return EXT2_FT_FIFO;
6211 if (LINUX_S_ISSOCK(mode))
6212 return EXT2_FT_SOCK;
6217 static int check_filetype(e2fsck_t ctx,
6218 struct ext2_dir_entry *dirent,
6219 struct problem_context *pctx)
6221 int filetype = dirent->name_len >> 8;
6222 int should_be = EXT2_FT_UNKNOWN;
6223 struct ext2_inode inode;
6225 if (!(ctx->fs->super->s_feature_incompat &
6226 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
6227 if (filetype == 0 ||
6228 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
6230 dirent->name_len = dirent->name_len & 0xFF;
6234 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
6235 should_be = EXT2_FT_DIR;
6236 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
6238 should_be = EXT2_FT_REG_FILE;
6239 } else if (ctx->inode_bad_map &&
6240 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6244 e2fsck_read_inode(ctx, dirent->inode, &inode,
6246 should_be = ext2_file_type(inode.i_mode);
6248 if (filetype == should_be)
6250 pctx->num = should_be;
6252 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
6256 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
6261 static void parse_int_node(ext2_filsys fs,
6262 struct ext2_db_entry *db,
6263 struct check_dir_struct *cd,
6264 struct dx_dir_info *dx_dir,
6267 struct ext2_dx_root_info *root;
6268 struct ext2_dx_entry *ent;
6269 struct ext2_dx_countlimit *limit;
6270 struct dx_dirblock_info *dx_db;
6271 int i, expect_limit, count;
6273 ext2_dirhash_t min_hash = 0xffffffff;
6274 ext2_dirhash_t max_hash = 0;
6275 ext2_dirhash_t hash = 0, prev_hash;
6277 if (db->blockcnt == 0) {
6278 root = (struct ext2_dx_root_info *) (block_buf + 24);
6279 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
6281 ent = (struct ext2_dx_entry *) (block_buf+8);
6283 limit = (struct ext2_dx_countlimit *) ent;
6285 count = ext2fs_le16_to_cpu(limit->count);
6286 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
6287 sizeof(struct ext2_dx_entry);
6288 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
6289 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
6290 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
6291 goto clear_and_exit;
6293 if (count > expect_limit) {
6294 cd->pctx.num = count;
6295 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
6296 goto clear_and_exit;
6297 count = expect_limit;
6300 for (i=0; i < count; i++) {
6302 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
6303 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
6304 /* Check to make sure the block is valid */
6305 if (blk > (blk_t) dx_dir->numblocks) {
6307 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
6309 goto clear_and_exit;
6311 if (hash < prev_hash &&
6312 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
6313 goto clear_and_exit;
6314 dx_db = &dx_dir->dx_block[blk];
6315 if (dx_db->flags & DX_FLAG_REFERENCED) {
6316 dx_db->flags |= DX_FLAG_DUP_REF;
6318 dx_db->flags |= DX_FLAG_REFERENCED;
6319 dx_db->parent = db->blockcnt;
6321 if (hash < min_hash)
6323 if (hash > max_hash)
6325 dx_db->node_min_hash = hash;
6327 dx_db->node_max_hash =
6328 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
6330 dx_db->node_max_hash = 0xfffffffe;
6331 dx_db->flags |= DX_FLAG_LAST;
6334 dx_db->flags |= DX_FLAG_FIRST;
6336 dx_db = &dx_dir->dx_block[db->blockcnt];
6337 dx_db->min_hash = min_hash;
6338 dx_db->max_hash = max_hash;
6342 clear_htree(cd->ctx, cd->pctx.ino);
6343 dx_dir->numblocks = 0;
6345 #endif /* ENABLE_HTREE */
6348 * Given a busted directory, try to salvage it somehow.
6351 static void salvage_directory(ext2_filsys fs,
6352 struct ext2_dir_entry *dirent,
6353 struct ext2_dir_entry *prev,
6354 unsigned int *offset)
6356 char *cp = (char *) dirent;
6357 int left = fs->blocksize - *offset - dirent->rec_len;
6358 int name_len = dirent->name_len & 0xFF;
6361 * Special case of directory entry of size 8: copy what's left
6362 * of the directory block up to cover up the invalid hole.
6364 if ((left >= 12) && (dirent->rec_len == 8)) {
6365 memmove(cp, cp+8, left);
6366 memset(cp + left, 0, 8);
6370 * If the directory entry overruns the end of the directory
6371 * block, and the name is small enough to fit, then adjust the
6375 (name_len + 8 <= dirent->rec_len + left) &&
6376 dirent->inode <= fs->super->s_inodes_count &&
6377 strnlen(dirent->name, name_len) == name_len) {
6378 dirent->rec_len += left;
6382 * If the directory entry is a multiple of four, so it is
6383 * valid, let the previous directory entry absorb the invalid
6386 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
6387 prev->rec_len += dirent->rec_len;
6388 *offset += dirent->rec_len;
6392 * Default salvage method --- kill all of the directory
6393 * entries for the rest of the block. We will either try to
6394 * absorb it into the previous directory entry, or create a
6395 * new empty directory entry the rest of the directory block.
6398 prev->rec_len += fs->blocksize - *offset;
6399 *offset = fs->blocksize;
6401 dirent->rec_len = fs->blocksize - *offset;
6402 dirent->name_len = 0;
6407 static int check_dir_block(ext2_filsys fs,
6408 struct ext2_db_entry *db,
6411 struct dir_info *subdir, *dir;
6412 struct dx_dir_info *dx_dir;
6414 struct dx_dirblock_info *dx_db = 0;
6415 #endif /* ENABLE_HTREE */
6416 struct ext2_dir_entry *dirent, *prev;
6417 ext2_dirhash_t hash;
6418 unsigned int offset = 0;
6419 int dir_modified = 0;
6421 blk_t block_nr = db->blk;
6422 ext2_ino_t ino = db->ino;
6424 struct check_dir_struct *cd;
6428 struct ext2_dx_root_info *root;
6429 struct ext2_dx_countlimit *limit;
6430 static dict_t de_dict;
6431 struct problem_context pctx;
6434 cd = (struct check_dir_struct *) priv_data;
6438 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6439 return DIRENT_ABORT;
6441 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6442 return DIRENT_ABORT;
6445 * Make sure the inode is still in use (could have been
6446 * deleted in the duplicate/bad blocks pass.
6448 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6452 cd->pctx.blk = block_nr;
6453 cd->pctx.blkcount = db->blockcnt;
6455 cd->pctx.dirent = 0;
6459 if (allocate_dir_block(ctx, db, &cd->pctx))
6469 if (ctx->dirs_to_hash &&
6470 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6473 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6474 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6475 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6476 if (cd->pctx.errcode) {
6477 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6478 ctx->flags |= E2F_FLAG_ABORT;
6479 return DIRENT_ABORT;
6481 memset(buf, 0, fs->blocksize);
6484 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6485 if (dx_dir && dx_dir->numblocks) {
6486 if (db->blockcnt >= dx_dir->numblocks) {
6487 printf("XXX should never happen!!!\n");
6490 dx_db = &dx_dir->dx_block[db->blockcnt];
6491 dx_db->type = DX_DIRBLOCK_LEAF;
6492 dx_db->phys = block_nr;
6493 dx_db->min_hash = ~0;
6494 dx_db->max_hash = 0;
6496 dirent = (struct ext2_dir_entry *) buf;
6497 limit = (struct ext2_dx_countlimit *) (buf+8);
6498 if (db->blockcnt == 0) {
6499 root = (struct ext2_dx_root_info *) (buf + 24);
6500 dx_db->type = DX_DIRBLOCK_ROOT;
6501 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6502 if ((root->reserved_zero ||
6503 root->info_length < 8 ||
6504 root->indirect_levels > 1) &&
6505 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6506 clear_htree(ctx, ino);
6507 dx_dir->numblocks = 0;
6510 dx_dir->hashversion = root->hash_version;
6511 dx_dir->depth = root->indirect_levels + 1;
6512 } else if ((dirent->inode == 0) &&
6513 (dirent->rec_len == fs->blocksize) &&
6514 (dirent->name_len == 0) &&
6515 (ext2fs_le16_to_cpu(limit->limit) ==
6516 ((fs->blocksize-8) /
6517 sizeof(struct ext2_dx_entry))))
6518 dx_db->type = DX_DIRBLOCK_NODE;
6520 #endif /* ENABLE_HTREE */
6522 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6526 dirent = (struct ext2_dir_entry *) (buf + offset);
6527 cd->pctx.dirent = dirent;
6528 cd->pctx.num = offset;
6529 if (((offset + dirent->rec_len) > fs->blocksize) ||
6530 (dirent->rec_len < 12) ||
6531 ((dirent->rec_len % 4) != 0) ||
6532 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6533 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6534 salvage_directory(fs, dirent, prev, &offset);
6538 goto abort_free_dict;
6540 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6541 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6542 dirent->name_len = EXT2_NAME_LEN;
6547 if (dot_state == 0) {
6548 if (check_dot(ctx, dirent, ino, &cd->pctx))
6550 } else if (dot_state == 1) {
6551 dir = e2fsck_get_dir_info(ctx, ino);
6553 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6554 goto abort_free_dict;
6556 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6558 } else if (dirent->inode == ino) {
6559 problem = PR_2_LINK_DOT;
6560 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6570 * Make sure the inode listed is a legal one.
6572 if (((dirent->inode != EXT2_ROOT_INO) &&
6573 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6574 (dirent->inode > fs->super->s_inodes_count)) {
6575 problem = PR_2_BAD_INO;
6576 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6579 * If the inode is unused, offer to clear it.
6581 problem = PR_2_UNUSED_INODE;
6582 } else if (ctx->inode_bb_map &&
6583 (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
6586 * If the inode is in a bad block, offer to
6589 problem = PR_2_BB_INODE;
6590 } else if ((dot_state > 1) &&
6591 ((dirent->name_len & 0xFF) == 1) &&
6592 (dirent->name[0] == '.')) {
6594 * If there's a '.' entry in anything other
6595 * than the first directory entry, it's a
6596 * duplicate entry that should be removed.
6598 problem = PR_2_DUP_DOT;
6599 } else if ((dot_state > 1) &&
6600 ((dirent->name_len & 0xFF) == 2) &&
6601 (dirent->name[0] == '.') &&
6602 (dirent->name[1] == '.')) {
6604 * If there's a '..' entry in anything other
6605 * than the second directory entry, it's a
6606 * duplicate entry that should be removed.
6608 problem = PR_2_DUP_DOT_DOT;
6609 } else if ((dot_state > 1) &&
6610 (dirent->inode == EXT2_ROOT_INO)) {
6612 * Don't allow links to the root directory.
6613 * We check this specially to make sure we
6614 * catch this error case even if the root
6615 * directory hasn't been created yet.
6617 problem = PR_2_LINK_ROOT;
6618 } else if ((dot_state > 1) &&
6619 (dirent->name_len & 0xFF) == 0) {
6621 * Don't allow zero-length directory names.
6623 problem = PR_2_NULL_NAME;
6627 if (fix_problem(ctx, problem, &cd->pctx)) {
6632 ext2fs_unmark_valid(fs);
6633 if (problem == PR_2_BAD_INO)
6639 * If the inode was marked as having bad fields in
6640 * pass1, process it and offer to fix/clear it.
6641 * (We wait until now so that we can display the
6642 * pathname to the user.)
6644 if (ctx->inode_bad_map &&
6645 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6647 if (e2fsck_process_bad_inode(ctx, ino,
6649 buf + fs->blocksize)) {
6654 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6655 return DIRENT_ABORT;
6658 if (check_name(ctx, dirent, &cd->pctx))
6661 if (check_filetype(ctx, dirent, &cd->pctx))
6666 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6667 (dirent->name_len & 0xFF),
6668 fs->super->s_hash_seed, &hash, 0);
6669 if (hash < dx_db->min_hash)
6670 dx_db->min_hash = hash;
6671 if (hash > dx_db->max_hash)
6672 dx_db->max_hash = hash;
6677 * If this is a directory, then mark its parent in its
6678 * dir_info structure. If the parent field is already
6679 * filled in, then this directory has more than one
6680 * hard link. We assume the first link is correct,
6681 * and ask the user if he/she wants to clear this one.
6683 if ((dot_state > 1) &&
6684 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6686 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6688 cd->pctx.ino = dirent->inode;
6689 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6690 goto abort_free_dict;
6692 if (subdir->parent) {
6693 cd->pctx.ino2 = subdir->parent;
6694 if (fix_problem(ctx, PR_2_LINK_DIR,
6702 subdir->parent = ino;
6707 } else if (dict_lookup(&de_dict, dirent)) {
6708 clear_problem_context(&pctx);
6710 pctx.dirent = dirent;
6711 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6712 if (!ctx->dirs_to_hash)
6713 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6714 if (ctx->dirs_to_hash)
6715 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6718 dict_alloc_insert(&de_dict, dirent, dirent);
6720 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6723 ctx->fs_links_count++;
6724 ctx->fs_total_count++;
6727 offset += dirent->rec_len;
6729 } while (offset < fs->blocksize);
6732 cd->pctx.dir = cd->pctx.ino;
6733 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6734 (dx_db->type == DX_DIRBLOCK_NODE))
6735 parse_int_node(fs, db, cd, dx_dir, buf);
6737 #endif /* ENABLE_HTREE */
6738 if (offset != fs->blocksize) {
6739 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6740 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6741 dirent->rec_len = cd->pctx.num;
6746 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6747 if (cd->pctx.errcode) {
6748 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6750 goto abort_free_dict;
6752 ext2fs_mark_changed(fs);
6754 dict_free_nodes(&de_dict);
6757 dict_free_nodes(&de_dict);
6758 ctx->flags |= E2F_FLAG_ABORT;
6759 return DIRENT_ABORT;
6763 * This function is called to deallocate a block, and is an interator
6764 * functioned called by deallocate inode via ext2fs_iterate_block().
6766 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6767 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6768 blk_t ref_block FSCK_ATTR((unused)),
6769 int ref_offset FSCK_ATTR((unused)),
6772 e2fsck_t ctx = (e2fsck_t) priv_data;
6774 if (HOLE_BLKADDR(*block_nr))
6776 if ((*block_nr < fs->super->s_first_data_block) ||
6777 (*block_nr >= fs->super->s_blocks_count))
6779 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6780 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6785 * This fuction deallocates an inode
6787 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6789 ext2_filsys fs = ctx->fs;
6790 struct ext2_inode inode;
6791 struct problem_context pctx;
6794 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6795 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6796 inode.i_links_count = 0;
6797 inode.i_dtime = time(0);
6798 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6799 clear_problem_context(&pctx);
6803 * Fix up the bitmaps...
6805 e2fsck_read_bitmaps(ctx);
6806 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6807 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6808 if (ctx->inode_bad_map)
6809 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6810 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6812 if (inode.i_file_acl &&
6813 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6814 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6815 block_buf, -1, &count);
6816 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6821 pctx.blk = inode.i_file_acl;
6822 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6823 ctx->flags |= E2F_FLAG_ABORT;
6827 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6829 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6831 inode.i_file_acl = 0;
6834 if (!ext2fs_inode_has_valid_blocks(&inode))
6837 if (LINUX_S_ISREG(inode.i_mode) &&
6838 (inode.i_size_high || inode.i_size & 0x80000000UL))
6841 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6842 deallocate_inode_block, ctx);
6844 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6845 ctx->flags |= E2F_FLAG_ABORT;
6851 * This fuction clears the htree flag on an inode
6853 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6855 struct ext2_inode inode;
6857 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6858 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6859 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6860 if (ctx->dirs_to_hash)
6861 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6865 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6866 ext2_ino_t ino, char *buf)
6868 ext2_filsys fs = ctx->fs;
6869 struct ext2_inode inode;
6870 int inode_modified = 0;
6872 unsigned char *frag, *fsize;
6873 struct problem_context pctx;
6876 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6878 clear_problem_context(&pctx);
6881 pctx.inode = &inode;
6883 if (inode.i_file_acl &&
6884 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6885 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6886 inode.i_file_acl = 0;
6889 * This is a special kludge to deal with long symlinks
6890 * on big endian systems. i_blocks had already been
6891 * decremented earlier in pass 1, but since i_file_acl
6892 * hadn't yet been cleared, ext2fs_read_inode()
6893 * assumed that the file was short symlink and would
6894 * not have byte swapped i_block[0]. Hence, we have
6895 * to byte-swap it here.
6897 if (LINUX_S_ISLNK(inode.i_mode) &&
6898 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6899 (inode.i_blocks == fs->blocksize >> 9))
6900 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6906 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6907 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6908 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6909 !(LINUX_S_ISSOCK(inode.i_mode)))
6910 problem = PR_2_BAD_MODE;
6911 else if (LINUX_S_ISCHR(inode.i_mode)
6912 && !e2fsck_pass1_check_device_inode(fs, &inode))
6913 problem = PR_2_BAD_CHAR_DEV;
6914 else if (LINUX_S_ISBLK(inode.i_mode)
6915 && !e2fsck_pass1_check_device_inode(fs, &inode))
6916 problem = PR_2_BAD_BLOCK_DEV;
6917 else if (LINUX_S_ISFIFO(inode.i_mode)
6918 && !e2fsck_pass1_check_device_inode(fs, &inode))
6919 problem = PR_2_BAD_FIFO;
6920 else if (LINUX_S_ISSOCK(inode.i_mode)
6921 && !e2fsck_pass1_check_device_inode(fs, &inode))
6922 problem = PR_2_BAD_SOCKET;
6923 else if (LINUX_S_ISLNK(inode.i_mode)
6924 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6925 problem = PR_2_INVALID_SYMLINK;
6929 if (fix_problem(ctx, problem, &pctx)) {
6930 deallocate_inode(ctx, ino, 0);
6931 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6939 if (inode.i_faddr) {
6940 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6947 switch (fs->super->s_creator_os) {
6949 frag = &inode.osd2.linux2.l_i_frag;
6950 fsize = &inode.osd2.linux2.l_i_fsize;
6953 frag = &inode.osd2.hurd2.h_i_frag;
6954 fsize = &inode.osd2.hurd2.h_i_fsize;
6957 frag = &inode.osd2.masix2.m_i_frag;
6958 fsize = &inode.osd2.masix2.m_i_fsize;
6963 if (frag && *frag) {
6965 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6972 if (fsize && *fsize) {
6974 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6982 if (inode.i_file_acl &&
6983 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6984 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6985 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6986 inode.i_file_acl = 0;
6991 if (inode.i_dir_acl &&
6992 LINUX_S_ISDIR(inode.i_mode)) {
6993 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6994 inode.i_dir_acl = 0;
7001 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
7003 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7009 * allocate_dir_block --- this function allocates a new directory
7010 * block for a particular inode; this is done if a directory has
7011 * a "hole" in it, or if a directory has a illegal block number
7012 * that was zeroed out and now needs to be replaced.
7014 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
7015 struct problem_context *pctx)
7017 ext2_filsys fs = ctx->fs;
7020 struct ext2_inode inode;
7022 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
7026 * Read the inode and block bitmaps in; we'll be messing with
7029 e2fsck_read_bitmaps(ctx);
7032 * First, find a free block
7034 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7035 if (pctx->errcode) {
7036 pctx->str = "ext2fs_new_block";
7037 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7040 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7041 ext2fs_mark_block_bitmap(fs->block_map, blk);
7042 ext2fs_mark_bb_dirty(fs);
7045 * Now let's create the actual data block for the inode
7048 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
7050 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
7051 EXT2_ROOT_INO, &block);
7053 if (pctx->errcode) {
7054 pctx->str = "ext2fs_new_dir_block";
7055 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7059 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
7060 ext2fs_free_mem(&block);
7061 if (pctx->errcode) {
7062 pctx->str = "ext2fs_write_dir_block";
7063 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7068 * Update the inode block count
7070 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
7071 inode.i_blocks += fs->blocksize / 512;
7072 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
7073 inode.i_size = (db->blockcnt+1) * fs->blocksize;
7074 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
7077 * Finally, update the block pointers for the inode
7080 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
7081 0, update_dir_block, db);
7082 if (pctx->errcode) {
7083 pctx->str = "ext2fs_block_iterate";
7084 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7092 * This is a helper function for allocate_dir_block().
7094 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
7096 e2_blkcnt_t blockcnt,
7097 blk_t ref_block FSCK_ATTR((unused)),
7098 int ref_offset FSCK_ATTR((unused)),
7101 struct ext2_db_entry *db;
7103 db = (struct ext2_db_entry *) priv_data;
7104 if (db->blockcnt == (int) blockcnt) {
7105 *block_nr = db->blk;
7106 return BLOCK_CHANGED;
7112 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
7114 * Pass #3 assures that all directories are connected to the
7115 * filesystem tree, using the following algorithm:
7117 * First, the root directory is checked to make sure it exists; if
7118 * not, e2fsck will offer to create a new one. It is then marked as
7121 * Then, pass3 interates over all directory inodes; for each directory
7122 * it attempts to trace up the filesystem tree, using dirinfo.parent
7123 * until it reaches a directory which has been marked "done". If it
7124 * can not do so, then the directory must be disconnected, and e2fsck
7125 * will offer to reconnect it to /lost+found. While it is chasing
7126 * parent pointers up the filesystem tree, if pass3 sees a directory
7127 * twice, then it has detected a filesystem loop, and it will again
7128 * offer to reconnect the directory to /lost+found in to break the
7131 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
7132 * reconnect inodes to /lost+found; this subroutine is also used by
7133 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
7134 * is responsible for creating /lost+found if it does not exist.
7136 * Pass 3 frees the following data structures:
7137 * - The dirinfo directory information cache.
7140 static void check_root(e2fsck_t ctx);
7141 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
7142 struct problem_context *pctx);
7143 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
7145 static ext2fs_inode_bitmap inode_loop_detect;
7146 static ext2fs_inode_bitmap inode_done_map;
7148 static void e2fsck_pass3(e2fsck_t ctx)
7150 ext2_filsys fs = ctx->fs;
7152 struct problem_context pctx;
7153 struct dir_info *dir;
7154 unsigned long maxdirs, count;
7156 clear_problem_context(&pctx);
7160 if (!(ctx->options & E2F_OPT_PREEN))
7161 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
7164 * Allocate some bitmaps to do loop detection.
7166 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
7170 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
7171 ctx->flags |= E2F_FLAG_ABORT;
7175 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7178 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
7180 maxdirs = e2fsck_get_num_dirinfo(ctx);
7184 if ((ctx->progress)(ctx, 3, 0, maxdirs))
7187 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
7188 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7190 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
7192 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
7193 if (check_directory(ctx, dir, &pctx))
7198 * Force the creation of /lost+found if not present
7200 if ((ctx->flags & E2F_OPT_READONLY) == 0)
7201 e2fsck_get_lost_and_found(ctx, 1);
7204 * If there are any directories that need to be indexed or
7205 * optimized, do it here.
7207 e2fsck_rehash_directories(ctx);
7210 e2fsck_free_dir_info(ctx);
7211 ext2fs_free_inode_bitmap(inode_loop_detect);
7212 inode_loop_detect = 0;
7213 ext2fs_free_inode_bitmap(inode_done_map);
7218 * This makes sure the root inode is present; if not, we ask if the
7219 * user wants us to create it. Not creating it is a fatal error.
7221 static void check_root(e2fsck_t ctx)
7223 ext2_filsys fs = ctx->fs;
7225 struct ext2_inode inode;
7227 struct problem_context pctx;
7229 clear_problem_context(&pctx);
7231 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
7233 * If the root inode is not a directory, die here. The
7234 * user must have answered 'no' in pass1 when we
7235 * offered to clear it.
7237 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
7239 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
7240 ctx->flags |= E2F_FLAG_ABORT;
7245 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
7246 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
7247 ctx->flags |= E2F_FLAG_ABORT;
7251 e2fsck_read_bitmaps(ctx);
7254 * First, find a free block
7256 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7258 pctx.str = "ext2fs_new_block";
7259 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7260 ctx->flags |= E2F_FLAG_ABORT;
7263 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7264 ext2fs_mark_block_bitmap(fs->block_map, blk);
7265 ext2fs_mark_bb_dirty(fs);
7268 * Now let's create the actual data block for the inode
7270 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
7273 pctx.str = "ext2fs_new_dir_block";
7274 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7275 ctx->flags |= E2F_FLAG_ABORT;
7279 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
7281 pctx.str = "ext2fs_write_dir_block";
7282 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7283 ctx->flags |= E2F_FLAG_ABORT;
7286 ext2fs_free_mem(&block);
7289 * Set up the inode structure
7291 memset(&inode, 0, sizeof(inode));
7292 inode.i_mode = 040755;
7293 inode.i_size = fs->blocksize;
7294 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7295 inode.i_links_count = 2;
7296 inode.i_blocks = fs->blocksize / 512;
7297 inode.i_block[0] = blk;
7300 * Write out the inode.
7302 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
7304 pctx.str = "ext2fs_write_inode";
7305 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7306 ctx->flags |= E2F_FLAG_ABORT;
7311 * Miscellaneous bookkeeping...
7313 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
7314 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
7315 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
7317 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
7318 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
7319 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
7320 ext2fs_mark_ib_dirty(fs);
7324 * This subroutine is responsible for making sure that a particular
7325 * directory is connected to the root; if it isn't we trace it up as
7326 * far as we can go, and then offer to connect the resulting parent to
7327 * the lost+found. We have to do loop detection; if we ever discover
7328 * a loop, we treat that as a disconnected directory and offer to
7329 * reparent it to lost+found.
7331 * However, loop detection is expensive, because for very large
7332 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
7333 * is non-trivial. Loops in filesystems are also a rare error case,
7334 * and we shouldn't optimize for error cases. So we try two passes of
7335 * the algorithm. The first time, we ignore loop detection and merely
7336 * increment a counter; if the counter exceeds some extreme threshold,
7337 * then we try again with the loop detection bitmap enabled.
7339 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
7340 struct problem_context *pctx)
7342 ext2_filsys fs = ctx->fs;
7343 struct dir_info *p = dir;
7344 int loop_pass = 0, parent_count = 0;
7351 * Mark this inode as being "done"; by the time we
7352 * return from this function, the inode we either be
7353 * verified as being connected to the directory tree,
7354 * or we will have offered to reconnect this to
7357 * If it was marked done already, then we've reached a
7358 * parent we've already checked.
7360 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
7364 * If this directory doesn't have a parent, or we've
7365 * seen the parent once already, then offer to
7366 * reparent it to lost+found
7370 (ext2fs_test_inode_bitmap(inode_loop_detect,
7373 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
7374 if (e2fsck_reconnect_file(ctx, pctx->ino))
7375 ext2fs_unmark_valid(fs);
7377 p = e2fsck_get_dir_info(ctx, pctx->ino);
7378 p->parent = ctx->lost_and_found;
7379 fix_dotdot(ctx, p, ctx->lost_and_found);
7384 p = e2fsck_get_dir_info(ctx, p->parent);
7386 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
7390 ext2fs_mark_inode_bitmap(inode_loop_detect,
7392 } else if (parent_count++ > 2048) {
7394 * If we've run into a path depth that's
7395 * greater than 2048, try again with the inode
7396 * loop bitmap turned on and start from the
7400 if (inode_loop_detect)
7401 ext2fs_clear_inode_bitmap(inode_loop_detect);
7403 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7404 if (pctx->errcode) {
7407 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7408 ctx->flags |= E2F_FLAG_ABORT;
7417 * Make sure that .. and the parent directory are the same;
7418 * offer to fix it if not.
7420 if (dir->parent != dir->dotdot) {
7421 pctx->ino = dir->ino;
7422 pctx->ino2 = dir->dotdot;
7423 pctx->dir = dir->parent;
7424 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7425 fix_dotdot(ctx, dir, dir->parent);
7431 * This routine gets the lost_and_found inode, making it a directory
7434 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7436 ext2_filsys fs = ctx->fs;
7440 struct ext2_inode inode;
7442 static const char name[] = "lost+found";
7443 struct problem_context pctx;
7444 struct dir_info *dirinfo;
7446 if (ctx->lost_and_found)
7447 return ctx->lost_and_found;
7449 clear_problem_context(&pctx);
7451 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7452 sizeof(name)-1, 0, &ino);
7456 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7457 ctx->lost_and_found = ino;
7461 /* Lost+found isn't a directory! */
7465 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7468 /* OK, unlink the old /lost+found file. */
7469 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7471 pctx.str = "ext2fs_unlink";
7472 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7475 dirinfo = e2fsck_get_dir_info(ctx, ino);
7477 dirinfo->parent = 0;
7478 e2fsck_adjust_inode_count(ctx, ino, -1);
7479 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7480 pctx.errcode = retval;
7481 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7483 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7487 * Read the inode and block bitmaps in; we'll be messing with
7490 e2fsck_read_bitmaps(ctx);
7493 * First, find a free block
7495 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7497 pctx.errcode = retval;
7498 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7501 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7502 ext2fs_block_alloc_stats(fs, blk, +1);
7505 * Next find a free inode.
7507 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7508 ctx->inode_used_map, &ino);
7510 pctx.errcode = retval;
7511 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7514 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7515 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7516 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7519 * Now let's create the actual data block for the inode
7521 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7523 pctx.errcode = retval;
7524 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7528 retval = ext2fs_write_dir_block(fs, blk, block);
7529 ext2fs_free_mem(&block);
7531 pctx.errcode = retval;
7532 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7537 * Set up the inode structure
7539 memset(&inode, 0, sizeof(inode));
7540 inode.i_mode = 040700;
7541 inode.i_size = fs->blocksize;
7542 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7543 inode.i_links_count = 2;
7544 inode.i_blocks = fs->blocksize / 512;
7545 inode.i_block[0] = blk;
7548 * Next, write out the inode.
7550 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7552 pctx.str = "ext2fs_write_inode";
7553 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7557 * Finally, create the directory link
7559 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7561 pctx.str = "ext2fs_link";
7562 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7567 * Miscellaneous bookkeeping that needs to be kept straight.
7569 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7570 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7571 ext2fs_icount_store(ctx->inode_count, ino, 2);
7572 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7573 ctx->lost_and_found = ino;
7578 * This routine will connect a file to lost+found
7580 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7582 ext2_filsys fs = ctx->fs;
7585 struct problem_context pctx;
7586 struct ext2_inode inode;
7589 clear_problem_context(&pctx);
7592 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7593 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7594 ctx->bad_lost_and_found++;
7596 if (ctx->bad_lost_and_found) {
7597 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7601 sprintf(name, "#%u", ino);
7602 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7603 file_type = ext2_file_type(inode.i_mode);
7604 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7605 if (retval == EXT2_ET_DIR_NO_SPACE) {
7606 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7608 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7611 pctx.errcode = retval;
7612 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7615 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7619 pctx.errcode = retval;
7620 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7623 e2fsck_adjust_inode_count(ctx, ino, 1);
7629 * Utility routine to adjust the inode counts on an inode.
7631 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7633 ext2_filsys fs = ctx->fs;
7635 struct ext2_inode inode;
7640 retval = ext2fs_read_inode(fs, ino, &inode);
7645 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7646 if (inode.i_links_count == (__u16) ~0)
7648 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7649 inode.i_links_count++;
7650 } else if (adj == -1) {
7651 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7652 if (inode.i_links_count == 0)
7654 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7655 inode.i_links_count--;
7658 retval = ext2fs_write_inode(fs, ino, &inode);
7666 * Fix parent --- this routine fixes up the parent of a directory.
7668 struct fix_dotdot_struct {
7675 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7676 int offset FSCK_ATTR((unused)),
7677 int blocksize FSCK_ATTR((unused)),
7678 char *buf FSCK_ATTR((unused)),
7681 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7683 struct problem_context pctx;
7685 if ((dirent->name_len & 0xFF) != 2)
7687 if (strncmp(dirent->name, "..", 2))
7690 clear_problem_context(&pctx);
7692 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7694 pctx.errcode = retval;
7695 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7697 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7699 pctx.errcode = retval;
7700 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7702 dirent->inode = fp->parent;
7705 return DIRENT_ABORT | DIRENT_CHANGED;
7708 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7710 ext2_filsys fs = ctx->fs;
7712 struct fix_dotdot_struct fp;
7713 struct problem_context pctx;
7720 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7721 0, fix_dotdot_proc, &fp);
7722 if (retval || !fp.done) {
7723 clear_problem_context(&pctx);
7724 pctx.ino = dir->ino;
7725 pctx.errcode = retval;
7726 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7727 PR_3_FIX_PARENT_NOFIND, &pctx);
7728 ext2fs_unmark_valid(fs);
7730 dir->dotdot = parent;
7736 * These routines are responsible for expanding a /lost+found if it is
7740 struct expand_dir_struct {
7742 int guaranteed_size;
7749 static int expand_dir_proc(ext2_filsys fs,
7751 e2_blkcnt_t blockcnt,
7752 blk_t ref_block FSCK_ATTR((unused)),
7753 int ref_offset FSCK_ATTR((unused)),
7756 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7758 static blk_t last_blk = 0;
7765 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7769 es->last_block = blockcnt;
7771 last_blk = *blocknr;
7774 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7781 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7787 retval = ext2fs_write_dir_block(fs, new_blk, block);
7789 retval = ext2fs_get_mem(fs->blocksize, &block);
7794 memset(block, 0, fs->blocksize);
7795 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7801 ext2fs_free_mem(&block);
7803 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7804 ext2fs_block_alloc_stats(fs, new_blk, +1);
7808 return (BLOCK_CHANGED | BLOCK_ABORT);
7810 return BLOCK_CHANGED;
7813 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7814 int num, int guaranteed_size)
7816 ext2_filsys fs = ctx->fs;
7818 struct expand_dir_struct es;
7819 struct ext2_inode inode;
7821 if (!(fs->flags & EXT2_FLAG_RW))
7822 return EXT2_ET_RO_FILSYS;
7825 * Read the inode and block bitmaps in; we'll be messing with
7828 e2fsck_read_bitmaps(ctx);
7830 retval = ext2fs_check_directory(fs, dir);
7835 es.guaranteed_size = guaranteed_size;
7841 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7842 0, expand_dir_proc, &es);
7848 * Update the size and block count fields in the inode.
7850 retval = ext2fs_read_inode(fs, dir, &inode);
7854 inode.i_size = (es.last_block + 1) * fs->blocksize;
7855 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7857 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7863 * pass4.c -- pass #4 of e2fsck: Check reference counts
7865 * Pass 4 frees the following data structures:
7866 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
7867 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7871 * This routine is called when an inode is not connected to the
7874 * This subroutine returns 1 then the caller shouldn't bother with the
7875 * rest of the pass 4 tests.
7877 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7879 ext2_filsys fs = ctx->fs;
7880 struct ext2_inode inode;
7881 struct problem_context pctx;
7883 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7884 clear_problem_context(&pctx);
7886 pctx.inode = &inode;
7889 * Offer to delete any zero-length files that does not have
7890 * blocks. If there is an EA block, it might have useful
7891 * information, so we won't prompt to delete it, but let it be
7892 * reconnected to lost+found.
7894 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7895 LINUX_S_ISDIR(inode.i_mode))) {
7896 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7897 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7898 inode.i_links_count = 0;
7899 inode.i_dtime = time(0);
7900 e2fsck_write_inode(ctx, i, &inode,
7901 "disconnect_inode");
7903 * Fix up the bitmaps...
7905 e2fsck_read_bitmaps(ctx);
7906 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7907 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7908 ext2fs_inode_alloc_stats2(fs, i, -1,
7909 LINUX_S_ISDIR(inode.i_mode));
7915 * Prompt to reconnect.
7917 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7918 if (e2fsck_reconnect_file(ctx, i))
7919 ext2fs_unmark_valid(fs);
7922 * If we don't attach the inode, then skip the
7923 * i_links_test since there's no point in trying to
7924 * force i_links_count to zero.
7926 ext2fs_unmark_valid(fs);
7933 static void e2fsck_pass4(e2fsck_t ctx)
7935 ext2_filsys fs = ctx->fs;
7937 struct ext2_inode inode;
7938 struct problem_context pctx;
7939 __u16 link_count, link_counted;
7941 int group, maxgroup;
7945 clear_problem_context(&pctx);
7947 if (!(ctx->options & E2F_OPT_PREEN))
7948 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7951 maxgroup = fs->group_desc_count;
7953 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7956 for (i=1; i <= fs->super->s_inodes_count; i++) {
7957 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7959 if ((i % fs->super->s_inodes_per_group) == 0) {
7962 if ((ctx->progress)(ctx, 4, group, maxgroup))
7965 if (i == EXT2_BAD_INO ||
7966 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7968 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7969 (ctx->inode_imagic_map &&
7970 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
7971 (ctx->inode_bb_map &&
7972 ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
7974 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7975 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7976 if (link_counted == 0) {
7978 buf = e2fsck_allocate_memory(ctx,
7979 fs->blocksize, "bad_inode buffer");
7980 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7982 if (disconnect_inode(ctx, i))
7984 ext2fs_icount_fetch(ctx->inode_link_info, i,
7986 ext2fs_icount_fetch(ctx->inode_count, i,
7989 if (link_counted != link_count) {
7990 e2fsck_read_inode(ctx, i, &inode, "pass4");
7992 pctx.inode = &inode;
7993 if (link_count != inode.i_links_count) {
7994 pctx.num = link_count;
7996 PR_4_INCONSISTENT_COUNT, &pctx);
7998 pctx.num = link_counted;
7999 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
8000 inode.i_links_count = link_counted;
8001 e2fsck_write_inode(ctx, i, &inode, "pass4");
8005 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
8006 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
8007 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
8008 ctx->inode_bb_map = 0;
8009 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
8010 ctx->inode_imagic_map = 0;
8011 ext2fs_free_mem(&buf);
8015 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
8018 #define NO_BLK ((blk_t) -1)
8020 static void print_bitmap_problem(e2fsck_t ctx, int problem,
8021 struct problem_context *pctx)
8024 case PR_5_BLOCK_UNUSED:
8025 if (pctx->blk == pctx->blk2)
8028 problem = PR_5_BLOCK_RANGE_UNUSED;
8030 case PR_5_BLOCK_USED:
8031 if (pctx->blk == pctx->blk2)
8034 problem = PR_5_BLOCK_RANGE_USED;
8036 case PR_5_INODE_UNUSED:
8037 if (pctx->ino == pctx->ino2)
8040 problem = PR_5_INODE_RANGE_UNUSED;
8042 case PR_5_INODE_USED:
8043 if (pctx->ino == pctx->ino2)
8046 problem = PR_5_INODE_RANGE_USED;
8049 fix_problem(ctx, problem, pctx);
8050 pctx->blk = pctx->blk2 = NO_BLK;
8051 pctx->ino = pctx->ino2 = 0;
8054 static void check_block_bitmaps(e2fsck_t ctx)
8056 ext2_filsys fs = ctx->fs;
8060 unsigned int blocks = 0;
8061 unsigned int free_blocks = 0;
8064 struct problem_context pctx;
8065 int problem, save_problem, fixit, had_problem;
8068 clear_problem_context(&pctx);
8069 free_array = (int *) e2fsck_allocate_memory(ctx,
8070 fs->group_desc_count * sizeof(int), "free block count array");
8072 if ((fs->super->s_first_data_block <
8073 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
8074 (fs->super->s_blocks_count-1 >
8075 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
8077 pctx.blk = fs->super->s_first_data_block;
8078 pctx.blk2 = fs->super->s_blocks_count -1;
8079 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
8080 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
8081 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8083 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8087 if ((fs->super->s_first_data_block <
8088 ext2fs_get_block_bitmap_start(fs->block_map)) ||
8089 (fs->super->s_blocks_count-1 >
8090 ext2fs_get_block_bitmap_end(fs->block_map))) {
8092 pctx.blk = fs->super->s_first_data_block;
8093 pctx.blk2 = fs->super->s_blocks_count -1;
8094 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
8095 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
8096 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8098 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8105 pctx.blk = pctx.blk2 = NO_BLK;
8106 for (i = fs->super->s_first_data_block;
8107 i < fs->super->s_blocks_count;
8109 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
8110 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
8112 if (actual == bitmap)
8115 if (!actual && bitmap) {
8117 * Block not used, but marked in use in the bitmap.
8119 problem = PR_5_BLOCK_UNUSED;
8122 * Block used, but not marked in use in the bitmap.
8124 problem = PR_5_BLOCK_USED;
8126 if (pctx.blk == NO_BLK) {
8127 pctx.blk = pctx.blk2 = i;
8128 save_problem = problem;
8130 if ((problem == save_problem) &&
8134 print_bitmap_problem(ctx, save_problem, &pctx);
8135 pctx.blk = pctx.blk2 = i;
8136 save_problem = problem;
8139 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
8148 if ((blocks == fs->super->s_blocks_per_group) ||
8149 (i == fs->super->s_blocks_count-1)) {
8150 free_array[group] = group_free;
8155 if ((ctx->progress)(ctx, 5, group,
8156 fs->group_desc_count*2))
8160 if (pctx.blk != NO_BLK)
8161 print_bitmap_problem(ctx, save_problem, &pctx);
8163 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
8166 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
8169 ext2fs_free_block_bitmap(fs->block_map);
8170 retval = ext2fs_copy_bitmap(ctx->block_found_map,
8173 clear_problem_context(&pctx);
8174 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
8175 ctx->flags |= E2F_FLAG_ABORT;
8178 ext2fs_set_bitmap_padding(fs->block_map);
8179 ext2fs_mark_bb_dirty(fs);
8181 /* Redo the counts */
8182 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
8183 memset(free_array, 0, fs->group_desc_count * sizeof(int));
8185 } else if (fixit == 0)
8186 ext2fs_unmark_valid(fs);
8188 for (i = 0; i < fs->group_desc_count; i++) {
8189 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
8191 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
8192 pctx.blk2 = free_array[i];
8194 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
8196 fs->group_desc[i].bg_free_blocks_count =
8198 ext2fs_mark_super_dirty(fs);
8200 ext2fs_unmark_valid(fs);
8203 if (free_blocks != fs->super->s_free_blocks_count) {
8205 pctx.blk = fs->super->s_free_blocks_count;
8206 pctx.blk2 = free_blocks;
8208 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
8209 fs->super->s_free_blocks_count = free_blocks;
8210 ext2fs_mark_super_dirty(fs);
8212 ext2fs_unmark_valid(fs);
8214 ext2fs_free_mem(&free_array);
8217 static void check_inode_bitmaps(e2fsck_t ctx)
8219 ext2_filsys fs = ctx->fs;
8221 unsigned int free_inodes = 0;
8225 unsigned int inodes = 0;
8230 struct problem_context pctx;
8231 int problem, save_problem, fixit, had_problem;
8233 clear_problem_context(&pctx);
8234 free_array = (int *) e2fsck_allocate_memory(ctx,
8235 fs->group_desc_count * sizeof(int), "free inode count array");
8237 dir_array = (int *) e2fsck_allocate_memory(ctx,
8238 fs->group_desc_count * sizeof(int), "directory count array");
8240 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
8241 (fs->super->s_inodes_count >
8242 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
8245 pctx.blk2 = fs->super->s_inodes_count;
8246 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
8247 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
8248 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8250 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8253 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
8254 (fs->super->s_inodes_count >
8255 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
8258 pctx.blk2 = fs->super->s_inodes_count;
8259 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
8260 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
8261 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8263 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8270 pctx.ino = pctx.ino2 = 0;
8271 for (i = 1; i <= fs->super->s_inodes_count; i++) {
8272 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
8273 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
8275 if (actual == bitmap)
8278 if (!actual && bitmap) {
8280 * Inode wasn't used, but marked in bitmap
8282 problem = PR_5_INODE_UNUSED;
8283 } else /* if (actual && !bitmap) */ {
8285 * Inode used, but not in bitmap
8287 problem = PR_5_INODE_USED;
8289 if (pctx.ino == 0) {
8290 pctx.ino = pctx.ino2 = i;
8291 save_problem = problem;
8293 if ((problem == save_problem) &&
8297 print_bitmap_problem(ctx, save_problem, &pctx);
8298 pctx.ino = pctx.ino2 = i;
8299 save_problem = problem;
8302 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
8310 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
8314 if ((inodes == fs->super->s_inodes_per_group) ||
8315 (i == fs->super->s_inodes_count)) {
8316 free_array[group] = group_free;
8317 dir_array[group] = dirs_count;
8323 if ((ctx->progress)(ctx, 5,
8324 group + fs->group_desc_count,
8325 fs->group_desc_count*2))
8330 print_bitmap_problem(ctx, save_problem, &pctx);
8333 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
8336 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
8339 ext2fs_free_inode_bitmap(fs->inode_map);
8340 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
8343 clear_problem_context(&pctx);
8344 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
8345 ctx->flags |= E2F_FLAG_ABORT;
8348 ext2fs_set_bitmap_padding(fs->inode_map);
8349 ext2fs_mark_ib_dirty(fs);
8352 inodes = 0; free_inodes = 0; group_free = 0;
8353 dirs_count = 0; group = 0;
8354 memset(free_array, 0, fs->group_desc_count * sizeof(int));
8355 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
8357 } else if (fixit == 0)
8358 ext2fs_unmark_valid(fs);
8360 for (i = 0; i < fs->group_desc_count; i++) {
8361 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
8363 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
8364 pctx.ino2 = free_array[i];
8365 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
8367 fs->group_desc[i].bg_free_inodes_count =
8369 ext2fs_mark_super_dirty(fs);
8371 ext2fs_unmark_valid(fs);
8373 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
8375 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
8376 pctx.ino2 = dir_array[i];
8378 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
8380 fs->group_desc[i].bg_used_dirs_count =
8382 ext2fs_mark_super_dirty(fs);
8384 ext2fs_unmark_valid(fs);
8387 if (free_inodes != fs->super->s_free_inodes_count) {
8389 pctx.ino = fs->super->s_free_inodes_count;
8390 pctx.ino2 = free_inodes;
8392 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
8393 fs->super->s_free_inodes_count = free_inodes;
8394 ext2fs_mark_super_dirty(fs);
8396 ext2fs_unmark_valid(fs);
8398 ext2fs_free_mem(&free_array);
8399 ext2fs_free_mem(&dir_array);
8402 static void check_inode_end(e2fsck_t ctx)
8404 ext2_filsys fs = ctx->fs;
8405 ext2_ino_t end, save_inodes_count, i;
8406 struct problem_context pctx;
8408 clear_problem_context(&pctx);
8410 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8411 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8412 &save_inodes_count);
8415 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8416 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8419 if (save_inodes_count == end)
8422 for (i = save_inodes_count + 1; i <= end; i++) {
8423 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8424 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8425 for (i = save_inodes_count + 1; i <= end; i++)
8426 ext2fs_mark_inode_bitmap(fs->inode_map,
8428 ext2fs_mark_ib_dirty(fs);
8430 ext2fs_unmark_valid(fs);
8435 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8436 save_inodes_count, 0);
8439 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8440 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8445 static void check_block_end(e2fsck_t ctx)
8447 ext2_filsys fs = ctx->fs;
8448 blk_t end, save_blocks_count, i;
8449 struct problem_context pctx;
8451 clear_problem_context(&pctx);
8453 end = fs->block_map->start +
8454 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8455 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8456 &save_blocks_count);
8459 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8460 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8463 if (save_blocks_count == end)
8466 for (i = save_blocks_count + 1; i <= end; i++) {
8467 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8468 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8469 for (i = save_blocks_count + 1; i <= end; i++)
8470 ext2fs_mark_block_bitmap(fs->block_map,
8472 ext2fs_mark_bb_dirty(fs);
8474 ext2fs_unmark_valid(fs);
8479 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8480 save_blocks_count, 0);
8483 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8484 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8489 static void e2fsck_pass5(e2fsck_t ctx)
8491 struct problem_context pctx;
8495 clear_problem_context(&pctx);
8497 if (!(ctx->options & E2F_OPT_PREEN))
8498 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8501 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8504 e2fsck_read_bitmaps(ctx);
8506 check_block_bitmaps(ctx);
8507 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8509 check_inode_bitmaps(ctx);
8510 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8512 check_inode_end(ctx);
8513 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8515 check_block_end(ctx);
8516 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8519 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8520 ctx->inode_used_map = 0;
8521 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8522 ctx->inode_dir_map = 0;
8523 ext2fs_free_block_bitmap(ctx->block_found_map);
8524 ctx->block_found_map = 0;
8528 * problem.c --- report filesystem problems to the user
8531 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8532 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8533 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8534 #define PR_MSG_ONLY 0x000008 /* Print message only */
8536 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8538 #define PR_FATAL 0x001000 /* Fatal error */
8539 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8541 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8542 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8543 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8544 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8545 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8548 #define PROMPT_NONE 0
8549 #define PROMPT_FIX 1
8550 #define PROMPT_CLEAR 2
8551 #define PROMPT_RELOCATE 3
8552 #define PROMPT_ALLOCATE 4
8553 #define PROMPT_EXPAND 5
8554 #define PROMPT_CONNECT 6
8555 #define PROMPT_CREATE 7
8556 #define PROMPT_SALVAGE 8
8557 #define PROMPT_TRUNCATE 9
8558 #define PROMPT_CLEAR_INODE 10
8559 #define PROMPT_ABORT 11
8560 #define PROMPT_SPLIT 12
8561 #define PROMPT_CONTINUE 13
8562 #define PROMPT_CLONE 14
8563 #define PROMPT_DELETE 15
8564 #define PROMPT_SUPPRESS 16
8565 #define PROMPT_UNLINK 17
8566 #define PROMPT_CLEAR_HTREE 18
8567 #define PROMPT_RECREATE 19
8568 #define PROMPT_NULL 20
8570 struct e2fsck_problem {
8572 const char * e2p_description;
8575 problem_t second_code;
8578 struct latch_descr {
8581 problem_t end_message;
8586 * These are the prompts which are used to ask the user if they want
8589 static const char * const prompt[] = {
8590 N_("(no prompt)"), /* 0 */
8592 N_("Clear"), /* 2 */
8593 N_("Relocate"), /* 3 */
8594 N_("Allocate"), /* 4 */
8595 N_("Expand"), /* 5 */
8596 N_("Connect to /lost+found"), /* 6 */
8597 N_("Create"), /* 7 */
8598 N_("Salvage"), /* 8 */
8599 N_("Truncate"), /* 9 */
8600 N_("Clear inode"), /* 10 */
8601 N_("Abort"), /* 11 */
8602 N_("Split"), /* 12 */
8603 N_("Continue"), /* 13 */
8604 N_("Clone multiply-claimed blocks"), /* 14 */
8605 N_("Delete file"), /* 15 */
8606 N_("Suppress messages"),/* 16 */
8607 N_("Unlink"), /* 17 */
8608 N_("Clear HTree index"),/* 18 */
8609 N_("Recreate"), /* 19 */
8614 * These messages are printed when we are preen mode and we will be
8615 * automatically fixing the problem.
8617 static const char * const preen_msg[] = {
8618 N_("(NONE)"), /* 0 */
8619 N_("FIXED"), /* 1 */
8620 N_("CLEARED"), /* 2 */
8621 N_("RELOCATED"), /* 3 */
8622 N_("ALLOCATED"), /* 4 */
8623 N_("EXPANDED"), /* 5 */
8624 N_("RECONNECTED"), /* 6 */
8625 N_("CREATED"), /* 7 */
8626 N_("SALVAGED"), /* 8 */
8627 N_("TRUNCATED"), /* 9 */
8628 N_("INODE CLEARED"), /* 10 */
8629 N_("ABORTED"), /* 11 */
8630 N_("SPLIT"), /* 12 */
8631 N_("CONTINUING"), /* 13 */
8632 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8633 N_("FILE DELETED"), /* 15 */
8634 N_("SUPPRESSED"), /* 16 */
8635 N_("UNLINKED"), /* 17 */
8636 N_("HTREE INDEX CLEARED"),/* 18 */
8637 N_("WILL RECREATE"), /* 19 */
8641 static const struct e2fsck_problem problem_table[] = {
8643 /* Pre-Pass 1 errors */
8645 /* Block bitmap not in group */
8646 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8647 PROMPT_RELOCATE, PR_LATCH_RELOC },
8649 /* Inode bitmap not in group */
8650 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8651 PROMPT_RELOCATE, PR_LATCH_RELOC },
8653 /* Inode table not in group */
8654 { PR_0_ITABLE_NOT_GROUP,
8655 N_("@i table for @g %g is not in @g. (@b %b)\n"
8656 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8657 PROMPT_RELOCATE, PR_LATCH_RELOC },
8659 /* Superblock corrupt */
8661 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8662 "@f. If the @v is valid and it really contains an ext2\n"
8663 "@f (and not swap or ufs or something else), then the @S\n"
8664 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8665 " e2fsck -b %S <@v>\n\n"),
8666 PROMPT_NONE, PR_FATAL },
8668 /* Filesystem size is wrong */
8669 { PR_0_FS_SIZE_WRONG,
8670 N_("The @f size (according to the @S) is %b @bs\n"
8671 "The physical size of the @v is %c @bs\n"
8672 "Either the @S or the partition table is likely to be corrupt!\n"),
8675 /* Fragments not supported */
8676 { PR_0_NO_FRAGMENTS,
8677 N_("@S @b_size = %b, fragsize = %c.\n"
8678 "This version of e2fsck does not support fragment sizes different\n"
8679 "from the @b size.\n"),
8680 PROMPT_NONE, PR_FATAL },
8682 /* Bad blocks_per_group */
8683 { PR_0_BLOCKS_PER_GROUP,
8684 N_("@S @bs_per_group = %b, should have been %c\n"),
8685 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8687 /* Bad first_data_block */
8688 { PR_0_FIRST_DATA_BLOCK,
8689 N_("@S first_data_@b = %b, should have been %c\n"),
8690 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8692 /* Adding UUID to filesystem */
8694 N_("@f did not have a UUID; generating one.\n\n"),
8698 { PR_0_RELOCATE_HINT,
8699 N_("Note: if several inode or block bitmap blocks or part\n"
8700 "of the inode table require relocation, you may wish to try\n"
8701 "running e2fsck with the '-b %S' option first. The problem\n"
8702 "may lie only with the primary block group descriptors, and\n"
8703 "the backup block group descriptors may be OK.\n\n"),
8704 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8706 /* Miscellaneous superblock corruption */
8707 { PR_0_MISC_CORRUPT_SUPER,
8708 N_("Corruption found in @S. (%s = %N).\n"),
8709 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8711 /* Error determing physical device size of filesystem */
8712 { PR_0_GETSIZE_ERROR,
8713 N_("Error determining size of the physical @v: %m\n"),
8714 PROMPT_NONE, PR_FATAL },
8716 /* Inode count in superblock is incorrect */
8717 { PR_0_INODE_COUNT_WRONG,
8718 N_("@i count in @S is %i, @s %j.\n"),
8721 { PR_0_HURD_CLEAR_FILETYPE,
8722 N_("The Hurd does not support the filetype feature.\n"),
8725 /* Journal inode is invalid */
8726 { PR_0_JOURNAL_BAD_INODE,
8727 N_("@S has an @n ext3 @j (@i %i).\n"),
8728 PROMPT_CLEAR, PR_PREEN_OK },
8730 /* The external journal has (unsupported) multiple filesystems */
8731 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8732 N_("External @j has multiple @f users (unsupported).\n"),
8733 PROMPT_NONE, PR_FATAL },
8735 /* Can't find external journal */
8736 { PR_0_CANT_FIND_JOURNAL,
8737 N_("Can't find external @j\n"),
8738 PROMPT_NONE, PR_FATAL },
8740 /* External journal has bad superblock */
8741 { PR_0_EXT_JOURNAL_BAD_SUPER,
8742 N_("External @j has bad @S\n"),
8743 PROMPT_NONE, PR_FATAL },
8745 /* Superblock has a bad journal UUID */
8746 { PR_0_JOURNAL_BAD_UUID,
8747 N_("External @j does not support this @f\n"),
8748 PROMPT_NONE, PR_FATAL },
8750 /* Journal has an unknown superblock type */
8751 { PR_0_JOURNAL_UNSUPP_SUPER,
8752 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8753 "It is likely that your copy of e2fsck is old and/or doesn't "
8754 "support this @j format.\n"
8755 "It is also possible the @j @S is corrupt.\n"),
8756 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8758 /* Journal superblock is corrupt */
8759 { PR_0_JOURNAL_BAD_SUPER,
8760 N_("Ext3 @j @S is corrupt.\n"),
8761 PROMPT_FIX, PR_PREEN_OK },
8763 /* Superblock flag should be cleared */
8764 { PR_0_JOURNAL_HAS_JOURNAL,
8765 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8766 PROMPT_CLEAR, PR_PREEN_OK },
8768 /* Superblock flag is incorrect */
8769 { PR_0_JOURNAL_RECOVER_SET,
8770 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8771 PROMPT_CLEAR, PR_PREEN_OK },
8773 /* Journal has data, but recovery flag is clear */
8774 { PR_0_JOURNAL_RECOVERY_CLEAR,
8775 N_("ext3 recovery flag is clear, but @j has data.\n"),
8778 /* Ask if we should clear the journal */
8779 { PR_0_JOURNAL_RESET_JOURNAL,
8781 PROMPT_NULL, PR_PREEN_NOMSG },
8783 /* Ask if we should run the journal anyway */
8785 N_("Run @j anyway"),
8788 /* Run the journal by default */
8789 { PR_0_JOURNAL_RUN_DEFAULT,
8790 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8793 /* Clearing orphan inode */
8794 { PR_0_ORPHAN_CLEAR_INODE,
8795 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8798 /* Illegal block found in orphaned inode */
8799 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8800 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8803 /* Already cleared block found in orphaned inode */
8804 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8805 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8808 /* Illegal orphan inode in superblock */
8809 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8810 N_("@I @o @i %i in @S.\n"),
8813 /* Illegal inode in orphaned inode list */
8814 { PR_0_ORPHAN_ILLEGAL_INODE,
8815 N_("@I @i %i in @o @i list.\n"),
8818 /* Filesystem revision is 0, but feature flags are set */
8819 { PR_0_FS_REV_LEVEL,
8820 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8821 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8823 /* Journal superblock has an unknown read-only feature flag set */
8824 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8825 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8828 /* Journal superblock has an unknown incompatible feature flag set */
8829 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8830 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8833 /* Journal has unsupported version number */
8834 { PR_0_JOURNAL_UNSUPP_VERSION,
8835 N_("@j version not supported by this e2fsck.\n"),
8838 /* Moving journal to hidden file */
8839 { PR_0_MOVE_JOURNAL,
8840 N_("Moving @j from /%s to hidden @i.\n\n"),
8843 /* Error moving journal to hidden file */
8844 { PR_0_ERR_MOVE_JOURNAL,
8845 N_("Error moving @j: %m\n\n"),
8848 /* Clearing V2 journal superblock */
8849 { PR_0_CLEAR_V2_JOURNAL,
8850 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8851 "Clearing fields beyond the V1 @j @S...\n\n"),
8854 /* Backup journal inode blocks */
8856 N_("Backing up @j @i @b information.\n\n"),
8859 /* Reserved blocks w/o resize_inode */
8860 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8861 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8862 "is %N; @s zero. "),
8865 /* Resize_inode not enabled, but resize inode is non-zero */
8866 { PR_0_CLEAR_RESIZE_INODE,
8867 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8870 /* Resize inode invalid */
8871 { PR_0_RESIZE_INODE_INVALID,
8872 N_("Resize @i not valid. "),
8873 PROMPT_RECREATE, 0 },
8877 /* Pass 1: Checking inodes, blocks, and sizes */
8879 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8882 /* Root directory is not an inode */
8883 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8886 /* Root directory has dtime set */
8888 N_("@r has dtime set (probably due to old mke2fs). "),
8889 PROMPT_FIX, PR_PREEN_OK },
8891 /* Reserved inode has bad mode */
8892 { PR_1_RESERVED_BAD_MODE,
8893 N_("Reserved @i %i (%Q) has @n mode. "),
8894 PROMPT_CLEAR, PR_PREEN_OK },
8896 /* Deleted inode has zero dtime */
8898 N_("@D @i %i has zero dtime. "),
8899 PROMPT_FIX, PR_PREEN_OK },
8901 /* Inode in use, but dtime set */
8903 N_("@i %i is in use, but has dtime set. "),
8904 PROMPT_FIX, PR_PREEN_OK },
8906 /* Zero-length directory */
8907 { PR_1_ZERO_LENGTH_DIR,
8908 N_("@i %i is a @z @d. "),
8909 PROMPT_CLEAR, PR_PREEN_OK },
8911 /* Block bitmap conflicts with some other fs block */
8913 N_("@g %g's @b @B at %b @C.\n"),
8914 PROMPT_RELOCATE, 0 },
8916 /* Inode bitmap conflicts with some other fs block */
8918 N_("@g %g's @i @B at %b @C.\n"),
8919 PROMPT_RELOCATE, 0 },
8921 /* Inode table conflicts with some other fs block */
8922 { PR_1_ITABLE_CONFLICT,
8923 N_("@g %g's @i table at %b @C.\n"),
8924 PROMPT_RELOCATE, 0 },
8926 /* Block bitmap is on a bad block */
8927 { PR_1_BB_BAD_BLOCK,
8928 N_("@g %g's @b @B (%b) is bad. "),
8929 PROMPT_RELOCATE, 0 },
8931 /* Inode bitmap is on a bad block */
8932 { PR_1_IB_BAD_BLOCK,
8933 N_("@g %g's @i @B (%b) is bad. "),
8934 PROMPT_RELOCATE, 0 },
8936 /* Inode has incorrect i_size */
8938 N_("@i %i, i_size is %Is, @s %N. "),
8939 PROMPT_FIX, PR_PREEN_OK },
8941 /* Inode has incorrect i_blocks */
8942 { PR_1_BAD_I_BLOCKS,
8943 N_("@i %i, i_@bs is %Ib, @s %N. "),
8944 PROMPT_FIX, PR_PREEN_OK },
8946 /* Illegal blocknumber in inode */
8947 { PR_1_ILLEGAL_BLOCK_NUM,
8948 N_("@I @b #%B (%b) in @i %i. "),
8949 PROMPT_CLEAR, PR_LATCH_BLOCK },
8951 /* Block number overlaps fs metadata */
8952 { PR_1_BLOCK_OVERLAPS_METADATA,
8953 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8954 PROMPT_CLEAR, PR_LATCH_BLOCK },
8956 /* Inode has illegal blocks (latch question) */
8957 { PR_1_INODE_BLOCK_LATCH,
8958 N_("@i %i has illegal @b(s). "),
8961 /* Too many bad blocks in inode */
8962 { PR_1_TOO_MANY_BAD_BLOCKS,
8963 N_("Too many illegal @bs in @i %i.\n"),
8964 PROMPT_CLEAR_INODE, PR_NO_OK },
8966 /* Illegal block number in bad block inode */
8967 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8968 N_("@I @b #%B (%b) in bad @b @i. "),
8969 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8971 /* Bad block inode has illegal blocks (latch question) */
8972 { PR_1_INODE_BBLOCK_LATCH,
8973 N_("Bad @b @i has illegal @b(s). "),
8976 /* Duplicate or bad blocks in use! */
8977 { PR_1_DUP_BLOCKS_PREENSTOP,
8978 N_("Duplicate or bad @b in use!\n"),
8981 /* Bad block used as bad block indirect block */
8982 { PR_1_BBINODE_BAD_METABLOCK,
8983 N_("Bad @b %b used as bad @b @i indirect @b. "),
8984 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8986 /* Inconsistency can't be fixed prompt */
8987 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8988 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8989 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8991 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8993 /* Bad primary block */
8994 { PR_1_BAD_PRIMARY_BLOCK,
8995 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
8996 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8998 /* Bad primary block prompt */
8999 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
9000 N_("You can remove this @b from the bad @b list and hope\n"
9001 "that the @b is really OK. But there are no guarantees.\n\n"),
9002 PROMPT_CLEAR, PR_PREEN_NOMSG },
9004 /* Bad primary superblock */
9005 { PR_1_BAD_PRIMARY_SUPERBLOCK,
9006 N_("The primary @S (%b) is on the bad @b list.\n"),
9007 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9009 /* Bad primary block group descriptors */
9010 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
9011 N_("Block %b in the primary @g descriptors "
9012 "is on the bad @b list\n"),
9013 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9015 /* Bad superblock in group */
9016 { PR_1_BAD_SUPERBLOCK,
9017 N_("Warning: Group %g's @S (%b) is bad.\n"),
9018 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9020 /* Bad block group descriptors in group */
9021 { PR_1_BAD_GROUP_DESCRIPTORS,
9022 N_("Warning: Group %g's copy of the @g descriptors has a bad "
9024 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9026 /* Block claimed for no reason */
9027 { PR_1_PROGERR_CLAIMED_BLOCK,
9028 N_("Programming error? @b #%b claimed for no reason in "
9029 "process_bad_@b.\n"),
9030 PROMPT_NONE, PR_PREEN_OK },
9032 /* Error allocating blocks for relocating metadata */
9033 { PR_1_RELOC_BLOCK_ALLOCATE,
9034 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
9035 PROMPT_NONE, PR_PREEN_OK },
9037 /* Error allocating block buffer during relocation process */
9038 { PR_1_RELOC_MEMORY_ALLOCATE,
9039 N_("@A @b buffer for relocating %s\n"),
9040 PROMPT_NONE, PR_PREEN_OK },
9042 /* Relocating metadata group information from X to Y */
9043 { PR_1_RELOC_FROM_TO,
9044 N_("Relocating @g %g's %s from %b to %c...\n"),
9045 PROMPT_NONE, PR_PREEN_OK },
9047 /* Relocating metatdata group information to X */
9049 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
9050 PROMPT_NONE, PR_PREEN_OK },
9052 /* Block read error during relocation process */
9053 { PR_1_RELOC_READ_ERR,
9054 N_("Warning: could not read @b %b of %s: %m\n"),
9055 PROMPT_NONE, PR_PREEN_OK },
9057 /* Block write error during relocation process */
9058 { PR_1_RELOC_WRITE_ERR,
9059 N_("Warning: could not write @b %b for %s: %m\n"),
9060 PROMPT_NONE, PR_PREEN_OK },
9062 /* Error allocating inode bitmap */
9063 { PR_1_ALLOCATE_IBITMAP_ERROR,
9064 N_("@A @i @B (%N): %m\n"),
9065 PROMPT_NONE, PR_FATAL },
9067 /* Error allocating block bitmap */
9068 { PR_1_ALLOCATE_BBITMAP_ERROR,
9069 N_("@A @b @B (%N): %m\n"),
9070 PROMPT_NONE, PR_FATAL },
9072 /* Error allocating icount structure */
9073 { PR_1_ALLOCATE_ICOUNT,
9074 N_("@A icount link information: %m\n"),
9075 PROMPT_NONE, PR_FATAL },
9077 /* Error allocating dbcount */
9078 { PR_1_ALLOCATE_DBCOUNT,
9079 N_("@A @d @b array: %m\n"),
9080 PROMPT_NONE, PR_FATAL },
9082 /* Error while scanning inodes */
9084 N_("Error while scanning @is (%i): %m\n"),
9085 PROMPT_NONE, PR_FATAL },
9087 /* Error while iterating over blocks */
9088 { PR_1_BLOCK_ITERATE,
9089 N_("Error while iterating over @bs in @i %i: %m\n"),
9090 PROMPT_NONE, PR_FATAL },
9092 /* Error while storing inode count information */
9093 { PR_1_ICOUNT_STORE,
9094 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
9095 PROMPT_NONE, PR_FATAL },
9097 /* Error while storing directory block information */
9099 N_("Error storing @d @b information "
9100 "(@i=%i, @b=%b, num=%N): %m\n"),
9101 PROMPT_NONE, PR_FATAL },
9103 /* Error while reading inode (for clearing) */
9105 N_("Error reading @i %i: %m\n"),
9106 PROMPT_NONE, PR_FATAL },
9108 /* Suppress messages prompt */
9109 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
9111 /* Imagic flag set on an inode when filesystem doesn't support it */
9113 N_("@i %i has imagic flag set. "),
9116 /* Immutable flag set on a device or socket inode */
9117 { PR_1_SET_IMMUTABLE,
9118 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
9119 "or append-only flag set. "),
9120 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
9122 /* Compression flag set on an inode when filesystem doesn't support it */
9124 N_("@i %i has @cion flag set on @f without @cion support. "),
9127 /* Non-zero size for device, fifo or socket inode */
9128 { PR_1_SET_NONZSIZE,
9129 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
9130 PROMPT_FIX, PR_PREEN_OK },
9132 /* Filesystem revision is 0, but feature flags are set */
9133 { PR_1_FS_REV_LEVEL,
9134 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
9135 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
9137 /* Journal inode is not in use, but contains data */
9138 { PR_1_JOURNAL_INODE_NOT_CLEAR,
9139 N_("@j @i is not in use, but contains data. "),
9140 PROMPT_CLEAR, PR_PREEN_OK },
9142 /* Journal has bad mode */
9143 { PR_1_JOURNAL_BAD_MODE,
9144 N_("@j is not regular file. "),
9145 PROMPT_FIX, PR_PREEN_OK },
9147 /* Deal with inodes that were part of orphan linked list */
9149 N_("@i %i was part of the @o @i list. "),
9150 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
9152 /* Deal with inodes that were part of corrupted orphan linked
9153 list (latch question) */
9154 { PR_1_ORPHAN_LIST_REFUGEES,
9155 N_("@is that were part of a corrupted orphan linked list found. "),
9158 /* Error allocating refcount structure */
9159 { PR_1_ALLOCATE_REFCOUNT,
9160 N_("@A refcount structure (%N): %m\n"),
9161 PROMPT_NONE, PR_FATAL },
9163 /* Error reading extended attribute block */
9164 { PR_1_READ_EA_BLOCK,
9165 N_("Error reading @a @b %b for @i %i. "),
9168 /* Invalid extended attribute block */
9169 { PR_1_BAD_EA_BLOCK,
9170 N_("@i %i has a bad @a @b %b. "),
9173 /* Error reading Extended Attribute block while fixing refcount */
9174 { PR_1_EXTATTR_READ_ABORT,
9175 N_("Error reading @a @b %b (%m). "),
9178 /* Extended attribute reference count incorrect */
9179 { PR_1_EXTATTR_REFCOUNT,
9180 N_("@a @b %b has reference count %B, @s %N. "),
9183 /* Error writing Extended Attribute block while fixing refcount */
9184 { PR_1_EXTATTR_WRITE,
9185 N_("Error writing @a @b %b (%m). "),
9188 /* Multiple EA blocks not supported */
9189 { PR_1_EA_MULTI_BLOCK,
9190 N_("@a @b %b has h_@bs > 1. "),
9193 /* Error allocating EA region allocation structure */
9194 { PR_1_EA_ALLOC_REGION,
9195 N_("@A @a @b %b. "),
9198 /* Error EA allocation collision */
9199 { PR_1_EA_ALLOC_COLLISION,
9200 N_("@a @b %b is corrupt (allocation collision). "),
9203 /* Bad extended attribute name */
9205 N_("@a @b %b is corrupt (@n name). "),
9208 /* Bad extended attribute value */
9209 { PR_1_EA_BAD_VALUE,
9210 N_("@a @b %b is corrupt (@n value). "),
9213 /* Inode too big (latch question) */
9214 { PR_1_INODE_TOOBIG,
9215 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
9217 /* Directory too big */
9219 N_("@b #%B (%b) causes @d to be too big. "),
9220 PROMPT_CLEAR, PR_LATCH_TOOBIG },
9222 /* Regular file too big */
9224 N_("@b #%B (%b) causes file to be too big. "),
9225 PROMPT_CLEAR, PR_LATCH_TOOBIG },
9227 /* Symlink too big */
9228 { PR_1_TOOBIG_SYMLINK,
9229 N_("@b #%B (%b) causes symlink to be too big. "),
9230 PROMPT_CLEAR, PR_LATCH_TOOBIG },
9232 /* INDEX_FL flag set on a non-HTREE filesystem */
9234 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
9235 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9237 /* INDEX_FL flag set on a non-directory */
9239 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
9240 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9242 /* Invalid root node in HTREE directory */
9243 { PR_1_HTREE_BADROOT,
9244 N_("@h %i has an @n root node.\n"),
9245 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9247 /* Unsupported hash version in HTREE directory */
9249 N_("@h %i has an unsupported hash version (%N)\n"),
9250 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9252 /* Incompatible flag in HTREE root node */
9253 { PR_1_HTREE_INCOMPAT,
9254 N_("@h %i uses an incompatible htree root node flag.\n"),
9255 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9257 /* HTREE too deep */
9259 N_("@h %i has a tree depth (%N) which is too big\n"),
9260 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9262 /* Bad block has indirect block that conflicts with filesystem block */
9264 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
9266 PROMPT_CLEAR, PR_LATCH_BBLOCK },
9268 /* Resize inode failed */
9269 { PR_1_RESIZE_INODE_CREATE,
9270 N_("Resize @i (re)creation failed: %m."),
9273 /* invalid inode->i_extra_isize */
9275 N_("@i %i has a extra size (%IS) which is @n\n"),
9276 PROMPT_FIX, PR_PREEN_OK },
9278 /* invalid ea entry->e_name_len */
9279 { PR_1_ATTR_NAME_LEN,
9280 N_("@a in @i %i has a namelen (%N) which is @n\n"),
9281 PROMPT_CLEAR, PR_PREEN_OK },
9283 /* invalid ea entry->e_value_size */
9284 { PR_1_ATTR_VALUE_SIZE,
9285 N_("@a in @i %i has a value size (%N) which is @n\n"),
9286 PROMPT_CLEAR, PR_PREEN_OK },
9288 /* invalid ea entry->e_value_offs */
9289 { PR_1_ATTR_VALUE_OFFSET,
9290 N_("@a in @i %i has a value offset (%N) which is @n\n"),
9291 PROMPT_CLEAR, PR_PREEN_OK },
9293 /* invalid ea entry->e_value_block */
9294 { PR_1_ATTR_VALUE_BLOCK,
9295 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
9296 PROMPT_CLEAR, PR_PREEN_OK },
9298 /* invalid ea entry->e_hash */
9300 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
9301 PROMPT_CLEAR, PR_PREEN_OK },
9303 /* Pass 1b errors */
9305 /* Pass 1B: Rescan for duplicate/bad blocks */
9306 { PR_1B_PASS_HEADER,
9307 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
9308 "Pass 1B: Rescanning for @m @bs\n"),
9311 /* Duplicate/bad block(s) header */
9312 { PR_1B_DUP_BLOCK_HEADER,
9313 N_("@m @b(s) in @i %i:"),
9316 /* Duplicate/bad block(s) in inode */
9319 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
9321 /* Duplicate/bad block(s) end */
9322 { PR_1B_DUP_BLOCK_END,
9324 PROMPT_NONE, PR_PREEN_NOHDR },
9326 /* Error while scanning inodes */
9327 { PR_1B_ISCAN_ERROR,
9328 N_("Error while scanning inodes (%i): %m\n"),
9329 PROMPT_NONE, PR_FATAL },
9331 /* Error allocating inode bitmap */
9332 { PR_1B_ALLOCATE_IBITMAP_ERROR,
9333 N_("@A @i @B (@i_dup_map): %m\n"),
9334 PROMPT_NONE, PR_FATAL },
9336 /* Error while iterating over blocks */
9337 { PR_1B_BLOCK_ITERATE,
9338 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
9341 /* Error adjusting EA refcount */
9342 { PR_1B_ADJ_EA_REFCOUNT,
9343 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9347 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
9348 { PR_1C_PASS_HEADER,
9349 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
9353 /* Pass 1D: Reconciling multiply-claimed blocks */
9354 { PR_1D_PASS_HEADER,
9355 N_("Pass 1D: Reconciling @m @bs\n"),
9358 /* File has duplicate blocks */
9360 N_("File %Q (@i #%i, mod time %IM) \n"
9361 " has %B @m @b(s), shared with %N file(s):\n"),
9364 /* List of files sharing duplicate blocks */
9365 { PR_1D_DUP_FILE_LIST,
9366 N_("\t%Q (@i #%i, mod time %IM)\n"),
9369 /* File sharing blocks with filesystem metadata */
9370 { PR_1D_SHARE_METADATA,
9371 N_("\t<@f metadata>\n"),
9374 /* Report of how many duplicate/bad inodes */
9375 { PR_1D_NUM_DUP_INODES,
9376 N_("(There are %N @is containing @m @bs.)\n\n"),
9379 /* Duplicated blocks already reassigned or cloned. */
9380 { PR_1D_DUP_BLOCKS_DEALT,
9381 N_("@m @bs already reassigned or cloned.\n\n"),
9384 /* Clone duplicate/bad blocks? */
9385 { PR_1D_CLONE_QUESTION,
9386 "", PROMPT_CLONE, PR_NO_OK },
9389 { PR_1D_DELETE_QUESTION,
9390 "", PROMPT_DELETE, 0 },
9392 /* Couldn't clone file (error) */
9393 { PR_1D_CLONE_ERROR,
9394 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
9398 /* Pass 2: Checking directory structure */
9400 N_("Pass 2: Checking @d structure\n"),
9403 /* Bad inode number for '.' */
9404 { PR_2_BAD_INODE_DOT,
9405 N_("@n @i number for '.' in @d @i %i.\n"),
9408 /* Directory entry has bad inode number */
9410 N_("@E has @n @i #: %Di.\n"),
9413 /* Directory entry has deleted or unused inode */
9414 { PR_2_UNUSED_INODE,
9415 N_("@E has @D/unused @i %Di. "),
9416 PROMPT_CLEAR, PR_PREEN_OK },
9418 /* Directry entry is link to '.' */
9420 N_("@E @L to '.' "),
9423 /* Directory entry points to inode now located in a bad block */
9425 N_("@E points to @i (%Di) located in a bad @b.\n"),
9428 /* Directory entry contains a link to a directory */
9430 N_("@E @L to @d %P (%Di).\n"),
9433 /* Directory entry contains a link to the root directry */
9435 N_("@E @L to the @r.\n"),
9438 /* Directory entry has illegal characters in its name */
9440 N_("@E has illegal characters in its name.\n"),
9443 /* Missing '.' in directory inode */
9445 N_("Missing '.' in @d @i %i.\n"),
9448 /* Missing '..' in directory inode */
9449 { PR_2_MISSING_DOT_DOT,
9450 N_("Missing '..' in @d @i %i.\n"),
9453 /* First entry in directory inode doesn't contain '.' */
9455 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9458 /* Second entry in directory inode doesn't contain '..' */
9459 { PR_2_2ND_NOT_DOT_DOT,
9460 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9463 /* i_faddr should be zero */
9465 N_("i_faddr @F %IF, @s zero.\n"),
9468 /* i_file_acl should be zero */
9469 { PR_2_FILE_ACL_ZERO,
9470 N_("i_file_acl @F %If, @s zero.\n"),
9473 /* i_dir_acl should be zero */
9474 { PR_2_DIR_ACL_ZERO,
9475 N_("i_dir_acl @F %Id, @s zero.\n"),
9478 /* i_frag should be zero */
9480 N_("i_frag @F %N, @s zero.\n"),
9483 /* i_fsize should be zero */
9485 N_("i_fsize @F %N, @s zero.\n"),
9488 /* inode has bad mode */
9490 N_("@i %i (%Q) has @n mode (%Im).\n"),
9493 /* directory corrupted */
9494 { PR_2_DIR_CORRUPTED,
9495 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9496 PROMPT_SALVAGE, 0 },
9498 /* filename too long */
9499 { PR_2_FILENAME_LONG,
9500 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9501 PROMPT_TRUNCATE, 0 },
9503 /* Directory inode has a missing block (hole) */
9504 { PR_2_DIRECTORY_HOLE,
9505 N_("@d @i %i has an unallocated @b #%B. "),
9506 PROMPT_ALLOCATE, 0 },
9508 /* '.' is not NULL terminated */
9509 { PR_2_DOT_NULL_TERM,
9510 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9513 /* '..' is not NULL terminated */
9514 { PR_2_DOT_DOT_NULL_TERM,
9515 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9518 /* Illegal character device inode */
9519 { PR_2_BAD_CHAR_DEV,
9520 N_("@i %i (%Q) is an @I character @v.\n"),
9523 /* Illegal block device inode */
9524 { PR_2_BAD_BLOCK_DEV,
9525 N_("@i %i (%Q) is an @I @b @v.\n"),
9528 /* Duplicate '.' entry */
9530 N_("@E is duplicate '.' @e.\n"),
9533 /* Duplicate '..' entry */
9535 N_("@E is duplicate '..' @e.\n"),
9538 /* Internal error: couldn't find dir_info */
9540 N_("Internal error: couldn't find dir_info for %i.\n"),
9541 PROMPT_NONE, PR_FATAL },
9543 /* Final rec_len is wrong */
9544 { PR_2_FINAL_RECLEN,
9545 N_("@E has rec_len of %Dr, @s %N.\n"),
9548 /* Error allocating icount structure */
9549 { PR_2_ALLOCATE_ICOUNT,
9550 N_("@A icount structure: %m\n"),
9551 PROMPT_NONE, PR_FATAL },
9553 /* Error iterating over directory blocks */
9554 { PR_2_DBLIST_ITERATE,
9555 N_("Error iterating over @d @bs: %m\n"),
9556 PROMPT_NONE, PR_FATAL },
9558 /* Error reading directory block */
9559 { PR_2_READ_DIRBLOCK,
9560 N_("Error reading @d @b %b (@i %i): %m\n"),
9561 PROMPT_CONTINUE, 0 },
9563 /* Error writing directory block */
9564 { PR_2_WRITE_DIRBLOCK,
9565 N_("Error writing @d @b %b (@i %i): %m\n"),
9566 PROMPT_CONTINUE, 0 },
9568 /* Error allocating new directory block */
9569 { PR_2_ALLOC_DIRBOCK,
9570 N_("@A new @d @b for @i %i (%s): %m\n"),
9573 /* Error deallocating inode */
9574 { PR_2_DEALLOC_INODE,
9575 N_("Error deallocating @i %i: %m\n"),
9576 PROMPT_NONE, PR_FATAL },
9578 /* Directory entry for '.' is big. Split? */
9580 N_("@d @e for '.' is big. "),
9581 PROMPT_SPLIT, PR_NO_OK },
9583 /* Illegal FIFO inode */
9585 N_("@i %i (%Q) is an @I FIFO.\n"),
9588 /* Illegal socket inode */
9590 N_("@i %i (%Q) is an @I socket.\n"),
9593 /* Directory filetype not set */
9594 { PR_2_SET_FILETYPE,
9595 N_("Setting filetype for @E to %N.\n"),
9596 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9598 /* Directory filetype incorrect */
9599 { PR_2_BAD_FILETYPE,
9600 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9603 /* Directory filetype set on filesystem */
9604 { PR_2_CLEAR_FILETYPE,
9605 N_("@E has filetype set.\n"),
9606 PROMPT_CLEAR, PR_PREEN_OK },
9608 /* Directory filename is null */
9610 N_("@E has a @z name.\n"),
9613 /* Invalid symlink */
9614 { PR_2_INVALID_SYMLINK,
9615 N_("Symlink %Q (@i #%i) is @n.\n"),
9618 /* i_file_acl (extended attribute block) is bad */
9619 { PR_2_FILE_ACL_BAD,
9620 N_("@a @b @F @n (%If).\n"),
9623 /* Filesystem contains large files, but has no such flag in sb */
9624 { PR_2_FEATURE_LARGE_FILES,
9625 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9628 /* Node in HTREE directory not referenced */
9629 { PR_2_HTREE_NOTREF,
9630 N_("@p @h %d: node (%B) not referenced\n"),
9633 /* Node in HTREE directory referenced twice */
9634 { PR_2_HTREE_DUPREF,
9635 N_("@p @h %d: node (%B) referenced twice\n"),
9638 /* Node in HTREE directory has bad min hash */
9639 { PR_2_HTREE_MIN_HASH,
9640 N_("@p @h %d: node (%B) has bad min hash\n"),
9643 /* Node in HTREE directory has bad max hash */
9644 { PR_2_HTREE_MAX_HASH,
9645 N_("@p @h %d: node (%B) has bad max hash\n"),
9648 /* Clear invalid HTREE directory */
9650 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9652 /* Bad block in htree interior node */
9653 { PR_2_HTREE_BADBLK,
9654 N_("@p @h %d (%q): bad @b number %b.\n"),
9655 PROMPT_CLEAR_HTREE, 0 },
9657 /* Error adjusting EA refcount */
9658 { PR_2_ADJ_EA_REFCOUNT,
9659 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9660 PROMPT_NONE, PR_FATAL },
9662 /* Invalid HTREE root node */
9663 { PR_2_HTREE_BAD_ROOT,
9664 N_("@p @h %d: root node is @n\n"),
9665 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9667 /* Invalid HTREE limit */
9668 { PR_2_HTREE_BAD_LIMIT,
9669 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9670 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9672 /* Invalid HTREE count */
9673 { PR_2_HTREE_BAD_COUNT,
9674 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9675 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9677 /* HTREE interior node has out-of-order hashes in table */
9678 { PR_2_HTREE_HASH_ORDER,
9679 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9680 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9682 /* Node in HTREE directory has invalid depth */
9683 { PR_2_HTREE_BAD_DEPTH,
9684 N_("@p @h %d: node (%B) has @n depth\n"),
9687 /* Duplicate directory entry found */
9688 { PR_2_DUPLICATE_DIRENT,
9689 N_("Duplicate @E found. "),
9692 /* Non-unique filename found */
9693 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9694 N_("@E has a non-unique filename.\nRename to %s"),
9697 /* Duplicate directory entry found */
9698 { PR_2_REPORT_DUP_DIRENT,
9699 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9704 /* Pass 3: Checking directory connectivity */
9706 N_("Pass 3: Checking @d connectivity\n"),
9709 /* Root inode not allocated */
9710 { PR_3_NO_ROOT_INODE,
9711 N_("@r not allocated. "),
9712 PROMPT_ALLOCATE, 0 },
9714 /* No room in lost+found */
9715 { PR_3_EXPAND_LF_DIR,
9716 N_("No room in @l @d. "),
9719 /* Unconnected directory inode */
9720 { PR_3_UNCONNECTED_DIR,
9721 N_("Unconnected @d @i %i (%p)\n"),
9722 PROMPT_CONNECT, 0 },
9724 /* /lost+found not found */
9726 N_("/@l not found. "),
9727 PROMPT_CREATE, PR_PREEN_OK },
9729 /* .. entry is incorrect */
9731 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9734 /* Bad or non-existent /lost+found. Cannot reconnect */
9736 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9739 /* Could not expand /lost+found */
9740 { PR_3_CANT_EXPAND_LPF,
9741 N_("Could not expand /@l: %m\n"),
9744 /* Could not reconnect inode */
9745 { PR_3_CANT_RECONNECT,
9746 N_("Could not reconnect %i: %m\n"),
9749 /* Error while trying to find /lost+found */
9750 { PR_3_ERR_FIND_LPF,
9751 N_("Error while trying to find /@l: %m\n"),
9754 /* Error in ext2fs_new_block while creating /lost+found */
9755 { PR_3_ERR_LPF_NEW_BLOCK,
9756 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9759 /* Error in ext2fs_new_inode while creating /lost+found */
9760 { PR_3_ERR_LPF_NEW_INODE,
9761 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9764 /* Error in ext2fs_new_dir_block while creating /lost+found */
9765 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9766 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9769 /* Error while writing directory block for /lost+found */
9770 { PR_3_ERR_LPF_WRITE_BLOCK,
9771 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9774 /* Error while adjusting inode count */
9775 { PR_3_ADJUST_INODE,
9776 N_("Error while adjusting @i count on @i %i\n"),
9779 /* Couldn't fix parent directory -- error */
9780 { PR_3_FIX_PARENT_ERR,
9781 N_("Couldn't fix parent of @i %i: %m\n\n"),
9784 /* Couldn't fix parent directory -- couldn't find it */
9785 { PR_3_FIX_PARENT_NOFIND,
9786 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9789 /* Error allocating inode bitmap */
9790 { PR_3_ALLOCATE_IBITMAP_ERROR,
9791 N_("@A @i @B (%N): %m\n"),
9792 PROMPT_NONE, PR_FATAL },
9794 /* Error creating root directory */
9795 { PR_3_CREATE_ROOT_ERROR,
9796 N_("Error creating root @d (%s): %m\n"),
9797 PROMPT_NONE, PR_FATAL },
9799 /* Error creating lost and found directory */
9800 { PR_3_CREATE_LPF_ERROR,
9801 N_("Error creating /@l @d (%s): %m\n"),
9802 PROMPT_NONE, PR_FATAL },
9804 /* Root inode is not directory; aborting */
9805 { PR_3_ROOT_NOT_DIR_ABORT,
9806 N_("@r is not a @d; aborting.\n"),
9807 PROMPT_NONE, PR_FATAL },
9809 /* Cannot proceed without a root inode. */
9810 { PR_3_NO_ROOT_INODE_ABORT,
9811 N_("Cannot proceed without a @r.\n"),
9812 PROMPT_NONE, PR_FATAL },
9814 /* Internal error: couldn't find dir_info */
9816 N_("Internal error: couldn't find dir_info for %i.\n"),
9817 PROMPT_NONE, PR_FATAL },
9819 /* Lost+found not a directory */
9821 N_("/@l is not a @d (ino=%i)\n"),
9824 /* Pass 3A Directory Optimization */
9826 /* Pass 3A: Optimizing directories */
9827 { PR_3A_PASS_HEADER,
9828 N_("Pass 3A: Optimizing directories\n"),
9829 PROMPT_NONE, PR_PREEN_NOMSG },
9831 /* Error iterating over directories */
9832 { PR_3A_OPTIMIZE_ITER,
9833 N_("Failed to create dirs_to_hash iterator: %m"),
9836 /* Error rehash directory */
9837 { PR_3A_OPTIMIZE_DIR_ERR,
9838 N_("Failed to optimize directory %q (%d): %m"),
9841 /* Rehashing dir header */
9842 { PR_3A_OPTIMIZE_DIR_HEADER,
9843 N_("Optimizing directories: "),
9844 PROMPT_NONE, PR_MSG_ONLY },
9846 /* Rehashing directory %d */
9847 { PR_3A_OPTIMIZE_DIR,
9849 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9851 /* Rehashing dir end */
9852 { PR_3A_OPTIMIZE_DIR_END,
9854 PROMPT_NONE, PR_PREEN_NOHDR },
9858 /* Pass 4: Checking reference counts */
9860 N_("Pass 4: Checking reference counts\n"),
9863 /* Unattached zero-length inode */
9864 { PR_4_ZERO_LEN_INODE,
9865 N_("@u @z @i %i. "),
9866 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9868 /* Unattached inode */
9869 { PR_4_UNATTACHED_INODE,
9871 PROMPT_CONNECT, 0 },
9873 /* Inode ref count wrong */
9874 { PR_4_BAD_REF_COUNT,
9875 N_("@i %i ref count is %Il, @s %N. "),
9876 PROMPT_FIX, PR_PREEN_OK },
9878 { PR_4_INCONSISTENT_COUNT,
9879 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9880 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9881 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9882 "They @s the same!\n"),
9887 /* Pass 5: Checking group summary information */
9889 N_("Pass 5: Checking @g summary information\n"),
9892 /* Padding at end of inode bitmap is not set. */
9893 { PR_5_INODE_BMAP_PADDING,
9894 N_("Padding at end of @i @B is not set. "),
9895 PROMPT_FIX, PR_PREEN_OK },
9897 /* Padding at end of block bitmap is not set. */
9898 { PR_5_BLOCK_BMAP_PADDING,
9899 N_("Padding at end of @b @B is not set. "),
9900 PROMPT_FIX, PR_PREEN_OK },
9902 /* Block bitmap differences header */
9903 { PR_5_BLOCK_BITMAP_HEADER,
9904 N_("@b @B differences: "),
9905 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9907 /* Block not used, but marked in bitmap */
9908 { PR_5_BLOCK_UNUSED,
9910 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9912 /* Block used, but not marked used in bitmap */
9915 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9917 /* Block bitmap differences end */
9918 { PR_5_BLOCK_BITMAP_END,
9920 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9922 /* Inode bitmap differences header */
9923 { PR_5_INODE_BITMAP_HEADER,
9924 N_("@i @B differences: "),
9925 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9927 /* Inode not used, but marked in bitmap */
9928 { PR_5_INODE_UNUSED,
9930 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9932 /* Inode used, but not marked used in bitmap */
9935 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9937 /* Inode bitmap differences end */
9938 { PR_5_INODE_BITMAP_END,
9940 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9942 /* Free inodes count for group wrong */
9943 { PR_5_FREE_INODE_COUNT_GROUP,
9944 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9945 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9947 /* Directories count for group wrong */
9948 { PR_5_FREE_DIR_COUNT_GROUP,
9949 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9950 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9952 /* Free inodes count wrong */
9953 { PR_5_FREE_INODE_COUNT,
9954 N_("Free @is count wrong (%i, counted=%j).\n"),
9955 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9957 /* Free blocks count for group wrong */
9958 { PR_5_FREE_BLOCK_COUNT_GROUP,
9959 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9960 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9962 /* Free blocks count wrong */
9963 { PR_5_FREE_BLOCK_COUNT,
9964 N_("Free @bs count wrong (%b, counted=%c).\n"),
9965 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9967 /* Programming error: bitmap endpoints don't match */
9968 { PR_5_BMAP_ENDPOINTS,
9969 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9970 "match calculated @B endpoints (%i, %j)\n"),
9971 PROMPT_NONE, PR_FATAL },
9973 /* Internal error: fudging end of bitmap */
9974 { PR_5_FUDGE_BITMAP_ERROR,
9975 N_("Internal error: fudging end of bitmap (%N)\n"),
9976 PROMPT_NONE, PR_FATAL },
9978 /* Error copying in replacement inode bitmap */
9979 { PR_5_COPY_IBITMAP_ERROR,
9980 N_("Error copying in replacement @i @B: %m\n"),
9981 PROMPT_NONE, PR_FATAL },
9983 /* Error copying in replacement block bitmap */
9984 { PR_5_COPY_BBITMAP_ERROR,
9985 N_("Error copying in replacement @b @B: %m\n"),
9986 PROMPT_NONE, PR_FATAL },
9988 /* Block range not used, but marked in bitmap */
9989 { PR_5_BLOCK_RANGE_UNUSED,
9991 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9993 /* Block range used, but not marked used in bitmap */
9994 { PR_5_BLOCK_RANGE_USED,
9996 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9998 /* Inode range not used, but marked in bitmap */
9999 { PR_5_INODE_RANGE_UNUSED,
10001 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10003 /* Inode range used, but not marked used in bitmap */
10004 { PR_5_INODE_RANGE_USED,
10006 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10012 * This is the latch flags register. It allows several problems to be
10013 * "latched" together. This means that the user has to answer but one
10014 * question for the set of problems, and all of the associated
10015 * problems will be either fixed or not fixed.
10017 static struct latch_descr pr_latch_info[] = {
10018 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
10019 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
10020 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
10021 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
10022 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
10023 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
10024 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
10025 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
10026 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
10030 static const struct e2fsck_problem *find_problem(problem_t code)
10034 for (i=0; problem_table[i].e2p_code; i++) {
10035 if (problem_table[i].e2p_code == code)
10036 return &problem_table[i];
10041 static struct latch_descr *find_latch(int code)
10045 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
10046 if (pr_latch_info[i].latch_code == code)
10047 return &pr_latch_info[i];
10052 int end_problem_latch(e2fsck_t ctx, int mask)
10054 struct latch_descr *ldesc;
10055 struct problem_context pctx;
10058 ldesc = find_latch(mask);
10059 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
10060 clear_problem_context(&pctx);
10061 answer = fix_problem(ctx, ldesc->end_message, &pctx);
10063 ldesc->flags &= ~(PRL_VARIABLE);
10067 int set_latch_flags(int mask, int setflags, int clearflags)
10069 struct latch_descr *ldesc;
10071 ldesc = find_latch(mask);
10074 ldesc->flags |= setflags;
10075 ldesc->flags &= ~clearflags;
10079 void clear_problem_context(struct problem_context *ctx)
10081 memset(ctx, 0, sizeof(struct problem_context));
10082 ctx->blkcount = -1;
10086 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
10088 ext2_filsys fs = ctx->fs;
10089 const struct e2fsck_problem *ptr;
10090 struct latch_descr *ldesc = 0;
10091 const char *message;
10092 int def_yn, answer, ans;
10093 int print_answer = 0;
10096 ptr = find_problem(code);
10098 printf(_("Unhandled error code (0x%x)!\n"), code);
10102 if ((ptr->flags & PR_NO_DEFAULT) ||
10103 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
10104 (ctx->options & E2F_OPT_NO))
10108 * Do special latch processing. This is where we ask the
10109 * latch question, if it exists
10111 if (ptr->flags & PR_LATCH_MASK) {
10112 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
10113 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
10114 ans = fix_problem(ctx, ldesc->question, pctx);
10116 ldesc->flags |= PRL_YES;
10118 ldesc->flags |= PRL_NO;
10119 ldesc->flags |= PRL_LATCHED;
10121 if (ldesc->flags & PRL_SUPPRESS)
10124 if ((ptr->flags & PR_PREEN_NOMSG) &&
10125 (ctx->options & E2F_OPT_PREEN))
10127 if ((ptr->flags & PR_NO_NOMSG) &&
10128 (ctx->options & E2F_OPT_NO))
10131 message = ptr->e2p_description;
10132 if ((ctx->options & E2F_OPT_PREEN) &&
10133 !(ptr->flags & PR_PREEN_NOHDR)) {
10134 printf("%s: ", ctx->device_name ?
10135 ctx->device_name : ctx->filesystem_name);
10138 print_e2fsck_message(ctx, _(message), pctx, 1);
10140 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
10143 if (ptr->flags & PR_FATAL)
10144 bb_error_msg_and_die(0);
10146 if (ptr->prompt == PROMPT_NONE) {
10147 if (ptr->flags & PR_NOCOLLATE)
10152 if (ctx->options & E2F_OPT_PREEN) {
10154 if (!(ptr->flags & PR_PREEN_NOMSG))
10156 } else if ((ptr->flags & PR_LATCH_MASK) &&
10157 (ldesc->flags & (PRL_YES | PRL_NO))) {
10160 if (ldesc->flags & PRL_YES)
10165 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
10166 if (!answer && !(ptr->flags & PR_NO_OK))
10167 ext2fs_unmark_valid(fs);
10170 printf("%s.\n", answer ?
10171 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
10175 if ((ptr->prompt == PROMPT_ABORT) && answer)
10176 bb_error_msg_and_die(0);
10178 if (ptr->flags & PR_AFTER_CODE)
10179 answer = fix_problem(ctx, ptr->second_code, pctx);
10185 * linux/fs/recovery.c
10187 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
10191 * Maintain information about the progress of the recovery job, so that
10192 * the different passes can carry information between them.
10194 struct recovery_info
10196 tid_t start_transaction;
10197 tid_t end_transaction;
10201 int nr_revoke_hits;
10204 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
10205 static int do_one_pass(journal_t *journal,
10206 struct recovery_info *info, enum passtype pass);
10207 static int scan_revoke_records(journal_t *, struct buffer_head *,
10208 tid_t, struct recovery_info *);
10211 * Read a block from the journal
10214 static int jread(struct buffer_head **bhp, journal_t *journal,
10215 unsigned int offset)
10218 unsigned long blocknr;
10219 struct buffer_head *bh;
10223 err = journal_bmap(journal, offset, &blocknr);
10226 printf ("JBD: bad block at offset %u\n", offset);
10230 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
10234 if (!buffer_uptodate(bh)) {
10235 /* If this is a brand new buffer, start readahead.
10236 Otherwise, we assume we are already reading it. */
10237 if (!buffer_req(bh))
10238 do_readahead(journal, offset);
10239 wait_on_buffer(bh);
10242 if (!buffer_uptodate(bh)) {
10243 printf ("JBD: Failed to read block at offset %u\n", offset);
10254 * Count the number of in-use tags in a journal descriptor block.
10257 static int count_tags(struct buffer_head *bh, int size)
10260 journal_block_tag_t * tag;
10263 tagp = &bh->b_data[sizeof(journal_header_t)];
10265 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
10266 tag = (journal_block_tag_t *) tagp;
10269 tagp += sizeof(journal_block_tag_t);
10270 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
10273 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
10281 /* Make sure we wrap around the log correctly! */
10282 #define wrap(journal, var) \
10284 if (var >= (journal)->j_last) \
10285 var -= ((journal)->j_last - (journal)->j_first); \
10289 * int journal_recover(journal_t *journal) - recovers a on-disk journal
10290 * @journal: the journal to recover
10292 * The primary function for recovering the log contents when mounting a
10293 * journaled device.
10295 * Recovery is done in three passes. In the first pass, we look for the
10296 * end of the log. In the second, we assemble the list of revoke
10297 * blocks. In the third and final pass, we replay any un-revoked blocks
10300 int journal_recover(journal_t *journal)
10303 journal_superblock_t * sb;
10305 struct recovery_info info;
10307 memset(&info, 0, sizeof(info));
10308 sb = journal->j_superblock;
10311 * The journal superblock's s_start field (the current log head)
10312 * is always zero if, and only if, the journal was cleanly
10316 if (!sb->s_start) {
10317 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
10321 err = do_one_pass(journal, &info, PASS_SCAN);
10323 err = do_one_pass(journal, &info, PASS_REVOKE);
10325 err = do_one_pass(journal, &info, PASS_REPLAY);
10327 /* Restart the log at the next transaction ID, thus invalidating
10328 * any existing commit records in the log. */
10329 journal->j_transaction_sequence = ++info.end_transaction;
10331 journal_clear_revoke(journal);
10332 sync_blockdev(journal->j_fs_dev);
10336 static int do_one_pass(journal_t *journal,
10337 struct recovery_info *info, enum passtype pass)
10339 unsigned int first_commit_ID, next_commit_ID;
10340 unsigned long next_log_block;
10341 int err, success = 0;
10342 journal_superblock_t * sb;
10343 journal_header_t * tmp;
10344 struct buffer_head * bh;
10345 unsigned int sequence;
10348 /* Precompute the maximum metadata descriptors in a descriptor block */
10349 int MAX_BLOCKS_PER_DESC;
10350 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
10351 / sizeof(journal_block_tag_t));
10354 * First thing is to establish what we expect to find in the log
10355 * (in terms of transaction IDs), and where (in terms of log
10356 * block offsets): query the superblock.
10359 sb = journal->j_superblock;
10360 next_commit_ID = ntohl(sb->s_sequence);
10361 next_log_block = ntohl(sb->s_start);
10363 first_commit_ID = next_commit_ID;
10364 if (pass == PASS_SCAN)
10365 info->start_transaction = first_commit_ID;
10368 * Now we walk through the log, transaction by transaction,
10369 * making sure that each transaction has a commit block in the
10370 * expected place. Each complete transaction gets replayed back
10371 * into the main filesystem.
10377 journal_block_tag_t * tag;
10378 struct buffer_head * obh;
10379 struct buffer_head * nbh;
10381 /* If we already know where to stop the log traversal,
10382 * check right now that we haven't gone past the end of
10385 if (pass != PASS_SCAN)
10386 if (tid_geq(next_commit_ID, info->end_transaction))
10389 /* Skip over each chunk of the transaction looking
10390 * either the next descriptor block or the final commit
10393 err = jread(&bh, journal, next_log_block);
10398 wrap(journal, next_log_block);
10400 /* What kind of buffer is it?
10402 * If it is a descriptor block, check that it has the
10403 * expected sequence number. Otherwise, we're all done
10406 tmp = (journal_header_t *)bh->b_data;
10408 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10413 blocktype = ntohl(tmp->h_blocktype);
10414 sequence = ntohl(tmp->h_sequence);
10416 if (sequence != next_commit_ID) {
10421 /* OK, we have a valid descriptor block which matches
10422 * all of the sequence number checks. What are we going
10423 * to do with it? That depends on the pass... */
10425 switch(blocktype) {
10426 case JFS_DESCRIPTOR_BLOCK:
10427 /* If it is a valid descriptor block, replay it
10428 * in pass REPLAY; otherwise, just skip over the
10429 * blocks it describes. */
10430 if (pass != PASS_REPLAY) {
10432 count_tags(bh, journal->j_blocksize);
10433 wrap(journal, next_log_block);
10438 /* A descriptor block: we can now write all of
10439 * the data blocks. Yay, useful work is finally
10440 * getting done here! */
10442 tagp = &bh->b_data[sizeof(journal_header_t)];
10443 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10444 <= journal->j_blocksize) {
10445 unsigned long io_block;
10447 tag = (journal_block_tag_t *) tagp;
10448 flags = ntohl(tag->t_flags);
10450 io_block = next_log_block++;
10451 wrap(journal, next_log_block);
10452 err = jread(&obh, journal, io_block);
10454 /* Recover what we can, but
10455 * report failure at the end. */
10457 printf ("JBD: IO error %d recovering "
10458 "block %ld in log\n",
10461 unsigned long blocknr;
10463 blocknr = ntohl(tag->t_blocknr);
10465 /* If the block has been
10466 * revoked, then we're all done
10468 if (journal_test_revoke
10472 ++info->nr_revoke_hits;
10476 /* Find a buffer for the new
10477 * data being restored */
10478 nbh = getblk(journal->j_fs_dev,
10480 journal->j_blocksize);
10482 printf ("JBD: Out of memory "
10483 "during recovery.\n");
10491 memcpy(nbh->b_data, obh->b_data,
10492 journal->j_blocksize);
10493 if (flags & JFS_FLAG_ESCAPE) {
10494 *((unsigned int *)bh->b_data) =
10495 htonl(JFS_MAGIC_NUMBER);
10498 mark_buffer_uptodate(nbh, 1);
10499 mark_buffer_dirty(nbh);
10500 ++info->nr_replays;
10501 /* ll_rw_block(WRITE, 1, &nbh); */
10502 unlock_buffer(nbh);
10508 tagp += sizeof(journal_block_tag_t);
10509 if (!(flags & JFS_FLAG_SAME_UUID))
10512 if (flags & JFS_FLAG_LAST_TAG)
10519 case JFS_COMMIT_BLOCK:
10520 /* Found an expected commit block: not much to
10521 * do other than move on to the next sequence
10527 case JFS_REVOKE_BLOCK:
10528 /* If we aren't in the REVOKE pass, then we can
10529 * just skip over this block. */
10530 if (pass != PASS_REVOKE) {
10535 err = scan_revoke_records(journal, bh,
10536 next_commit_ID, info);
10549 * We broke out of the log scan loop: either we came to the
10550 * known end of the log or we found an unexpected block in the
10551 * log. If the latter happened, then we know that the "current"
10552 * transaction marks the end of the valid log.
10555 if (pass == PASS_SCAN)
10556 info->end_transaction = next_commit_ID;
10558 /* It's really bad news if different passes end up at
10559 * different places (but possible due to IO errors). */
10560 if (info->end_transaction != next_commit_ID) {
10561 printf ("JBD: recovery pass %d ended at "
10562 "transaction %u, expected %u\n",
10563 pass, next_commit_ID, info->end_transaction);
10576 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10578 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10579 tid_t sequence, struct recovery_info *info)
10581 journal_revoke_header_t *header;
10584 header = (journal_revoke_header_t *) bh->b_data;
10585 offset = sizeof(journal_revoke_header_t);
10586 max = ntohl(header->r_count);
10588 while (offset < max) {
10589 unsigned long blocknr;
10592 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10594 err = journal_set_revoke(journal, blocknr, sequence);
10597 ++info->nr_revokes;
10604 * rehash.c --- rebuild hash tree directories
10606 * This algorithm is designed for simplicity of implementation and to
10607 * pack the directory as much as possible. It however requires twice
10608 * as much memory as the size of the directory. The maximum size
10609 * directory supported using a 4k blocksize is roughly a gigabyte, and
10610 * so there may very well be problems with machines that don't have
10611 * virtual memory, and obscenely large directories.
10613 * An alternate algorithm which is much more disk intensive could be
10614 * written, and probably will need to be written in the future. The
10615 * design goals of such an algorithm are: (a) use (roughly) constant
10616 * amounts of memory, no matter how large the directory, (b) the
10617 * directory must be safe at all times, even if e2fsck is interrupted
10618 * in the middle, (c) we must use minimal amounts of extra disk
10619 * blocks. This pretty much requires an incremental approach, where
10620 * we are reading from one part of the directory, and inserting into
10621 * the front half. So the algorithm will have to keep track of a
10622 * moving block boundary between the new tree and the old tree, and
10623 * files will need to be moved from the old directory and inserted
10624 * into the new tree. If the new directory requires space which isn't
10625 * yet available, blocks from the beginning part of the old directory
10626 * may need to be moved to the end of the directory to make room for
10629 * --------------------------------------------------------
10630 * | new tree | | old tree |
10631 * --------------------------------------------------------
10633 * tail new head old
10635 * This is going to be a pain in the tuckus to implement, and will
10636 * require a lot more disk accesses. So I'm going to skip it for now;
10637 * it's only really going to be an issue for really, really big
10638 * filesystems (when we reach the level of tens of millions of files
10639 * in a single directory). It will probably be easier to simply
10640 * require that e2fsck use VM first.
10643 struct fill_dir_struct {
10645 struct ext2_inode *inode;
10648 struct hash_entry *harray;
10649 int max_array, num_array;
10655 struct hash_entry {
10656 ext2_dirhash_t hash;
10657 ext2_dirhash_t minor_hash;
10658 struct ext2_dir_entry *dir;
10665 ext2_dirhash_t *hashes;
10668 static int fill_dir_block(ext2_filsys fs,
10670 e2_blkcnt_t blockcnt,
10671 blk_t ref_block FSCK_ATTR((unused)),
10672 int ref_offset FSCK_ATTR((unused)),
10675 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10676 struct hash_entry *new_array, *ent;
10677 struct ext2_dir_entry *dirent;
10679 unsigned int offset, dir_offset;
10684 offset = blockcnt * fs->blocksize;
10685 if (offset + fs->blocksize > fd->inode->i_size) {
10686 fd->err = EXT2_ET_DIR_CORRUPTED;
10687 return BLOCK_ABORT;
10689 dir = (fd->buf+offset);
10690 if (HOLE_BLKADDR(*block_nr)) {
10691 memset(dir, 0, fs->blocksize);
10692 dirent = (struct ext2_dir_entry *) dir;
10693 dirent->rec_len = fs->blocksize;
10695 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10697 return BLOCK_ABORT;
10699 /* While the directory block is "hot", index it. */
10701 while (dir_offset < fs->blocksize) {
10702 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10703 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10704 (dirent->rec_len < 8) ||
10705 ((dirent->rec_len % 4) != 0) ||
10706 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10707 fd->err = EXT2_ET_DIR_CORRUPTED;
10708 return BLOCK_ABORT;
10710 dir_offset += dirent->rec_len;
10711 if (dirent->inode == 0)
10713 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10714 (dirent->name[0] == '.'))
10716 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10717 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10718 fd->parent = dirent->inode;
10721 if (fd->num_array >= fd->max_array) {
10722 new_array = realloc(fd->harray,
10723 sizeof(struct hash_entry) * (fd->max_array+500));
10726 return BLOCK_ABORT;
10728 fd->harray = new_array;
10729 fd->max_array += 500;
10731 ent = fd->harray + fd->num_array++;
10733 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10735 ent->hash = ent->minor_hash = 0;
10737 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10739 dirent->name_len & 0xFF,
10740 fs->super->s_hash_seed,
10741 &ent->hash, &ent->minor_hash);
10743 return BLOCK_ABORT;
10750 /* Used for sorting the hash entry */
10751 static int name_cmp(const void *a, const void *b)
10753 const struct hash_entry *he_a = (const struct hash_entry *) a;
10754 const struct hash_entry *he_b = (const struct hash_entry *) b;
10758 min_len = he_a->dir->name_len;
10759 if (min_len > he_b->dir->name_len)
10760 min_len = he_b->dir->name_len;
10762 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10764 if (he_a->dir->name_len > he_b->dir->name_len)
10766 else if (he_a->dir->name_len < he_b->dir->name_len)
10769 ret = he_b->dir->inode - he_a->dir->inode;
10774 /* Used for sorting the hash entry */
10775 static int hash_cmp(const void *a, const void *b)
10777 const struct hash_entry *he_a = (const struct hash_entry *) a;
10778 const struct hash_entry *he_b = (const struct hash_entry *) b;
10781 if (he_a->hash > he_b->hash)
10783 else if (he_a->hash < he_b->hash)
10786 if (he_a->minor_hash > he_b->minor_hash)
10788 else if (he_a->minor_hash < he_b->minor_hash)
10791 ret = name_cmp(a, b);
10796 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10802 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10805 outdir->buf = new_mem;
10806 new_mem = realloc(outdir->hashes,
10807 blocks * sizeof(ext2_dirhash_t));
10810 outdir->hashes = new_mem;
10812 outdir->buf = malloc(blocks * fs->blocksize);
10813 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10816 outdir->max = blocks;
10820 static void free_out_dir(struct out_dir *outdir)
10823 free(outdir->hashes);
10828 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10833 if (outdir->num >= outdir->max) {
10834 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10838 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10839 memset(*ret, 0, fs->blocksize);
10844 * This function is used to make a unique filename. We do this by
10845 * appending ~0, and then incrementing the number. However, we cannot
10846 * expand the length of the filename beyond the padding available in
10847 * the directory entry.
10849 static void mutate_name(char *str, __u16 *len)
10852 __u16 l = *len & 0xFF, h = *len & 0xff00;
10855 * First check to see if it looks the name has been mutated
10858 for (i = l-1; i > 0; i--) {
10859 if (!isdigit(str[i]))
10862 if ((i == l-1) || (str[i] != '~')) {
10863 if (((l-1) & 3) < 2)
10872 for (i = l-1; i >= 0; i--) {
10873 if (isdigit(str[i])) {
10885 else if (str[0] == 'Z') {
10890 } else if (i > 0) {
10903 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10905 struct fill_dir_struct *fd)
10907 struct problem_context pctx;
10908 struct hash_entry *ent, *prev;
10911 char new_name[256];
10914 clear_problem_context(&pctx);
10917 for (i=1; i < fd->num_array; i++) {
10918 ent = fd->harray + i;
10920 if (!ent->dir->inode ||
10921 ((ent->dir->name_len & 0xFF) !=
10922 (prev->dir->name_len & 0xFF)) ||
10923 (strncmp(ent->dir->name, prev->dir->name,
10924 ent->dir->name_len & 0xFF)))
10926 pctx.dirent = ent->dir;
10927 if ((ent->dir->inode == prev->dir->inode) &&
10928 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10929 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10930 ent->dir->inode = 0;
10934 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10935 new_len = ent->dir->name_len;
10936 mutate_name(new_name, &new_len);
10937 for (j=0; j < fd->num_array; j++) {
10939 ((ent->dir->name_len & 0xFF) !=
10940 (fd->harray[j].dir->name_len & 0xFF)) ||
10941 (strncmp(new_name, fd->harray[j].dir->name,
10944 mutate_name(new_name, &new_len);
10948 new_name[new_len & 0xFF] = 0;
10949 pctx.str = new_name;
10950 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10951 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10952 ent->dir->name_len = new_len;
10953 ext2fs_dirhash(fs->super->s_def_hash_version,
10955 ent->dir->name_len & 0xFF,
10956 fs->super->s_hash_seed,
10957 &ent->hash, &ent->minor_hash);
10965 static errcode_t copy_dir_entries(ext2_filsys fs,
10966 struct fill_dir_struct *fd,
10967 struct out_dir *outdir)
10971 struct hash_entry *ent;
10972 struct ext2_dir_entry *dirent;
10973 int i, rec_len, left;
10974 ext2_dirhash_t prev_hash;
10978 retval = alloc_size_dir(fs, outdir,
10979 (fd->dir_size / fs->blocksize) + 2);
10982 outdir->num = fd->compress ? 0 : 1;
10984 outdir->hashes[0] = 0;
10986 if ((retval = get_next_block(fs, outdir, &block_start)))
10988 dirent = (struct ext2_dir_entry *) block_start;
10989 left = fs->blocksize;
10990 for (i=0; i < fd->num_array; i++) {
10991 ent = fd->harray + i;
10992 if (ent->dir->inode == 0)
10994 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10995 if (rec_len > left) {
10997 dirent->rec_len += left;
10998 if ((retval = get_next_block(fs, outdir,
11003 left = fs->blocksize - offset;
11004 dirent = (struct ext2_dir_entry *) (block_start + offset);
11006 if (ent->hash == prev_hash)
11007 outdir->hashes[outdir->num-1] = ent->hash | 1;
11009 outdir->hashes[outdir->num-1] = ent->hash;
11011 dirent->inode = ent->dir->inode;
11012 dirent->name_len = ent->dir->name_len;
11013 dirent->rec_len = rec_len;
11014 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
11018 dirent->rec_len += left;
11022 prev_hash = ent->hash;
11025 dirent->rec_len += left;
11031 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
11032 ext2_ino_t ino, ext2_ino_t parent)
11034 struct ext2_dir_entry *dir;
11035 struct ext2_dx_root_info *root;
11036 struct ext2_dx_countlimit *limits;
11039 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
11040 filetype = EXT2_FT_DIR << 8;
11042 memset(buf, 0, fs->blocksize);
11043 dir = (struct ext2_dir_entry *) buf;
11045 dir->name[0] = '.';
11046 dir->name_len = 1 | filetype;
11048 dir = (struct ext2_dir_entry *) (buf + 12);
11049 dir->inode = parent;
11050 dir->name[0] = '.';
11051 dir->name[1] = '.';
11052 dir->name_len = 2 | filetype;
11053 dir->rec_len = fs->blocksize - 12;
11055 root = (struct ext2_dx_root_info *) (buf+24);
11056 root->reserved_zero = 0;
11057 root->hash_version = fs->super->s_def_hash_version;
11058 root->info_length = 8;
11059 root->indirect_levels = 0;
11060 root->unused_flags = 0;
11062 limits = (struct ext2_dx_countlimit *) (buf+32);
11063 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
11070 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
11072 struct ext2_dir_entry *dir;
11073 struct ext2_dx_countlimit *limits;
11075 memset(buf, 0, fs->blocksize);
11076 dir = (struct ext2_dir_entry *) buf;
11078 dir->rec_len = fs->blocksize;
11080 limits = (struct ext2_dx_countlimit *) (buf+8);
11081 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
11084 return (struct ext2_dx_entry *) limits;
11088 * This function takes the leaf nodes which have been written in
11089 * outdir, and populates the root node and any necessary interior nodes.
11091 static errcode_t calculate_tree(ext2_filsys fs,
11092 struct out_dir *outdir,
11096 struct ext2_dx_root_info *root_info;
11097 struct ext2_dx_entry *root, *dx_ent = 0;
11098 struct ext2_dx_countlimit *root_limit, *limit;
11100 char * block_start;
11101 int i, c1, c2, nblks;
11102 int limit_offset, root_offset;
11104 root_info = set_root_node(fs, outdir->buf, ino, parent);
11105 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
11106 root_info->info_length;
11107 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11108 c1 = root_limit->limit;
11109 nblks = outdir->num;
11111 /* Write out the pointer blocks */
11112 if (nblks-1 <= c1) {
11113 /* Just write out the root block, and we're done */
11114 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
11115 for (i=1; i < nblks; i++) {
11116 root->block = ext2fs_cpu_to_le32(i);
11119 ext2fs_cpu_to_le32(outdir->hashes[i]);
11126 root_info->indirect_levels = 1;
11127 for (i=1; i < nblks; i++) {
11132 limit->limit = limit->count =
11133 ext2fs_cpu_to_le16(limit->limit);
11134 root = (struct ext2_dx_entry *)
11135 (outdir->buf + root_offset);
11136 root->block = ext2fs_cpu_to_le32(outdir->num);
11139 ext2fs_cpu_to_le32(outdir->hashes[i]);
11140 if ((retval = get_next_block(fs, outdir,
11143 dx_ent = set_int_node(fs, block_start);
11144 limit = (struct ext2_dx_countlimit *) dx_ent;
11146 root_offset += sizeof(struct ext2_dx_entry);
11149 dx_ent->block = ext2fs_cpu_to_le32(i);
11150 if (c2 != limit->limit)
11152 ext2fs_cpu_to_le32(outdir->hashes[i]);
11156 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
11157 limit->limit = ext2fs_cpu_to_le16(limit->limit);
11159 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11160 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
11161 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
11166 struct write_dir_struct {
11167 struct out_dir *outdir;
11174 * Helper function which writes out a directory block.
11176 static int write_dir_block(ext2_filsys fs,
11178 e2_blkcnt_t blockcnt,
11179 blk_t ref_block FSCK_ATTR((unused)),
11180 int ref_offset FSCK_ATTR((unused)),
11183 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
11187 if (*block_nr == 0)
11189 if (blockcnt >= wd->outdir->num) {
11190 e2fsck_read_bitmaps(wd->ctx);
11192 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
11193 ext2fs_block_alloc_stats(fs, blk, -1);
11196 return BLOCK_CHANGED;
11201 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
11202 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
11204 return BLOCK_ABORT;
11208 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
11209 struct out_dir *outdir,
11210 ext2_ino_t ino, int compress)
11212 struct write_dir_struct wd;
11214 struct ext2_inode inode;
11216 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
11220 wd.outdir = outdir;
11225 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
11226 write_dir_block, &wd);
11232 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
11234 inode.i_flags &= ~EXT2_INDEX_FL;
11236 inode.i_flags |= EXT2_INDEX_FL;
11237 inode.i_size = outdir->num * fs->blocksize;
11238 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
11239 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
11244 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
11246 ext2_filsys fs = ctx->fs;
11248 struct ext2_inode inode;
11250 struct fill_dir_struct fd;
11251 struct out_dir outdir;
11253 outdir.max = outdir.num = 0;
11256 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
11260 dir_buf = malloc(inode.i_size);
11264 fd.max_array = inode.i_size / 32;
11266 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
11276 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
11277 (inode.i_size / fs->blocksize) < 2)
11281 /* Read in the entire directory into memory */
11282 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
11283 fill_dir_block, &fd);
11289 /* Sort the list */
11292 qsort(fd.harray+2, fd.num_array-2,
11293 sizeof(struct hash_entry), name_cmp);
11295 qsort(fd.harray, fd.num_array,
11296 sizeof(struct hash_entry), hash_cmp);
11299 * Look for duplicates
11301 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
11304 if (ctx->options & E2F_OPT_NO) {
11310 * Copy the directory entries. In a htree directory these
11311 * will become the leaf nodes.
11313 retval = copy_dir_entries(fs, &fd, &outdir);
11317 free(dir_buf); dir_buf = 0;
11319 if (!fd.compress) {
11320 /* Calculate the interior nodes */
11321 retval = calculate_tree(fs, &outdir, ino, fd.parent);
11326 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
11332 free_out_dir(&outdir);
11336 void e2fsck_rehash_directories(e2fsck_t ctx)
11338 struct problem_context pctx;
11339 struct dir_info *dir;
11340 ext2_u32_iterate iter;
11343 int i, cur, max, all_dirs, dir_index, first = 1;
11345 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
11347 if (!ctx->dirs_to_hash && !all_dirs)
11350 e2fsck_get_lost_and_found(ctx, 0);
11352 clear_problem_context(&pctx);
11354 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
11358 max = e2fsck_get_num_dirinfo(ctx);
11360 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
11363 pctx.errcode = retval;
11364 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
11367 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
11371 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
11375 if (!ext2fs_u32_list_iterate(iter, &ino))
11378 if (ino == ctx->lost_and_found)
11382 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
11385 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
11386 if (pctx.errcode) {
11387 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11388 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
11390 if (ctx->progress && !ctx->progress_fd)
11391 e2fsck_simple_progress(ctx, "Rebuilding directory",
11392 100.0 * (float) (++cur) / (float) max, ino);
11394 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11396 ext2fs_u32_list_iterate_end(iter);
11398 ext2fs_u32_list_free(ctx->dirs_to_hash);
11399 ctx->dirs_to_hash = 0;
11403 * linux/fs/revoke.c
11405 * Journal revoke routines for the generic filesystem journaling code;
11406 * part of the ext2fs journaling system.
11408 * Revoke is the mechanism used to prevent old log records for deleted
11409 * metadata from being replayed on top of newer data using the same
11410 * blocks. The revoke mechanism is used in two separate places:
11412 * + Commit: during commit we write the entire list of the current
11413 * transaction's revoked blocks to the journal
11415 * + Recovery: during recovery we record the transaction ID of all
11416 * revoked blocks. If there are multiple revoke records in the log
11417 * for a single block, only the last one counts, and if there is a log
11418 * entry for a block beyond the last revoke, then that log entry still
11421 * We can get interactions between revokes and new log data within a
11422 * single transaction:
11424 * Block is revoked and then journaled:
11425 * The desired end result is the journaling of the new block, so we
11426 * cancel the revoke before the transaction commits.
11428 * Block is journaled and then revoked:
11429 * The revoke must take precedence over the write of the block, so we
11430 * need either to cancel the journal entry or to write the revoke
11431 * later in the log than the log block. In this case, we choose the
11432 * latter: journaling a block cancels any revoke record for that block
11433 * in the current transaction, so any revoke for that block in the
11434 * transaction must have happened after the block was journaled and so
11435 * the revoke must take precedence.
11437 * Block is revoked and then written as data:
11438 * The data write is allowed to succeed, but the revoke is _not_
11439 * cancelled. We still need to prevent old log records from
11440 * overwriting the new data. We don't even need to clear the revoke
11443 * Revoke information on buffers is a tri-state value:
11445 * RevokeValid clear: no cached revoke status, need to look it up
11446 * RevokeValid set, Revoked clear:
11447 * buffer has not been revoked, and cancel_revoke
11449 * RevokeValid set, Revoked set:
11450 * buffer has been revoked.
11453 static kmem_cache_t *revoke_record_cache;
11454 static kmem_cache_t *revoke_table_cache;
11456 /* Each revoke record represents one single revoked block. During
11457 journal replay, this involves recording the transaction ID of the
11458 last transaction to revoke this block. */
11460 struct jbd_revoke_record_s
11462 struct list_head hash;
11463 tid_t sequence; /* Used for recovery only */
11464 unsigned long blocknr;
11468 /* The revoke table is just a simple hash table of revoke records. */
11469 struct jbd_revoke_table_s
11471 /* It is conceivable that we might want a larger hash table
11472 * for recovery. Must be a power of two. */
11475 struct list_head *hash_table;
11479 /* Utility functions to maintain the revoke table */
11481 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11482 static inline int hash(journal_t *journal, unsigned long block)
11484 struct jbd_revoke_table_s *table = journal->j_revoke;
11485 int hash_shift = table->hash_shift;
11487 return ((block << (hash_shift - 6)) ^
11489 (block << (hash_shift - 12))) & (table->hash_size - 1);
11492 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11495 struct list_head *hash_list;
11496 struct jbd_revoke_record_s *record;
11498 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11502 record->sequence = seq;
11503 record->blocknr = blocknr;
11504 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11505 list_add(&record->hash, hash_list);
11512 /* Find a revoke record in the journal's hash table. */
11514 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11515 unsigned long blocknr)
11517 struct list_head *hash_list;
11518 struct jbd_revoke_record_s *record;
11520 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11522 record = (struct jbd_revoke_record_s *) hash_list->next;
11523 while (&(record->hash) != hash_list) {
11524 if (record->blocknr == blocknr)
11526 record = (struct jbd_revoke_record_s *) record->hash.next;
11531 int journal_init_revoke_caches(void)
11533 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11534 if (revoke_record_cache == 0)
11537 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11538 if (revoke_table_cache == 0) {
11539 do_cache_destroy(revoke_record_cache);
11540 revoke_record_cache = NULL;
11546 void journal_destroy_revoke_caches(void)
11548 do_cache_destroy(revoke_record_cache);
11549 revoke_record_cache = 0;
11550 do_cache_destroy(revoke_table_cache);
11551 revoke_table_cache = 0;
11554 /* Initialise the revoke table for a given journal to a given size. */
11556 int journal_init_revoke(journal_t *journal, int hash_size)
11560 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11561 if (!journal->j_revoke)
11564 /* Check that the hash_size is a power of two */
11565 journal->j_revoke->hash_size = hash_size;
11569 while((tmp >>= 1UL) != 0UL)
11571 journal->j_revoke->hash_shift = shift;
11573 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11574 if (!journal->j_revoke->hash_table) {
11575 free(journal->j_revoke);
11576 journal->j_revoke = NULL;
11580 for (tmp = 0; tmp < hash_size; tmp++)
11581 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11586 /* Destoy a journal's revoke table. The table must already be empty! */
11588 void journal_destroy_revoke(journal_t *journal)
11590 struct jbd_revoke_table_s *table;
11591 struct list_head *hash_list;
11594 table = journal->j_revoke;
11598 for (i=0; i<table->hash_size; i++) {
11599 hash_list = &table->hash_table[i];
11602 free(table->hash_table);
11604 journal->j_revoke = NULL;
11608 * Revoke support for recovery.
11610 * Recovery needs to be able to:
11612 * record all revoke records, including the tid of the latest instance
11613 * of each revoke in the journal
11615 * check whether a given block in a given transaction should be replayed
11616 * (ie. has not been revoked by a revoke record in that or a subsequent
11619 * empty the revoke table after recovery.
11623 * First, setting revoke records. We create a new revoke record for
11624 * every block ever revoked in the log as we scan it for recovery, and
11625 * we update the existing records if we find multiple revokes for a
11629 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11632 struct jbd_revoke_record_s *record;
11634 record = find_revoke_record(journal, blocknr);
11636 /* If we have multiple occurences, only record the
11637 * latest sequence number in the hashed record */
11638 if (tid_gt(sequence, record->sequence))
11639 record->sequence = sequence;
11642 return insert_revoke_hash(journal, blocknr, sequence);
11646 * Test revoke records. For a given block referenced in the log, has
11647 * that block been revoked? A revoke record with a given transaction
11648 * sequence number revokes all blocks in that transaction and earlier
11649 * ones, but later transactions still need replayed.
11652 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11655 struct jbd_revoke_record_s *record;
11657 record = find_revoke_record(journal, blocknr);
11660 if (tid_gt(sequence, record->sequence))
11666 * Finally, once recovery is over, we need to clear the revoke table so
11667 * that it can be reused by the running filesystem.
11670 void journal_clear_revoke(journal_t *journal)
11673 struct list_head *hash_list;
11674 struct jbd_revoke_record_s *record;
11675 struct jbd_revoke_table_s *revoke_var;
11677 revoke_var = journal->j_revoke;
11679 for (i = 0; i < revoke_var->hash_size; i++) {
11680 hash_list = &revoke_var->hash_table[i];
11681 while (!list_empty(hash_list)) {
11682 record = (struct jbd_revoke_record_s*) hash_list->next;
11683 list_del(&record->hash);
11690 * e2fsck.c - superblock checks
11693 #define MIN_CHECK 1
11694 #define MAX_CHECK 2
11696 static void check_super_value(e2fsck_t ctx, const char *descr,
11697 unsigned long value, int flags,
11698 unsigned long min_val, unsigned long max_val)
11700 struct problem_context pctx;
11702 if (((flags & MIN_CHECK) && (value < min_val)) ||
11703 ((flags & MAX_CHECK) && (value > max_val))) {
11704 clear_problem_context(&pctx);
11707 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11708 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11713 * This routine may get stubbed out in special compilations of the
11716 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11717 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11719 return (ext2fs_get_device_size(ctx->filesystem_name,
11720 EXT2_BLOCK_SIZE(ctx->fs->super),
11721 &ctx->num_blocks));
11726 * helper function to release an inode
11728 struct process_block_struct {
11731 struct problem_context *pctx;
11733 int truncate_offset;
11734 e2_blkcnt_t truncate_block;
11735 int truncated_blocks;
11740 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11741 e2_blkcnt_t blockcnt,
11742 blk_t ref_blk FSCK_ATTR((unused)),
11743 int ref_offset FSCK_ATTR((unused)),
11746 struct process_block_struct *pb;
11748 struct problem_context *pctx;
11749 blk_t blk = *block_nr;
11752 pb = (struct process_block_struct *) priv_data;
11757 pctx->blkcount = blockcnt;
11759 if (HOLE_BLKADDR(blk))
11762 if ((blk < fs->super->s_first_data_block) ||
11763 (blk >= fs->super->s_blocks_count)) {
11764 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11767 return BLOCK_ABORT;
11770 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11771 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11776 * If we are deleting an orphan, then we leave the fields alone.
11777 * If we are truncating an orphan, then update the inode fields
11778 * and clean up any partial block data.
11780 if (pb->truncating) {
11782 * We only remove indirect blocks if they are
11783 * completely empty.
11785 if (blockcnt < 0) {
11789 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11794 limit = fs->blocksize >> 2;
11795 for (i = 0, bp = (blk_t *) pb->buf;
11796 i < limit; i++, bp++)
11801 * We don't remove direct blocks until we've reached
11802 * the truncation block.
11804 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11807 * If part of the last block needs truncating, we do
11810 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11811 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11815 memset(pb->buf + pb->truncate_offset, 0,
11816 fs->blocksize - pb->truncate_offset);
11817 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11822 pb->truncated_blocks++;
11824 retval |= BLOCK_CHANGED;
11827 ext2fs_block_alloc_stats(fs, blk, -1);
11832 * This function releases an inode. Returns 1 if an inconsistency was
11833 * found. If the inode has a link count, then it is being truncated and
11836 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11837 struct ext2_inode *inode, char *block_buf,
11838 struct problem_context *pctx)
11840 struct process_block_struct pb;
11841 ext2_filsys fs = ctx->fs;
11845 if (!ext2fs_inode_has_valid_blocks(inode))
11848 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11853 if (inode->i_links_count) {
11855 pb.truncate_block = (e2_blkcnt_t)
11856 ((((long long)inode->i_size_high << 32) +
11857 inode->i_size + fs->blocksize - 1) /
11859 pb.truncate_offset = inode->i_size % fs->blocksize;
11862 pb.truncate_block = 0;
11863 pb.truncate_offset = 0;
11865 pb.truncated_blocks = 0;
11866 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11867 block_buf, release_inode_block, &pb);
11869 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11876 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11877 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11879 if (pb.truncated_blocks)
11880 inode->i_blocks -= pb.truncated_blocks *
11881 (fs->blocksize / 512);
11883 if (inode->i_file_acl) {
11884 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11885 block_buf, -1, &count);
11886 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11891 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11896 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11897 inode->i_file_acl = 0;
11903 * This function releases all of the orphan inodes. It returns 1 if
11904 * it hit some error, and 0 on success.
11906 static int release_orphan_inodes(e2fsck_t ctx)
11908 ext2_filsys fs = ctx->fs;
11909 ext2_ino_t ino, next_ino;
11910 struct ext2_inode inode;
11911 struct problem_context pctx;
11914 if ((ino = fs->super->s_last_orphan) == 0)
11918 * Win or lose, we won't be using the head of the orphan inode
11921 fs->super->s_last_orphan = 0;
11922 ext2fs_mark_super_dirty(fs);
11925 * If the filesystem contains errors, don't run the orphan
11926 * list, since the orphan list can't be trusted; and we're
11927 * going to be running a full e2fsck run anyway...
11929 if (fs->super->s_state & EXT2_ERROR_FS)
11932 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11933 (ino > fs->super->s_inodes_count)) {
11934 clear_problem_context(&pctx);
11936 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11940 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11941 "block iterate buffer");
11942 e2fsck_read_bitmaps(ctx);
11945 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11946 clear_problem_context(&pctx);
11948 pctx.inode = &inode;
11949 pctx.str = inode.i_links_count ? _("Truncating") :
11952 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11954 next_ino = inode.i_dtime;
11956 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11957 (next_ino > fs->super->s_inodes_count))) {
11958 pctx.ino = next_ino;
11959 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11963 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11966 if (!inode.i_links_count) {
11967 ext2fs_inode_alloc_stats2(fs, ino, -1,
11968 LINUX_S_ISDIR(inode.i_mode));
11969 inode.i_dtime = time(0);
11973 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11976 ext2fs_free_mem(&block_buf);
11979 ext2fs_free_mem(&block_buf);
11984 * Check the resize inode to make sure it is sane. We check both for
11985 * the case where on-line resizing is not enabled (in which case the
11986 * resize inode should be cleared) as well as the case where on-line
11987 * resizing is enabled.
11989 static void check_resize_inode(e2fsck_t ctx)
11991 ext2_filsys fs = ctx->fs;
11992 struct ext2_inode inode;
11993 struct problem_context pctx;
11994 int i, j, gdt_off, ind_off;
11995 blk_t blk, pblk, expect;
11996 __u32 *dind_buf = 0, *ind_buf;
11999 clear_problem_context(&pctx);
12002 * If the resize inode feature isn't set, then
12003 * s_reserved_gdt_blocks must be zero.
12005 if (!(fs->super->s_feature_compat &
12006 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12007 if (fs->super->s_reserved_gdt_blocks) {
12008 pctx.num = fs->super->s_reserved_gdt_blocks;
12009 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
12011 fs->super->s_reserved_gdt_blocks = 0;
12012 ext2fs_mark_super_dirty(fs);
12017 /* Read the resize inode */
12018 pctx.ino = EXT2_RESIZE_INO;
12019 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
12021 if (fs->super->s_feature_compat &
12022 EXT2_FEATURE_COMPAT_RESIZE_INODE)
12023 ctx->flags |= E2F_FLAG_RESIZE_INODE;
12028 * If the resize inode feature isn't set, check to make sure
12029 * the resize inode is cleared; then we're done.
12031 if (!(fs->super->s_feature_compat &
12032 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12033 for (i=0; i < EXT2_N_BLOCKS; i++) {
12034 if (inode.i_block[i])
12037 if ((i < EXT2_N_BLOCKS) &&
12038 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
12039 memset(&inode, 0, sizeof(inode));
12040 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12047 * The resize inode feature is enabled; check to make sure the
12048 * only block in use is the double indirect block
12050 blk = inode.i_block[EXT2_DIND_BLOCK];
12051 for (i=0; i < EXT2_N_BLOCKS; i++) {
12052 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
12055 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
12056 !(inode.i_mode & LINUX_S_IFREG) ||
12057 (blk < fs->super->s_first_data_block ||
12058 blk >= fs->super->s_blocks_count)) {
12059 resize_inode_invalid:
12060 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
12061 memset(&inode, 0, sizeof(inode));
12062 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12064 ctx->flags |= E2F_FLAG_RESIZE_INODE;
12066 if (!(ctx->options & E2F_OPT_READONLY)) {
12067 fs->super->s_state &= ~EXT2_VALID_FS;
12068 ext2fs_mark_super_dirty(fs);
12072 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
12073 "resize dind buffer");
12074 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
12076 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
12078 goto resize_inode_invalid;
12080 gdt_off = fs->desc_blocks;
12081 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
12082 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
12083 i++, gdt_off++, pblk++) {
12084 gdt_off %= fs->blocksize/4;
12085 if (dind_buf[gdt_off] != pblk)
12086 goto resize_inode_invalid;
12087 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
12089 goto resize_inode_invalid;
12091 for (j = 1; j < fs->group_desc_count; j++) {
12092 if (!ext2fs_bg_has_super(fs, j))
12094 expect = pblk + (j * fs->super->s_blocks_per_group);
12095 if (ind_buf[ind_off] != expect)
12096 goto resize_inode_invalid;
12102 ext2fs_free_mem(&dind_buf);
12106 static void check_super_block(e2fsck_t ctx)
12108 ext2_filsys fs = ctx->fs;
12109 blk_t first_block, last_block;
12110 struct ext2_super_block *sb = fs->super;
12111 struct ext2_group_desc *gd;
12112 blk_t blocks_per_group = fs->super->s_blocks_per_group;
12114 int inodes_per_block;
12119 struct problem_context pctx;
12120 __u32 free_blocks = 0, free_inodes = 0;
12122 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
12123 ipg_max = inodes_per_block * (blocks_per_group - 4);
12124 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
12125 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
12126 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
12127 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
12128 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
12130 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
12131 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
12132 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
12133 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
12134 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
12135 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
12137 clear_problem_context(&pctx);
12140 * Verify the super block constants...
12142 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
12144 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
12146 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
12147 MAX_CHECK, 0, sb->s_blocks_count);
12148 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
12149 MIN_CHECK | MAX_CHECK, 0,
12150 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
12151 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
12152 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
12153 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
12154 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
12156 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
12157 MIN_CHECK | MAX_CHECK, 8, bpg_max);
12158 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
12159 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
12160 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
12161 MAX_CHECK, 0, sb->s_blocks_count / 2);
12162 check_super_value(ctx, "reserved_gdt_blocks",
12163 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
12165 inode_size = EXT2_INODE_SIZE(sb);
12166 check_super_value(ctx, "inode_size",
12167 inode_size, MIN_CHECK | MAX_CHECK,
12168 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
12169 if (inode_size & (inode_size - 1)) {
12170 pctx.num = inode_size;
12171 pctx.str = "inode_size";
12172 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
12173 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
12177 if (!ctx->num_blocks) {
12178 pctx.errcode = e2fsck_get_device_size(ctx);
12179 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
12180 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
12181 ctx->flags |= E2F_FLAG_ABORT;
12184 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
12185 (ctx->num_blocks < sb->s_blocks_count)) {
12186 pctx.blk = sb->s_blocks_count;
12187 pctx.blk2 = ctx->num_blocks;
12188 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
12189 ctx->flags |= E2F_FLAG_ABORT;
12195 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
12196 pctx.blk = EXT2_BLOCK_SIZE(sb);
12197 pctx.blk2 = EXT2_FRAG_SIZE(sb);
12198 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
12199 ctx->flags |= E2F_FLAG_ABORT;
12203 should_be = sb->s_frags_per_group >>
12204 (sb->s_log_block_size - sb->s_log_frag_size);
12205 if (sb->s_blocks_per_group != should_be) {
12206 pctx.blk = sb->s_blocks_per_group;
12207 pctx.blk2 = should_be;
12208 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
12209 ctx->flags |= E2F_FLAG_ABORT;
12213 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
12214 if (sb->s_first_data_block != should_be) {
12215 pctx.blk = sb->s_first_data_block;
12216 pctx.blk2 = should_be;
12217 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
12218 ctx->flags |= E2F_FLAG_ABORT;
12222 should_be = sb->s_inodes_per_group * fs->group_desc_count;
12223 if (sb->s_inodes_count != should_be) {
12224 pctx.ino = sb->s_inodes_count;
12225 pctx.ino2 = should_be;
12226 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
12227 sb->s_inodes_count = should_be;
12228 ext2fs_mark_super_dirty(fs);
12233 * Verify the group descriptors....
12235 first_block = sb->s_first_data_block;
12236 last_block = first_block + blocks_per_group;
12238 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
12241 if (i == fs->group_desc_count - 1)
12242 last_block = sb->s_blocks_count;
12243 if ((gd->bg_block_bitmap < first_block) ||
12244 (gd->bg_block_bitmap >= last_block)) {
12245 pctx.blk = gd->bg_block_bitmap;
12246 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
12247 gd->bg_block_bitmap = 0;
12249 if (gd->bg_block_bitmap == 0) {
12250 ctx->invalid_block_bitmap_flag[i]++;
12251 ctx->invalid_bitmaps++;
12253 if ((gd->bg_inode_bitmap < first_block) ||
12254 (gd->bg_inode_bitmap >= last_block)) {
12255 pctx.blk = gd->bg_inode_bitmap;
12256 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
12257 gd->bg_inode_bitmap = 0;
12259 if (gd->bg_inode_bitmap == 0) {
12260 ctx->invalid_inode_bitmap_flag[i]++;
12261 ctx->invalid_bitmaps++;
12263 if ((gd->bg_inode_table < first_block) ||
12264 ((gd->bg_inode_table +
12265 fs->inode_blocks_per_group - 1) >= last_block)) {
12266 pctx.blk = gd->bg_inode_table;
12267 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
12268 gd->bg_inode_table = 0;
12270 if (gd->bg_inode_table == 0) {
12271 ctx->invalid_inode_table_flag[i]++;
12272 ctx->invalid_bitmaps++;
12274 free_blocks += gd->bg_free_blocks_count;
12275 free_inodes += gd->bg_free_inodes_count;
12276 first_block += sb->s_blocks_per_group;
12277 last_block += sb->s_blocks_per_group;
12279 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
12280 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
12281 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
12282 ext2fs_unmark_valid(fs);
12287 * Update the global counts from the block group counts. This
12288 * is needed for an experimental patch which eliminates
12289 * locking the entire filesystem when allocating blocks or
12290 * inodes; if the filesystem is not unmounted cleanly, the
12291 * global counts may not be accurate.
12293 if ((free_blocks != sb->s_free_blocks_count) ||
12294 (free_inodes != sb->s_free_inodes_count)) {
12295 if (ctx->options & E2F_OPT_READONLY)
12296 ext2fs_unmark_valid(fs);
12298 sb->s_free_blocks_count = free_blocks;
12299 sb->s_free_inodes_count = free_inodes;
12300 ext2fs_mark_super_dirty(fs);
12304 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
12305 (sb->s_free_inodes_count > sb->s_inodes_count))
12306 ext2fs_unmark_valid(fs);
12310 * If we have invalid bitmaps, set the error state of the
12313 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
12314 sb->s_state &= ~EXT2_VALID_FS;
12315 ext2fs_mark_super_dirty(fs);
12318 clear_problem_context(&pctx);
12321 * If the UUID field isn't assigned, assign it.
12323 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
12324 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
12325 uuid_generate(sb->s_uuid);
12326 ext2fs_mark_super_dirty(fs);
12327 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12331 /* FIXME - HURD support?
12332 * For the Hurd, check to see if the filetype option is set,
12333 * since it doesn't support it.
12335 if (!(ctx->options & E2F_OPT_READONLY) &&
12336 fs->super->s_creator_os == EXT2_OS_HURD &&
12337 (fs->super->s_feature_incompat &
12338 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
12339 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
12340 fs->super->s_feature_incompat &=
12341 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
12342 ext2fs_mark_super_dirty(fs);
12348 * If we have any of the compatibility flags set, we need to have a
12349 * revision 1 filesystem. Most kernels will not check the flags on
12350 * a rev 0 filesystem and we may have corruption issues because of
12351 * the incompatible changes to the filesystem.
12353 if (!(ctx->options & E2F_OPT_READONLY) &&
12354 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
12355 (fs->super->s_feature_compat ||
12356 fs->super->s_feature_ro_compat ||
12357 fs->super->s_feature_incompat) &&
12358 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
12359 ext2fs_update_dynamic_rev(fs);
12360 ext2fs_mark_super_dirty(fs);
12363 check_resize_inode(ctx);
12366 * Clean up any orphan inodes, if present.
12368 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
12369 fs->super->s_state &= ~EXT2_VALID_FS;
12370 ext2fs_mark_super_dirty(fs);
12374 * Move the ext3 journal file, if necessary.
12376 e2fsck_move_ext3_journal(ctx);
12381 * swapfs.c --- byte-swap an ext2 filesystem
12384 #ifdef ENABLE_SWAPFS
12386 struct swap_block_struct {
12391 struct ext2_inode *inode;
12395 * This is a helper function for block_iterate. We mark all of the
12396 * indirect and direct blocks as changed, so that block_iterate will
12399 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
12404 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
12406 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
12407 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
12409 sb->errcode = retval;
12410 return BLOCK_ABORT;
12412 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
12414 sb->errcode = retval;
12415 return BLOCK_ABORT;
12418 if (blockcnt >= 0) {
12419 if (blockcnt < EXT2_NDIR_BLOCKS)
12421 return BLOCK_CHANGED;
12423 if (blockcnt == BLOCK_COUNT_IND) {
12424 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
12426 return BLOCK_CHANGED;
12428 if (blockcnt == BLOCK_COUNT_DIND) {
12429 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12431 return BLOCK_CHANGED;
12433 if (blockcnt == BLOCK_COUNT_TIND) {
12434 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12436 return BLOCK_CHANGED;
12438 return BLOCK_CHANGED;
12442 * This function is responsible for byte-swapping all of the indirect,
12443 * block pointers. It is also responsible for byte-swapping directories.
12445 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12446 struct ext2_inode *inode)
12449 struct swap_block_struct sb;
12453 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12456 if (LINUX_S_ISDIR(inode->i_mode))
12459 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12462 bb_error_msg(_("while calling ext2fs_block_iterate"));
12463 ctx->flags |= E2F_FLAG_ABORT;
12467 bb_error_msg(_("while calling iterator function"));
12468 ctx->flags |= E2F_FLAG_ABORT;
12473 static void swap_inodes(e2fsck_t ctx)
12475 ext2_filsys fs = ctx->fs;
12478 ext2_ino_t ino = 1;
12479 char *buf, *block_buf;
12481 struct ext2_inode * inode;
12483 e2fsck_use_inode_shortcuts(ctx, 1);
12485 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12488 bb_error_msg(_("while allocating inode buffer"));
12489 ctx->flags |= E2F_FLAG_ABORT;
12492 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12493 "block interate buffer");
12494 for (group = 0; group < fs->group_desc_count; group++) {
12495 retval = io_channel_read_blk(fs->io,
12496 fs->group_desc[group].bg_inode_table,
12497 fs->inode_blocks_per_group, buf);
12499 bb_error_msg(_("while reading inode table (group %d)"),
12501 ctx->flags |= E2F_FLAG_ABORT;
12504 inode = (struct ext2_inode *) buf;
12505 for (i=0; i < fs->super->s_inodes_per_group;
12506 i++, ino++, inode++) {
12507 ctx->stashed_ino = ino;
12508 ctx->stashed_inode = inode;
12510 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12511 ext2fs_swap_inode(fs, inode, inode, 0);
12514 * Skip deleted files.
12516 if (inode->i_links_count == 0)
12519 if (LINUX_S_ISDIR(inode->i_mode) ||
12520 ((inode->i_block[EXT2_IND_BLOCK] ||
12521 inode->i_block[EXT2_DIND_BLOCK] ||
12522 inode->i_block[EXT2_TIND_BLOCK]) &&
12523 ext2fs_inode_has_valid_blocks(inode)))
12524 swap_inode_blocks(ctx, ino, block_buf, inode);
12526 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12529 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12530 ext2fs_swap_inode(fs, inode, inode, 1);
12532 retval = io_channel_write_blk(fs->io,
12533 fs->group_desc[group].bg_inode_table,
12534 fs->inode_blocks_per_group, buf);
12536 bb_error_msg(_("while writing inode table (group %d)"),
12538 ctx->flags |= E2F_FLAG_ABORT;
12542 ext2fs_free_mem(&buf);
12543 ext2fs_free_mem(&block_buf);
12544 e2fsck_use_inode_shortcuts(ctx, 0);
12545 ext2fs_flush_icache(fs);
12548 #if defined(__powerpc__) && BB_BIG_ENDIAN
12550 * On the PowerPC, the big-endian variant of the ext2 filesystem
12551 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12552 * of each word. Thus a bitmap with only bit 0 set would be, as
12553 * a string of bytes, 00 00 00 01 00 ...
12554 * To cope with this, we byte-reverse each word of a bitmap if
12555 * we have a big-endian filesystem, that is, if we are *not*
12556 * byte-swapping other word-sized numbers.
12558 #define EXT2_BIG_ENDIAN_BITMAPS
12561 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12562 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12564 __u32 *p = (__u32 *) bmap->bitmap;
12565 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12567 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12568 *p = ext2fs_swab32(*p);
12573 #ifdef ENABLE_SWAPFS
12574 static void swap_filesys(e2fsck_t ctx)
12576 ext2_filsys fs = ctx->fs;
12577 if (!(ctx->options & E2F_OPT_PREEN))
12578 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12582 if (fs->super->s_mnt_count) {
12583 fprintf(stderr, _("%s: the filesystem must be freshly "
12584 "checked using fsck\n"
12585 "and not mounted before trying to "
12586 "byte-swap it.\n"), ctx->device_name);
12587 ctx->flags |= E2F_FLAG_ABORT;
12590 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12591 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12592 EXT2_FLAG_SWAP_BYTES_WRITE);
12593 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12595 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12596 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12599 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12601 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12602 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12603 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12604 EXT2_FLAG_SWAP_BYTES_WRITE);
12606 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12607 e2fsck_read_bitmaps(ctx);
12608 ext2fs_swap_bitmap(fs->inode_map);
12609 ext2fs_swap_bitmap(fs->block_map);
12610 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12612 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12614 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12616 #endif /* ENABLE_SWAPFS */
12621 * util.c --- miscellaneous utilities
12625 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12626 const char *description)
12631 ret = malloc(size);
12633 sprintf(buf, "Can't allocate %s\n", description);
12634 bb_error_msg_and_die(buf);
12636 memset(ret, 0, size);
12640 static char *string_copy(const char *str, int len)
12648 ret = malloc(len+1);
12650 strncpy(ret, str, len);
12656 #ifndef HAVE_CONIO_H
12657 static int read_a_char(void)
12664 if (e2fsck_global_ctx &&
12665 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12668 r = read(0, &c, 1);
12678 static int ask_yn(const char * string, int def)
12681 const char *defstr;
12682 static const char short_yes[] = "yY";
12683 static const char short_no[] = "nN";
12685 #ifdef HAVE_TERMIOS_H
12686 struct termios termios, tmp;
12688 tcgetattr (0, &termios);
12690 tmp.c_lflag &= ~(ICANON | ECHO);
12691 tmp.c_cc[VMIN] = 1;
12692 tmp.c_cc[VTIME] = 0;
12693 tcsetattr (0, TCSANOW, &tmp);
12702 printf("%s%s? ", string, defstr);
12705 if ((c = read_a_char()) == EOF)
12708 #ifdef HAVE_TERMIOS_H
12709 tcsetattr (0, TCSANOW, &termios);
12711 if (e2fsck_global_ctx &&
12712 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12714 longjmp(e2fsck_global_ctx->abort_loc, 1);
12716 puts(_("cancelled!\n"));
12719 if (strchr(short_yes, (char) c)) {
12723 else if (strchr(short_no, (char) c)) {
12727 else if ((c == ' ' || c == '\n') && (def != -1))
12734 #ifdef HAVE_TERMIOS_H
12735 tcsetattr (0, TCSANOW, &termios);
12740 int ask (e2fsck_t ctx, const char * string, int def)
12742 if (ctx->options & E2F_OPT_NO) {
12743 printf (_("%s? no\n\n"), string);
12746 if (ctx->options & E2F_OPT_YES) {
12747 printf (_("%s? yes\n\n"), string);
12750 if (ctx->options & E2F_OPT_PREEN) {
12751 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
12754 return ask_yn(string, def);
12757 void e2fsck_read_bitmaps(e2fsck_t ctx)
12759 ext2_filsys fs = ctx->fs;
12762 if (ctx->invalid_bitmaps) {
12763 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12765 bb_error_msg_and_die(0);
12768 ehandler_operation(_("reading inode and block bitmaps"));
12769 retval = ext2fs_read_bitmaps(fs);
12770 ehandler_operation(0);
12772 bb_error_msg(_("while retrying to read bitmaps for %s"),
12774 bb_error_msg_and_die(0);
12778 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12780 ext2_filsys fs = ctx->fs;
12783 if (ext2fs_test_bb_dirty(fs)) {
12784 ehandler_operation(_("writing block bitmaps"));
12785 retval = ext2fs_write_block_bitmap(fs);
12786 ehandler_operation(0);
12788 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12790 bb_error_msg_and_die(0);
12794 if (ext2fs_test_ib_dirty(fs)) {
12795 ehandler_operation(_("writing inode bitmaps"));
12796 retval = ext2fs_write_inode_bitmap(fs);
12797 ehandler_operation(0);
12799 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12801 bb_error_msg_and_die(0);
12806 void preenhalt(e2fsck_t ctx)
12808 ext2_filsys fs = ctx->fs;
12810 if (!(ctx->options & E2F_OPT_PREEN))
12812 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12813 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12816 fs->super->s_state |= EXT2_ERROR_FS;
12817 ext2fs_mark_super_dirty(fs);
12820 exit(EXIT_UNCORRECTED);
12823 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12824 struct ext2_inode * inode, const char *proc)
12828 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12830 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12831 bb_error_msg_and_die(0);
12835 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12836 struct ext2_inode * inode, int bufsize,
12841 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12843 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12844 bb_error_msg_and_die(0);
12848 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12849 struct ext2_inode * inode, const char *proc)
12853 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12855 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12856 bb_error_msg_and_die(0);
12860 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12861 io_manager manager)
12863 struct ext2_super_block *sb;
12864 io_channel io = NULL;
12867 blk_t superblock, ret_sb = 8193;
12869 if (fs && fs->super) {
12870 ret_sb = (fs->super->s_blocks_per_group +
12871 fs->super->s_first_data_block);
12873 ctx->superblock = ret_sb;
12874 ctx->blocksize = fs->blocksize;
12880 if (ctx->blocksize) {
12881 ret_sb = ctx->blocksize * 8;
12882 if (ctx->blocksize == 1024)
12884 ctx->superblock = ret_sb;
12887 ctx->superblock = ret_sb;
12888 ctx->blocksize = 1024;
12891 if (!name || !manager)
12894 if (manager->open(name, 0, &io) != 0)
12897 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12899 sb = (struct ext2_super_block *) buf;
12901 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12902 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
12903 superblock = blocksize*8;
12904 if (blocksize == 1024)
12906 io_channel_set_blksize(io, blocksize);
12907 if (io_channel_read_blk(io, superblock,
12908 -SUPERBLOCK_SIZE, buf))
12911 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12912 ext2fs_swap_super(sb);
12914 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12915 ret_sb = superblock;
12917 ctx->superblock = superblock;
12918 ctx->blocksize = blocksize;
12926 io_channel_close(io);
12927 ext2fs_free_mem(&buf);
12933 * This function runs through the e2fsck passes and calls them all,
12934 * returning restart, abort, or cancel as necessary...
12936 typedef void (*pass_t)(e2fsck_t ctx);
12938 static const pass_t e2fsck_passes[] = {
12939 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12942 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12944 static int e2fsck_run(e2fsck_t ctx)
12947 pass_t e2fsck_pass;
12949 if (setjmp(ctx->abort_loc)) {
12950 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12951 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12953 ctx->flags |= E2F_FLAG_SETJMP_OK;
12955 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12956 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12960 (void) (ctx->progress)(ctx, 0, 0, 0);
12962 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12964 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12965 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12971 * unix.c - The unix-specific code for e2fsck
12975 /* Command line options */
12977 #ifdef ENABLE_SWAPFS
12978 static int normalize_swapfs;
12980 static int cflag; /* check disk */
12981 static int show_version_only;
12982 static int verbose;
12984 static int replace_bad_blocks;
12985 static int keep_bad_blocks;
12986 static char *bad_blocks_file;
12988 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12990 static void show_stats(e2fsck_t ctx)
12992 ext2_filsys fs = ctx->fs;
12993 int inodes, inodes_used, blocks, blocks_used;
12995 int num_files, num_links;
12998 dir_links = 2 * ctx->fs_directory_count - 1;
12999 num_files = ctx->fs_total_count - dir_links;
13000 num_links = ctx->fs_links_count - dir_links;
13001 inodes = fs->super->s_inodes_count;
13002 inodes_used = (fs->super->s_inodes_count -
13003 fs->super->s_free_inodes_count);
13004 blocks = fs->super->s_blocks_count;
13005 blocks_used = (fs->super->s_blocks_count -
13006 fs->super->s_free_blocks_count);
13008 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
13009 frag_percent = (frag_percent + 5) / 10;
13012 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
13013 ctx->device_name, inodes_used, inodes,
13014 frag_percent / 10, frag_percent % 10,
13015 blocks_used, blocks);
13018 printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
13019 100 * inodes_used / inodes);
13020 printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
13021 P_E2("", "s", ctx->fs_fragmented),
13022 frag_percent / 10, frag_percent % 10);
13023 printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
13024 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
13025 printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
13026 (int) ((long long) 100 * blocks_used / blocks));
13027 printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count));
13028 printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
13029 printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
13030 printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
13031 printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
13032 printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
13033 printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
13034 printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
13035 printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
13036 printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
13037 printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
13038 printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
13041 static void check_mount(e2fsck_t ctx)
13046 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
13047 &ctx->mount_flags);
13049 bb_error_msg(_("while determining whether %s is mounted."),
13050 ctx->filesystem_name);
13055 * If the filesystem isn't mounted, or it's the root filesystem
13056 * and it's mounted read-only, then everything's fine.
13058 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
13059 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
13060 (ctx->mount_flags & EXT2_MF_READONLY)))
13063 if (ctx->options & E2F_OPT_READONLY) {
13064 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
13068 printf(_("%s is mounted. "), ctx->filesystem_name);
13069 if (!ctx->interactive)
13070 bb_error_msg_and_die(_("Cannot continue, aborting.\n\n"));
13071 printf(_("\n\n\007\007\007\007WARNING!!! "
13072 "Running e2fsck on a mounted filesystem may cause\n"
13073 "SEVERE filesystem damage.\007\007\007\n\n"));
13074 cont = ask_yn(_("Do you really want to continue"), -1);
13076 printf (_("check aborted.\n"));
13082 static int is_on_batt(void)
13086 char tmp[80], tmp2[80], fname[80];
13087 unsigned int acflag;
13090 f = fopen("/proc/apm", "r");
13092 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
13095 return (acflag != 1);
13097 d = opendir("/proc/acpi/ac_adapter");
13099 while ((de=readdir(d)) != NULL) {
13100 if (!strncmp(".", de->d_name, 1))
13102 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
13104 f = fopen(fname, "r");
13107 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
13110 if (strncmp(tmp, "off-line", 8) == 0) {
13121 * This routine checks to see if a filesystem can be skipped; if so,
13122 * it will exit with EXIT_OK. Under some conditions it will print a
13123 * message explaining why a check is being forced.
13125 static void check_if_skip(e2fsck_t ctx)
13127 ext2_filsys fs = ctx->fs;
13128 const char *reason = NULL;
13129 unsigned int reason_arg = 0;
13131 int batt = is_on_batt();
13132 time_t now = time(0);
13134 if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
13138 if ((fs->super->s_state & EXT2_ERROR_FS) ||
13139 !ext2fs_test_valid(fs))
13140 reason = _(" contains a file system with errors");
13141 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
13142 reason = _(" was not cleanly unmounted");
13143 else if ((fs->super->s_max_mnt_count > 0) &&
13144 (fs->super->s_mnt_count >=
13145 (unsigned) fs->super->s_max_mnt_count)) {
13146 reason = _(" has been mounted %u times without being checked");
13147 reason_arg = fs->super->s_mnt_count;
13148 if (batt && (fs->super->s_mnt_count <
13149 (unsigned) fs->super->s_max_mnt_count*2))
13151 } else if (fs->super->s_checkinterval &&
13152 ((now - fs->super->s_lastcheck) >=
13153 fs->super->s_checkinterval)) {
13154 reason = _(" has gone %u days without being checked");
13155 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
13156 if (batt && ((now - fs->super->s_lastcheck) <
13157 fs->super->s_checkinterval*2))
13161 fputs(ctx->device_name, stdout);
13162 printf(reason, reason_arg);
13163 fputs(_(", check forced.\n"), stdout);
13166 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
13167 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
13168 fs->super->s_inodes_count,
13169 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
13170 fs->super->s_blocks_count);
13171 next_check = 100000;
13172 if (fs->super->s_max_mnt_count > 0) {
13173 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
13174 if (next_check <= 0)
13177 if (fs->super->s_checkinterval &&
13178 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
13180 if (next_check <= 5) {
13181 if (next_check == 1)
13182 fputs(_(" (check after next mount)"), stdout);
13184 printf(_(" (check in %ld mounts)"), next_check);
13186 fputc('\n', stdout);
13189 e2fsck_free_context(ctx);
13194 * For completion notice
13196 struct percent_tbl {
13200 static const struct percent_tbl e2fsck_tbl = {
13201 5, { 0, 70, 90, 92, 95, 100 }
13204 static char bar[128], spaces[128];
13206 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
13213 if (pass > tbl->max_pass || max == 0)
13215 percent = ((float) curr) / ((float) max);
13216 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
13217 + tbl->table[pass-1]);
13220 void e2fsck_clear_progbar(e2fsck_t ctx)
13222 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
13225 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
13228 ctx->flags &= ~E2F_FLAG_PROG_BAR;
13231 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
13232 unsigned int dpynum)
13234 static const char spinner[] = "\\|/-";
13241 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
13245 * Calculate the new progress position. If the
13246 * percentage hasn't changed, then we skip out right
13249 fixed_percent = (int) ((10 * percent) + 0.5);
13250 if (ctx->progress_last_percent == fixed_percent)
13252 ctx->progress_last_percent = fixed_percent;
13255 * If we've already updated the spinner once within
13256 * the last 1/8th of a second, no point doing it
13259 gettimeofday(&tv, NULL);
13260 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
13261 if ((tick == ctx->progress_last_time) &&
13262 (fixed_percent != 0) && (fixed_percent != 1000))
13264 ctx->progress_last_time = tick;
13267 * Advance the spinner, and note that the progress bar
13268 * will be on the screen
13270 ctx->progress_pos = (ctx->progress_pos+1) & 3;
13271 ctx->flags |= E2F_FLAG_PROG_BAR;
13273 dpywidth = 66 - strlen(label);
13274 dpywidth = 8 * (dpywidth / 8);
13278 i = ((percent * dpywidth) + 50) / 100;
13279 printf("%s%s: |%s%s", ctx->start_meta, label,
13280 bar + (sizeof(bar) - (i+1)),
13281 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
13282 if (fixed_percent == 1000)
13283 fputc('|', stdout);
13285 fputc(spinner[ctx->progress_pos & 3], stdout);
13286 printf(" %4.1f%% ", percent);
13288 printf("%u\r", dpynum);
13290 fputs(" \r", stdout);
13291 fputs(ctx->stop_meta, stdout);
13293 if (fixed_percent == 1000)
13294 e2fsck_clear_progbar(ctx);
13300 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
13301 unsigned long cur, unsigned long max)
13309 if (ctx->progress_fd) {
13310 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
13311 write(ctx->progress_fd, buf, strlen(buf));
13313 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
13314 e2fsck_simple_progress(ctx, ctx->device_name,
13320 static void reserve_stdio_fds(void)
13325 fd = open(bb_dev_null, O_RDWR);
13329 fprintf(stderr, _("ERROR: Couldn't open "
13330 "/dev/null (%s)\n"),
13338 static void signal_progress_on(int sig FSCK_ATTR((unused)))
13340 e2fsck_t ctx = e2fsck_global_ctx;
13345 ctx->progress = e2fsck_update_progress;
13346 ctx->progress_fd = 0;
13349 static void signal_progress_off(int sig FSCK_ATTR((unused)))
13351 e2fsck_t ctx = e2fsck_global_ctx;
13356 e2fsck_clear_progbar(ctx);
13360 static void signal_cancel(int sig FSCK_ATTR((unused)))
13362 e2fsck_t ctx = e2fsck_global_ctx;
13365 exit(FSCK_CANCELED);
13367 ctx->flags |= E2F_FLAG_CANCEL;
13370 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
13372 char *buf, *token, *next, *p, *arg;
13374 int extended_usage = 0;
13376 buf = string_copy(opts, 0);
13377 for (token = buf; token && *token; token = next) {
13378 p = strchr(token, ',');
13384 arg = strchr(token, '=');
13389 if (strcmp(token, "ea_ver") == 0) {
13394 ea_ver = strtoul(arg, &p, 0);
13396 ((ea_ver != 1) && (ea_ver != 2))) {
13398 _("Invalid EA version.\n"));
13402 ctx->ext_attr_ver = ea_ver;
13404 fprintf(stderr, _("Unknown extended option: %s\n"),
13409 if (extended_usage) {
13410 bb_error_msg_and_die(
13411 "Extended options are separated by commas, "
13412 "and may take an argument which\n"
13413 "is set off by an equals ('=') sign. "
13414 "Valid extended options are:\n"
13415 "\tea_ver=<ea_version (1 or 2)>\n\n");
13420 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
13426 struct sigaction sa;
13427 char *extended_opts = 0;
13429 retval = e2fsck_allocate_context(&ctx);
13435 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
13436 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
13437 if (isatty(0) && isatty(1)) {
13438 ctx->interactive = 1;
13440 ctx->start_meta[0] = '\001';
13441 ctx->stop_meta[0] = '\002';
13443 memset(bar, '=', sizeof(bar)-1);
13444 memset(spaces, ' ', sizeof(spaces)-1);
13445 blkid_get_cache(&ctx->blkid, NULL);
13448 ctx->program_name = *argv;
13450 ctx->program_name = "e2fsck";
13451 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13454 ctx->progress = e2fsck_update_progress;
13455 ctx->progress_fd = atoi(optarg);
13456 if (!ctx->progress_fd)
13458 /* Validate the file descriptor to avoid disasters */
13459 fd = dup(ctx->progress_fd);
13462 _("Error validating file descriptor %d: %s\n"),
13464 error_message(errno));
13465 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13470 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13473 extended_opts = optarg;
13477 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13479 bb_error_msg_and_die(_("Only one the options -p/-a, -n or -y may be specified."));
13481 ctx->options |= E2F_OPT_PREEN;
13484 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13486 ctx->options |= E2F_OPT_NO;
13489 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13491 ctx->options |= E2F_OPT_YES;
13494 /* FIXME - This needs to go away in a future path - will change binary */
13495 fprintf(stderr, _("The -t option is not "
13496 "supported on this version of e2fsck.\n"));
13500 ctx->options |= E2F_OPT_WRITECHECK;
13501 ctx->options |= E2F_OPT_CHECKBLOCKS;
13504 /* What we do by default, anyway! */
13507 ctx->use_superblock = atoi(optarg);
13508 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13511 ctx->blocksize = atoi(optarg);
13514 ctx->inode_buffer_blocks = atoi(optarg);
13517 ctx->journal_name = string_copy(optarg, 0);
13520 ctx->process_inode_size = atoi(optarg);
13523 replace_bad_blocks++;
13525 bad_blocks_file = string_copy(optarg, 0);
13528 ctx->options |= E2F_OPT_DEBUG;
13531 ctx->options |= E2F_OPT_FORCE;
13540 show_version_only = 1;
13543 ctx->device_name = optarg;
13545 #ifdef ENABLE_SWAPFS
13547 normalize_swapfs = 1;
13554 fprintf(stderr, _("Byte-swapping filesystems "
13555 "not compiled in this version "
13565 if (show_version_only)
13567 if (optind != argc - 1)
13569 if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
13570 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13571 ctx->options |= E2F_OPT_READONLY;
13572 ctx->io_options = strchr(argv[optind], '?');
13573 if (ctx->io_options)
13574 *ctx->io_options++ = 0;
13575 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13576 if (!ctx->filesystem_name) {
13577 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13578 bb_error_msg_and_die(0);
13581 parse_extended_opts(ctx, extended_opts);
13584 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13586 bb_error_msg(_("while opening %s for flushing"),
13587 ctx->filesystem_name);
13588 bb_error_msg_and_die(0);
13590 if ((retval = ext2fs_sync_device(fd, 1))) {
13591 bb_error_msg(_("while trying to flush %s"),
13592 ctx->filesystem_name);
13593 bb_error_msg_and_die(0);
13597 #ifdef ENABLE_SWAPFS
13599 if (cflag || bad_blocks_file) {
13600 fprintf(stderr, _("Incompatible options not "
13601 "allowed when byte-swapping.\n"));
13606 if (cflag && bad_blocks_file) {
13607 fprintf(stderr, _("The -c and the -l/-L options may "
13608 "not be both used at the same time.\n"));
13612 * Set up signal action
13614 memset(&sa, 0, sizeof(struct sigaction));
13615 sa.sa_handler = signal_cancel;
13616 sigaction(SIGINT, &sa, 0);
13617 sigaction(SIGTERM, &sa, 0);
13619 sa.sa_flags = SA_RESTART;
13621 e2fsck_global_ctx = ctx;
13622 sa.sa_handler = signal_progress_on;
13623 sigaction(SIGUSR1, &sa, 0);
13624 sa.sa_handler = signal_progress_off;
13625 sigaction(SIGUSR2, &sa, 0);
13627 /* Update our PATH to include /sbin if we need to run badblocks */
13629 e2fs_set_sbin_path();
13633 static const char my_ver_string[] = E2FSPROGS_VERSION;
13634 static const char my_ver_date[] = E2FSPROGS_DATE;
13636 int e2fsck_main (int argc, char *argv[])
13639 int exit_value = EXIT_OK;
13640 ext2_filsys fs = 0;
13642 struct ext2_super_block *sb;
13643 const char *lib_ver_date;
13644 int my_ver, lib_ver;
13646 struct problem_context pctx;
13647 int flags, run_result;
13649 clear_problem_context(&pctx);
13651 my_ver = ext2fs_parse_version_string(my_ver_string);
13652 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13653 if (my_ver > lib_ver) {
13654 fprintf( stderr, _("Error: ext2fs library version "
13655 "out of date!\n"));
13656 show_version_only++;
13659 retval = PRS(argc, argv, &ctx);
13661 bb_error_msg(_("while trying to initialize program"));
13664 reserve_stdio_fds();
13666 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13667 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13670 if (show_version_only) {
13671 fprintf(stderr, _("\tUsing %s, %s\n"),
13672 error_message(EXT2_ET_BASE), lib_ver_date);
13678 if (!(ctx->options & E2F_OPT_PREEN) &&
13679 !(ctx->options & E2F_OPT_NO) &&
13680 !(ctx->options & E2F_OPT_YES)) {
13681 if (!ctx->interactive)
13682 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13684 ctx->superblock = ctx->use_superblock;
13686 #ifdef CONFIG_TESTIO_DEBUG
13687 io_ptr = test_io_manager;
13688 test_io_backing_manager = unix_io_manager;
13690 io_ptr = unix_io_manager;
13693 if ((ctx->options & E2F_OPT_READONLY) == 0)
13694 flags |= EXT2_FLAG_RW;
13696 if (ctx->superblock && ctx->blocksize) {
13697 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13698 flags, ctx->superblock, ctx->blocksize,
13700 } else if (ctx->superblock) {
13702 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13703 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13704 retval = ext2fs_open2(ctx->filesystem_name,
13705 ctx->io_options, flags,
13706 ctx->superblock, blocksize,
13712 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13713 flags, 0, 0, io_ptr, &fs);
13714 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13715 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13716 ((retval == EXT2_ET_BAD_MAGIC) ||
13717 ((retval == 0) && ext2fs_check_desc(fs)))) {
13718 if (!fs || (fs->group_desc_count > 1)) {
13719 printf(_("%s trying backup blocks...\n"),
13720 retval ? _("Couldn't find ext2 superblock,") :
13721 _("Group descriptors look bad..."));
13722 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13729 bb_error_msg(_("while trying to open %s"),
13730 ctx->filesystem_name);
13731 if (retval == EXT2_ET_REV_TOO_HIGH) {
13732 printf(_("The filesystem revision is apparently "
13733 "too high for this version of e2fsck.\n"
13734 "(Or the filesystem superblock "
13735 "is corrupt)\n\n"));
13736 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13737 } else if (retval == EXT2_ET_SHORT_READ)
13738 printf(_("Could this be a zero-length partition?\n"));
13739 else if ((retval == EPERM) || (retval == EACCES))
13740 printf(_("You must have %s access to the "
13741 "filesystem or be root\n"),
13742 (ctx->options & E2F_OPT_READONLY) ?
13744 else if (retval == ENXIO)
13745 printf(_("Possibly non-existent or swap device?\n"));
13747 else if (retval == EROFS)
13748 printf(_("Disk write-protected; use the -n option "
13749 "to do a read-only\n"
13750 "check of the device.\n"));
13753 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13754 bb_error_msg_and_die(0);
13757 fs->priv_data = ctx;
13759 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13760 bb_error_msg(_("while trying to open %s"),
13761 ctx->filesystem_name);
13763 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13767 * Set the device name, which is used whenever we print error
13768 * or informational messages to the user.
13770 if (ctx->device_name == 0 &&
13771 (sb->s_volume_name[0] != 0)) {
13772 ctx->device_name = string_copy(sb->s_volume_name,
13773 sizeof(sb->s_volume_name));
13775 if (ctx->device_name == 0)
13776 ctx->device_name = ctx->filesystem_name;
13779 * Make sure the ext3 superblock fields are consistent.
13781 retval = e2fsck_check_ext3_journal(ctx);
13783 bb_error_msg(_("while checking ext3 journal for %s"),
13785 bb_error_msg_and_die(0);
13789 * Check to see if we need to do ext3-style recovery. If so,
13790 * do it, and then restart the fsck.
13792 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13793 if (ctx->options & E2F_OPT_READONLY) {
13794 printf(_("Warning: skipping journal recovery "
13795 "because doing a read-only filesystem "
13797 io_channel_flush(ctx->fs->io);
13799 if (ctx->flags & E2F_FLAG_RESTARTED) {
13801 * Whoops, we attempted to run the
13802 * journal twice. This should never
13803 * happen, unless the hardware or
13804 * device driver is being bogus.
13806 bb_error_msg(_("unable to set superblock flags on %s\n"), ctx->device_name);
13807 bb_error_msg_and_die(0);
13809 retval = e2fsck_run_ext3_journal(ctx);
13811 bb_error_msg(_("while recovering ext3 journal of %s"),
13813 bb_error_msg_and_die(0);
13815 ext2fs_close(ctx->fs);
13817 ctx->flags |= E2F_FLAG_RESTARTED;
13823 * Check for compatibility with the feature sets. We need to
13824 * be more stringent than ext2fs_open().
13826 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13827 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13828 bb_error_msg("(%s)", ctx->device_name);
13831 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13832 bb_error_msg("(%s)", ctx->device_name);
13835 #ifdef ENABLE_COMPRESSION
13836 /* FIXME - do we support this at all? */
13837 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13838 bb_error_msg(_("Warning: compression support is experimental.\n"));
13840 #ifndef ENABLE_HTREE
13841 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13842 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13843 "but filesystem %s has HTREE directories.\n"),
13850 * If the user specified a specific superblock, presumably the
13851 * master superblock has been trashed. So we mark the
13852 * superblock as dirty, so it can be written out.
13854 if (ctx->superblock &&
13855 !(ctx->options & E2F_OPT_READONLY))
13856 ext2fs_mark_super_dirty(fs);
13859 * We only update the master superblock because (a) paranoia;
13860 * we don't want to corrupt the backup superblocks, and (b) we
13861 * don't need to update the mount count and last checked
13862 * fields in the backup superblock (the kernel doesn't
13863 * update the backup superblocks anyway).
13865 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13867 ehandler_init(fs->io);
13869 if (ctx->superblock)
13870 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13871 ext2fs_mark_valid(fs);
13872 check_super_block(ctx);
13873 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13874 bb_error_msg_and_die(0);
13875 check_if_skip(ctx);
13876 if (bad_blocks_file)
13877 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
13879 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
13880 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13881 bb_error_msg_and_die(0);
13882 #ifdef ENABLE_SWAPFS
13884 #ifdef WORDS_BIGENDIAN
13885 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13887 #define NATIVE_FLAG 0
13891 if (normalize_swapfs) {
13892 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13893 fprintf(stderr, _("%s: Filesystem byte order "
13894 "already normalized.\n"), ctx->device_name);
13895 bb_error_msg_and_die(0);
13900 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13901 bb_error_msg_and_die(0);
13906 * Mark the system as valid, 'til proven otherwise
13908 ext2fs_mark_valid(fs);
13910 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13912 bb_error_msg(_("while reading bad blocks inode"));
13914 printf(_("This doesn't bode well,"
13915 " but we'll try to go on...\n"));
13918 run_result = e2fsck_run(ctx);
13919 e2fsck_clear_progbar(ctx);
13920 if (run_result == E2F_FLAG_RESTART) {
13921 printf(_("Restarting e2fsck from the beginning...\n"));
13922 retval = e2fsck_reset_context(ctx);
13924 bb_error_msg(_("while resetting context"));
13925 bb_error_msg_and_die(0);
13930 if (run_result & E2F_FLAG_CANCEL) {
13931 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13932 ctx->device_name : ctx->filesystem_name);
13933 exit_value |= FSCK_CANCELED;
13935 if (run_result & E2F_FLAG_ABORT)
13936 bb_error_msg_and_die(_("aborted"));
13939 if (ext2fs_test_changed(fs)) {
13940 exit_value |= EXIT_NONDESTRUCT;
13941 if (!(ctx->options & E2F_OPT_PREEN))
13942 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13944 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13945 printf(_("%s: ***** REBOOT LINUX *****\n"),
13947 exit_value |= EXIT_DESTRUCT;
13950 if (!ext2fs_test_valid(fs)) {
13951 printf(_("\n%s: ********** WARNING: Filesystem still has "
13952 "errors **********\n\n"), ctx->device_name);
13953 exit_value |= EXIT_UNCORRECTED;
13954 exit_value &= ~EXIT_NONDESTRUCT;
13956 if (exit_value & FSCK_CANCELED)
13957 exit_value &= ~EXIT_NONDESTRUCT;
13960 if (!(ctx->options & E2F_OPT_READONLY)) {
13961 if (ext2fs_test_valid(fs)) {
13962 if (!(sb->s_state & EXT2_VALID_FS))
13963 exit_value |= EXIT_NONDESTRUCT;
13964 sb->s_state = EXT2_VALID_FS;
13966 sb->s_state &= ~EXT2_VALID_FS;
13967 sb->s_mnt_count = 0;
13968 sb->s_lastcheck = time(NULL);
13969 ext2fs_mark_super_dirty(fs);
13973 e2fsck_write_bitmaps(ctx);
13977 free(ctx->filesystem_name);
13978 free(ctx->journal_name);
13979 e2fsck_free_context(ctx);