4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6 * redistributed under the terms of the GNU Public License.
9 * Dictionary Abstract Data Type
10 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
11 * Free Software License:
12 * All rights are reserved by the author, with the following exceptions:
13 * Permission is granted to freely reproduce and distribute this software,
14 * possibly in exchange for a fee, provided that this copyright notice appears
15 * intact. Permission is also granted to adapt this software to produce
16 * derivative works, as long as the modified versions carry this copyright
17 * notice and additional notices stating that the work has been modified.
18 * This source code may be translated into executable form and incorporated
19 * into proprietary software; there is no requirement for such software to
20 * contain a copyright notice related to this source.
22 * linux/fs/recovery and linux/fs/revoke
23 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
25 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
27 * This file is part of the Linux kernel and is made available under
28 * the terms of the GNU General Public License, version 2, or at your
29 * option, any later version, incorporated herein by reference.
31 * Journal recovery routines for the generic filesystem journaling code;
32 * part of the ext2fs journaling system.
36 #define _GNU_SOURCE 1 /* get strnlen() */
39 #include "e2fsck.h" /*Put all of our defines here to clean things up*/
42 #define _INLINE_ __inline__
43 #define EXT2FS_ATTR(x) __attribute__(x)
46 #define EXT2FS_ATTR(x)
50 * Procedure declarations
53 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
56 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
59 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
60 ext2_ino_t ino, char *buf);
63 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
64 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
65 int num, int gauranteed_size);
66 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
67 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
71 static void e2fsck_rehash_directories(e2fsck_t ctx);
74 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
75 const char *description);
76 static int ask(e2fsck_t ctx, const char * string, int def);
77 static void e2fsck_read_bitmaps(e2fsck_t ctx);
78 static void preenhalt(e2fsck_t ctx);
79 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
80 struct ext2_inode * inode, const char * proc);
81 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
82 struct ext2_inode * inode, const char * proc);
83 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
84 const char *name, io_manager manager);
87 static void e2fsck_clear_progbar(e2fsck_t ctx);
88 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
89 float percent, unsigned int dpynum);
93 * problem.h --- e2fsck problem error codes
96 typedef __u32 problem_t;
98 struct problem_context {
100 ext2_ino_t ino, ino2, dir;
101 struct ext2_inode *inode;
102 struct ext2_dir_entry *dirent;
104 e2_blkcnt_t blkcount;
113 * Function declarations
115 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
116 static int end_problem_latch(e2fsck_t ctx, int mask);
117 static int set_latch_flags(int mask, int setflags, int clearflags);
118 static void clear_problem_context(struct problem_context *ctx);
121 * Dictionary Abstract Data Type
122 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
124 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
132 * Blurb for inclusion into C++ translation units
135 typedef unsigned long dictcount_t;
136 #define DICTCOUNT_T_MAX ULONG_MAX
139 * The dictionary is implemented as a red-black tree
142 typedef enum { dnode_red, dnode_black } dnode_color_t;
144 typedef struct dnode_t {
145 struct dnode_t *dict_left;
146 struct dnode_t *dict_right;
147 struct dnode_t *dict_parent;
148 dnode_color_t dict_color;
149 const void *dict_key;
153 typedef int (*dict_comp_t)(const void *, const void *);
154 typedef void (*dnode_free_t)(dnode_t *);
156 typedef struct dict_t {
157 dnode_t dict_nilnode;
158 dictcount_t dict_nodecount;
159 dictcount_t dict_maxcount;
160 dict_comp_t dict_compare;
161 dnode_free_t dict_freenode;
165 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
167 typedef struct dict_load_t {
168 dict_t *dict_dictptr;
169 dnode_t dict_nilnode;
172 #define dict_count(D) ((D)->dict_nodecount)
173 #define dnode_get(N) ((N)->dict_data)
174 #define dnode_getkey(N) ((N)->dict_key)
179 * Compatibility header file for e2fsck which should be included
180 * instead of linux/jfs.h
182 * Copyright (C) 2000 Stephen C. Tweedie
186 * Pull in the definition of the e2fsck context structure
202 #define K_DEV_JOURNAL 2
204 #define lock_buffer(bh) do {} while(0)
205 #define unlock_buffer(bh) do {} while(0)
206 #define buffer_req(bh) 1
207 #define do_readahead(journal, start) do {} while(0)
209 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
215 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
218 * We use the standard libext2fs portability tricks for inline
222 static _INLINE_ kmem_cache_t * do_cache_create(int len)
224 kmem_cache_t *new_cache;
226 new_cache = malloc(sizeof(*new_cache));
228 new_cache->object_length = len;
232 static _INLINE_ void do_cache_destroy(kmem_cache_t *cache)
238 * badblocks.c --- replace/append bad blocks to the bad block inode
241 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
245 static void invalid_block(ext2_filsys fs FSCK_ATTR((unused)), blk_t blk)
247 printf(_("Bad block %u out of range; ignored.\n"), blk);
251 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
252 int replace_bad_blocks)
254 ext2_filsys fs = ctx->fs;
256 badblocks_list bb_list = 0;
260 e2fsck_read_bitmaps(ctx);
263 * Make sure the bad block inode is sane. If there are any
264 * illegal blocks, clear them.
266 retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
267 check_bb_inode_blocks, 0);
269 com_err("ext2fs_block_iterate", retval,
270 _("while sanity checking the bad blocks inode"));
275 * If we're appending to the bad blocks inode, read in the
276 * current bad blocks.
278 if (!replace_bad_blocks) {
279 retval = ext2fs_read_bb_inode(fs, &bb_list);
281 com_err("ext2fs_read_bb_inode", retval,
282 _("while reading the bad blocks inode"));
288 * Now read in the bad blocks from the file; if
289 * bad_blocks_file is null, then try to run the badblocks
292 if (bad_blocks_file) {
293 f = fopen(bad_blocks_file, "r");
295 com_err("read_bad_blocks_file", errno,
296 _("while trying to open %s"), bad_blocks_file);
300 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
301 (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
302 (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
303 fs->device_name, fs->super->s_blocks_count);
306 com_err("read_bad_blocks_file", errno,
307 _("while trying popen '%s'"), buf);
311 retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
317 com_err("ext2fs_read_bb_FILE", retval,
318 _("while reading in list of bad blocks from file"));
323 * Finally, update the bad blocks from the bad_block_map
325 retval = ext2fs_update_bb_inode(fs, bb_list);
327 com_err("ext2fs_update_bb_inode", retval,
328 _("while updating bad block inode"));
332 ext2fs_badblocks_list_free(bb_list);
336 ctx->flags |= E2F_FLAG_ABORT;
341 static int check_bb_inode_blocks(ext2_filsys fs,
343 int blockcnt FSCK_ATTR((unused)),
344 void *priv_data FSCK_ATTR((unused)))
350 * If the block number is outrageous, clear it and ignore it.
352 if (*block_nr >= fs->super->s_blocks_count ||
353 *block_nr < fs->super->s_first_data_block) {
354 printf(_("Warning illegal block %u found in bad block inode. Cleared.\n"), *block_nr);
356 return BLOCK_CHANGED;
363 * Dictionary Abstract Data Type
368 * These macros provide short convenient names for structure members,
369 * which are embellished with dict_ prefixes so that they are
370 * properly confined to the documented namespace. It's legal for a
371 * program which uses dict to define, for instance, a macro called ``parent''.
372 * Such a macro would interfere with the dnode_t struct definition.
373 * In general, highly portable and reusable C modules which expose their
374 * structures need to confine structure member names to well-defined spaces.
375 * The resulting identifiers aren't necessarily convenient to use, nor
376 * readable, in the implementation, however!
379 #define left dict_left
380 #define right dict_right
381 #define parent dict_parent
382 #define color dict_color
384 #define data dict_data
386 #define nilnode dict_nilnode
387 #define maxcount dict_maxcount
388 #define compare dict_compare
389 #define dupes dict_dupes
391 #define dict_root(D) ((D)->nilnode.left)
392 #define dict_nil(D) (&(D)->nilnode)
393 #define DICT_DEPTH_MAX 64
395 static void dnode_free(dnode_t *node);
398 * Perform a ``left rotation'' adjustment on the tree. The given node P and
399 * its right child C are rearranged so that the P instead becomes the left
400 * child of C. The left subtree of C is inherited as the new right subtree
401 * for P. The ordering of the keys within the tree is thus preserved.
404 static void rotate_left(dnode_t *upper)
406 dnode_t *lower, *lowleft, *upparent;
408 lower = upper->right;
409 upper->right = lowleft = lower->left;
410 lowleft->parent = upper;
412 lower->parent = upparent = upper->parent;
414 /* don't need to check for root node here because root->parent is
415 the sentinel nil node, and root->parent->left points back to root */
417 if (upper == upparent->left) {
418 upparent->left = lower;
420 assert (upper == upparent->right);
421 upparent->right = lower;
425 upper->parent = lower;
429 * This operation is the ``mirror'' image of rotate_left. It is
430 * the same procedure, but with left and right interchanged.
433 static void rotate_right(dnode_t *upper)
435 dnode_t *lower, *lowright, *upparent;
438 upper->left = lowright = lower->right;
439 lowright->parent = upper;
441 lower->parent = upparent = upper->parent;
443 if (upper == upparent->right) {
444 upparent->right = lower;
446 assert (upper == upparent->left);
447 upparent->left = lower;
450 lower->right = upper;
451 upper->parent = lower;
455 * Do a postorder traversal of the tree rooted at the specified
456 * node and free everything under it. Used by dict_free().
459 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
463 free_nodes(dict, node->left, nil);
464 free_nodes(dict, node->right, nil);
465 dict->dict_freenode(node);
469 * Verify that the tree contains the given node. This is done by
470 * traversing all of the nodes and comparing their pointers to the
471 * given pointer. Returns 1 if the node is found, otherwise
472 * returns zero. It is intended for debugging purposes.
475 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
479 || verify_dict_has_node(nil, root->left, node)
480 || verify_dict_has_node(nil, root->right, node);
487 * Select a different set of node allocator routines.
490 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
492 assert (dict_count(dict) == 0);
493 dict->dict_freenode = fr;
497 * Free all the nodes in the dictionary by using the dictionary's
498 * installed free routine. The dictionary is emptied.
501 static void dict_free_nodes(dict_t *dict)
503 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
504 free_nodes(dict, root, nil);
505 dict->dict_nodecount = 0;
506 dict->nilnode.left = &dict->nilnode;
507 dict->nilnode.right = &dict->nilnode;
511 * Initialize a user-supplied dictionary object.
514 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
516 dict->compare = comp;
517 dict->dict_freenode = dnode_free;
518 dict->dict_nodecount = 0;
519 dict->maxcount = maxcount;
520 dict->nilnode.left = &dict->nilnode;
521 dict->nilnode.right = &dict->nilnode;
522 dict->nilnode.parent = &dict->nilnode;
523 dict->nilnode.color = dnode_black;
529 * Locate a node in the dictionary having the given key.
530 * If the node is not found, a null a pointer is returned (rather than
531 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
532 * located node is returned.
535 static dnode_t *dict_lookup(dict_t *dict, const void *key)
537 dnode_t *root = dict_root(dict);
538 dnode_t *nil = dict_nil(dict);
542 /* simple binary search adapted for trees that contain duplicate keys */
544 while (root != nil) {
545 result = dict->compare(key, root->key);
551 if (!dict->dupes) { /* no duplicates, return match */
553 } else { /* could be dupes, find leftmost one */
557 while (root != nil && dict->compare(key, root->key))
559 } while (root != nil);
569 * Insert a node into the dictionary. The node should have been
570 * initialized with a data field. All other fields are ignored.
571 * The behavior is undefined if the user attempts to insert into
572 * a dictionary that is already full (for which the dict_isfull()
573 * function returns true).
576 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
578 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
579 dnode_t *parent = nil, *uncle, *grandpa;
584 /* basic binary tree insert */
586 while (where != nil) {
588 result = dict->compare(key, where->key);
589 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
590 assert (dict->dupes || result != 0);
594 where = where->right;
597 assert (where == nil);
602 parent->right = node;
604 node->parent = parent;
608 dict->dict_nodecount++;
610 /* red black adjustments */
612 node->color = dnode_red;
614 while (parent->color == dnode_red) {
615 grandpa = parent->parent;
616 if (parent == grandpa->left) {
617 uncle = grandpa->right;
618 if (uncle->color == dnode_red) { /* red parent, red uncle */
619 parent->color = dnode_black;
620 uncle->color = dnode_black;
621 grandpa->color = dnode_red;
623 parent = grandpa->parent;
624 } else { /* red parent, black uncle */
625 if (node == parent->right) {
628 assert (grandpa == parent->parent);
629 /* rotation between parent and child preserves grandpa */
631 parent->color = dnode_black;
632 grandpa->color = dnode_red;
633 rotate_right(grandpa);
636 } else { /* symmetric cases: parent == parent->parent->right */
637 uncle = grandpa->left;
638 if (uncle->color == dnode_red) {
639 parent->color = dnode_black;
640 uncle->color = dnode_black;
641 grandpa->color = dnode_red;
643 parent = grandpa->parent;
645 if (node == parent->left) {
646 rotate_right(parent);
648 assert (grandpa == parent->parent);
650 parent->color = dnode_black;
651 grandpa->color = dnode_red;
652 rotate_left(grandpa);
658 dict_root(dict)->color = dnode_black;
663 * Allocate a node using the dictionary's allocator routine, give it
667 static dnode_t *dnode_init(dnode_t *dnode, void *data)
670 dnode->parent = NULL;
676 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
678 dnode_t *node = malloc(sizeof(dnode_t));
681 dnode_init(node, data);
682 dict_insert(dict, node, key);
689 * Return the node with the lowest (leftmost) key. If the dictionary is empty
690 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
693 static dnode_t *dict_first(dict_t *dict)
695 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
698 while ((left = root->left) != nil)
701 return (root == nil) ? NULL : root;
705 * Return the given node's successor node---the node which has the
706 * next key in the the left to right ordering. If the node has
707 * no successor, a null pointer is returned rather than a pointer to
711 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
713 dnode_t *nil = dict_nil(dict), *parent, *left;
715 if (curr->right != nil) {
717 while ((left = curr->left) != nil)
722 parent = curr->parent;
724 while (parent != nil && curr == parent->right) {
726 parent = curr->parent;
729 return (parent == nil) ? NULL : parent;
733 static void dnode_free(dnode_t *node)
753 * dirinfo.c --- maintains the directory information table for e2fsck.
757 * This subroutine is called during pass1 to create a directory info
758 * entry. During pass1, the passed-in parent is 0; it will get filled
761 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
763 struct dir_info *dir;
767 unsigned long old_size;
769 if (!ctx->dir_info) {
770 ctx->dir_info_count = 0;
771 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
773 num_dirs = 1024; /* Guess */
774 ctx->dir_info_size = num_dirs + 10;
775 ctx->dir_info = (struct dir_info *)
776 e2fsck_allocate_memory(ctx, ctx->dir_info_size
777 * sizeof (struct dir_info),
781 if (ctx->dir_info_count >= ctx->dir_info_size) {
782 old_size = ctx->dir_info_size * sizeof(struct dir_info);
783 ctx->dir_info_size += 10;
784 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
785 sizeof(struct dir_info),
788 ctx->dir_info_size -= 10;
794 * Normally, add_dir_info is called with each inode in
795 * sequential order; but once in a while (like when pass 3
796 * needs to recreate the root directory or lost+found
797 * directory) it is called out of order. In those cases, we
798 * need to move the dir_info entries down to make room, since
799 * the dir_info array needs to be sorted by inode number for
800 * get_dir_info()'s sake.
802 if (ctx->dir_info_count &&
803 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
804 for (i = ctx->dir_info_count-1; i > 0; i--)
805 if (ctx->dir_info[i-1].ino < ino)
807 dir = &ctx->dir_info[i];
809 for (j = ctx->dir_info_count++; j > i; j--)
810 ctx->dir_info[j] = ctx->dir_info[j-1];
812 dir = &ctx->dir_info[ctx->dir_info_count++];
815 dir->dotdot = parent;
816 dir->parent = parent;
820 * get_dir_info() --- given an inode number, try to find the directory
821 * information entry for it.
823 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
828 high = ctx->dir_info_count-1;
831 if (ino == ctx->dir_info[low].ino)
832 return &ctx->dir_info[low];
833 if (ino == ctx->dir_info[high].ino)
834 return &ctx->dir_info[high];
838 if (mid == low || mid == high)
840 if (ino == ctx->dir_info[mid].ino)
841 return &ctx->dir_info[mid];
842 if (ino < ctx->dir_info[mid].ino)
851 * Free the dir_info structure when it isn't needed any more.
853 static void e2fsck_free_dir_info(e2fsck_t ctx)
855 ext2fs_free_mem(&ctx->dir_info);
856 ctx->dir_info_size = 0;
857 ctx->dir_info_count = 0;
861 * Return the count of number of directories in the dir_info structure
863 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
865 return ctx->dir_info_count;
869 * A simple interator function
871 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
873 if (*control >= ctx->dir_info_count)
876 return(ctx->dir_info + (*control)++);
880 * dirinfo.c --- maintains the directory information table for e2fsck.
887 * This subroutine is called during pass1 to create a directory info
888 * entry. During pass1, the passed-in parent is 0; it will get filled
891 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
893 struct dx_dir_info *dir;
896 unsigned long old_size;
898 if (!ctx->dx_dir_info) {
899 ctx->dx_dir_info_count = 0;
900 ctx->dx_dir_info_size = 100; /* Guess */
901 ctx->dx_dir_info = (struct dx_dir_info *)
902 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
903 * sizeof (struct dx_dir_info),
907 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
908 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
909 ctx->dx_dir_info_size += 10;
910 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
911 sizeof(struct dx_dir_info),
914 ctx->dx_dir_info_size -= 10;
920 * Normally, add_dx_dir_info is called with each inode in
921 * sequential order; but once in a while (like when pass 3
922 * needs to recreate the root directory or lost+found
923 * directory) it is called out of order. In those cases, we
924 * need to move the dx_dir_info entries down to make room, since
925 * the dx_dir_info array needs to be sorted by inode number for
926 * get_dx_dir_info()'s sake.
928 if (ctx->dx_dir_info_count &&
929 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
930 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
931 if (ctx->dx_dir_info[i-1].ino < ino)
933 dir = &ctx->dx_dir_info[i];
935 for (j = ctx->dx_dir_info_count++; j > i; j--)
936 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
938 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
941 dir->numblocks = num_blocks;
942 dir->hashversion = 0;
943 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
944 * sizeof (struct dx_dirblock_info),
945 "dx_block info array");
950 * get_dx_dir_info() --- given an inode number, try to find the directory
951 * information entry for it.
953 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
958 high = ctx->dx_dir_info_count-1;
959 if (!ctx->dx_dir_info)
961 if (ino == ctx->dx_dir_info[low].ino)
962 return &ctx->dx_dir_info[low];
963 if (ino == ctx->dx_dir_info[high].ino)
964 return &ctx->dx_dir_info[high];
968 if (mid == low || mid == high)
970 if (ino == ctx->dx_dir_info[mid].ino)
971 return &ctx->dx_dir_info[mid];
972 if (ino < ctx->dx_dir_info[mid].ino)
981 * Free the dx_dir_info structure when it isn't needed any more.
983 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
986 struct dx_dir_info *dir;
988 if (ctx->dx_dir_info) {
989 dir = ctx->dx_dir_info;
990 for (i=0; i < ctx->dx_dir_info_count; i++) {
991 ext2fs_free_mem(&dir->dx_block);
993 ext2fs_free_mem(&ctx->dx_dir_info);
995 ctx->dx_dir_info_size = 0;
996 ctx->dx_dir_info_count = 0;
1000 * A simple interator function
1002 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
1004 if (*control >= ctx->dx_dir_info_count)
1007 return(ctx->dx_dir_info + (*control)++);
1010 #endif /* ENABLE_HTREE */
1012 * e2fsck.c - a consistency checker for the new extended file system.
1017 * This function allocates an e2fsck context
1019 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
1024 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
1028 memset(context, 0, sizeof(struct e2fsck_struct));
1030 context->process_inode_size = 256;
1031 context->ext_attr_ver = 2;
1037 struct ea_refcount_el {
1042 struct ea_refcount {
1046 struct ea_refcount_el *list;
1049 static void ea_refcount_free(ext2_refcount_t refcount)
1054 ext2fs_free_mem(&refcount->list);
1055 ext2fs_free_mem(&refcount);
1059 * This function resets an e2fsck context; it is called when e2fsck
1060 * needs to be restarted.
1062 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
1065 ctx->lost_and_found = 0;
1066 ctx->bad_lost_and_found = 0;
1067 ext2fs_free_inode_bitmap(ctx->inode_used_map);
1068 ctx->inode_used_map = 0;
1069 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
1070 ctx->inode_dir_map = 0;
1071 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
1072 ctx->inode_reg_map = 0;
1073 ext2fs_free_block_bitmap(ctx->block_found_map);
1074 ctx->block_found_map = 0;
1075 ext2fs_free_icount(ctx->inode_link_info);
1076 ctx->inode_link_info = 0;
1077 if (ctx->journal_io) {
1078 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1079 io_channel_close(ctx->journal_io);
1080 ctx->journal_io = 0;
1083 ext2fs_free_dblist(ctx->fs->dblist);
1084 ctx->fs->dblist = 0;
1086 e2fsck_free_dir_info(ctx);
1088 e2fsck_free_dx_dir_info(ctx);
1090 ea_refcount_free(ctx->refcount);
1092 ea_refcount_free(ctx->refcount_extra);
1093 ctx->refcount_extra = 0;
1094 ext2fs_free_block_bitmap(ctx->block_dup_map);
1095 ctx->block_dup_map = 0;
1096 ext2fs_free_block_bitmap(ctx->block_ea_map);
1097 ctx->block_ea_map = 0;
1098 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
1099 ctx->inode_bb_map = 0;
1100 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
1101 ctx->inode_bad_map = 0;
1102 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
1103 ctx->inode_imagic_map = 0;
1104 ext2fs_u32_list_free(ctx->dirs_to_hash);
1105 ctx->dirs_to_hash = 0;
1108 * Clear the array of invalid meta-data flags
1110 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
1111 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
1112 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
1114 /* Clear statistic counters */
1115 ctx->fs_directory_count = 0;
1116 ctx->fs_regular_count = 0;
1117 ctx->fs_blockdev_count = 0;
1118 ctx->fs_chardev_count = 0;
1119 ctx->fs_links_count = 0;
1120 ctx->fs_symlinks_count = 0;
1121 ctx->fs_fast_symlinks_count = 0;
1122 ctx->fs_fifo_count = 0;
1123 ctx->fs_total_count = 0;
1124 ctx->fs_badblocks_count = 0;
1125 ctx->fs_sockets_count = 0;
1126 ctx->fs_ind_count = 0;
1127 ctx->fs_dind_count = 0;
1128 ctx->fs_tind_count = 0;
1129 ctx->fs_fragmented = 0;
1130 ctx->large_files = 0;
1132 /* Reset the superblock to the user's requested value */
1133 ctx->superblock = ctx->use_superblock;
1138 static void e2fsck_free_context(e2fsck_t ctx)
1143 e2fsck_reset_context(ctx);
1145 blkid_put_cache(ctx->blkid);
1147 ext2fs_free_mem(&ctx);
1155 * The strategy we use for keeping track of EA refcounts is as
1156 * follows. We keep a sorted array of first EA blocks and its
1157 * reference counts. Once the refcount has dropped to zero, it is
1158 * removed from the array to save memory space. Once the EA block is
1159 * checked, its bit is set in the block_ea_map bitmap.
1163 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1165 ext2_refcount_t refcount;
1169 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1172 memset(refcount, 0, sizeof(struct ea_refcount));
1176 refcount->size = size;
1177 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1179 printf("Refcount allocated %d entries, %d bytes.\n",
1180 refcount->size, bytes);
1182 retval = ext2fs_get_mem(bytes, &refcount->list);
1185 memset(refcount->list, 0, bytes);
1187 refcount->count = 0;
1188 refcount->cursor = 0;
1194 ea_refcount_free(refcount);
1199 * collapse_refcount() --- go through the refcount array, and get rid
1200 * of any count == zero entries
1202 static void refcount_collapse(ext2_refcount_t refcount)
1205 struct ea_refcount_el *list;
1207 list = refcount->list;
1208 for (i = 0, j = 0; i < refcount->count; i++) {
1209 if (list[i].ea_count) {
1215 #if defined(DEBUG) || defined(TEST_PROGRAM)
1216 printf("Refcount_collapse: size was %d, now %d\n",
1217 refcount->count, j);
1219 refcount->count = j;
1224 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1225 * specified position.
1227 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1230 struct ea_refcount_el *el;
1235 if (refcount->count >= refcount->size) {
1236 new_size = refcount->size + 100;
1238 printf("Reallocating refcount %d entries...\n", new_size);
1240 retval = ext2fs_resize_mem((size_t) refcount->size *
1241 sizeof(struct ea_refcount_el),
1243 sizeof(struct ea_refcount_el),
1247 refcount->size = new_size;
1249 num = (int) refcount->count - pos;
1251 return 0; /* should never happen */
1253 memmove(&refcount->list[pos+1], &refcount->list[pos],
1254 sizeof(struct ea_refcount_el) * num);
1257 el = &refcount->list[pos];
1265 * get_refcount_el() --- given an block number, try to find refcount
1266 * information in the sorted list. If the create flag is set,
1267 * and we can't find an entry, create one in the sorted list.
1269 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1270 blk_t blk, int create)
1274 blk_t lowval, highval;
1276 if (!refcount || !refcount->list)
1280 high = (int) refcount->count-1;
1281 if (create && ((refcount->count == 0) ||
1282 (blk > refcount->list[high].ea_blk))) {
1283 if (refcount->count >= refcount->size)
1284 refcount_collapse(refcount);
1286 return insert_refcount_el(refcount, blk,
1287 (unsigned) refcount->count);
1289 if (refcount->count == 0)
1292 if (refcount->cursor >= refcount->count)
1293 refcount->cursor = 0;
1294 if (blk == refcount->list[refcount->cursor].ea_blk)
1295 return &refcount->list[refcount->cursor++];
1297 printf("Non-cursor get_refcount_el: %u\n", blk);
1299 while (low <= high) {
1303 /* Interpolate for efficiency */
1304 lowval = refcount->list[low].ea_blk;
1305 highval = refcount->list[high].ea_blk;
1309 else if (blk > highval)
1312 range = ((float) (blk - lowval)) /
1314 mid = low + ((int) (range * (high-low)));
1317 if (blk == refcount->list[mid].ea_blk) {
1318 refcount->cursor = mid+1;
1319 return &refcount->list[mid];
1321 if (blk < refcount->list[mid].ea_blk)
1327 * If we need to create a new entry, it should be right at
1328 * low (where high will be left at low-1).
1331 if (refcount->count >= refcount->size) {
1332 refcount_collapse(refcount);
1333 if (refcount->count < refcount->size)
1336 return insert_refcount_el(refcount, blk, low);
1342 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1344 struct ea_refcount_el *el;
1346 el = get_refcount_el(refcount, blk, 1);
1348 return EXT2_ET_NO_MEMORY;
1352 *ret = el->ea_count;
1357 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1359 struct ea_refcount_el *el;
1361 el = get_refcount_el(refcount, blk, 0);
1362 if (!el || el->ea_count == 0)
1363 return EXT2_ET_INVALID_ARGUMENT;
1368 *ret = el->ea_count;
1373 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1375 struct ea_refcount_el *el;
1378 * Get the refcount element
1380 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1382 return count ? EXT2_ET_NO_MEMORY : 0;
1383 el->ea_count = count;
1387 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1389 refcount->cursor = 0;
1393 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1395 struct ea_refcount_el *list;
1398 if (refcount->cursor >= refcount->count)
1400 list = refcount->list;
1401 if (list[refcount->cursor].ea_count) {
1403 *ret = list[refcount->cursor].ea_count;
1404 return list[refcount->cursor++].ea_blk;
1412 * ehandler.c --- handle bad block errors which come up during the
1413 * course of an e2fsck session.
1417 static const char *operation;
1420 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1421 void *data, size_t size FSCK_ATTR((unused)),
1422 int actual FSCK_ATTR((unused)), errcode_t error)
1426 ext2_filsys fs = (ext2_filsys) channel->app_data;
1429 ctx = (e2fsck_t) fs->priv_data;
1432 * If more than one block was read, try reading each block
1433 * separately. We could use the actual bytes read to figure
1434 * out where to start, but we don't bother.
1438 for (i=0; i < count; i++, p += channel->block_size, block++) {
1439 error = io_channel_read_blk(channel, block,
1447 printf(_("Error reading block %lu (%s) while %s. "), block,
1448 error_message(error), operation);
1450 printf(_("Error reading block %lu (%s). "), block,
1451 error_message(error));
1453 if (ask(ctx, _("Ignore error"), 1)) {
1454 if (ask(ctx, _("Force rewrite"), 1))
1455 io_channel_write_blk(channel, block, 1, data);
1463 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1464 const void *data, size_t size FSCK_ATTR((unused)),
1465 int actual FSCK_ATTR((unused)), errcode_t error)
1469 ext2_filsys fs = (ext2_filsys) channel->app_data;
1472 ctx = (e2fsck_t) fs->priv_data;
1475 * If more than one block was written, try writing each block
1476 * separately. We could use the actual bytes read to figure
1477 * out where to start, but we don't bother.
1480 p = (const char *) data;
1481 for (i=0; i < count; i++, p += channel->block_size, block++) {
1482 error = io_channel_write_blk(channel, block,
1491 printf(_("Error writing block %lu (%s) while %s. "), block,
1492 error_message(error), operation);
1494 printf(_("Error writing block %lu (%s). "), block,
1495 error_message(error));
1497 if (ask(ctx, _("Ignore error"), 1))
1503 static inline const char *ehandler_operation(const char *op)
1505 const char *ret = operation;
1511 static void ehandler_init(io_channel channel)
1513 channel->read_error = e2fsck_handle_read_error;
1514 channel->write_error = e2fsck_handle_write_error;
1518 * journal.c --- code for handling the "ext3" journal
1520 * Copyright (C) 2000 Andreas Dilger
1521 * Copyright (C) 2000 Theodore Ts'o
1523 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1524 * Copyright (C) 1999 Red Hat Software
1526 * This file may be redistributed under the terms of the
1527 * GNU General Public License version 2 or at your discretion
1528 * any later version.
1531 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
1534 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1535 * This creates a larger static binary, and a smaller binary using
1536 * shared libraries. It's also probably slightly less CPU-efficient,
1537 * which is why it's not on by default. But, it's a good way of
1538 * testing the functions in inode_io.c and fileio.c.
1542 /* Kernel compatibility functions for handling the journal. These allow us
1543 * to use the recovery.c file virtually unchanged from the kernel, so we
1544 * don't have to do much to keep kernel and user recovery in sync.
1546 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1552 struct inode *inode = journal->j_inode;
1561 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1562 &inode->i_ext2, NULL, 0, block, &pblk);
1568 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1570 struct buffer_head *bh;
1572 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1576 bh->b_ctx = kdev->k_ctx;
1577 if (kdev->k_dev == K_DEV_FS)
1578 bh->b_io = kdev->k_ctx->fs->io;
1580 bh->b_io = kdev->k_ctx->journal_io;
1581 bh->b_size = blocksize;
1582 bh->b_blocknr = blocknr;
1587 static void sync_blockdev(kdev_t kdev)
1591 if (kdev->k_dev == K_DEV_FS)
1592 io = kdev->k_ctx->fs->io;
1594 io = kdev->k_ctx->journal_io;
1596 io_channel_flush(io);
1599 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1602 struct buffer_head *bh;
1604 for (; nr > 0; --nr) {
1606 if (rw == READ && !bh->b_uptodate) {
1607 retval = io_channel_read_blk(bh->b_io,
1611 com_err(bh->b_ctx->device_name, retval,
1612 "while reading block %lu\n",
1613 (unsigned long) bh->b_blocknr);
1618 } else if (rw == WRITE && bh->b_dirty) {
1619 retval = io_channel_write_blk(bh->b_io,
1623 com_err(bh->b_ctx->device_name, retval,
1624 "while writing block %lu\n",
1625 (unsigned long) bh->b_blocknr);
1635 static inline void mark_buffer_dirty(struct buffer_head *bh)
1640 static inline void mark_buffer_clean(struct buffer_head * bh)
1645 static void brelse(struct buffer_head *bh)
1648 ll_rw_block(WRITE, 1, &bh);
1649 ext2fs_free_mem(&bh);
1652 static inline int buffer_uptodate(struct buffer_head *bh)
1654 return bh->b_uptodate;
1657 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1659 bh->b_uptodate = val;
1662 static void wait_on_buffer(struct buffer_head *bh)
1664 if (!bh->b_uptodate)
1665 ll_rw_block(READ, 1, &bh);
1669 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1671 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1673 /* if we had an error doing journal recovery, we need a full fsck */
1675 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1676 ext2fs_mark_super_dirty(ctx->fs);
1679 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1681 struct ext2_super_block *sb = ctx->fs->super;
1682 struct ext2_super_block jsuper;
1683 struct problem_context pctx;
1684 struct buffer_head *bh;
1685 struct inode *j_inode = NULL;
1686 struct kdev_s *dev_fs = NULL, *dev_journal;
1687 const char *journal_name = 0;
1688 journal_t *journal = NULL;
1689 errcode_t retval = 0;
1690 io_manager io_ptr = 0;
1691 unsigned long start = 0;
1693 int ext_journal = 0;
1694 int tried_backup_jnl = 0;
1697 clear_problem_context(&pctx);
1699 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1701 return EXT2_ET_NO_MEMORY;
1704 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1706 retval = EXT2_ET_NO_MEMORY;
1709 dev_journal = dev_fs+1;
1711 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1712 dev_fs->k_dev = K_DEV_FS;
1713 dev_journal->k_dev = K_DEV_JOURNAL;
1715 journal->j_dev = dev_journal;
1716 journal->j_fs_dev = dev_fs;
1717 journal->j_inode = NULL;
1718 journal->j_blocksize = ctx->fs->blocksize;
1720 if (uuid_is_null(sb->s_journal_uuid)) {
1721 if (!sb->s_journal_inum)
1722 return EXT2_ET_BAD_INODE_NUM;
1723 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1726 retval = EXT2_ET_NO_MEMORY;
1730 j_inode->i_ctx = ctx;
1731 j_inode->i_ino = sb->s_journal_inum;
1733 if ((retval = ext2fs_read_inode(ctx->fs,
1735 &j_inode->i_ext2))) {
1737 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1740 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1741 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1743 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1744 j_inode->i_ext2.i_links_count = 1;
1745 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1748 if (!j_inode->i_ext2.i_links_count ||
1749 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1750 retval = EXT2_ET_NO_JOURNAL;
1751 goto try_backup_journal;
1753 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1754 JFS_MIN_JOURNAL_BLOCKS) {
1755 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1756 goto try_backup_journal;
1758 for (i=0; i < EXT2_N_BLOCKS; i++) {
1759 blk = j_inode->i_ext2.i_block[i];
1761 if (i < EXT2_NDIR_BLOCKS) {
1762 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1763 goto try_backup_journal;
1767 if (blk < sb->s_first_data_block ||
1768 blk >= sb->s_blocks_count) {
1769 retval = EXT2_ET_BAD_BLOCK_NUM;
1770 goto try_backup_journal;
1773 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1776 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1782 io_ptr = inode_io_manager;
1784 journal->j_inode = j_inode;
1785 ctx->journal_io = ctx->fs->io;
1786 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1791 if (!ctx->journal_name) {
1794 uuid_unparse(sb->s_journal_uuid, uuid);
1795 ctx->journal_name = blkid_get_devname(ctx->blkid,
1797 if (!ctx->journal_name)
1798 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1800 journal_name = ctx->journal_name;
1802 if (!journal_name) {
1803 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1804 return EXT2_ET_LOAD_EXT_JOURNAL;
1807 io_ptr = unix_io_manager;
1810 #ifndef USE_INODE_IO
1813 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1818 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1821 if (ctx->fs->blocksize == 1024)
1823 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1825 retval = EXT2_ET_NO_MEMORY;
1828 ll_rw_block(READ, 1, &bh);
1829 if ((retval = bh->b_err) != 0)
1831 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1834 #ifdef EXT2FS_ENABLE_SWAPFS
1835 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1836 ext2fs_swap_super(&jsuper);
1838 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1839 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1840 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1841 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1844 /* Make sure the journal UUID is correct */
1845 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1846 sizeof(jsuper.s_uuid))) {
1847 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1848 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1852 journal->j_maxlen = jsuper.s_blocks_count;
1856 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1857 retval = EXT2_ET_NO_MEMORY;
1861 journal->j_sb_buffer = bh;
1862 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1865 ext2fs_free_mem(&j_inode);
1868 *ret_journal = journal;
1872 ext2fs_free_mem(&dev_fs);
1873 ext2fs_free_mem(&j_inode);
1874 ext2fs_free_mem(&journal);
1879 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1880 struct problem_context *pctx)
1882 struct ext2_super_block *sb = ctx->fs->super;
1883 int recover = ctx->fs->super->s_feature_incompat &
1884 EXT3_FEATURE_INCOMPAT_RECOVER;
1885 int has_journal = ctx->fs->super->s_feature_compat &
1886 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1888 if (has_journal || sb->s_journal_inum) {
1889 /* The journal inode is bogus, remove and force full fsck */
1890 pctx->ino = sb->s_journal_inum;
1891 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1892 if (has_journal && sb->s_journal_inum)
1893 printf("*** ext3 journal has been deleted - "
1894 "filesystem is now ext2 only ***\n\n");
1895 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1896 sb->s_journal_inum = 0;
1897 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1898 e2fsck_clear_recover(ctx, 1);
1901 return EXT2_ET_BAD_INODE_NUM;
1902 } else if (recover) {
1903 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1904 e2fsck_clear_recover(ctx, 1);
1907 return EXT2_ET_UNSUPP_FEATURE;
1912 #define V1_SB_SIZE 0x0024
1913 static void clear_v2_journal_fields(journal_t *journal)
1915 e2fsck_t ctx = journal->j_dev->k_ctx;
1916 struct problem_context pctx;
1918 clear_problem_context(&pctx);
1920 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1923 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1924 ctx->fs->blocksize-V1_SB_SIZE);
1925 mark_buffer_dirty(journal->j_sb_buffer);
1929 static errcode_t e2fsck_journal_load(journal_t *journal)
1931 e2fsck_t ctx = journal->j_dev->k_ctx;
1932 journal_superblock_t *jsb;
1933 struct buffer_head *jbh = journal->j_sb_buffer;
1934 struct problem_context pctx;
1936 clear_problem_context(&pctx);
1938 ll_rw_block(READ, 1, &jbh);
1940 com_err(ctx->device_name, jbh->b_err,
1941 _("reading journal superblock\n"));
1945 jsb = journal->j_superblock;
1946 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1947 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1948 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1950 switch (ntohl(jsb->s_header.h_blocktype)) {
1951 case JFS_SUPERBLOCK_V1:
1952 journal->j_format_version = 1;
1953 if (jsb->s_feature_compat ||
1954 jsb->s_feature_incompat ||
1955 jsb->s_feature_ro_compat ||
1957 clear_v2_journal_fields(journal);
1960 case JFS_SUPERBLOCK_V2:
1961 journal->j_format_version = 2;
1962 if (ntohl(jsb->s_nr_users) > 1 &&
1963 uuid_is_null(ctx->fs->super->s_journal_uuid))
1964 clear_v2_journal_fields(journal);
1965 if (ntohl(jsb->s_nr_users) > 1) {
1966 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1967 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1972 * These should never appear in a journal super block, so if
1973 * they do, the journal is badly corrupted.
1975 case JFS_DESCRIPTOR_BLOCK:
1976 case JFS_COMMIT_BLOCK:
1977 case JFS_REVOKE_BLOCK:
1978 return EXT2_ET_CORRUPT_SUPERBLOCK;
1980 /* If we don't understand the superblock major type, but there
1981 * is a magic number, then it is likely to be a new format we
1982 * just don't understand, so leave it alone. */
1984 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1987 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1988 return EXT2_ET_UNSUPP_FEATURE;
1990 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1991 return EXT2_ET_RO_UNSUPP_FEATURE;
1993 /* We have now checked whether we know enough about the journal
1994 * format to be able to proceed safely, so any other checks that
1995 * fail we should attempt to recover from. */
1996 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1997 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
1998 _("%s: no valid journal superblock found\n"),
2000 return EXT2_ET_CORRUPT_SUPERBLOCK;
2003 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
2004 journal->j_maxlen = ntohl(jsb->s_maxlen);
2005 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
2006 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
2007 _("%s: journal too short\n"),
2009 return EXT2_ET_CORRUPT_SUPERBLOCK;
2012 journal->j_tail_sequence = ntohl(jsb->s_sequence);
2013 journal->j_transaction_sequence = journal->j_tail_sequence;
2014 journal->j_tail = ntohl(jsb->s_start);
2015 journal->j_first = ntohl(jsb->s_first);
2016 journal->j_last = ntohl(jsb->s_maxlen);
2021 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
2032 /* Leave a valid existing V1 superblock signature alone.
2033 * Anything unrecognisable we overwrite with a new V2
2036 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
2037 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
2038 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
2039 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
2042 /* Zero out everything else beyond the superblock header */
2044 p = ((char *) jsb) + sizeof(journal_header_t);
2045 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
2047 jsb->s_blocksize = htonl(ctx->fs->blocksize);
2048 jsb->s_maxlen = htonl(journal->j_maxlen);
2049 jsb->s_first = htonl(1);
2051 /* Initialize the journal sequence number so that there is "no"
2052 * chance we will find old "valid" transactions in the journal.
2053 * This avoids the need to zero the whole journal (slow to do,
2054 * and risky when we are just recovering the filesystem).
2056 uuid_generate(u.uuid);
2057 for (i = 0; i < 4; i ++)
2058 new_seq ^= u.val[i];
2059 jsb->s_sequence = htonl(new_seq);
2061 mark_buffer_dirty(journal->j_sb_buffer);
2062 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
2065 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
2067 struct problem_context *pctx)
2069 struct ext2_super_block *sb = ctx->fs->super;
2070 int recover = ctx->fs->super->s_feature_incompat &
2071 EXT3_FEATURE_INCOMPAT_RECOVER;
2073 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
2074 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
2075 e2fsck_journal_reset_super(ctx, journal->j_superblock,
2077 journal->j_transaction_sequence = 1;
2078 e2fsck_clear_recover(ctx, recover);
2081 return EXT2_ET_CORRUPT_SUPERBLOCK;
2082 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
2083 return EXT2_ET_CORRUPT_SUPERBLOCK;
2088 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
2089 int reset, int drop)
2091 journal_superblock_t *jsb;
2094 mark_buffer_clean(journal->j_sb_buffer);
2095 else if (!(ctx->options & E2F_OPT_READONLY)) {
2096 jsb = journal->j_superblock;
2097 jsb->s_sequence = htonl(journal->j_transaction_sequence);
2099 jsb->s_start = 0; /* this marks the journal as empty */
2100 mark_buffer_dirty(journal->j_sb_buffer);
2102 brelse(journal->j_sb_buffer);
2104 if (ctx->journal_io) {
2105 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2106 io_channel_close(ctx->journal_io);
2107 ctx->journal_io = 0;
2110 #ifndef USE_INODE_IO
2111 ext2fs_free_mem(&journal->j_inode);
2113 ext2fs_free_mem(&journal->j_fs_dev);
2114 ext2fs_free_mem(&journal);
2118 * This function makes sure that the superblock fields regarding the
2119 * journal are consistent.
2121 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
2123 struct ext2_super_block *sb = ctx->fs->super;
2125 int recover = ctx->fs->super->s_feature_incompat &
2126 EXT3_FEATURE_INCOMPAT_RECOVER;
2127 struct problem_context pctx;
2129 int reset = 0, force_fsck = 0;
2132 /* If we don't have any journal features, don't do anything more */
2133 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
2134 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
2135 uuid_is_null(sb->s_journal_uuid))
2138 clear_problem_context(&pctx);
2139 pctx.num = sb->s_journal_inum;
2141 retval = e2fsck_get_journal(ctx, &journal);
2143 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2144 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2145 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2146 (retval == EXT2_ET_NO_JOURNAL))
2147 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2151 retval = e2fsck_journal_load(journal);
2153 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2154 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2155 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2157 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2158 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2160 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2161 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2162 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2164 e2fsck_journal_release(ctx, journal, 0, 1);
2169 * We want to make the flags consistent here. We will not leave with
2170 * needs_recovery set but has_journal clear. We can't get in a loop
2171 * with -y, -n, or -p, only if a user isn't making up their mind.
2174 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2175 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2177 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2179 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2180 goto no_has_journal;
2182 * Need a full fsck if we are releasing a
2183 * journal stored on a reserved inode.
2185 force_fsck = recover ||
2186 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2187 /* Clear all of the journal fields */
2188 sb->s_journal_inum = 0;
2189 sb->s_journal_dev = 0;
2190 memset(sb->s_journal_uuid, 0,
2191 sizeof(sb->s_journal_uuid));
2192 e2fsck_clear_recover(ctx, force_fsck);
2193 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2194 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2195 ext2fs_mark_super_dirty(ctx->fs);
2199 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2200 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2201 journal->j_superblock->s_start != 0) {
2202 /* Print status information */
2203 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2204 if (ctx->superblock)
2205 problem = PR_0_JOURNAL_RUN_DEFAULT;
2207 problem = PR_0_JOURNAL_RUN;
2208 if (fix_problem(ctx, problem, &pctx)) {
2209 ctx->options |= E2F_OPT_FORCE;
2210 sb->s_feature_incompat |=
2211 EXT3_FEATURE_INCOMPAT_RECOVER;
2212 ext2fs_mark_super_dirty(ctx->fs);
2213 } else if (fix_problem(ctx,
2214 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2216 sb->s_state &= ~EXT2_VALID_FS;
2217 ext2fs_mark_super_dirty(ctx->fs);
2220 * If the user answers no to the above question, we
2221 * ignore the fact that journal apparently has data;
2222 * accidentally replaying over valid data would be far
2223 * worse than skipping a questionable recovery.
2225 * XXX should we abort with a fatal error here? What
2226 * will the ext3 kernel code do if a filesystem with
2227 * !NEEDS_RECOVERY but with a non-zero
2228 * journal->j_superblock->s_start is mounted?
2232 e2fsck_journal_release(ctx, journal, reset, 0);
2236 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2241 journal_init_revoke_caches();
2242 retval = e2fsck_get_journal(ctx, &journal);
2246 retval = e2fsck_journal_load(journal);
2250 retval = journal_init_revoke(journal, 1024);
2254 retval = -journal_recover(journal);
2258 if (journal->j_superblock->s_errno) {
2259 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2260 ext2fs_mark_super_dirty(ctx->fs);
2261 journal->j_superblock->s_errno = 0;
2262 mark_buffer_dirty(journal->j_sb_buffer);
2266 journal_destroy_revoke(journal);
2267 journal_destroy_revoke_caches();
2268 e2fsck_journal_release(ctx, journal, 1, 0);
2272 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2274 io_manager io_ptr = ctx->fs->io->manager;
2275 int blocksize = ctx->fs->blocksize;
2276 errcode_t retval, recover_retval;
2278 printf(_("%s: recovering journal\n"), ctx->device_name);
2279 if (ctx->options & E2F_OPT_READONLY) {
2280 printf(_("%s: won't do journal recovery while read-only\n"),
2282 return EXT2_ET_FILE_RO;
2285 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2286 ext2fs_flush(ctx->fs); /* Force out any modifications */
2288 recover_retval = recover_ext3_journal(ctx);
2291 * Reload the filesystem context to get up-to-date data from disk
2292 * because journal recovery will change the filesystem under us.
2294 ext2fs_close(ctx->fs);
2295 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2296 ctx->superblock, blocksize, io_ptr,
2300 com_err(ctx->program_name, retval,
2301 _("while trying to re-open %s"),
2303 fatal_error(ctx, 0);
2305 ctx->fs->priv_data = ctx;
2307 /* Set the superblock flags */
2308 e2fsck_clear_recover(ctx, recover_retval);
2309 return recover_retval;
2313 * This function will move the journal inode from a visible file in
2314 * the filesystem directory hierarchy to the reserved inode if necessary.
2316 static const char * const journal_names[] = {
2317 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2319 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2321 struct ext2_super_block *sb = ctx->fs->super;
2322 struct problem_context pctx;
2323 struct ext2_inode inode;
2324 ext2_filsys fs = ctx->fs;
2327 const char * const * cpp;
2328 int group, mount_flags;
2330 clear_problem_context(&pctx);
2333 * If the filesystem is opened read-only, or there is no
2334 * journal, then do nothing.
2336 if ((ctx->options & E2F_OPT_READONLY) ||
2337 (sb->s_journal_inum == 0) ||
2338 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2342 * Read in the journal inode
2344 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2348 * If it's necessary to backup the journal inode, do so.
2350 if ((sb->s_jnl_backup_type == 0) ||
2351 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2352 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2353 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2354 memcpy(sb->s_jnl_blocks, inode.i_block,
2356 sb->s_jnl_blocks[16] = inode.i_size;
2357 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2358 ext2fs_mark_super_dirty(fs);
2359 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2364 * If the journal is already the hidden inode, then do nothing
2366 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2370 * The journal inode had better have only one link and not be readable.
2372 if (inode.i_links_count != 1)
2376 * If the filesystem is mounted, or we can't tell whether
2377 * or not it's mounted, do nothing.
2379 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2380 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2384 * If we can't find the name of the journal inode, then do
2387 for (cpp = journal_names; *cpp; cpp++) {
2388 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2389 strlen(*cpp), 0, &ino);
2390 if ((retval == 0) && (ino == sb->s_journal_inum))
2396 /* We need the inode bitmap to be loaded */
2397 retval = ext2fs_read_bitmaps(fs);
2402 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2406 * OK, we've done all the checks, let's actually move the
2407 * journal inode. Errors at this point mean we need to force
2408 * an ext2 filesystem check.
2410 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2412 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2414 sb->s_journal_inum = EXT2_JOURNAL_INO;
2415 ext2fs_mark_super_dirty(fs);
2416 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2417 inode.i_links_count = 0;
2418 inode.i_dtime = time(0);
2419 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2422 group = ext2fs_group_of_ino(fs, ino);
2423 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2424 ext2fs_mark_ib_dirty(fs);
2425 fs->group_desc[group].bg_free_inodes_count++;
2426 fs->super->s_free_inodes_count++;
2430 pctx.errcode = retval;
2431 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2432 fs->super->s_state &= ~EXT2_VALID_FS;
2433 ext2fs_mark_super_dirty(fs);
2438 * message.c --- print e2fsck messages (with compression)
2440 * print_e2fsck_message() prints a message to the user, using
2441 * compression techniques and expansions of abbreviations.
2443 * The following % expansions are supported:
2445 * %b <blk> block number
2446 * %B <blkcount> integer
2447 * %c <blk2> block number
2448 * %Di <dirent>->ino inode number
2449 * %Dn <dirent>->name string
2450 * %Dr <dirent>->rec_len
2451 * %Dl <dirent>->name_len
2452 * %Dt <dirent>->filetype
2453 * %d <dir> inode number
2454 * %g <group> integer
2455 * %i <ino> inode number
2456 * %Is <inode> -> i_size
2457 * %IS <inode> -> i_extra_isize
2458 * %Ib <inode> -> i_blocks
2459 * %Il <inode> -> i_links_count
2460 * %Im <inode> -> i_mode
2461 * %IM <inode> -> i_mtime
2462 * %IF <inode> -> i_faddr
2463 * %If <inode> -> i_file_acl
2464 * %Id <inode> -> i_dir_acl
2465 * %Iu <inode> -> i_uid
2466 * %Ig <inode> -> i_gid
2467 * %j <ino2> inode number
2468 * %m <com_err error message>
2470 * %p ext2fs_get_pathname of directory <ino>
2471 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2472 * the containing directory. (If dirent is NULL
2473 * then return the pathname of directory <ino2>)
2474 * %q ext2fs_get_pathname of directory <dir>
2475 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2476 * the containing directory.
2477 * %s <str> miscellaneous string
2478 * %S backup superblock
2479 * %X <num> hexadecimal format
2481 * The following '@' expansions are supported:
2483 * @a extended attribute
2484 * @A error allocating
2488 * @C conflicts with some other fs block
2492 * @E Entry '%Dn' in %p (%i)
2494 * @F for @i %i (%Q) is
2496 * @h HTREE directory inode
2502 * @m multiply-claimed
2516 * This structure defines the abbreviations used by the text strings
2517 * below. The first character in the string is the index letter. An
2518 * abbreviation of the form '@<i>' is expanded by looking up the index
2519 * letter <i> in the table below.
2521 static const char * const abbrevs[] = {
2522 N_("aextended attribute"),
2523 N_("Aerror allocating"),
2527 N_("Cconflicts with some other fs @b"),
2534 N_("E@e '%Dn' in %p (%i)"),
2536 N_("Ffor @i %i (%Q) is"),
2541 N_("mmultiply-claimed"),
2556 * Give more user friendly names to the "special" inodes.
2558 #define num_special_inodes 11
2559 static const char * const special_inode_name[] =
2561 N_("<The NULL inode>"), /* 0 */
2562 N_("<The bad blocks inode>"), /* 1 */
2564 N_("<The ACL index inode>"), /* 3 */
2565 N_("<The ACL data inode>"), /* 4 */
2566 N_("<The boot loader inode>"), /* 5 */
2567 N_("<The undelete directory inode>"), /* 6 */
2568 N_("<The group descriptor inode>"), /* 7 */
2569 N_("<The journal inode>"), /* 8 */
2570 N_("<Reserved inode 9>"), /* 9 */
2571 N_("<Reserved inode 10>"), /* 10 */
2575 * This function does "safe" printing. It will convert non-printable
2576 * ASCII characters using '^' and M- notation.
2578 static void safe_print(const char *cp, int len)
2588 fputs("M-", stdout);
2591 if ((ch < 32) || (ch == 0x7f)) {
2593 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2601 * This function prints a pathname, using the ext2fs_get_pathname
2604 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2609 if (!dir && (ino < num_special_inodes)) {
2610 fputs(_(special_inode_name[ino]), stdout);
2614 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2616 fputs("???", stdout);
2618 safe_print(path, -1);
2619 ext2fs_free_mem(&path);
2623 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2624 struct problem_context *pctx, int first);
2626 * This function handles the '@' expansion. We allow recursive
2627 * expansion; an @ expression can contain further '@' and '%'
2630 static void expand_at_expression(e2fsck_t ctx, char ch,
2631 struct problem_context *pctx,
2634 const char * const *cpp;
2637 /* Search for the abbreviation */
2638 for (cpp = abbrevs; *cpp; cpp++) {
2644 if (*first && islower(*str)) {
2646 fputc(toupper(*str++), stdout);
2648 print_e2fsck_message(ctx, str, pctx, *first);
2654 * This function expands '%IX' expressions
2656 static void expand_inode_expression(char ch,
2657 struct problem_context *ctx)
2659 struct ext2_inode *inode;
2660 struct ext2_inode_large *large_inode;
2665 if (!ctx || !ctx->inode)
2669 large_inode = (struct ext2_inode_large *) inode;
2673 if (LINUX_S_ISDIR(inode->i_mode))
2674 printf("%u", inode->i_size);
2676 #ifdef EXT2_NO_64_TYPE
2677 if (inode->i_size_high)
2678 printf("0x%x%08x", inode->i_size_high,
2681 printf("%u", inode->i_size);
2683 printf("%llu", (inode->i_size |
2684 ((__u64) inode->i_size_high << 32)));
2689 printf("%u", large_inode->i_extra_isize);
2692 printf("%u", inode->i_blocks);
2695 printf("%d", inode->i_links_count);
2698 printf("0%o", inode->i_mode);
2701 /* The diet libc doesn't respect the TZ environemnt variable */
2703 time_str = getenv("TZ");
2706 do_gmt = !strcmp(time_str, "GMT");
2709 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2710 printf("%.24s", time_str);
2713 printf("%u", inode->i_faddr);
2716 printf("%u", inode->i_file_acl);
2719 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2720 inode->i_dir_acl : 0));
2723 printf("%d", (inode->i_uid |
2724 (inode->osd2.linux2.l_i_uid_high << 16)));
2727 printf("%d", (inode->i_gid |
2728 (inode->osd2.linux2.l_i_gid_high << 16)));
2732 printf("%%I%c", ch);
2738 * This function expands '%dX' expressions
2740 static _INLINE_ void expand_dirent_expression(char ch,
2741 struct problem_context *ctx)
2743 struct ext2_dir_entry *dirent;
2746 if (!ctx || !ctx->dirent)
2749 dirent = ctx->dirent;
2753 printf("%u", dirent->inode);
2756 len = dirent->name_len & 0xFF;
2757 if (len > EXT2_NAME_LEN)
2758 len = EXT2_NAME_LEN;
2759 if (len > dirent->rec_len)
2760 len = dirent->rec_len;
2761 safe_print(dirent->name, len);
2764 printf("%u", dirent->rec_len);
2767 printf("%u", dirent->name_len & 0xFF);
2770 printf("%u", dirent->name_len >> 8);
2774 printf("%%D%c", ch);
2779 static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
2780 struct problem_context *ctx)
2790 printf("%u", ctx->blk);
2793 #ifdef EXT2_NO_64_TYPE
2794 printf("%d", ctx->blkcount);
2796 printf("%lld", ctx->blkcount);
2800 printf("%u", ctx->blk2);
2803 printf("%u", ctx->dir);
2806 printf("%d", ctx->group);
2809 printf("%u", ctx->ino);
2812 printf("%u", ctx->ino2);
2815 printf("%s", error_message(ctx->errcode));
2818 #ifdef EXT2_NO_64_TYPE
2819 printf("%u", ctx->num);
2821 printf("%llu", ctx->num);
2825 print_pathname(fs, ctx->ino, 0);
2828 print_pathname(fs, ctx->ino2,
2829 ctx->dirent ? ctx->dirent->inode : 0);
2832 print_pathname(fs, ctx->dir, 0);
2835 print_pathname(fs, ctx->dir, ctx->ino);
2838 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2841 printf("%s", ctx->str ? ctx->str : "NULL");
2844 #ifdef EXT2_NO_64_TYPE
2845 printf("0x%x", ctx->num);
2847 printf("0x%llx", ctx->num);
2858 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2859 struct problem_context *pctx, int first)
2861 ext2_filsys fs = ctx->fs;
2865 e2fsck_clear_progbar(ctx);
2866 for (cp = msg; *cp; cp++) {
2869 expand_at_expression(ctx, *cp, pctx, &first);
2870 } else if (cp[0] == '%' && cp[1] == 'I') {
2872 expand_inode_expression(*cp, pctx);
2873 } else if (cp[0] == '%' && cp[1] == 'D') {
2875 expand_dirent_expression(*cp, pctx);
2876 } else if ((cp[0] == '%')) {
2878 expand_percent_expression(fs, *cp, pctx);
2880 for (i=0; cp[i]; i++)
2881 if ((cp[i] == '@') || cp[i] == '%')
2883 printf("%.*s", i, cp);
2892 * region.c --- code which manages allocations within a region.
2896 region_addr_t start;
2898 struct region_el *next;
2901 struct region_struct {
2904 struct region_el *allocated;
2907 static region_t region_create(region_addr_t min, region_addr_t max)
2911 region = malloc(sizeof(struct region_struct));
2914 memset(region, 0, sizeof(struct region_struct));
2920 static void region_free(region_t region)
2922 struct region_el *r, *next;
2924 for (r = region->allocated; r; r = next) {
2928 memset(region, 0, sizeof(struct region_struct));
2932 static int region_allocate(region_t region, region_addr_t start, int n)
2934 struct region_el *r, *new_region, *prev, *next;
2938 if ((start < region->min) || (end > region->max))
2944 * Search through the linked list. If we find that it
2945 * conflicts witih something that's already allocated, return
2946 * 1; if we can find an existing region which we can grow, do
2947 * so. Otherwise, stop when we find the appropriate place
2948 * insert a new region element into the linked list.
2950 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2951 if (((start >= r->start) && (start < r->end)) ||
2952 ((end > r->start) && (end <= r->end)) ||
2953 ((start <= r->start) && (end >= r->end)))
2955 if (end == r->start) {
2959 if (start == r->end) {
2960 if ((next = r->next)) {
2961 if (end > next->start)
2963 if (end == next->start) {
2965 r->next = next->next;
2973 if (start < r->start)
2977 * Insert a new region element structure into the linked list
2979 new_region = malloc(sizeof(struct region_el));
2982 new_region->start = start;
2983 new_region->end = start + n;
2984 new_region->next = r;
2986 prev->next = new_region;
2988 region->allocated = new_region;
2993 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2995 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2996 * and applies the following tests to each inode:
2998 * - The mode field of the inode must be legal.
2999 * - The size and block count fields of the inode are correct.
3000 * - A data block must not be used by another inode
3002 * Pass 1 also gathers the collects the following information:
3004 * - A bitmap of which inodes are in use. (inode_used_map)
3005 * - A bitmap of which inodes are directories. (inode_dir_map)
3006 * - A bitmap of which inodes are regular files. (inode_reg_map)
3007 * - A bitmap of which inodes have bad fields. (inode_bad_map)
3008 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
3009 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
3010 * - A bitmap of which blocks are in use. (block_found_map)
3011 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
3012 * - The data blocks of the directory inodes. (dir_map)
3014 * Pass 1 is designed to stash away enough information so that the
3015 * other passes should not need to read in the inode information
3016 * during the normal course of a filesystem check. (Althogh if an
3017 * inconsistency is detected, other passes may need to read in an
3020 * Note that pass 1B will be invoked if there are any duplicate blocks
3025 static int process_block(ext2_filsys fs, blk_t *blocknr,
3026 e2_blkcnt_t blockcnt, blk_t ref_blk,
3027 int ref_offset, void *priv_data);
3028 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
3029 e2_blkcnt_t blockcnt, blk_t ref_blk,
3030 int ref_offset, void *priv_data);
3031 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
3033 static void mark_table_blocks(e2fsck_t ctx);
3034 static void alloc_bb_map(e2fsck_t ctx);
3035 static void alloc_imagic_map(e2fsck_t ctx);
3036 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
3037 static void handle_fs_bad_blocks(e2fsck_t ctx);
3038 static void process_inodes(e2fsck_t ctx, char *block_buf);
3039 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
3040 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
3041 dgrp_t group, void * priv_data);
3042 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3043 char *block_buf, int adjust_sign);
3044 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
3046 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
3047 struct ext2_inode * inode, int bufsize,
3050 struct process_block_struct_1 {
3052 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
3053 fragmented:1, compressed:1, bbcheck:1;
3056 e2_blkcnt_t last_block;
3057 int num_illegal_blocks;
3058 blk_t previous_block;
3059 struct ext2_inode *inode;
3060 struct problem_context *pctx;
3061 ext2fs_block_bitmap fs_meta_blocks;
3065 struct process_inode_block {
3067 struct ext2_inode inode;
3070 struct scan_callback_struct {
3076 * For the inodes to process list.
3078 static struct process_inode_block *inodes_to_process;
3079 static int process_inode_count;
3081 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
3082 EXT2_MIN_BLOCK_LOG_SIZE + 1];
3085 * Free all memory allocated by pass1 in preparation for restarting
3088 static void unwind_pass1(void)
3090 ext2fs_free_mem(&inodes_to_process);
3094 * Check to make sure a device inode is real. Returns 1 if the device
3095 * checks out, 0 if not.
3097 * Note: this routine is now also used to check FIFO's and Sockets,
3098 * since they have the same requirement; the i_block fields should be
3102 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
3107 * If i_blocks is non-zero, or the index flag is set, then
3108 * this is a bogus device/fifo/socket
3110 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
3111 (inode->i_flags & EXT2_INDEX_FL))
3115 * We should be able to do the test below all the time, but
3116 * because the kernel doesn't forcibly clear the device
3117 * inode's additional i_block fields, there are some rare
3118 * occasions when a legitimate device inode will have non-zero
3119 * additional i_block fields. So for now, we only complain
3120 * when the immutable flag is set, which should never happen
3121 * for devices. (And that's when the problem is caused, since
3122 * you can't set or clear immutable flags for devices.) Once
3123 * the kernel has been fixed we can change this...
3125 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
3126 for (i=4; i < EXT2_N_BLOCKS; i++)
3127 if (inode->i_block[i])
3134 * Check to make sure a symlink inode is real. Returns 1 if the symlink
3135 * checks out, 0 if not.
3138 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
3144 if ((inode->i_size_high || inode->i_size == 0) ||
3145 (inode->i_flags & EXT2_INDEX_FL))
3148 blocks = ext2fs_inode_data_blocks(fs, inode);
3150 if ((inode->i_size >= fs->blocksize) ||
3151 (blocks != fs->blocksize >> 9) ||
3152 (inode->i_block[0] < fs->super->s_first_data_block) ||
3153 (inode->i_block[0] >= fs->super->s_blocks_count))
3156 for (i = 1; i < EXT2_N_BLOCKS; i++)
3157 if (inode->i_block[i])
3160 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
3163 len = strnlen(buf, fs->blocksize);
3164 if (len == fs->blocksize)
3167 if (inode->i_size >= sizeof(inode->i_block))
3170 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3171 if (len == sizeof(inode->i_block))
3174 if (len != inode->i_size)
3180 * If the immutable (or append-only) flag is set on the inode, offer
3183 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3184 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3186 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3189 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3192 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3193 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3197 * If device, fifo or socket, check size is zero -- if not offer to
3200 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3202 struct ext2_inode *inode = pctx->inode;
3204 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3207 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3211 inode->i_size_high = 0;
3212 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3215 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3217 struct ext2_super_block *sb = ctx->fs->super;
3218 struct ext2_inode_large *inode;
3219 struct ext2_ext_attr_entry *entry;
3221 int storage_size, remain, offs;
3224 inode = (struct ext2_inode_large *) pctx->inode;
3225 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3226 inode->i_extra_isize;
3227 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3228 inode->i_extra_isize + sizeof(__u32);
3229 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3230 entry = (struct ext2_ext_attr_entry *) start;
3232 /* scan all entry's headers first */
3234 /* take finish entry 0UL into account */
3235 remain = storage_size - sizeof(__u32);
3238 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3240 /* header eats this space */
3241 remain -= sizeof(struct ext2_ext_attr_entry);
3243 /* is attribute name valid? */
3244 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3245 pctx->num = entry->e_name_len;
3246 problem = PR_1_ATTR_NAME_LEN;
3250 /* attribute len eats this space */
3251 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3253 /* check value size */
3254 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3255 pctx->num = entry->e_value_size;
3256 problem = PR_1_ATTR_VALUE_SIZE;
3260 /* check value placement */
3261 if (entry->e_value_offs +
3262 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3263 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3264 pctx->num = entry->e_value_offs;
3265 problem = PR_1_ATTR_VALUE_OFFSET;
3269 /* e_value_block must be 0 in inode's ea */
3270 if (entry->e_value_block != 0) {
3271 pctx->num = entry->e_value_block;
3272 problem = PR_1_ATTR_VALUE_BLOCK;
3276 /* e_hash must be 0 in inode's ea */
3277 if (entry->e_hash != 0) {
3278 pctx->num = entry->e_hash;
3279 problem = PR_1_ATTR_HASH;
3283 remain -= entry->e_value_size;
3284 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3286 entry = EXT2_EXT_ATTR_NEXT(entry);
3290 * it seems like a corruption. it's very unlikely we could repair
3291 * EA(s) in automatic fashion -bzzz
3293 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3296 /* simple remove all possible EA(s) */
3297 *((__u32 *)start) = 0UL;
3298 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3299 EXT2_INODE_SIZE(sb), "pass1");
3302 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3304 struct ext2_super_block *sb = ctx->fs->super;
3305 struct ext2_inode_large *inode;
3309 inode = (struct ext2_inode_large *) pctx->inode;
3310 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3311 /* this isn't large inode. so, nothing to check */
3315 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3316 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3317 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3319 * For now we will allow i_extra_isize to be 0, but really
3320 * implementations should never allow i_extra_isize to be 0
3322 if (inode->i_extra_isize &&
3323 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3324 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3326 inode->i_extra_isize = min;
3327 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3328 EXT2_INODE_SIZE(sb), "pass1");
3332 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3333 inode->i_extra_isize);
3334 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3335 /* it seems inode has an extended attribute(s) in body */
3336 check_ea_in_inode(ctx, pctx);
3340 static void e2fsck_pass1(e2fsck_t ctx)
3344 ext2_filsys fs = ctx->fs;
3346 struct ext2_inode *inode;
3347 ext2_inode_scan scan;
3349 unsigned char frag, fsize;
3350 struct problem_context pctx;
3351 struct scan_callback_struct scan_struct;
3352 struct ext2_super_block *sb = ctx->fs->super;
3354 int busted_fs_time = 0;
3357 clear_problem_context(&pctx);
3359 if (!(ctx->options & E2F_OPT_PREEN))
3360 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3362 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3363 !(ctx->options & E2F_OPT_NO)) {
3364 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3365 ctx->dirs_to_hash = 0;
3370 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3372 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3373 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3374 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3375 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3376 max_sizes = (max_sizes * (1UL << i)) - 1;
3377 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3381 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3384 * Allocate bitmaps structures
3386 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3387 &ctx->inode_used_map);
3390 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3391 ctx->flags |= E2F_FLAG_ABORT;
3394 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3395 _("directory inode map"), &ctx->inode_dir_map);
3398 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3399 ctx->flags |= E2F_FLAG_ABORT;
3402 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3403 _("regular file inode map"), &ctx->inode_reg_map);
3406 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3407 ctx->flags |= E2F_FLAG_ABORT;
3410 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3411 &ctx->block_found_map);
3414 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3415 ctx->flags |= E2F_FLAG_ABORT;
3418 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3419 &ctx->inode_link_info);
3421 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3422 ctx->flags |= E2F_FLAG_ABORT;
3425 inode_size = EXT2_INODE_SIZE(fs->super);
3426 inode = (struct ext2_inode *)
3427 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3429 inodes_to_process = (struct process_inode_block *)
3430 e2fsck_allocate_memory(ctx,
3431 (ctx->process_inode_size *
3432 sizeof(struct process_inode_block)),
3433 "array of inodes to process");
3434 process_inode_count = 0;
3436 pctx.errcode = ext2fs_init_dblist(fs, 0);
3438 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3439 ctx->flags |= E2F_FLAG_ABORT;
3444 * If the last orphan field is set, clear it, since the pass1
3445 * processing will automatically find and clear the orphans.
3446 * In the future, we may want to try using the last_orphan
3447 * linked list ourselves, but for now, we clear it so that the
3448 * ext3 mount code won't get confused.
3450 if (!(ctx->options & E2F_OPT_READONLY)) {
3451 if (fs->super->s_last_orphan) {
3452 fs->super->s_last_orphan = 0;
3453 ext2fs_mark_super_dirty(fs);
3457 mark_table_blocks(ctx);
3458 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3459 "block interate buffer");
3460 e2fsck_use_inode_shortcuts(ctx, 1);
3461 ehandler_operation(_("doing inode scan"));
3462 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3465 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3466 ctx->flags |= E2F_FLAG_ABORT;
3469 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3470 ctx->stashed_inode = inode;
3471 scan_struct.ctx = ctx;
3472 scan_struct.block_buf = block_buf;
3473 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3475 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3477 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3478 (fs->super->s_mtime < fs->super->s_inodes_count))
3482 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3484 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3486 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3487 if (!ctx->inode_bb_map)
3489 ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
3490 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3494 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3495 ctx->flags |= E2F_FLAG_ABORT;
3502 ctx->stashed_ino = ino;
3503 if (inode->i_links_count) {
3504 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3505 ino, inode->i_links_count);
3507 pctx.num = inode->i_links_count;
3508 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3509 ctx->flags |= E2F_FLAG_ABORT;
3513 if (ino == EXT2_BAD_INO) {
3514 struct process_block_struct_1 pb;
3516 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3517 &pb.fs_meta_blocks);
3520 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3521 ctx->flags |= E2F_FLAG_ABORT;
3524 pb.ino = EXT2_BAD_INO;
3525 pb.num_blocks = pb.last_block = 0;
3526 pb.num_illegal_blocks = 0;
3527 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3528 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3532 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3533 block_buf, process_bad_block, &pb);
3534 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3536 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3537 ctx->flags |= E2F_FLAG_ABORT;
3541 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3542 ctx->flags |= E2F_FLAG_ABORT;
3545 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3546 clear_problem_context(&pctx);
3548 } else if (ino == EXT2_ROOT_INO) {
3550 * Make sure the root inode is a directory; if
3551 * not, offer to clear it. It will be
3552 * regnerated in pass #3.
3554 if (!LINUX_S_ISDIR(inode->i_mode)) {
3555 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3556 inode->i_dtime = time(0);
3557 inode->i_links_count = 0;
3558 ext2fs_icount_store(ctx->inode_link_info,
3560 e2fsck_write_inode(ctx, ino, inode,
3566 * If dtime is set, offer to clear it. mke2fs
3567 * version 0.2b created filesystems with the
3568 * dtime field set for the root and lost+found
3569 * directories. We won't worry about
3570 * /lost+found, since that can be regenerated
3571 * easily. But we will fix the root directory
3572 * as a special case.
3574 if (inode->i_dtime && inode->i_links_count) {
3575 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3577 e2fsck_write_inode(ctx, ino, inode,
3581 } else if (ino == EXT2_JOURNAL_INO) {
3582 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3583 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3584 if (!LINUX_S_ISREG(inode->i_mode) &&
3585 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3587 inode->i_mode = LINUX_S_IFREG;
3588 e2fsck_write_inode(ctx, ino, inode,
3591 check_blocks(ctx, &pctx, block_buf);
3594 if ((inode->i_links_count || inode->i_blocks ||
3595 inode->i_blocks || inode->i_block[0]) &&
3596 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3598 memset(inode, 0, inode_size);
3599 ext2fs_icount_store(ctx->inode_link_info,
3601 e2fsck_write_inode_full(ctx, ino, inode,
3602 inode_size, "pass1");
3604 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3607 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3608 if (ino == EXT2_BOOT_LOADER_INO) {
3609 if (LINUX_S_ISDIR(inode->i_mode))
3610 problem = PR_1_RESERVED_BAD_MODE;
3611 } else if (ino == EXT2_RESIZE_INO) {
3612 if (inode->i_mode &&
3613 !LINUX_S_ISREG(inode->i_mode))
3614 problem = PR_1_RESERVED_BAD_MODE;
3616 if (inode->i_mode != 0)
3617 problem = PR_1_RESERVED_BAD_MODE;
3620 if (fix_problem(ctx, problem, &pctx)) {
3622 e2fsck_write_inode(ctx, ino, inode,
3626 check_blocks(ctx, &pctx, block_buf);
3630 * Check for inodes who might have been part of the
3631 * orphaned list linked list. They should have gotten
3632 * dealt with by now, unless the list had somehow been
3635 * FIXME: In the future, inodes which are still in use
3636 * (and which are therefore) pending truncation should
3637 * be handled specially. Right now we just clear the
3638 * dtime field, and the normal e2fsck handling of
3639 * inodes where i_size and the inode blocks are
3640 * inconsistent is to fix i_size, instead of releasing
3641 * the extra blocks. This won't catch the inodes that
3642 * was at the end of the orphan list, but it's better
3643 * than nothing. The right answer is that there
3644 * shouldn't be any bugs in the orphan list handling. :-)
3646 if (inode->i_dtime && !busted_fs_time &&
3647 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3648 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3649 inode->i_dtime = inode->i_links_count ?
3651 e2fsck_write_inode(ctx, ino, inode,
3657 * This code assumes that deleted inodes have
3658 * i_links_count set to 0.
3660 if (!inode->i_links_count) {
3661 if (!inode->i_dtime && inode->i_mode) {
3662 if (fix_problem(ctx,
3663 PR_1_ZERO_DTIME, &pctx)) {
3664 inode->i_dtime = time(0);
3665 e2fsck_write_inode(ctx, ino, inode,
3672 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3673 * deleted files. Oops.
3675 * Since all new ext2 implementations get this right,
3676 * we now assume that the case of non-zero
3677 * i_links_count and non-zero dtime means that we
3678 * should keep the file, not delete it.
3681 if (inode->i_dtime) {
3682 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3684 e2fsck_write_inode(ctx, ino, inode, "pass1");
3688 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3689 switch (fs->super->s_creator_os) {
3691 frag = inode->osd2.linux2.l_i_frag;
3692 fsize = inode->osd2.linux2.l_i_fsize;
3695 frag = inode->osd2.hurd2.h_i_frag;
3696 fsize = inode->osd2.hurd2.h_i_fsize;
3699 frag = inode->osd2.masix2.m_i_frag;
3700 fsize = inode->osd2.masix2.m_i_fsize;
3706 if (inode->i_faddr || frag || fsize ||
3707 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3708 mark_inode_bad(ctx, ino);
3709 if (inode->i_flags & EXT2_IMAGIC_FL) {
3711 if (!ctx->inode_imagic_map)
3712 alloc_imagic_map(ctx);
3713 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3716 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3717 inode->i_flags &= ~EXT2_IMAGIC_FL;
3718 e2fsck_write_inode(ctx, ino,
3724 check_inode_extra_space(ctx, &pctx);
3726 if (LINUX_S_ISDIR(inode->i_mode)) {
3727 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3728 e2fsck_add_dir_info(ctx, ino, 0);
3729 ctx->fs_directory_count++;
3730 } else if (LINUX_S_ISREG (inode->i_mode)) {
3731 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3732 ctx->fs_regular_count++;
3733 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3734 e2fsck_pass1_check_device_inode(fs, inode)) {
3735 check_immutable(ctx, &pctx);
3736 check_size(ctx, &pctx);
3737 ctx->fs_chardev_count++;
3738 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3739 e2fsck_pass1_check_device_inode(fs, inode)) {
3740 check_immutable(ctx, &pctx);
3741 check_size(ctx, &pctx);
3742 ctx->fs_blockdev_count++;
3743 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3744 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3745 check_immutable(ctx, &pctx);
3746 ctx->fs_symlinks_count++;
3747 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3748 ctx->fs_fast_symlinks_count++;
3749 check_blocks(ctx, &pctx, block_buf);
3753 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3754 e2fsck_pass1_check_device_inode(fs, inode)) {
3755 check_immutable(ctx, &pctx);
3756 check_size(ctx, &pctx);
3757 ctx->fs_fifo_count++;
3758 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3759 e2fsck_pass1_check_device_inode(fs, inode)) {
3760 check_immutable(ctx, &pctx);
3761 check_size(ctx, &pctx);
3762 ctx->fs_sockets_count++;
3764 mark_inode_bad(ctx, ino);
3765 if (inode->i_block[EXT2_IND_BLOCK])
3766 ctx->fs_ind_count++;
3767 if (inode->i_block[EXT2_DIND_BLOCK])
3768 ctx->fs_dind_count++;
3769 if (inode->i_block[EXT2_TIND_BLOCK])
3770 ctx->fs_tind_count++;
3771 if (inode->i_block[EXT2_IND_BLOCK] ||
3772 inode->i_block[EXT2_DIND_BLOCK] ||
3773 inode->i_block[EXT2_TIND_BLOCK] ||
3774 inode->i_file_acl) {
3775 inodes_to_process[process_inode_count].ino = ino;
3776 inodes_to_process[process_inode_count].inode = *inode;
3777 process_inode_count++;
3779 check_blocks(ctx, &pctx, block_buf);
3781 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3784 if (process_inode_count >= ctx->process_inode_size) {
3785 process_inodes(ctx, block_buf);
3787 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3791 process_inodes(ctx, block_buf);
3792 ext2fs_close_inode_scan(scan);
3793 ehandler_operation(0);
3796 * If any extended attribute blocks' reference counts need to
3797 * be adjusted, either up (ctx->refcount_extra), or down
3798 * (ctx->refcount), then fix them.
3800 if (ctx->refcount) {
3801 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3802 ea_refcount_free(ctx->refcount);
3805 if (ctx->refcount_extra) {
3806 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3808 ea_refcount_free(ctx->refcount_extra);
3809 ctx->refcount_extra = 0;
3812 if (ctx->invalid_bitmaps)
3813 handle_fs_bad_blocks(ctx);
3815 /* We don't need the block_ea_map any more */
3816 ext2fs_free_block_bitmap(ctx->block_ea_map);
3817 ctx->block_ea_map = 0;
3819 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3820 ext2fs_block_bitmap save_bmap;
3822 save_bmap = fs->block_map;
3823 fs->block_map = ctx->block_found_map;
3824 clear_problem_context(&pctx);
3825 pctx.errcode = ext2fs_create_resize_inode(fs);
3827 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3828 /* Should never get here */
3829 ctx->flags |= E2F_FLAG_ABORT;
3832 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3834 inode->i_mtime = time(0);
3835 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3837 fs->block_map = save_bmap;
3838 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3841 if (ctx->flags & E2F_FLAG_RESTART) {
3843 * Only the master copy of the superblock and block
3844 * group descriptors are going to be written during a
3845 * restart, so set the superblock to be used to be the
3846 * master superblock.
3848 ctx->use_superblock = 0;
3853 if (ctx->block_dup_map) {
3854 if (ctx->options & E2F_OPT_PREEN) {
3855 clear_problem_context(&pctx);
3856 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3858 e2fsck_pass1_dupblocks(ctx, block_buf);
3860 ext2fs_free_mem(&inodes_to_process);
3862 e2fsck_use_inode_shortcuts(ctx, 0);
3864 ext2fs_free_mem(&block_buf);
3865 ext2fs_free_mem(&inode);
3870 * When the inode_scan routines call this callback at the end of the
3871 * glock group, call process_inodes.
3873 static errcode_t scan_callback(ext2_filsys fs,
3874 ext2_inode_scan scan FSCK_ATTR((unused)),
3875 dgrp_t group, void * priv_data)
3877 struct scan_callback_struct *scan_struct;
3880 scan_struct = (struct scan_callback_struct *) priv_data;
3881 ctx = scan_struct->ctx;
3883 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3886 if ((ctx->progress)(ctx, 1, group+1,
3887 ctx->fs->group_desc_count))
3888 return EXT2_ET_CANCEL_REQUESTED;
3894 * Process the inodes in the "inodes to process" list.
3896 static void process_inodes(e2fsck_t ctx, char *block_buf)
3899 struct ext2_inode *old_stashed_inode;
3900 ext2_ino_t old_stashed_ino;
3901 const char *old_operation;
3903 struct problem_context pctx;
3905 /* begin process_inodes */
3906 if (process_inode_count == 0)
3908 old_operation = ehandler_operation(0);
3909 old_stashed_inode = ctx->stashed_inode;
3910 old_stashed_ino = ctx->stashed_ino;
3911 qsort(inodes_to_process, process_inode_count,
3912 sizeof(struct process_inode_block), process_inode_cmp);
3913 clear_problem_context(&pctx);
3914 for (i=0; i < process_inode_count; i++) {
3915 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3916 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3917 sprintf(buf, _("reading indirect blocks of inode %u"),
3919 ehandler_operation(buf);
3920 check_blocks(ctx, &pctx, block_buf);
3921 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3924 ctx->stashed_inode = old_stashed_inode;
3925 ctx->stashed_ino = old_stashed_ino;
3926 process_inode_count = 0;
3927 /* end process inodes */
3929 ehandler_operation(old_operation);
3932 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
3934 const struct process_inode_block *ib_a =
3935 (const struct process_inode_block *) a;
3936 const struct process_inode_block *ib_b =
3937 (const struct process_inode_block *) b;
3940 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3941 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3943 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3948 * Mark an inode as being bad in some what
3950 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3952 struct problem_context pctx;
3954 if (!ctx->inode_bad_map) {
3955 clear_problem_context(&pctx);
3957 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3958 _("bad inode map"), &ctx->inode_bad_map);
3961 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3962 /* Should never get here */
3963 ctx->flags |= E2F_FLAG_ABORT;
3967 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3972 * This procedure will allocate the inode "bb" (badblock) map table
3974 static void alloc_bb_map(e2fsck_t ctx)
3976 struct problem_context pctx;
3978 clear_problem_context(&pctx);
3979 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3980 _("inode in bad block map"),
3981 &ctx->inode_bb_map);
3984 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3985 /* Should never get here */
3986 ctx->flags |= E2F_FLAG_ABORT;
3992 * This procedure will allocate the inode imagic table
3994 static void alloc_imagic_map(e2fsck_t ctx)
3996 struct problem_context pctx;
3998 clear_problem_context(&pctx);
3999 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
4000 _("imagic inode map"),
4001 &ctx->inode_imagic_map);
4004 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4005 /* Should never get here */
4006 ctx->flags |= E2F_FLAG_ABORT;
4012 * Marks a block as in use, setting the dup_map if it's been set
4013 * already. Called by process_block and process_bad_block.
4015 * WARNING: Assumes checks have already been done to make sure block
4016 * is valid. This is true in both process_block and process_bad_block.
4018 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
4020 struct problem_context pctx;
4022 clear_problem_context(&pctx);
4024 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
4025 if (!ctx->block_dup_map) {
4026 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
4027 _("multiply claimed block map"),
4028 &ctx->block_dup_map);
4031 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
4033 /* Should never get here */
4034 ctx->flags |= E2F_FLAG_ABORT;
4038 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
4040 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
4045 * Adjust the extended attribute block's reference counts at the end
4046 * of pass 1, either by subtracting out references for EA blocks that
4047 * are still referenced in ctx->refcount, or by adding references for
4048 * EA blocks that had extra references as accounted for in
4049 * ctx->refcount_extra.
4051 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4052 char *block_buf, int adjust_sign)
4054 struct ext2_ext_attr_header *header;
4055 struct problem_context pctx;
4056 ext2_filsys fs = ctx->fs;
4061 clear_problem_context(&pctx);
4063 ea_refcount_intr_begin(refcount);
4065 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
4068 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4070 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
4073 header = (struct ext2_ext_attr_header *) block_buf;
4074 pctx.blkcount = header->h_refcount;
4075 should_be = header->h_refcount + adjust_sign * count;
4076 pctx.num = should_be;
4077 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
4078 header->h_refcount = should_be;
4079 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
4082 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
4090 * Handle processing the extended attribute blocks
4092 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
4095 ext2_filsys fs = ctx->fs;
4096 ext2_ino_t ino = pctx->ino;
4097 struct ext2_inode *inode = pctx->inode;
4100 struct ext2_ext_attr_header *header;
4101 struct ext2_ext_attr_entry *entry;
4105 blk = inode->i_file_acl;
4110 * If the Extended attribute flag isn't set, then a non-zero
4111 * file acl means that the inode is corrupted.
4113 * Or if the extended attribute block is an invalid block,
4114 * then the inode is also corrupted.
4116 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
4117 (blk < fs->super->s_first_data_block) ||
4118 (blk >= fs->super->s_blocks_count)) {
4119 mark_inode_bad(ctx, ino);
4123 /* If ea bitmap hasn't been allocated, create it */
4124 if (!ctx->block_ea_map) {
4125 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
4126 _("ext attr block map"),
4127 &ctx->block_ea_map);
4128 if (pctx->errcode) {
4130 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
4131 ctx->flags |= E2F_FLAG_ABORT;
4136 /* Create the EA refcount structure if necessary */
4137 if (!ctx->refcount) {
4138 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
4139 if (pctx->errcode) {
4141 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4142 ctx->flags |= E2F_FLAG_ABORT;
4147 /* Have we seen this EA block before? */
4148 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
4149 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
4151 /* Ooops, this EA was referenced more than it stated */
4152 if (!ctx->refcount_extra) {
4153 pctx->errcode = ea_refcount_create(0,
4154 &ctx->refcount_extra);
4155 if (pctx->errcode) {
4157 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
4158 ctx->flags |= E2F_FLAG_ABORT;
4162 ea_refcount_increment(ctx->refcount_extra, blk, 0);
4167 * OK, we haven't seen this EA block yet. So we need to
4171 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4172 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
4174 header = (struct ext2_ext_attr_header *) block_buf;
4175 pctx->blk = inode->i_file_acl;
4176 if (((ctx->ext_attr_ver == 1) &&
4177 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
4178 ((ctx->ext_attr_ver == 2) &&
4179 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
4180 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
4184 if (header->h_blocks != 1) {
4185 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
4189 region = region_create(0, fs->blocksize);
4191 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
4192 ctx->flags |= E2F_FLAG_ABORT;
4195 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4196 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4200 entry = (struct ext2_ext_attr_entry *)(header+1);
4201 end = block_buf + fs->blocksize;
4202 while ((char *)entry < end && *(__u32 *)entry) {
4203 if (region_allocate(region, (char *)entry - (char *)header,
4204 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4205 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4208 if ((ctx->ext_attr_ver == 1 &&
4209 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4210 (ctx->ext_attr_ver == 2 &&
4211 entry->e_name_index == 0)) {
4212 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4215 if (entry->e_value_block != 0) {
4216 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4219 if (entry->e_value_size &&
4220 region_allocate(region, entry->e_value_offs,
4221 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4222 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4225 entry = EXT2_EXT_ATTR_NEXT(entry);
4227 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4228 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4231 region_free(region);
4233 count = header->h_refcount - 1;
4235 ea_refcount_store(ctx->refcount, blk, count);
4236 mark_block_used(ctx, blk);
4237 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4242 inode->i_file_acl = 0;
4243 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4247 /* Returns 1 if bad htree, 0 if OK */
4248 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4249 ext2_ino_t ino FSCK_ATTR((unused)),
4250 struct ext2_inode *inode,
4253 struct ext2_dx_root_info *root;
4254 ext2_filsys fs = ctx->fs;
4258 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4259 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4260 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4261 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4264 blk = inode->i_block[0];
4266 (blk < fs->super->s_first_data_block) ||
4267 (blk >= fs->super->s_blocks_count)) &&
4268 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4271 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4272 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4275 /* XXX should check that beginning matches a directory */
4276 root = (struct ext2_dx_root_info *) (block_buf + 24);
4278 if ((root->reserved_zero || root->info_length < 8) &&
4279 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4282 pctx->num = root->hash_version;
4283 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4284 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4285 (root->hash_version != EXT2_HASH_TEA) &&
4286 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4289 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4290 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4293 pctx->num = root->indirect_levels;
4294 if ((root->indirect_levels > 1) &&
4295 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4302 * This subroutine is called on each inode to account for all of the
4303 * blocks used by that inode.
4305 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4308 ext2_filsys fs = ctx->fs;
4309 struct process_block_struct_1 pb;
4310 ext2_ino_t ino = pctx->ino;
4311 struct ext2_inode *inode = pctx->inode;
4313 int dirty_inode = 0;
4319 pb.num_illegal_blocks = 0;
4320 pb.suppress = 0; pb.clear = 0;
4323 pb.previous_block = 0;
4324 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4325 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4326 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4333 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4334 if (fs->super->s_feature_incompat &
4335 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4338 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4339 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4345 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4348 if (ext2fs_inode_has_valid_blocks(inode))
4349 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4350 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4351 block_buf, process_block, &pb);
4352 end_problem_latch(ctx, PR_LATCH_BLOCK);
4353 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4354 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4357 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4359 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4360 ctx->fs_fragmented++;
4363 inode->i_links_count = 0;
4364 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4365 inode->i_dtime = time(0);
4367 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4368 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4369 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4371 * The inode was probably partially accounted for
4372 * before processing was aborted, so we need to
4373 * restart the pass 1 scan.
4375 ctx->flags |= E2F_FLAG_RESTART;
4379 if (inode->i_flags & EXT2_INDEX_FL) {
4380 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4381 inode->i_flags &= ~EXT2_INDEX_FL;
4385 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4389 if (ctx->dirs_to_hash && pb.is_dir &&
4390 !(inode->i_flags & EXT2_INDEX_FL) &&
4391 ((inode->i_size / fs->blocksize) >= 3))
4392 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4394 if (!pb.num_blocks && pb.is_dir) {
4395 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4396 inode->i_links_count = 0;
4397 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4398 inode->i_dtime = time(0);
4400 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4401 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4402 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4403 ctx->fs_directory_count--;
4408 pb.num_blocks *= (fs->blocksize / 512);
4411 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4412 if (nblock > (pb.last_block + 1))
4414 else if (nblock < (pb.last_block + 1)) {
4415 if (((pb.last_block + 1) - nblock) >
4416 fs->super->s_prealloc_dir_blocks)
4420 size = EXT2_I_SIZE(inode);
4421 if ((pb.last_block >= 0) &&
4422 (size < (__u64) pb.last_block * fs->blocksize))
4424 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4427 /* i_size for symlinks is checked elsewhere */
4428 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4429 pctx->num = (pb.last_block+1) * fs->blocksize;
4430 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4431 inode->i_size = pctx->num;
4432 if (!LINUX_S_ISDIR(inode->i_mode))
4433 inode->i_size_high = pctx->num >> 32;
4438 if (LINUX_S_ISREG(inode->i_mode) &&
4439 (inode->i_size_high || inode->i_size & 0x80000000UL))
4441 if (pb.num_blocks != inode->i_blocks) {
4442 pctx->num = pb.num_blocks;
4443 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4444 inode->i_blocks = pb.num_blocks;
4451 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4456 * This is a helper function for check_blocks().
4458 static int process_block(ext2_filsys fs,
4460 e2_blkcnt_t blockcnt,
4461 blk_t ref_block FSCK_ATTR((unused)),
4462 int ref_offset FSCK_ATTR((unused)),
4465 struct process_block_struct_1 *p;
4466 struct problem_context *pctx;
4467 blk_t blk = *block_nr;
4472 p = (struct process_block_struct_1 *) priv_data;
4476 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4477 /* todo: Check that the comprblk_fl is high, that the
4478 blkaddr pattern looks right (all non-holes up to
4479 first EXT2FS_COMPRESSED_BLKADDR, then all
4480 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4481 that the feature_incompat bit is high, and that the
4482 inode is a regular file. If we're doing a "full
4483 check" (a concept introduced to e2fsck by e2compr,
4484 meaning that we look at data blocks as well as
4485 metadata) then call some library routine that
4486 checks the compressed data. I'll have to think
4487 about this, because one particularly important
4488 problem to be able to fix is to recalculate the
4489 cluster size if necessary. I think that perhaps
4490 we'd better do most/all e2compr-specific checks
4491 separately, after the non-e2compr checks. If not
4492 doing a full check, it may be useful to test that
4493 the personality is linux; e.g. if it isn't then
4494 perhaps this really is just an illegal block. */
4499 if (p->is_dir == 0) {
4501 * Should never happen, since only directories
4502 * get called with BLOCK_FLAG_HOLE
4505 printf("process_block() called with blk == 0, "
4506 "blockcnt=%d, inode %lu???\n",
4513 if (blockcnt * fs->blocksize < p->inode->i_size) {
4520 * Simplistic fragmentation check. We merely require that the
4521 * file be contiguous. (Which can never be true for really
4522 * big files that are greater than a block group.)
4524 if (!HOLE_BLKADDR(p->previous_block)) {
4525 if (p->previous_block+1 != blk)
4528 p->previous_block = blk;
4530 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4531 problem = PR_1_TOOBIG_DIR;
4532 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4533 problem = PR_1_TOOBIG_REG;
4534 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4535 problem = PR_1_TOOBIG_SYMLINK;
4537 if (blk < fs->super->s_first_data_block ||
4538 blk >= fs->super->s_blocks_count)
4539 problem = PR_1_ILLEGAL_BLOCK_NUM;
4542 p->num_illegal_blocks++;
4543 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4544 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4548 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4550 set_latch_flags(PR_LATCH_BLOCK,
4555 pctx->blkcount = blockcnt;
4556 if (fix_problem(ctx, problem, pctx)) {
4557 blk = *block_nr = 0;
4558 ret_code = BLOCK_CHANGED;
4564 if (p->ino == EXT2_RESIZE_INO) {
4566 * The resize inode has already be sanity checked
4567 * during pass #0 (the superblock checks). All we
4568 * have to do is mark the double indirect block as
4569 * being in use; all of the other blocks are handled
4570 * by mark_table_blocks()).
4572 if (blockcnt == BLOCK_COUNT_DIND)
4573 mark_block_used(ctx, blk);
4575 mark_block_used(ctx, blk);
4578 p->last_block = blockcnt;
4580 if (p->is_dir && (blockcnt >= 0)) {
4581 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4583 if (pctx->errcode) {
4585 pctx->num = blockcnt;
4586 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4587 /* Should never get here */
4588 ctx->flags |= E2F_FLAG_ABORT;
4595 static int process_bad_block(ext2_filsys fs,
4597 e2_blkcnt_t blockcnt,
4598 blk_t ref_block FSCK_ATTR((unused)),
4599 int ref_offset FSCK_ATTR((unused)),
4602 struct process_block_struct_1 *p;
4603 blk_t blk = *block_nr;
4606 struct problem_context *pctx;
4610 * Note: This function processes blocks for the bad blocks
4611 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4617 p = (struct process_block_struct_1 *) priv_data;
4621 pctx->ino = EXT2_BAD_INO;
4623 pctx->blkcount = blockcnt;
4625 if ((blk < fs->super->s_first_data_block) ||
4626 (blk >= fs->super->s_blocks_count)) {
4627 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
4629 return BLOCK_CHANGED;
4635 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
4637 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
4639 return BLOCK_CHANGED;
4641 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
4644 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
4647 return BLOCK_CHANGED;
4649 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4652 mark_block_used(ctx, blk);
4656 ctx->fs_badblocks_count++;
4658 * If the block is not used, then mark it as used and return.
4659 * If it is already marked as found, this must mean that
4660 * there's an overlap between the filesystem table blocks
4661 * (bitmaps and inode table) and the bad block list.
4663 if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
4664 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
4668 * Try to find the where the filesystem block was used...
4670 first_block = fs->super->s_first_data_block;
4672 for (i = 0; i < fs->group_desc_count; i++ ) {
4675 if (!ext2fs_bg_has_super(fs, i))
4677 if (blk == first_block) {
4679 if (fix_problem(ctx,
4680 PR_1_BAD_PRIMARY_SUPERBLOCK,
4683 return BLOCK_CHANGED;
4687 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
4690 if ((blk > first_block) &&
4691 (blk <= first_block + fs->desc_blocks)) {
4693 pctx->blk = *block_nr;
4694 if (fix_problem(ctx,
4695 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
4697 return BLOCK_CHANGED;
4701 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
4705 if (blk == fs->group_desc[i].bg_block_bitmap) {
4706 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
4707 ctx->invalid_block_bitmap_flag[i]++;
4708 ctx->invalid_bitmaps++;
4712 if (blk == fs->group_desc[i].bg_inode_bitmap) {
4713 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
4714 ctx->invalid_inode_bitmap_flag[i]++;
4715 ctx->invalid_bitmaps++;
4719 if ((blk >= fs->group_desc[i].bg_inode_table) &&
4720 (blk < (fs->group_desc[i].bg_inode_table +
4721 fs->inode_blocks_per_group))) {
4723 * If there are bad blocks in the inode table,
4724 * the inode scan code will try to do
4725 * something reasonable automatically.
4729 first_block += fs->super->s_blocks_per_group;
4732 * If we've gotten to this point, then the only
4733 * possibility is that the bad block inode meta data
4734 * is using a bad block.
4736 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
4737 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
4738 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
4740 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
4742 return BLOCK_CHANGED;
4744 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4751 /* Warn user that the block wasn't claimed */
4752 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
4757 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
4758 const char *name, int num, blk_t *new_block)
4760 ext2_filsys fs = ctx->fs;
4761 blk_t old_block = *new_block;
4764 struct problem_context pctx;
4766 clear_problem_context(&pctx);
4769 pctx.blk = old_block;
4772 pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
4773 first_block + fs->super->s_blocks_per_group,
4774 num, ctx->block_found_map, new_block);
4777 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
4778 ext2fs_unmark_valid(fs);
4781 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
4783 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
4784 ext2fs_unmark_valid(fs);
4787 ext2fs_mark_super_dirty(fs);
4788 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
4789 pctx.blk2 = *new_block;
4790 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
4791 PR_1_RELOC_TO), &pctx);
4793 for (i = 0; i < num; i++) {
4795 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
4797 pctx.errcode = io_channel_read_blk(fs->io,
4798 old_block + i, 1, buf);
4800 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
4802 memset(buf, 0, fs->blocksize);
4804 pctx.blk = (*new_block) + i;
4805 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
4808 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
4810 ext2fs_free_mem(&buf);
4814 * This routine gets called at the end of pass 1 if bad blocks are
4815 * detected in the superblock, group descriptors, inode_bitmaps, or
4816 * block bitmaps. At this point, all of the blocks have been mapped
4817 * out, so we can try to allocate new block(s) to replace the bad
4820 static void handle_fs_bad_blocks(e2fsck_t ctx)
4822 ext2_filsys fs = ctx->fs;
4824 int first_block = fs->super->s_first_data_block;
4826 for (i = 0; i < fs->group_desc_count; i++) {
4827 if (ctx->invalid_block_bitmap_flag[i]) {
4828 new_table_block(ctx, first_block, i, _("block bitmap"),
4829 1, &fs->group_desc[i].bg_block_bitmap);
4831 if (ctx->invalid_inode_bitmap_flag[i]) {
4832 new_table_block(ctx, first_block, i, _("inode bitmap"),
4833 1, &fs->group_desc[i].bg_inode_bitmap);
4835 if (ctx->invalid_inode_table_flag[i]) {
4836 new_table_block(ctx, first_block, i, _("inode table"),
4837 fs->inode_blocks_per_group,
4838 &fs->group_desc[i].bg_inode_table);
4839 ctx->flags |= E2F_FLAG_RESTART;
4841 first_block += fs->super->s_blocks_per_group;
4843 ctx->invalid_bitmaps = 0;
4847 * This routine marks all blocks which are used by the superblock,
4848 * group descriptors, inode bitmaps, and block bitmaps.
4850 static void mark_table_blocks(e2fsck_t ctx)
4852 ext2_filsys fs = ctx->fs;
4856 struct problem_context pctx;
4858 clear_problem_context(&pctx);
4860 block = fs->super->s_first_data_block;
4861 for (i = 0; i < fs->group_desc_count; i++) {
4864 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4867 * Mark the blocks used for the inode table
4869 if (fs->group_desc[i].bg_inode_table) {
4870 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4871 j < fs->inode_blocks_per_group;
4873 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4876 if (fix_problem(ctx,
4877 PR_1_ITABLE_CONFLICT, &pctx)) {
4878 ctx->invalid_inode_table_flag[i]++;
4879 ctx->invalid_bitmaps++;
4882 ext2fs_mark_block_bitmap(ctx->block_found_map,
4889 * Mark block used for the block bitmap
4891 if (fs->group_desc[i].bg_block_bitmap) {
4892 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4893 fs->group_desc[i].bg_block_bitmap)) {
4894 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4895 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4896 ctx->invalid_block_bitmap_flag[i]++;
4897 ctx->invalid_bitmaps++;
4900 ext2fs_mark_block_bitmap(ctx->block_found_map,
4901 fs->group_desc[i].bg_block_bitmap);
4906 * Mark block used for the inode bitmap
4908 if (fs->group_desc[i].bg_inode_bitmap) {
4909 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4910 fs->group_desc[i].bg_inode_bitmap)) {
4911 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4912 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4913 ctx->invalid_inode_bitmap_flag[i]++;
4914 ctx->invalid_bitmaps++;
4917 ext2fs_mark_block_bitmap(ctx->block_found_map,
4918 fs->group_desc[i].bg_inode_bitmap);
4921 block += fs->super->s_blocks_per_group;
4926 * Thes subroutines short circuits ext2fs_get_blocks and
4927 * ext2fs_check_directory; we use them since we already have the inode
4928 * structure, so there's no point in letting the ext2fs library read
4931 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4934 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4937 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4938 return EXT2_ET_CALLBACK_NOTHANDLED;
4940 for (i=0; i < EXT2_N_BLOCKS; i++)
4941 blocks[i] = ctx->stashed_inode->i_block[i];
4945 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4946 struct ext2_inode *inode)
4948 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4950 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4951 return EXT2_ET_CALLBACK_NOTHANDLED;
4952 *inode = *ctx->stashed_inode;
4956 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4957 struct ext2_inode *inode)
4959 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4961 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4962 *ctx->stashed_inode = *inode;
4963 return EXT2_ET_CALLBACK_NOTHANDLED;
4966 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4968 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4970 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4971 return EXT2_ET_CALLBACK_NOTHANDLED;
4973 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4974 return EXT2_ET_NO_DIRECTORY;
4978 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4980 ext2_filsys fs = ctx->fs;
4983 fs->get_blocks = pass1_get_blocks;
4984 fs->check_directory = pass1_check_directory;
4985 fs->read_inode = pass1_read_inode;
4986 fs->write_inode = pass1_write_inode;
4987 ctx->stashed_ino = 0;
4990 fs->check_directory = 0;
4992 fs->write_inode = 0;
4997 * pass1b.c --- Pass #1b of e2fsck
4999 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
5000 * only invoked if pass 1 discovered blocks which are in use by more
5003 * Pass1B scans the data blocks of all the inodes again, generating a
5004 * complete list of duplicate blocks and which inodes have claimed
5007 * Pass1C does a tree-traversal of the filesystem, to determine the
5008 * parent directories of these inodes. This step is necessary so that
5009 * e2fsck can print out the pathnames of affected inodes.
5011 * Pass1D is a reconciliation pass. For each inode with duplicate
5012 * blocks, the user is prompted if s/he would like to clone the file
5013 * (so that the file gets a fresh copy of the duplicated blocks) or
5014 * simply to delete the file.
5019 /* Needed for architectures where sizeof(int) != sizeof(void *) */
5020 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
5021 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
5023 /* Define an extension to the ext2 library's block count information */
5024 #define BLOCK_COUNT_EXTATTR (-5)
5028 struct block_el *next;
5033 struct inode_el *next;
5038 struct inode_el *inode_list;
5042 * This structure stores information about a particular inode which
5043 * is sharing blocks with other inodes. This information is collected
5044 * to display to the user, so that the user knows what files he or she
5045 * is dealing with, when trying to decide how to resolve the conflict
5046 * of multiply-claimed blocks.
5051 struct ext2_inode inode;
5052 struct block_el *block_list;
5055 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
5056 e2_blkcnt_t blockcnt, blk_t ref_blk,
5057 int ref_offset, void *priv_data);
5058 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5059 struct dup_inode *dp, char *block_buf);
5060 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5061 struct dup_inode *dp, char* block_buf);
5062 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
5064 static void pass1b(e2fsck_t ctx, char *block_buf);
5065 static void pass1c(e2fsck_t ctx, char *block_buf);
5066 static void pass1d(e2fsck_t ctx, char *block_buf);
5068 static int dup_inode_count = 0;
5070 static dict_t blk_dict, ino_dict;
5072 static ext2fs_inode_bitmap inode_dup_map;
5074 static int dict_int_cmp(const void *a, const void *b)
5085 * Add a duplicate block record
5087 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
5088 struct ext2_inode *inode)
5091 struct dup_block *db;
5092 struct dup_inode *di;
5093 struct block_el *blk_el;
5094 struct inode_el *ino_el;
5096 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5098 db = (struct dup_block *) dnode_get(n);
5100 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
5101 sizeof(struct dup_block), "duplicate block header");
5104 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
5106 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
5107 sizeof(struct inode_el), "inode element");
5108 ino_el->inode = ino;
5109 ino_el->next = db->inode_list;
5110 db->inode_list = ino_el;
5113 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
5115 di = (struct dup_inode *) dnode_get(n);
5117 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
5118 sizeof(struct dup_inode), "duplicate inode header");
5119 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
5120 di->num_dupblocks = 0;
5123 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
5125 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
5126 sizeof(struct block_el), "block element");
5127 blk_el->block = blk;
5128 blk_el->next = di->block_list;
5129 di->block_list = blk_el;
5130 di->num_dupblocks++;
5134 * Free a duplicate inode record
5136 static void inode_dnode_free(dnode_t *node)
5138 struct dup_inode *di;
5139 struct block_el *p, *next;
5141 di = (struct dup_inode *) dnode_get(node);
5142 for (p = di->block_list; p; p = next) {
5150 * Free a duplicate block record
5152 static void block_dnode_free(dnode_t *node)
5154 struct dup_block *db;
5155 struct inode_el *p, *next;
5157 db = (struct dup_block *) dnode_get(node);
5158 for (p = db->inode_list; p; p = next) {
5167 * Main procedure for handling duplicate blocks
5169 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
5171 ext2_filsys fs = ctx->fs;
5172 struct problem_context pctx;
5174 clear_problem_context(&pctx);
5176 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
5177 _("multiply claimed inode map"), &inode_dup_map);
5179 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
5180 ctx->flags |= E2F_FLAG_ABORT;
5184 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
5185 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
5186 dict_set_allocator(&ino_dict, inode_dnode_free);
5187 dict_set_allocator(&blk_dict, block_dnode_free);
5189 pass1b(ctx, block_buf);
5190 pass1c(ctx, block_buf);
5191 pass1d(ctx, block_buf);
5194 * Time to free all of the accumulated data structures that we
5195 * don't need anymore.
5197 dict_free_nodes(&ino_dict);
5198 dict_free_nodes(&blk_dict);
5202 * Scan the inodes looking for inodes that contain duplicate blocks.
5204 struct process_block_struct_1b {
5208 struct ext2_inode *inode;
5209 struct problem_context *pctx;
5212 static void pass1b(e2fsck_t ctx, char *block_buf)
5214 ext2_filsys fs = ctx->fs;
5216 struct ext2_inode inode;
5217 ext2_inode_scan scan;
5218 struct process_block_struct_1b pb;
5219 struct problem_context pctx;
5221 clear_problem_context(&pctx);
5223 if (!(ctx->options & E2F_OPT_PREEN))
5224 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
5225 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
5228 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
5229 ctx->flags |= E2F_FLAG_ABORT;
5232 ctx->stashed_inode = &inode;
5235 pctx.str = "pass1b";
5237 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
5238 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
5241 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
5242 ctx->flags |= E2F_FLAG_ABORT;
5247 pctx.ino = ctx->stashed_ino = ino;
5248 if ((ino != EXT2_BAD_INO) &&
5249 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
5256 if (ext2fs_inode_has_valid_blocks(&inode) ||
5257 (ino == EXT2_BAD_INO))
5258 pctx.errcode = ext2fs_block_iterate2(fs, ino,
5259 0, block_buf, process_pass1b_block, &pb);
5260 if (inode.i_file_acl)
5261 process_pass1b_block(fs, &inode.i_file_acl,
5262 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5263 if (pb.dup_blocks) {
5264 end_problem_latch(ctx, PR_LATCH_DBLOCK);
5265 if (ino >= EXT2_FIRST_INODE(fs->super) ||
5266 ino == EXT2_ROOT_INO)
5270 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5272 ext2fs_close_inode_scan(scan);
5273 e2fsck_use_inode_shortcuts(ctx, 0);
5276 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
5278 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5279 blk_t ref_blk FSCK_ATTR((unused)),
5280 int ref_offset FSCK_ATTR((unused)),
5283 struct process_block_struct_1b *p;
5286 if (HOLE_BLKADDR(*block_nr))
5288 p = (struct process_block_struct_1b *) priv_data;
5291 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
5294 /* OK, this is a duplicate block */
5295 if (p->ino != EXT2_BAD_INO) {
5296 p->pctx->blk = *block_nr;
5297 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
5300 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
5302 add_dupe(ctx, p->ino, *block_nr, p->inode);
5308 * Pass 1c: Scan directories for inodes with duplicate blocks. This
5309 * is used so that we can print pathnames when prompting the user for
5312 struct search_dir_struct {
5314 ext2_ino_t first_inode;
5315 ext2_ino_t max_inode;
5318 static int search_dirent_proc(ext2_ino_t dir, int entry,
5319 struct ext2_dir_entry *dirent,
5320 int offset FSCK_ATTR((unused)),
5321 int blocksize FSCK_ATTR((unused)),
5322 char *buf FSCK_ATTR((unused)),
5325 struct search_dir_struct *sd;
5326 struct dup_inode *p;
5329 sd = (struct search_dir_struct *) priv_data;
5331 if (dirent->inode > sd->max_inode)
5332 /* Should abort this inode, but not everything */
5335 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
5336 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
5339 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
5342 p = (struct dup_inode *) dnode_get(n);
5346 return(sd->count ? 0 : DIRENT_ABORT);
5350 static void pass1c(e2fsck_t ctx, char *block_buf)
5352 ext2_filsys fs = ctx->fs;
5353 struct search_dir_struct sd;
5354 struct problem_context pctx;
5356 clear_problem_context(&pctx);
5358 if (!(ctx->options & E2F_OPT_PREEN))
5359 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
5362 * Search through all directories to translate inodes to names
5363 * (by searching for the containing directory for that inode.)
5365 sd.count = dup_inode_count;
5366 sd.first_inode = EXT2_FIRST_INODE(fs->super);
5367 sd.max_inode = fs->super->s_inodes_count;
5368 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
5369 search_dirent_proc, &sd);
5372 static void pass1d(e2fsck_t ctx, char *block_buf)
5374 ext2_filsys fs = ctx->fs;
5375 struct dup_inode *p, *t;
5376 struct dup_block *q;
5377 ext2_ino_t *shared, ino;
5382 struct problem_context pctx;
5387 clear_problem_context(&pctx);
5389 if (!(ctx->options & E2F_OPT_PREEN))
5390 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
5391 e2fsck_read_bitmaps(ctx);
5393 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
5394 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
5395 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
5396 sizeof(ext2_ino_t) * dict_count(&ino_dict),
5397 "Shared inode list");
5398 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
5399 p = (struct dup_inode *) dnode_get(n);
5402 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
5403 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
5407 * Find all of the inodes which share blocks with this
5408 * one. First we find all of the duplicate blocks
5409 * belonging to this inode, and then search each block
5410 * get the list of inodes, and merge them together.
5412 for (s = p->block_list; s; s = s->next) {
5413 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5415 continue; /* Should never happen... */
5416 q = (struct dup_block *) dnode_get(m);
5419 if (check_if_fs_block(ctx, s->block)) {
5425 * Add all inodes used by this block to the
5426 * shared[] --- which is a unique list, so
5427 * if an inode is already in shared[], don't
5430 for (r = q->inode_list; r; r = r->next) {
5431 if (r->inode == ino)
5433 for (i = 0; i < shared_len; i++)
5434 if (shared[i] == r->inode)
5436 if (i == shared_len) {
5437 shared[shared_len++] = r->inode;
5443 * Report the inode that we are working on
5445 pctx.inode = &p->inode;
5448 pctx.blkcount = p->num_dupblocks;
5449 pctx.num = meta_data ? shared_len+1 : shared_len;
5450 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5455 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5457 for (i = 0; i < shared_len; i++) {
5458 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5460 continue; /* should never happen */
5461 t = (struct dup_inode *) dnode_get(m);
5463 * Report the inode that we are sharing with
5465 pctx.inode = &t->inode;
5466 pctx.ino = shared[i];
5468 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5471 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5474 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5475 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5477 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5481 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5482 delete_file(ctx, ino, p, block_buf);
5484 ext2fs_unmark_valid(fs);
5486 ext2fs_free_mem(&shared);
5490 * Drop the refcount on the dup_block structure, and clear the entry
5491 * in the block_dup_map if appropriate.
5493 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5496 if (p->num_bad <= 0 ||
5497 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5498 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5501 static int delete_file_block(ext2_filsys fs,
5503 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5504 blk_t ref_block FSCK_ATTR((unused)),
5505 int ref_offset FSCK_ATTR((unused)),
5508 struct process_block_struct_1b *pb;
5509 struct dup_block *p;
5513 pb = (struct process_block_struct_1b *) priv_data;
5516 if (HOLE_BLKADDR(*block_nr))
5519 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5520 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5522 p = (struct dup_block *) dnode_get(n);
5523 decrement_badcount(ctx, *block_nr, p);
5525 com_err("delete_file_block", 0,
5526 _("internal error; can't find dup_blk for %d\n"),
5529 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5530 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5536 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5537 struct dup_inode *dp, char* block_buf)
5539 ext2_filsys fs = ctx->fs;
5540 struct process_block_struct_1b pb;
5541 struct ext2_inode inode;
5542 struct problem_context pctx;
5545 clear_problem_context(&pctx);
5546 pctx.ino = pb.ino = ino;
5547 pb.dup_blocks = dp->num_dupblocks;
5549 pctx.str = "delete_file";
5551 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5552 if (ext2fs_inode_has_valid_blocks(&inode))
5553 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5554 delete_file_block, &pb);
5556 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5557 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5558 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5559 if (ctx->inode_bad_map)
5560 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5561 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5563 /* Inode may have changed by block_iterate, so reread it */
5564 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5565 inode.i_links_count = 0;
5566 inode.i_dtime = time(0);
5567 if (inode.i_file_acl &&
5568 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5570 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5571 block_buf, -1, &count);
5572 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5577 pctx.blk = inode.i_file_acl;
5578 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5581 * If the count is zero, then arrange to have the
5582 * block deleted. If the block is in the block_dup_map,
5583 * also call delete_file_block since it will take care
5584 * of keeping the accounting straight.
5587 ext2fs_test_block_bitmap(ctx->block_dup_map,
5589 delete_file_block(fs, &inode.i_file_acl,
5590 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5592 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5595 struct clone_struct {
5602 static int clone_file_block(ext2_filsys fs,
5604 e2_blkcnt_t blockcnt,
5605 blk_t ref_block FSCK_ATTR((unused)),
5606 int ref_offset FSCK_ATTR((unused)),
5609 struct dup_block *p;
5612 struct clone_struct *cs = (struct clone_struct *) priv_data;
5618 if (HOLE_BLKADDR(*block_nr))
5621 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5622 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5624 p = (struct dup_block *) dnode_get(n);
5625 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5628 cs->errcode = retval;
5631 if (cs->dir && (blockcnt >= 0)) {
5632 retval = ext2fs_set_dir_block(fs->dblist,
5633 cs->dir, new_block, blockcnt);
5635 cs->errcode = retval;
5640 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5643 cs->errcode = retval;
5646 retval = io_channel_write_blk(fs->io, new_block, 1,
5649 cs->errcode = retval;
5652 decrement_badcount(ctx, *block_nr, p);
5653 *block_nr = new_block;
5654 ext2fs_mark_block_bitmap(ctx->block_found_map,
5656 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5657 return BLOCK_CHANGED;
5659 com_err("clone_file_block", 0,
5660 _("internal error; can't find dup_blk for %d\n"),
5666 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5667 struct dup_inode *dp, char* block_buf)
5669 ext2_filsys fs = ctx->fs;
5671 struct clone_struct cs;
5672 struct problem_context pctx;
5675 struct inode_el *ino_el;
5676 struct dup_block *db;
5677 struct dup_inode *di;
5679 clear_problem_context(&pctx);
5683 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5687 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5691 pctx.str = "clone_file";
5692 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5693 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5694 clone_file_block, &cs);
5695 ext2fs_mark_bb_dirty(fs);
5697 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5698 retval = pctx.errcode;
5702 com_err("clone_file", cs.errcode,
5703 _("returned from clone_file_block"));
5704 retval = cs.errcode;
5707 /* The inode may have changed on disk, so we have to re-read it */
5708 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5709 blk = dp->inode.i_file_acl;
5710 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5711 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5713 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5715 * If we cloned the EA block, find all other inodes
5716 * which refered to that EA block, and modify
5717 * them to point to the new EA block.
5719 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5720 db = (struct dup_block *) dnode_get(n);
5721 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5722 if (ino_el->inode == ino)
5724 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5725 di = (struct dup_inode *) dnode_get(n);
5726 if (di->inode.i_file_acl == blk) {
5727 di->inode.i_file_acl = dp->inode.i_file_acl;
5728 e2fsck_write_inode(ctx, ino_el->inode,
5729 &di->inode, "clone file EA");
5730 decrement_badcount(ctx, blk, db);
5736 ext2fs_free_mem(&cs.buf);
5741 * This routine returns 1 if a block overlaps with one of the superblocks,
5742 * group descriptors, inode bitmaps, or block bitmaps.
5744 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5746 ext2_filsys fs = ctx->fs;
5750 block = fs->super->s_first_data_block;
5751 for (i = 0; i < fs->group_desc_count; i++) {
5753 /* Check superblocks/block group descriptros */
5754 if (ext2fs_bg_has_super(fs, i)) {
5755 if (test_block >= block &&
5756 (test_block <= block + fs->desc_blocks))
5760 /* Check the inode table */
5761 if ((fs->group_desc[i].bg_inode_table) &&
5762 (test_block >= fs->group_desc[i].bg_inode_table) &&
5763 (test_block < (fs->group_desc[i].bg_inode_table +
5764 fs->inode_blocks_per_group)))
5767 /* Check the bitmap blocks */
5768 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5769 (test_block == fs->group_desc[i].bg_inode_bitmap))
5772 block += fs->super->s_blocks_per_group;
5777 * pass2.c --- check directory structure
5779 * Pass 2 of e2fsck iterates through all active directory inodes, and
5780 * applies to following tests to each directory entry in the directory
5781 * blocks in the inodes:
5783 * - The length of the directory entry (rec_len) should be at
5784 * least 8 bytes, and no more than the remaining space
5785 * left in the directory block.
5786 * - The length of the name in the directory entry (name_len)
5787 * should be less than (rec_len - 8).
5788 * - The inode number in the directory entry should be within
5790 * - The inode number should refer to a in-use inode.
5791 * - The first entry should be '.', and its inode should be
5792 * the inode of the directory.
5793 * - The second entry should be '..'.
5795 * To minimize disk seek time, the directory blocks are processed in
5796 * sorted order of block numbers.
5798 * Pass 2 also collects the following information:
5799 * - The inode numbers of the subdirectories for each directory.
5801 * Pass 2 relies on the following information from previous passes:
5802 * - The directory information collected in pass 1.
5803 * - The inode_used_map bitmap
5804 * - The inode_bad_map bitmap
5805 * - The inode_dir_map bitmap
5807 * Pass 2 frees the following data structures
5808 * - The inode_bad_map bitmap
5809 * - The inode_reg_map bitmap
5813 * Keeps track of how many times an inode is referenced.
5815 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5816 static int check_dir_block(ext2_filsys fs,
5817 struct ext2_db_entry *dir_blocks_info,
5819 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5820 struct problem_context *pctx);
5821 static int update_dir_block(ext2_filsys fs,
5823 e2_blkcnt_t blockcnt,
5827 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5828 static int htree_depth(struct dx_dir_info *dx_dir,
5829 struct dx_dirblock_info *dx_db);
5830 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
5832 struct check_dir_struct {
5834 struct problem_context pctx;
5839 static void e2fsck_pass2(e2fsck_t ctx)
5841 struct ext2_super_block *sb = ctx->fs->super;
5842 struct problem_context pctx;
5843 ext2_filsys fs = ctx->fs;
5845 struct dir_info *dir;
5846 struct check_dir_struct cd;
5847 struct dx_dir_info *dx_dir;
5848 struct dx_dirblock_info *dx_db, *dx_parent;
5854 clear_problem_context(&cd.pctx);
5858 if (!(ctx->options & E2F_OPT_PREEN))
5859 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5861 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5862 0, ctx->inode_link_info,
5864 if (cd.pctx.errcode) {
5865 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5866 ctx->flags |= E2F_FLAG_ABORT;
5869 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5870 "directory scan buffer");
5873 * Set up the parent pointer for the root directory, if
5874 * present. (If the root directory is not present, we will
5875 * create it in pass 3.)
5877 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5879 dir->parent = EXT2_ROOT_INO;
5884 cd.max = ext2fs_dblist_count(fs->dblist);
5887 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5889 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5890 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5892 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5894 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5896 if (cd.pctx.errcode) {
5897 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5898 ctx->flags |= E2F_FLAG_ABORT;
5903 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5904 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5906 if (dx_dir->numblocks == 0)
5908 clear_problem_context(&pctx);
5910 pctx.dir = dx_dir->ino;
5911 dx_db = dx_dir->dx_block;
5912 if (dx_db->flags & DX_FLAG_REFERENCED)
5913 dx_db->flags |= DX_FLAG_DUP_REF;
5915 dx_db->flags |= DX_FLAG_REFERENCED;
5917 * Find all of the first and last leaf blocks, and
5918 * update their parent's min and max hash values
5920 for (b=0, dx_db = dx_dir->dx_block;
5921 b < dx_dir->numblocks;
5923 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5924 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5926 dx_parent = &dx_dir->dx_block[dx_db->parent];
5928 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5930 if (dx_db->flags & DX_FLAG_FIRST)
5931 dx_parent->min_hash = dx_db->min_hash;
5933 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5935 if (dx_db->flags & DX_FLAG_LAST)
5936 dx_parent->max_hash = dx_db->max_hash;
5939 for (b=0, dx_db = dx_dir->dx_block;
5940 b < dx_dir->numblocks;
5943 pctx.group = dx_db->parent;
5945 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5946 (dx_db->min_hash < dx_db->node_min_hash)) {
5947 pctx.blk = dx_db->min_hash;
5948 pctx.blk2 = dx_db->node_min_hash;
5949 code = PR_2_HTREE_MIN_HASH;
5950 fix_problem(ctx, code, &pctx);
5953 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5954 depth = htree_depth(dx_dir, dx_db);
5955 if (depth != dx_dir->depth) {
5956 code = PR_2_HTREE_BAD_DEPTH;
5957 fix_problem(ctx, code, &pctx);
5962 * This test doesn't apply for the root block
5966 (dx_db->max_hash > dx_db->node_max_hash)) {
5967 pctx.blk = dx_db->max_hash;
5968 pctx.blk2 = dx_db->node_max_hash;
5969 code = PR_2_HTREE_MAX_HASH;
5970 fix_problem(ctx, code, &pctx);
5973 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5974 code = PR_2_HTREE_NOTREF;
5975 fix_problem(ctx, code, &pctx);
5977 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5978 code = PR_2_HTREE_DUPREF;
5979 fix_problem(ctx, code, &pctx);
5985 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5986 clear_htree(ctx, dx_dir->ino);
5987 dx_dir->numblocks = 0;
5991 ext2fs_free_mem(&buf);
5992 ext2fs_free_dblist(fs->dblist);
5994 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5995 ctx->inode_bad_map = 0;
5996 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5997 ctx->inode_reg_map = 0;
5999 clear_problem_context(&pctx);
6000 if (ctx->large_files) {
6001 if (!(sb->s_feature_ro_compat &
6002 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
6003 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
6004 sb->s_feature_ro_compat |=
6005 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
6006 ext2fs_mark_super_dirty(fs);
6008 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
6009 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
6010 ext2fs_update_dynamic_rev(fs);
6011 ext2fs_mark_super_dirty(fs);
6013 } else if (!ctx->large_files &&
6014 (sb->s_feature_ro_compat &
6015 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
6016 if (fs->flags & EXT2_FLAG_RW) {
6017 sb->s_feature_ro_compat &=
6018 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
6019 ext2fs_mark_super_dirty(fs);
6025 #define MAX_DEPTH 32000
6026 static int htree_depth(struct dx_dir_info *dx_dir,
6027 struct dx_dirblock_info *dx_db)
6031 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
6032 dx_db = &dx_dir->dx_block[dx_db->parent];
6038 static int dict_de_cmp(const void *a, const void *b)
6040 const struct ext2_dir_entry *de_a, *de_b;
6043 de_a = (const struct ext2_dir_entry *) a;
6044 a_len = de_a->name_len & 0xFF;
6045 de_b = (const struct ext2_dir_entry *) b;
6046 b_len = de_b->name_len & 0xFF;
6049 return (a_len - b_len);
6051 return strncmp(de_a->name, de_b->name, a_len);
6055 * This is special sort function that makes sure that directory blocks
6056 * with a dirblock of zero are sorted to the beginning of the list.
6057 * This guarantees that the root node of the htree directories are
6058 * processed first, so we know what hash version to use.
6060 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b)
6062 const struct ext2_db_entry *db_a =
6063 (const struct ext2_db_entry *) a;
6064 const struct ext2_db_entry *db_b =
6065 (const struct ext2_db_entry *) b;
6067 if (db_a->blockcnt && !db_b->blockcnt)
6070 if (!db_a->blockcnt && db_b->blockcnt)
6073 if (db_a->blk != db_b->blk)
6074 return (int) (db_a->blk - db_b->blk);
6076 if (db_a->ino != db_b->ino)
6077 return (int) (db_a->ino - db_b->ino);
6079 return (int) (db_a->blockcnt - db_b->blockcnt);
6084 * Make sure the first entry in the directory is '.', and that the
6085 * directory entry is sane.
6087 static int check_dot(e2fsck_t ctx,
6088 struct ext2_dir_entry *dirent,
6089 ext2_ino_t ino, struct problem_context *pctx)
6091 struct ext2_dir_entry *nextdir;
6098 problem = PR_2_MISSING_DOT;
6099 else if (((dirent->name_len & 0xFF) != 1) ||
6100 (dirent->name[0] != '.'))
6101 problem = PR_2_1ST_NOT_DOT;
6102 else if (dirent->name[1] != '\0')
6103 problem = PR_2_DOT_NULL_TERM;
6106 if (fix_problem(ctx, problem, pctx)) {
6107 if (dirent->rec_len < 12)
6108 dirent->rec_len = 12;
6109 dirent->inode = ino;
6110 dirent->name_len = 1;
6111 dirent->name[0] = '.';
6112 dirent->name[1] = '\0';
6117 if (dirent->inode != ino) {
6118 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
6119 dirent->inode = ino;
6123 if (dirent->rec_len > 12) {
6124 new_len = dirent->rec_len - 12;
6127 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
6128 nextdir = (struct ext2_dir_entry *)
6129 ((char *) dirent + 12);
6130 dirent->rec_len = 12;
6131 nextdir->rec_len = new_len;
6133 nextdir->name_len = 0;
6142 * Make sure the second entry in the directory is '..', and that the
6143 * directory entry is sane. We do not check the inode number of '..'
6144 * here; this gets done in pass 3.
6146 static int check_dotdot(e2fsck_t ctx,
6147 struct ext2_dir_entry *dirent,
6148 struct dir_info *dir, struct problem_context *pctx)
6153 problem = PR_2_MISSING_DOT_DOT;
6154 else if (((dirent->name_len & 0xFF) != 2) ||
6155 (dirent->name[0] != '.') ||
6156 (dirent->name[1] != '.'))
6157 problem = PR_2_2ND_NOT_DOT_DOT;
6158 else if (dirent->name[2] != '\0')
6159 problem = PR_2_DOT_DOT_NULL_TERM;
6162 if (fix_problem(ctx, problem, pctx)) {
6163 if (dirent->rec_len < 12)
6164 dirent->rec_len = 12;
6166 * Note: we don't have the parent inode just
6167 * yet, so we will fill it in with the root
6168 * inode. This will get fixed in pass 3.
6170 dirent->inode = EXT2_ROOT_INO;
6171 dirent->name_len = 2;
6172 dirent->name[0] = '.';
6173 dirent->name[1] = '.';
6174 dirent->name[2] = '\0';
6179 dir->dotdot = dirent->inode;
6184 * Check to make sure a directory entry doesn't contain any illegal
6187 static int check_name(e2fsck_t ctx,
6188 struct ext2_dir_entry *dirent,
6189 struct problem_context *pctx)
6195 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
6196 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
6198 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
6201 dirent->name[i] = '.';
6210 * Check the directory filetype (if present)
6214 * Given a mode, return the ext2 file type
6216 static int ext2_file_type(unsigned int mode)
6218 if (LINUX_S_ISREG(mode))
6219 return EXT2_FT_REG_FILE;
6221 if (LINUX_S_ISDIR(mode))
6224 if (LINUX_S_ISCHR(mode))
6225 return EXT2_FT_CHRDEV;
6227 if (LINUX_S_ISBLK(mode))
6228 return EXT2_FT_BLKDEV;
6230 if (LINUX_S_ISLNK(mode))
6231 return EXT2_FT_SYMLINK;
6233 if (LINUX_S_ISFIFO(mode))
6234 return EXT2_FT_FIFO;
6236 if (LINUX_S_ISSOCK(mode))
6237 return EXT2_FT_SOCK;
6242 static _INLINE_ int check_filetype(e2fsck_t ctx,
6243 struct ext2_dir_entry *dirent,
6244 struct problem_context *pctx)
6246 int filetype = dirent->name_len >> 8;
6247 int should_be = EXT2_FT_UNKNOWN;
6248 struct ext2_inode inode;
6250 if (!(ctx->fs->super->s_feature_incompat &
6251 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
6252 if (filetype == 0 ||
6253 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
6255 dirent->name_len = dirent->name_len & 0xFF;
6259 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
6260 should_be = EXT2_FT_DIR;
6261 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
6263 should_be = EXT2_FT_REG_FILE;
6264 } else if (ctx->inode_bad_map &&
6265 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6269 e2fsck_read_inode(ctx, dirent->inode, &inode,
6271 should_be = ext2_file_type(inode.i_mode);
6273 if (filetype == should_be)
6275 pctx->num = should_be;
6277 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
6281 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
6286 static void parse_int_node(ext2_filsys fs,
6287 struct ext2_db_entry *db,
6288 struct check_dir_struct *cd,
6289 struct dx_dir_info *dx_dir,
6292 struct ext2_dx_root_info *root;
6293 struct ext2_dx_entry *ent;
6294 struct ext2_dx_countlimit *limit;
6295 struct dx_dirblock_info *dx_db;
6296 int i, expect_limit, count;
6298 ext2_dirhash_t min_hash = 0xffffffff;
6299 ext2_dirhash_t max_hash = 0;
6300 ext2_dirhash_t hash = 0, prev_hash;
6302 if (db->blockcnt == 0) {
6303 root = (struct ext2_dx_root_info *) (block_buf + 24);
6304 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
6306 ent = (struct ext2_dx_entry *) (block_buf+8);
6308 limit = (struct ext2_dx_countlimit *) ent;
6310 count = ext2fs_le16_to_cpu(limit->count);
6311 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
6312 sizeof(struct ext2_dx_entry);
6313 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
6314 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
6315 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
6316 goto clear_and_exit;
6318 if (count > expect_limit) {
6319 cd->pctx.num = count;
6320 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
6321 goto clear_and_exit;
6322 count = expect_limit;
6325 for (i=0; i < count; i++) {
6327 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
6328 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
6329 /* Check to make sure the block is valid */
6330 if (blk > (blk_t) dx_dir->numblocks) {
6332 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
6334 goto clear_and_exit;
6336 if (hash < prev_hash &&
6337 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
6338 goto clear_and_exit;
6339 dx_db = &dx_dir->dx_block[blk];
6340 if (dx_db->flags & DX_FLAG_REFERENCED) {
6341 dx_db->flags |= DX_FLAG_DUP_REF;
6343 dx_db->flags |= DX_FLAG_REFERENCED;
6344 dx_db->parent = db->blockcnt;
6346 if (hash < min_hash)
6348 if (hash > max_hash)
6350 dx_db->node_min_hash = hash;
6352 dx_db->node_max_hash =
6353 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
6355 dx_db->node_max_hash = 0xfffffffe;
6356 dx_db->flags |= DX_FLAG_LAST;
6359 dx_db->flags |= DX_FLAG_FIRST;
6361 dx_db = &dx_dir->dx_block[db->blockcnt];
6362 dx_db->min_hash = min_hash;
6363 dx_db->max_hash = max_hash;
6367 clear_htree(cd->ctx, cd->pctx.ino);
6368 dx_dir->numblocks = 0;
6370 #endif /* ENABLE_HTREE */
6373 * Given a busted directory, try to salvage it somehow.
6376 static void salvage_directory(ext2_filsys fs,
6377 struct ext2_dir_entry *dirent,
6378 struct ext2_dir_entry *prev,
6379 unsigned int *offset)
6381 char *cp = (char *) dirent;
6382 int left = fs->blocksize - *offset - dirent->rec_len;
6383 int name_len = dirent->name_len & 0xFF;
6386 * Special case of directory entry of size 8: copy what's left
6387 * of the directory block up to cover up the invalid hole.
6389 if ((left >= 12) && (dirent->rec_len == 8)) {
6390 memmove(cp, cp+8, left);
6391 memset(cp + left, 0, 8);
6395 * If the directory entry overruns the end of the directory
6396 * block, and the name is small enough to fit, then adjust the
6400 (name_len + 8 <= dirent->rec_len + left) &&
6401 dirent->inode <= fs->super->s_inodes_count &&
6402 strnlen(dirent->name, name_len) == name_len) {
6403 dirent->rec_len += left;
6407 * If the directory entry is a multiple of four, so it is
6408 * valid, let the previous directory entry absorb the invalid
6411 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
6412 prev->rec_len += dirent->rec_len;
6413 *offset += dirent->rec_len;
6417 * Default salvage method --- kill all of the directory
6418 * entries for the rest of the block. We will either try to
6419 * absorb it into the previous directory entry, or create a
6420 * new empty directory entry the rest of the directory block.
6423 prev->rec_len += fs->blocksize - *offset;
6424 *offset = fs->blocksize;
6426 dirent->rec_len = fs->blocksize - *offset;
6427 dirent->name_len = 0;
6432 static int check_dir_block(ext2_filsys fs,
6433 struct ext2_db_entry *db,
6436 struct dir_info *subdir, *dir;
6437 struct dx_dir_info *dx_dir;
6439 struct dx_dirblock_info *dx_db = 0;
6440 #endif /* ENABLE_HTREE */
6441 struct ext2_dir_entry *dirent, *prev;
6442 ext2_dirhash_t hash;
6443 unsigned int offset = 0;
6444 int dir_modified = 0;
6446 blk_t block_nr = db->blk;
6447 ext2_ino_t ino = db->ino;
6449 struct check_dir_struct *cd;
6453 struct ext2_dx_root_info *root;
6454 struct ext2_dx_countlimit *limit;
6455 static dict_t de_dict;
6456 struct problem_context pctx;
6459 cd = (struct check_dir_struct *) priv_data;
6463 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6464 return DIRENT_ABORT;
6466 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6467 return DIRENT_ABORT;
6470 * Make sure the inode is still in use (could have been
6471 * deleted in the duplicate/bad blocks pass.
6473 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6477 cd->pctx.blk = block_nr;
6478 cd->pctx.blkcount = db->blockcnt;
6480 cd->pctx.dirent = 0;
6484 if (allocate_dir_block(ctx, db, &cd->pctx))
6494 if (ctx->dirs_to_hash &&
6495 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6498 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6499 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6500 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6501 if (cd->pctx.errcode) {
6502 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6503 ctx->flags |= E2F_FLAG_ABORT;
6504 return DIRENT_ABORT;
6506 memset(buf, 0, fs->blocksize);
6509 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6510 if (dx_dir && dx_dir->numblocks) {
6511 if (db->blockcnt >= dx_dir->numblocks) {
6512 printf("XXX should never happen!!!\n");
6515 dx_db = &dx_dir->dx_block[db->blockcnt];
6516 dx_db->type = DX_DIRBLOCK_LEAF;
6517 dx_db->phys = block_nr;
6518 dx_db->min_hash = ~0;
6519 dx_db->max_hash = 0;
6521 dirent = (struct ext2_dir_entry *) buf;
6522 limit = (struct ext2_dx_countlimit *) (buf+8);
6523 if (db->blockcnt == 0) {
6524 root = (struct ext2_dx_root_info *) (buf + 24);
6525 dx_db->type = DX_DIRBLOCK_ROOT;
6526 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6527 if ((root->reserved_zero ||
6528 root->info_length < 8 ||
6529 root->indirect_levels > 1) &&
6530 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6531 clear_htree(ctx, ino);
6532 dx_dir->numblocks = 0;
6535 dx_dir->hashversion = root->hash_version;
6536 dx_dir->depth = root->indirect_levels + 1;
6537 } else if ((dirent->inode == 0) &&
6538 (dirent->rec_len == fs->blocksize) &&
6539 (dirent->name_len == 0) &&
6540 (ext2fs_le16_to_cpu(limit->limit) ==
6541 ((fs->blocksize-8) /
6542 sizeof(struct ext2_dx_entry))))
6543 dx_db->type = DX_DIRBLOCK_NODE;
6545 #endif /* ENABLE_HTREE */
6547 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6551 dirent = (struct ext2_dir_entry *) (buf + offset);
6552 cd->pctx.dirent = dirent;
6553 cd->pctx.num = offset;
6554 if (((offset + dirent->rec_len) > fs->blocksize) ||
6555 (dirent->rec_len < 12) ||
6556 ((dirent->rec_len % 4) != 0) ||
6557 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6558 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6559 salvage_directory(fs, dirent, prev, &offset);
6563 goto abort_free_dict;
6565 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6566 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6567 dirent->name_len = EXT2_NAME_LEN;
6572 if (dot_state == 0) {
6573 if (check_dot(ctx, dirent, ino, &cd->pctx))
6575 } else if (dot_state == 1) {
6576 dir = e2fsck_get_dir_info(ctx, ino);
6578 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6579 goto abort_free_dict;
6581 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6583 } else if (dirent->inode == ino) {
6584 problem = PR_2_LINK_DOT;
6585 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6595 * Make sure the inode listed is a legal one.
6597 if (((dirent->inode != EXT2_ROOT_INO) &&
6598 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6599 (dirent->inode > fs->super->s_inodes_count)) {
6600 problem = PR_2_BAD_INO;
6601 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6604 * If the inode is unused, offer to clear it.
6606 problem = PR_2_UNUSED_INODE;
6607 } else if (ctx->inode_bb_map &&
6608 (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
6611 * If the inode is in a bad block, offer to
6614 problem = PR_2_BB_INODE;
6615 } else if ((dot_state > 1) &&
6616 ((dirent->name_len & 0xFF) == 1) &&
6617 (dirent->name[0] == '.')) {
6619 * If there's a '.' entry in anything other
6620 * than the first directory entry, it's a
6621 * duplicate entry that should be removed.
6623 problem = PR_2_DUP_DOT;
6624 } else if ((dot_state > 1) &&
6625 ((dirent->name_len & 0xFF) == 2) &&
6626 (dirent->name[0] == '.') &&
6627 (dirent->name[1] == '.')) {
6629 * If there's a '..' entry in anything other
6630 * than the second directory entry, it's a
6631 * duplicate entry that should be removed.
6633 problem = PR_2_DUP_DOT_DOT;
6634 } else if ((dot_state > 1) &&
6635 (dirent->inode == EXT2_ROOT_INO)) {
6637 * Don't allow links to the root directory.
6638 * We check this specially to make sure we
6639 * catch this error case even if the root
6640 * directory hasn't been created yet.
6642 problem = PR_2_LINK_ROOT;
6643 } else if ((dot_state > 1) &&
6644 (dirent->name_len & 0xFF) == 0) {
6646 * Don't allow zero-length directory names.
6648 problem = PR_2_NULL_NAME;
6652 if (fix_problem(ctx, problem, &cd->pctx)) {
6657 ext2fs_unmark_valid(fs);
6658 if (problem == PR_2_BAD_INO)
6664 * If the inode was marked as having bad fields in
6665 * pass1, process it and offer to fix/clear it.
6666 * (We wait until now so that we can display the
6667 * pathname to the user.)
6669 if (ctx->inode_bad_map &&
6670 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6672 if (e2fsck_process_bad_inode(ctx, ino,
6674 buf + fs->blocksize)) {
6679 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6680 return DIRENT_ABORT;
6683 if (check_name(ctx, dirent, &cd->pctx))
6686 if (check_filetype(ctx, dirent, &cd->pctx))
6691 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6692 (dirent->name_len & 0xFF),
6693 fs->super->s_hash_seed, &hash, 0);
6694 if (hash < dx_db->min_hash)
6695 dx_db->min_hash = hash;
6696 if (hash > dx_db->max_hash)
6697 dx_db->max_hash = hash;
6702 * If this is a directory, then mark its parent in its
6703 * dir_info structure. If the parent field is already
6704 * filled in, then this directory has more than one
6705 * hard link. We assume the first link is correct,
6706 * and ask the user if he/she wants to clear this one.
6708 if ((dot_state > 1) &&
6709 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6711 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6713 cd->pctx.ino = dirent->inode;
6714 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6715 goto abort_free_dict;
6717 if (subdir->parent) {
6718 cd->pctx.ino2 = subdir->parent;
6719 if (fix_problem(ctx, PR_2_LINK_DIR,
6727 subdir->parent = ino;
6732 } else if (dict_lookup(&de_dict, dirent)) {
6733 clear_problem_context(&pctx);
6735 pctx.dirent = dirent;
6736 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6737 if (!ctx->dirs_to_hash)
6738 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6739 if (ctx->dirs_to_hash)
6740 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6743 dict_alloc_insert(&de_dict, dirent, dirent);
6745 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6748 ctx->fs_links_count++;
6749 ctx->fs_total_count++;
6752 offset += dirent->rec_len;
6754 } while (offset < fs->blocksize);
6757 cd->pctx.dir = cd->pctx.ino;
6758 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6759 (dx_db->type == DX_DIRBLOCK_NODE))
6760 parse_int_node(fs, db, cd, dx_dir, buf);
6762 #endif /* ENABLE_HTREE */
6763 if (offset != fs->blocksize) {
6764 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6765 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6766 dirent->rec_len = cd->pctx.num;
6771 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6772 if (cd->pctx.errcode) {
6773 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6775 goto abort_free_dict;
6777 ext2fs_mark_changed(fs);
6779 dict_free_nodes(&de_dict);
6782 dict_free_nodes(&de_dict);
6783 ctx->flags |= E2F_FLAG_ABORT;
6784 return DIRENT_ABORT;
6788 * This function is called to deallocate a block, and is an interator
6789 * functioned called by deallocate inode via ext2fs_iterate_block().
6791 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6792 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6793 blk_t ref_block FSCK_ATTR((unused)),
6794 int ref_offset FSCK_ATTR((unused)),
6797 e2fsck_t ctx = (e2fsck_t) priv_data;
6799 if (HOLE_BLKADDR(*block_nr))
6801 if ((*block_nr < fs->super->s_first_data_block) ||
6802 (*block_nr >= fs->super->s_blocks_count))
6804 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6805 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6810 * This fuction deallocates an inode
6812 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6814 ext2_filsys fs = ctx->fs;
6815 struct ext2_inode inode;
6816 struct problem_context pctx;
6819 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6820 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6821 inode.i_links_count = 0;
6822 inode.i_dtime = time(0);
6823 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6824 clear_problem_context(&pctx);
6828 * Fix up the bitmaps...
6830 e2fsck_read_bitmaps(ctx);
6831 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6832 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6833 if (ctx->inode_bad_map)
6834 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6835 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6837 if (inode.i_file_acl &&
6838 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6839 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6840 block_buf, -1, &count);
6841 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6846 pctx.blk = inode.i_file_acl;
6847 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6848 ctx->flags |= E2F_FLAG_ABORT;
6852 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6854 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6856 inode.i_file_acl = 0;
6859 if (!ext2fs_inode_has_valid_blocks(&inode))
6862 if (LINUX_S_ISREG(inode.i_mode) &&
6863 (inode.i_size_high || inode.i_size & 0x80000000UL))
6866 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6867 deallocate_inode_block, ctx);
6869 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6870 ctx->flags |= E2F_FLAG_ABORT;
6876 * This fuction clears the htree flag on an inode
6878 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6880 struct ext2_inode inode;
6882 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6883 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6884 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6885 if (ctx->dirs_to_hash)
6886 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6890 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6891 ext2_ino_t ino, char *buf)
6893 ext2_filsys fs = ctx->fs;
6894 struct ext2_inode inode;
6895 int inode_modified = 0;
6897 unsigned char *frag, *fsize;
6898 struct problem_context pctx;
6901 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6903 clear_problem_context(&pctx);
6906 pctx.inode = &inode;
6908 if (inode.i_file_acl &&
6909 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6910 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6911 inode.i_file_acl = 0;
6912 #ifdef EXT2FS_ENABLE_SWAPFS
6914 * This is a special kludge to deal with long symlinks
6915 * on big endian systems. i_blocks had already been
6916 * decremented earlier in pass 1, but since i_file_acl
6917 * hadn't yet been cleared, ext2fs_read_inode()
6918 * assumed that the file was short symlink and would
6919 * not have byte swapped i_block[0]. Hence, we have
6920 * to byte-swap it here.
6922 if (LINUX_S_ISLNK(inode.i_mode) &&
6923 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6924 (inode.i_blocks == fs->blocksize >> 9))
6925 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6931 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6932 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6933 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6934 !(LINUX_S_ISSOCK(inode.i_mode)))
6935 problem = PR_2_BAD_MODE;
6936 else if (LINUX_S_ISCHR(inode.i_mode)
6937 && !e2fsck_pass1_check_device_inode(fs, &inode))
6938 problem = PR_2_BAD_CHAR_DEV;
6939 else if (LINUX_S_ISBLK(inode.i_mode)
6940 && !e2fsck_pass1_check_device_inode(fs, &inode))
6941 problem = PR_2_BAD_BLOCK_DEV;
6942 else if (LINUX_S_ISFIFO(inode.i_mode)
6943 && !e2fsck_pass1_check_device_inode(fs, &inode))
6944 problem = PR_2_BAD_FIFO;
6945 else if (LINUX_S_ISSOCK(inode.i_mode)
6946 && !e2fsck_pass1_check_device_inode(fs, &inode))
6947 problem = PR_2_BAD_SOCKET;
6948 else if (LINUX_S_ISLNK(inode.i_mode)
6949 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6950 problem = PR_2_INVALID_SYMLINK;
6954 if (fix_problem(ctx, problem, &pctx)) {
6955 deallocate_inode(ctx, ino, 0);
6956 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6964 if (inode.i_faddr) {
6965 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6972 switch (fs->super->s_creator_os) {
6974 frag = &inode.osd2.linux2.l_i_frag;
6975 fsize = &inode.osd2.linux2.l_i_fsize;
6978 frag = &inode.osd2.hurd2.h_i_frag;
6979 fsize = &inode.osd2.hurd2.h_i_fsize;
6982 frag = &inode.osd2.masix2.m_i_frag;
6983 fsize = &inode.osd2.masix2.m_i_fsize;
6988 if (frag && *frag) {
6990 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6997 if (fsize && *fsize) {
6999 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
7007 if (inode.i_file_acl &&
7008 ((inode.i_file_acl < fs->super->s_first_data_block) ||
7009 (inode.i_file_acl >= fs->super->s_blocks_count))) {
7010 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
7011 inode.i_file_acl = 0;
7016 if (inode.i_dir_acl &&
7017 LINUX_S_ISDIR(inode.i_mode)) {
7018 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
7019 inode.i_dir_acl = 0;
7026 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
7028 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
7034 * allocate_dir_block --- this function allocates a new directory
7035 * block for a particular inode; this is done if a directory has
7036 * a "hole" in it, or if a directory has a illegal block number
7037 * that was zeroed out and now needs to be replaced.
7039 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
7040 struct problem_context *pctx)
7042 ext2_filsys fs = ctx->fs;
7045 struct ext2_inode inode;
7047 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
7051 * Read the inode and block bitmaps in; we'll be messing with
7054 e2fsck_read_bitmaps(ctx);
7057 * First, find a free block
7059 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7060 if (pctx->errcode) {
7061 pctx->str = "ext2fs_new_block";
7062 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7065 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7066 ext2fs_mark_block_bitmap(fs->block_map, blk);
7067 ext2fs_mark_bb_dirty(fs);
7070 * Now let's create the actual data block for the inode
7073 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
7075 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
7076 EXT2_ROOT_INO, &block);
7078 if (pctx->errcode) {
7079 pctx->str = "ext2fs_new_dir_block";
7080 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7084 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
7085 ext2fs_free_mem(&block);
7086 if (pctx->errcode) {
7087 pctx->str = "ext2fs_write_dir_block";
7088 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7093 * Update the inode block count
7095 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
7096 inode.i_blocks += fs->blocksize / 512;
7097 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
7098 inode.i_size = (db->blockcnt+1) * fs->blocksize;
7099 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
7102 * Finally, update the block pointers for the inode
7105 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
7106 0, update_dir_block, db);
7107 if (pctx->errcode) {
7108 pctx->str = "ext2fs_block_iterate";
7109 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
7117 * This is a helper function for allocate_dir_block().
7119 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
7121 e2_blkcnt_t blockcnt,
7122 blk_t ref_block FSCK_ATTR((unused)),
7123 int ref_offset FSCK_ATTR((unused)),
7126 struct ext2_db_entry *db;
7128 db = (struct ext2_db_entry *) priv_data;
7129 if (db->blockcnt == (int) blockcnt) {
7130 *block_nr = db->blk;
7131 return BLOCK_CHANGED;
7137 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
7139 * Pass #3 assures that all directories are connected to the
7140 * filesystem tree, using the following algorithm:
7142 * First, the root directory is checked to make sure it exists; if
7143 * not, e2fsck will offer to create a new one. It is then marked as
7146 * Then, pass3 interates over all directory inodes; for each directory
7147 * it attempts to trace up the filesystem tree, using dirinfo.parent
7148 * until it reaches a directory which has been marked "done". If it
7149 * can not do so, then the directory must be disconnected, and e2fsck
7150 * will offer to reconnect it to /lost+found. While it is chasing
7151 * parent pointers up the filesystem tree, if pass3 sees a directory
7152 * twice, then it has detected a filesystem loop, and it will again
7153 * offer to reconnect the directory to /lost+found in to break the
7156 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
7157 * reconnect inodes to /lost+found; this subroutine is also used by
7158 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
7159 * is responsible for creating /lost+found if it does not exist.
7161 * Pass 3 frees the following data structures:
7162 * - The dirinfo directory information cache.
7165 static void check_root(e2fsck_t ctx);
7166 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
7167 struct problem_context *pctx);
7168 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
7170 static ext2fs_inode_bitmap inode_loop_detect;
7171 static ext2fs_inode_bitmap inode_done_map;
7173 static void e2fsck_pass3(e2fsck_t ctx)
7175 ext2_filsys fs = ctx->fs;
7177 struct problem_context pctx;
7178 struct dir_info *dir;
7179 unsigned long maxdirs, count;
7181 clear_problem_context(&pctx);
7185 if (!(ctx->options & E2F_OPT_PREEN))
7186 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
7189 * Allocate some bitmaps to do loop detection.
7191 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
7195 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
7196 ctx->flags |= E2F_FLAG_ABORT;
7200 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7203 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
7205 maxdirs = e2fsck_get_num_dirinfo(ctx);
7209 if ((ctx->progress)(ctx, 3, 0, maxdirs))
7212 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
7213 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7215 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
7217 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
7218 if (check_directory(ctx, dir, &pctx))
7223 * Force the creation of /lost+found if not present
7225 if ((ctx->flags & E2F_OPT_READONLY) == 0)
7226 e2fsck_get_lost_and_found(ctx, 1);
7229 * If there are any directories that need to be indexed or
7230 * optimized, do it here.
7232 e2fsck_rehash_directories(ctx);
7235 e2fsck_free_dir_info(ctx);
7236 ext2fs_free_inode_bitmap(inode_loop_detect);
7237 inode_loop_detect = 0;
7238 ext2fs_free_inode_bitmap(inode_done_map);
7243 * This makes sure the root inode is present; if not, we ask if the
7244 * user wants us to create it. Not creating it is a fatal error.
7246 static void check_root(e2fsck_t ctx)
7248 ext2_filsys fs = ctx->fs;
7250 struct ext2_inode inode;
7252 struct problem_context pctx;
7254 clear_problem_context(&pctx);
7256 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
7258 * If the root inode is not a directory, die here. The
7259 * user must have answered 'no' in pass1 when we
7260 * offered to clear it.
7262 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
7264 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
7265 ctx->flags |= E2F_FLAG_ABORT;
7270 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
7271 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
7272 ctx->flags |= E2F_FLAG_ABORT;
7276 e2fsck_read_bitmaps(ctx);
7279 * First, find a free block
7281 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7283 pctx.str = "ext2fs_new_block";
7284 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7285 ctx->flags |= E2F_FLAG_ABORT;
7288 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7289 ext2fs_mark_block_bitmap(fs->block_map, blk);
7290 ext2fs_mark_bb_dirty(fs);
7293 * Now let's create the actual data block for the inode
7295 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
7298 pctx.str = "ext2fs_new_dir_block";
7299 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7300 ctx->flags |= E2F_FLAG_ABORT;
7304 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
7306 pctx.str = "ext2fs_write_dir_block";
7307 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7308 ctx->flags |= E2F_FLAG_ABORT;
7311 ext2fs_free_mem(&block);
7314 * Set up the inode structure
7316 memset(&inode, 0, sizeof(inode));
7317 inode.i_mode = 040755;
7318 inode.i_size = fs->blocksize;
7319 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7320 inode.i_links_count = 2;
7321 inode.i_blocks = fs->blocksize / 512;
7322 inode.i_block[0] = blk;
7325 * Write out the inode.
7327 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
7329 pctx.str = "ext2fs_write_inode";
7330 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
7331 ctx->flags |= E2F_FLAG_ABORT;
7336 * Miscellaneous bookkeeping...
7338 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
7339 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
7340 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
7342 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
7343 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
7344 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
7345 ext2fs_mark_ib_dirty(fs);
7349 * This subroutine is responsible for making sure that a particular
7350 * directory is connected to the root; if it isn't we trace it up as
7351 * far as we can go, and then offer to connect the resulting parent to
7352 * the lost+found. We have to do loop detection; if we ever discover
7353 * a loop, we treat that as a disconnected directory and offer to
7354 * reparent it to lost+found.
7356 * However, loop detection is expensive, because for very large
7357 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
7358 * is non-trivial. Loops in filesystems are also a rare error case,
7359 * and we shouldn't optimize for error cases. So we try two passes of
7360 * the algorithm. The first time, we ignore loop detection and merely
7361 * increment a counter; if the counter exceeds some extreme threshold,
7362 * then we try again with the loop detection bitmap enabled.
7364 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
7365 struct problem_context *pctx)
7367 ext2_filsys fs = ctx->fs;
7368 struct dir_info *p = dir;
7369 int loop_pass = 0, parent_count = 0;
7376 * Mark this inode as being "done"; by the time we
7377 * return from this function, the inode we either be
7378 * verified as being connected to the directory tree,
7379 * or we will have offered to reconnect this to
7382 * If it was marked done already, then we've reached a
7383 * parent we've already checked.
7385 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
7389 * If this directory doesn't have a parent, or we've
7390 * seen the parent once already, then offer to
7391 * reparent it to lost+found
7395 (ext2fs_test_inode_bitmap(inode_loop_detect,
7398 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
7399 if (e2fsck_reconnect_file(ctx, pctx->ino))
7400 ext2fs_unmark_valid(fs);
7402 p = e2fsck_get_dir_info(ctx, pctx->ino);
7403 p->parent = ctx->lost_and_found;
7404 fix_dotdot(ctx, p, ctx->lost_and_found);
7409 p = e2fsck_get_dir_info(ctx, p->parent);
7411 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
7415 ext2fs_mark_inode_bitmap(inode_loop_detect,
7417 } else if (parent_count++ > 2048) {
7419 * If we've run into a path depth that's
7420 * greater than 2048, try again with the inode
7421 * loop bitmap turned on and start from the
7425 if (inode_loop_detect)
7426 ext2fs_clear_inode_bitmap(inode_loop_detect);
7428 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7429 if (pctx->errcode) {
7432 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7433 ctx->flags |= E2F_FLAG_ABORT;
7442 * Make sure that .. and the parent directory are the same;
7443 * offer to fix it if not.
7445 if (dir->parent != dir->dotdot) {
7446 pctx->ino = dir->ino;
7447 pctx->ino2 = dir->dotdot;
7448 pctx->dir = dir->parent;
7449 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7450 fix_dotdot(ctx, dir, dir->parent);
7456 * This routine gets the lost_and_found inode, making it a directory
7459 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7461 ext2_filsys fs = ctx->fs;
7465 struct ext2_inode inode;
7467 static const char name[] = "lost+found";
7468 struct problem_context pctx;
7469 struct dir_info *dirinfo;
7471 if (ctx->lost_and_found)
7472 return ctx->lost_and_found;
7474 clear_problem_context(&pctx);
7476 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7477 sizeof(name)-1, 0, &ino);
7481 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7482 ctx->lost_and_found = ino;
7486 /* Lost+found isn't a directory! */
7490 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7493 /* OK, unlink the old /lost+found file. */
7494 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7496 pctx.str = "ext2fs_unlink";
7497 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7500 dirinfo = e2fsck_get_dir_info(ctx, ino);
7502 dirinfo->parent = 0;
7503 e2fsck_adjust_inode_count(ctx, ino, -1);
7504 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7505 pctx.errcode = retval;
7506 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7508 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7512 * Read the inode and block bitmaps in; we'll be messing with
7515 e2fsck_read_bitmaps(ctx);
7518 * First, find a free block
7520 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7522 pctx.errcode = retval;
7523 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7526 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7527 ext2fs_block_alloc_stats(fs, blk, +1);
7530 * Next find a free inode.
7532 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7533 ctx->inode_used_map, &ino);
7535 pctx.errcode = retval;
7536 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7539 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7540 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7541 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7544 * Now let's create the actual data block for the inode
7546 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7548 pctx.errcode = retval;
7549 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7553 retval = ext2fs_write_dir_block(fs, blk, block);
7554 ext2fs_free_mem(&block);
7556 pctx.errcode = retval;
7557 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7562 * Set up the inode structure
7564 memset(&inode, 0, sizeof(inode));
7565 inode.i_mode = 040700;
7566 inode.i_size = fs->blocksize;
7567 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7568 inode.i_links_count = 2;
7569 inode.i_blocks = fs->blocksize / 512;
7570 inode.i_block[0] = blk;
7573 * Next, write out the inode.
7575 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7577 pctx.str = "ext2fs_write_inode";
7578 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7582 * Finally, create the directory link
7584 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7586 pctx.str = "ext2fs_link";
7587 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7592 * Miscellaneous bookkeeping that needs to be kept straight.
7594 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7595 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7596 ext2fs_icount_store(ctx->inode_count, ino, 2);
7597 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7598 ctx->lost_and_found = ino;
7603 * This routine will connect a file to lost+found
7605 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7607 ext2_filsys fs = ctx->fs;
7610 struct problem_context pctx;
7611 struct ext2_inode inode;
7614 clear_problem_context(&pctx);
7617 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7618 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7619 ctx->bad_lost_and_found++;
7621 if (ctx->bad_lost_and_found) {
7622 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7626 sprintf(name, "#%u", ino);
7627 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7628 file_type = ext2_file_type(inode.i_mode);
7629 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7630 if (retval == EXT2_ET_DIR_NO_SPACE) {
7631 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7633 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7636 pctx.errcode = retval;
7637 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7640 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7644 pctx.errcode = retval;
7645 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7648 e2fsck_adjust_inode_count(ctx, ino, 1);
7654 * Utility routine to adjust the inode counts on an inode.
7656 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7658 ext2_filsys fs = ctx->fs;
7660 struct ext2_inode inode;
7665 retval = ext2fs_read_inode(fs, ino, &inode);
7670 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7671 if (inode.i_links_count == (__u16) ~0)
7673 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7674 inode.i_links_count++;
7675 } else if (adj == -1) {
7676 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7677 if (inode.i_links_count == 0)
7679 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7680 inode.i_links_count--;
7683 retval = ext2fs_write_inode(fs, ino, &inode);
7691 * Fix parent --- this routine fixes up the parent of a directory.
7693 struct fix_dotdot_struct {
7700 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7701 int offset FSCK_ATTR((unused)),
7702 int blocksize FSCK_ATTR((unused)),
7703 char *buf FSCK_ATTR((unused)),
7706 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7708 struct problem_context pctx;
7710 if ((dirent->name_len & 0xFF) != 2)
7712 if (strncmp(dirent->name, "..", 2))
7715 clear_problem_context(&pctx);
7717 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7719 pctx.errcode = retval;
7720 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7722 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7724 pctx.errcode = retval;
7725 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7727 dirent->inode = fp->parent;
7730 return DIRENT_ABORT | DIRENT_CHANGED;
7733 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7735 ext2_filsys fs = ctx->fs;
7737 struct fix_dotdot_struct fp;
7738 struct problem_context pctx;
7745 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7746 0, fix_dotdot_proc, &fp);
7747 if (retval || !fp.done) {
7748 clear_problem_context(&pctx);
7749 pctx.ino = dir->ino;
7750 pctx.errcode = retval;
7751 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7752 PR_3_FIX_PARENT_NOFIND, &pctx);
7753 ext2fs_unmark_valid(fs);
7755 dir->dotdot = parent;
7761 * These routines are responsible for expanding a /lost+found if it is
7765 struct expand_dir_struct {
7767 int guaranteed_size;
7774 static int expand_dir_proc(ext2_filsys fs,
7776 e2_blkcnt_t blockcnt,
7777 blk_t ref_block FSCK_ATTR((unused)),
7778 int ref_offset FSCK_ATTR((unused)),
7781 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7783 static blk_t last_blk = 0;
7790 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7794 es->last_block = blockcnt;
7796 last_blk = *blocknr;
7799 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7806 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7812 retval = ext2fs_write_dir_block(fs, new_blk, block);
7814 retval = ext2fs_get_mem(fs->blocksize, &block);
7819 memset(block, 0, fs->blocksize);
7820 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7826 ext2fs_free_mem(&block);
7828 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7829 ext2fs_block_alloc_stats(fs, new_blk, +1);
7833 return (BLOCK_CHANGED | BLOCK_ABORT);
7835 return BLOCK_CHANGED;
7838 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7839 int num, int guaranteed_size)
7841 ext2_filsys fs = ctx->fs;
7843 struct expand_dir_struct es;
7844 struct ext2_inode inode;
7846 if (!(fs->flags & EXT2_FLAG_RW))
7847 return EXT2_ET_RO_FILSYS;
7850 * Read the inode and block bitmaps in; we'll be messing with
7853 e2fsck_read_bitmaps(ctx);
7855 retval = ext2fs_check_directory(fs, dir);
7860 es.guaranteed_size = guaranteed_size;
7866 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7867 0, expand_dir_proc, &es);
7873 * Update the size and block count fields in the inode.
7875 retval = ext2fs_read_inode(fs, dir, &inode);
7879 inode.i_size = (es.last_block + 1) * fs->blocksize;
7880 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7882 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7888 * pass4.c -- pass #4 of e2fsck: Check reference counts
7890 * Pass 4 frees the following data structures:
7891 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
7892 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7896 * This routine is called when an inode is not connected to the
7899 * This subroutine returns 1 then the caller shouldn't bother with the
7900 * rest of the pass 4 tests.
7902 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7904 ext2_filsys fs = ctx->fs;
7905 struct ext2_inode inode;
7906 struct problem_context pctx;
7908 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7909 clear_problem_context(&pctx);
7911 pctx.inode = &inode;
7914 * Offer to delete any zero-length files that does not have
7915 * blocks. If there is an EA block, it might have useful
7916 * information, so we won't prompt to delete it, but let it be
7917 * reconnected to lost+found.
7919 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7920 LINUX_S_ISDIR(inode.i_mode))) {
7921 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7922 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7923 inode.i_links_count = 0;
7924 inode.i_dtime = time(0);
7925 e2fsck_write_inode(ctx, i, &inode,
7926 "disconnect_inode");
7928 * Fix up the bitmaps...
7930 e2fsck_read_bitmaps(ctx);
7931 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7932 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7933 ext2fs_inode_alloc_stats2(fs, i, -1,
7934 LINUX_S_ISDIR(inode.i_mode));
7940 * Prompt to reconnect.
7942 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7943 if (e2fsck_reconnect_file(ctx, i))
7944 ext2fs_unmark_valid(fs);
7947 * If we don't attach the inode, then skip the
7948 * i_links_test since there's no point in trying to
7949 * force i_links_count to zero.
7951 ext2fs_unmark_valid(fs);
7958 static void e2fsck_pass4(e2fsck_t ctx)
7960 ext2_filsys fs = ctx->fs;
7962 struct ext2_inode inode;
7963 struct problem_context pctx;
7964 __u16 link_count, link_counted;
7966 int group, maxgroup;
7970 clear_problem_context(&pctx);
7972 if (!(ctx->options & E2F_OPT_PREEN))
7973 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7976 maxgroup = fs->group_desc_count;
7978 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7981 for (i=1; i <= fs->super->s_inodes_count; i++) {
7982 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7984 if ((i % fs->super->s_inodes_per_group) == 0) {
7987 if ((ctx->progress)(ctx, 4, group, maxgroup))
7990 if (i == EXT2_BAD_INO ||
7991 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7993 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7994 (ctx->inode_imagic_map &&
7995 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
7996 (ctx->inode_bb_map &&
7997 ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
7999 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
8000 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
8001 if (link_counted == 0) {
8003 buf = e2fsck_allocate_memory(ctx,
8004 fs->blocksize, "bad_inode buffer");
8005 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
8007 if (disconnect_inode(ctx, i))
8009 ext2fs_icount_fetch(ctx->inode_link_info, i,
8011 ext2fs_icount_fetch(ctx->inode_count, i,
8014 if (link_counted != link_count) {
8015 e2fsck_read_inode(ctx, i, &inode, "pass4");
8017 pctx.inode = &inode;
8018 if (link_count != inode.i_links_count) {
8019 pctx.num = link_count;
8021 PR_4_INCONSISTENT_COUNT, &pctx);
8023 pctx.num = link_counted;
8024 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
8025 inode.i_links_count = link_counted;
8026 e2fsck_write_inode(ctx, i, &inode, "pass4");
8030 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
8031 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
8032 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
8033 ctx->inode_bb_map = 0;
8034 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
8035 ctx->inode_imagic_map = 0;
8036 ext2fs_free_mem(&buf);
8040 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
8043 #define NO_BLK ((blk_t) -1)
8045 static void print_bitmap_problem(e2fsck_t ctx, int problem,
8046 struct problem_context *pctx)
8049 case PR_5_BLOCK_UNUSED:
8050 if (pctx->blk == pctx->blk2)
8053 problem = PR_5_BLOCK_RANGE_UNUSED;
8055 case PR_5_BLOCK_USED:
8056 if (pctx->blk == pctx->blk2)
8059 problem = PR_5_BLOCK_RANGE_USED;
8061 case PR_5_INODE_UNUSED:
8062 if (pctx->ino == pctx->ino2)
8065 problem = PR_5_INODE_RANGE_UNUSED;
8067 case PR_5_INODE_USED:
8068 if (pctx->ino == pctx->ino2)
8071 problem = PR_5_INODE_RANGE_USED;
8074 fix_problem(ctx, problem, pctx);
8075 pctx->blk = pctx->blk2 = NO_BLK;
8076 pctx->ino = pctx->ino2 = 0;
8079 static void check_block_bitmaps(e2fsck_t ctx)
8081 ext2_filsys fs = ctx->fs;
8085 unsigned int blocks = 0;
8086 unsigned int free_blocks = 0;
8089 struct problem_context pctx;
8090 int problem, save_problem, fixit, had_problem;
8093 clear_problem_context(&pctx);
8094 free_array = (int *) e2fsck_allocate_memory(ctx,
8095 fs->group_desc_count * sizeof(int), "free block count array");
8097 if ((fs->super->s_first_data_block <
8098 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
8099 (fs->super->s_blocks_count-1 >
8100 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
8102 pctx.blk = fs->super->s_first_data_block;
8103 pctx.blk2 = fs->super->s_blocks_count -1;
8104 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
8105 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
8106 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8108 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8112 if ((fs->super->s_first_data_block <
8113 ext2fs_get_block_bitmap_start(fs->block_map)) ||
8114 (fs->super->s_blocks_count-1 >
8115 ext2fs_get_block_bitmap_end(fs->block_map))) {
8117 pctx.blk = fs->super->s_first_data_block;
8118 pctx.blk2 = fs->super->s_blocks_count -1;
8119 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
8120 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
8121 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8123 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8130 pctx.blk = pctx.blk2 = NO_BLK;
8131 for (i = fs->super->s_first_data_block;
8132 i < fs->super->s_blocks_count;
8134 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
8135 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
8137 if (actual == bitmap)
8140 if (!actual && bitmap) {
8142 * Block not used, but marked in use in the bitmap.
8144 problem = PR_5_BLOCK_UNUSED;
8147 * Block used, but not marked in use in the bitmap.
8149 problem = PR_5_BLOCK_USED;
8151 if (pctx.blk == NO_BLK) {
8152 pctx.blk = pctx.blk2 = i;
8153 save_problem = problem;
8155 if ((problem == save_problem) &&
8159 print_bitmap_problem(ctx, save_problem, &pctx);
8160 pctx.blk = pctx.blk2 = i;
8161 save_problem = problem;
8164 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
8173 if ((blocks == fs->super->s_blocks_per_group) ||
8174 (i == fs->super->s_blocks_count-1)) {
8175 free_array[group] = group_free;
8180 if ((ctx->progress)(ctx, 5, group,
8181 fs->group_desc_count*2))
8185 if (pctx.blk != NO_BLK)
8186 print_bitmap_problem(ctx, save_problem, &pctx);
8188 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
8191 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
8194 ext2fs_free_block_bitmap(fs->block_map);
8195 retval = ext2fs_copy_bitmap(ctx->block_found_map,
8198 clear_problem_context(&pctx);
8199 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
8200 ctx->flags |= E2F_FLAG_ABORT;
8203 ext2fs_set_bitmap_padding(fs->block_map);
8204 ext2fs_mark_bb_dirty(fs);
8206 /* Redo the counts */
8207 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
8208 memset(free_array, 0, fs->group_desc_count * sizeof(int));
8210 } else if (fixit == 0)
8211 ext2fs_unmark_valid(fs);
8213 for (i = 0; i < fs->group_desc_count; i++) {
8214 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
8216 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
8217 pctx.blk2 = free_array[i];
8219 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
8221 fs->group_desc[i].bg_free_blocks_count =
8223 ext2fs_mark_super_dirty(fs);
8225 ext2fs_unmark_valid(fs);
8228 if (free_blocks != fs->super->s_free_blocks_count) {
8230 pctx.blk = fs->super->s_free_blocks_count;
8231 pctx.blk2 = free_blocks;
8233 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
8234 fs->super->s_free_blocks_count = free_blocks;
8235 ext2fs_mark_super_dirty(fs);
8237 ext2fs_unmark_valid(fs);
8239 ext2fs_free_mem(&free_array);
8242 static void check_inode_bitmaps(e2fsck_t ctx)
8244 ext2_filsys fs = ctx->fs;
8246 unsigned int free_inodes = 0;
8250 unsigned int inodes = 0;
8255 struct problem_context pctx;
8256 int problem, save_problem, fixit, had_problem;
8258 clear_problem_context(&pctx);
8259 free_array = (int *) e2fsck_allocate_memory(ctx,
8260 fs->group_desc_count * sizeof(int), "free inode count array");
8262 dir_array = (int *) e2fsck_allocate_memory(ctx,
8263 fs->group_desc_count * sizeof(int), "directory count array");
8265 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
8266 (fs->super->s_inodes_count >
8267 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
8270 pctx.blk2 = fs->super->s_inodes_count;
8271 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
8272 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
8273 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8275 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8278 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
8279 (fs->super->s_inodes_count >
8280 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
8283 pctx.blk2 = fs->super->s_inodes_count;
8284 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
8285 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
8286 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
8288 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8295 pctx.ino = pctx.ino2 = 0;
8296 for (i = 1; i <= fs->super->s_inodes_count; i++) {
8297 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
8298 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
8300 if (actual == bitmap)
8303 if (!actual && bitmap) {
8305 * Inode wasn't used, but marked in bitmap
8307 problem = PR_5_INODE_UNUSED;
8308 } else /* if (actual && !bitmap) */ {
8310 * Inode used, but not in bitmap
8312 problem = PR_5_INODE_USED;
8314 if (pctx.ino == 0) {
8315 pctx.ino = pctx.ino2 = i;
8316 save_problem = problem;
8318 if ((problem == save_problem) &&
8322 print_bitmap_problem(ctx, save_problem, &pctx);
8323 pctx.ino = pctx.ino2 = i;
8324 save_problem = problem;
8327 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
8335 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
8339 if ((inodes == fs->super->s_inodes_per_group) ||
8340 (i == fs->super->s_inodes_count)) {
8341 free_array[group] = group_free;
8342 dir_array[group] = dirs_count;
8348 if ((ctx->progress)(ctx, 5,
8349 group + fs->group_desc_count,
8350 fs->group_desc_count*2))
8355 print_bitmap_problem(ctx, save_problem, &pctx);
8358 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
8361 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
8364 ext2fs_free_inode_bitmap(fs->inode_map);
8365 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
8368 clear_problem_context(&pctx);
8369 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
8370 ctx->flags |= E2F_FLAG_ABORT;
8373 ext2fs_set_bitmap_padding(fs->inode_map);
8374 ext2fs_mark_ib_dirty(fs);
8377 inodes = 0; free_inodes = 0; group_free = 0;
8378 dirs_count = 0; group = 0;
8379 memset(free_array, 0, fs->group_desc_count * sizeof(int));
8380 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
8382 } else if (fixit == 0)
8383 ext2fs_unmark_valid(fs);
8385 for (i = 0; i < fs->group_desc_count; i++) {
8386 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
8388 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
8389 pctx.ino2 = free_array[i];
8390 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
8392 fs->group_desc[i].bg_free_inodes_count =
8394 ext2fs_mark_super_dirty(fs);
8396 ext2fs_unmark_valid(fs);
8398 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
8400 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
8401 pctx.ino2 = dir_array[i];
8403 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
8405 fs->group_desc[i].bg_used_dirs_count =
8407 ext2fs_mark_super_dirty(fs);
8409 ext2fs_unmark_valid(fs);
8412 if (free_inodes != fs->super->s_free_inodes_count) {
8414 pctx.ino = fs->super->s_free_inodes_count;
8415 pctx.ino2 = free_inodes;
8417 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
8418 fs->super->s_free_inodes_count = free_inodes;
8419 ext2fs_mark_super_dirty(fs);
8421 ext2fs_unmark_valid(fs);
8423 ext2fs_free_mem(&free_array);
8424 ext2fs_free_mem(&dir_array);
8427 static void check_inode_end(e2fsck_t ctx)
8429 ext2_filsys fs = ctx->fs;
8430 ext2_ino_t end, save_inodes_count, i;
8431 struct problem_context pctx;
8433 clear_problem_context(&pctx);
8435 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8436 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8437 &save_inodes_count);
8440 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8441 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8444 if (save_inodes_count == end)
8447 for (i = save_inodes_count + 1; i <= end; i++) {
8448 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8449 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8450 for (i = save_inodes_count + 1; i <= end; i++)
8451 ext2fs_mark_inode_bitmap(fs->inode_map,
8453 ext2fs_mark_ib_dirty(fs);
8455 ext2fs_unmark_valid(fs);
8460 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8461 save_inodes_count, 0);
8464 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8465 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8470 static void check_block_end(e2fsck_t ctx)
8472 ext2_filsys fs = ctx->fs;
8473 blk_t end, save_blocks_count, i;
8474 struct problem_context pctx;
8476 clear_problem_context(&pctx);
8478 end = fs->block_map->start +
8479 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8480 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8481 &save_blocks_count);
8484 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8485 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8488 if (save_blocks_count == end)
8491 for (i = save_blocks_count + 1; i <= end; i++) {
8492 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8493 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8494 for (i = save_blocks_count + 1; i <= end; i++)
8495 ext2fs_mark_block_bitmap(fs->block_map,
8497 ext2fs_mark_bb_dirty(fs);
8499 ext2fs_unmark_valid(fs);
8504 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8505 save_blocks_count, 0);
8508 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8509 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8514 static void e2fsck_pass5(e2fsck_t ctx)
8516 struct problem_context pctx;
8520 clear_problem_context(&pctx);
8522 if (!(ctx->options & E2F_OPT_PREEN))
8523 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8526 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8529 e2fsck_read_bitmaps(ctx);
8531 check_block_bitmaps(ctx);
8532 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8534 check_inode_bitmaps(ctx);
8535 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8537 check_inode_end(ctx);
8538 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8540 check_block_end(ctx);
8541 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8544 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8545 ctx->inode_used_map = 0;
8546 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8547 ctx->inode_dir_map = 0;
8548 ext2fs_free_block_bitmap(ctx->block_found_map);
8549 ctx->block_found_map = 0;
8553 * problem.c --- report filesystem problems to the user
8556 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8557 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8558 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8559 #define PR_MSG_ONLY 0x000008 /* Print message only */
8561 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8563 #define PR_FATAL 0x001000 /* Fatal error */
8564 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8566 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8567 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8568 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8569 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8570 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8573 #define PROMPT_NONE 0
8574 #define PROMPT_FIX 1
8575 #define PROMPT_CLEAR 2
8576 #define PROMPT_RELOCATE 3
8577 #define PROMPT_ALLOCATE 4
8578 #define PROMPT_EXPAND 5
8579 #define PROMPT_CONNECT 6
8580 #define PROMPT_CREATE 7
8581 #define PROMPT_SALVAGE 8
8582 #define PROMPT_TRUNCATE 9
8583 #define PROMPT_CLEAR_INODE 10
8584 #define PROMPT_ABORT 11
8585 #define PROMPT_SPLIT 12
8586 #define PROMPT_CONTINUE 13
8587 #define PROMPT_CLONE 14
8588 #define PROMPT_DELETE 15
8589 #define PROMPT_SUPPRESS 16
8590 #define PROMPT_UNLINK 17
8591 #define PROMPT_CLEAR_HTREE 18
8592 #define PROMPT_RECREATE 19
8593 #define PROMPT_NULL 20
8595 struct e2fsck_problem {
8597 const char * e2p_description;
8600 problem_t second_code;
8603 struct latch_descr {
8606 problem_t end_message;
8611 * These are the prompts which are used to ask the user if they want
8614 static const char * const prompt[] = {
8615 N_("(no prompt)"), /* 0 */
8617 N_("Clear"), /* 2 */
8618 N_("Relocate"), /* 3 */
8619 N_("Allocate"), /* 4 */
8620 N_("Expand"), /* 5 */
8621 N_("Connect to /lost+found"), /* 6 */
8622 N_("Create"), /* 7 */
8623 N_("Salvage"), /* 8 */
8624 N_("Truncate"), /* 9 */
8625 N_("Clear inode"), /* 10 */
8626 N_("Abort"), /* 11 */
8627 N_("Split"), /* 12 */
8628 N_("Continue"), /* 13 */
8629 N_("Clone multiply-claimed blocks"), /* 14 */
8630 N_("Delete file"), /* 15 */
8631 N_("Suppress messages"),/* 16 */
8632 N_("Unlink"), /* 17 */
8633 N_("Clear HTree index"),/* 18 */
8634 N_("Recreate"), /* 19 */
8639 * These messages are printed when we are preen mode and we will be
8640 * automatically fixing the problem.
8642 static const char * const preen_msg[] = {
8643 N_("(NONE)"), /* 0 */
8644 N_("FIXED"), /* 1 */
8645 N_("CLEARED"), /* 2 */
8646 N_("RELOCATED"), /* 3 */
8647 N_("ALLOCATED"), /* 4 */
8648 N_("EXPANDED"), /* 5 */
8649 N_("RECONNECTED"), /* 6 */
8650 N_("CREATED"), /* 7 */
8651 N_("SALVAGED"), /* 8 */
8652 N_("TRUNCATED"), /* 9 */
8653 N_("INODE CLEARED"), /* 10 */
8654 N_("ABORTED"), /* 11 */
8655 N_("SPLIT"), /* 12 */
8656 N_("CONTINUING"), /* 13 */
8657 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8658 N_("FILE DELETED"), /* 15 */
8659 N_("SUPPRESSED"), /* 16 */
8660 N_("UNLINKED"), /* 17 */
8661 N_("HTREE INDEX CLEARED"),/* 18 */
8662 N_("WILL RECREATE"), /* 19 */
8666 static const struct e2fsck_problem problem_table[] = {
8668 /* Pre-Pass 1 errors */
8670 /* Block bitmap not in group */
8671 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8672 PROMPT_RELOCATE, PR_LATCH_RELOC },
8674 /* Inode bitmap not in group */
8675 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8676 PROMPT_RELOCATE, PR_LATCH_RELOC },
8678 /* Inode table not in group */
8679 { PR_0_ITABLE_NOT_GROUP,
8680 N_("@i table for @g %g is not in @g. (@b %b)\n"
8681 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8682 PROMPT_RELOCATE, PR_LATCH_RELOC },
8684 /* Superblock corrupt */
8686 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8687 "@f. If the @v is valid and it really contains an ext2\n"
8688 "@f (and not swap or ufs or something else), then the @S\n"
8689 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8690 " e2fsck -b %S <@v>\n\n"),
8691 PROMPT_NONE, PR_FATAL },
8693 /* Filesystem size is wrong */
8694 { PR_0_FS_SIZE_WRONG,
8695 N_("The @f size (according to the @S) is %b @bs\n"
8696 "The physical size of the @v is %c @bs\n"
8697 "Either the @S or the partition table is likely to be corrupt!\n"),
8700 /* Fragments not supported */
8701 { PR_0_NO_FRAGMENTS,
8702 N_("@S @b_size = %b, fragsize = %c.\n"
8703 "This version of e2fsck does not support fragment sizes different\n"
8704 "from the @b size.\n"),
8705 PROMPT_NONE, PR_FATAL },
8707 /* Bad blocks_per_group */
8708 { PR_0_BLOCKS_PER_GROUP,
8709 N_("@S @bs_per_group = %b, should have been %c\n"),
8710 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8712 /* Bad first_data_block */
8713 { PR_0_FIRST_DATA_BLOCK,
8714 N_("@S first_data_@b = %b, should have been %c\n"),
8715 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8717 /* Adding UUID to filesystem */
8719 N_("@f did not have a UUID; generating one.\n\n"),
8723 { PR_0_RELOCATE_HINT,
8724 N_("Note: if several inode or block bitmap blocks or part\n"
8725 "of the inode table require relocation, you may wish to try\n"
8726 "running e2fsck with the '-b %S' option first. The problem\n"
8727 "may lie only with the primary block group descriptors, and\n"
8728 "the backup block group descriptors may be OK.\n\n"),
8729 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8731 /* Miscellaneous superblock corruption */
8732 { PR_0_MISC_CORRUPT_SUPER,
8733 N_("Corruption found in @S. (%s = %N).\n"),
8734 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8736 /* Error determing physical device size of filesystem */
8737 { PR_0_GETSIZE_ERROR,
8738 N_("Error determining size of the physical @v: %m\n"),
8739 PROMPT_NONE, PR_FATAL },
8741 /* Inode count in superblock is incorrect */
8742 { PR_0_INODE_COUNT_WRONG,
8743 N_("@i count in @S is %i, @s %j.\n"),
8746 { PR_0_HURD_CLEAR_FILETYPE,
8747 N_("The Hurd does not support the filetype feature.\n"),
8750 /* Journal inode is invalid */
8751 { PR_0_JOURNAL_BAD_INODE,
8752 N_("@S has an @n ext3 @j (@i %i).\n"),
8753 PROMPT_CLEAR, PR_PREEN_OK },
8755 /* The external journal has (unsupported) multiple filesystems */
8756 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8757 N_("External @j has multiple @f users (unsupported).\n"),
8758 PROMPT_NONE, PR_FATAL },
8760 /* Can't find external journal */
8761 { PR_0_CANT_FIND_JOURNAL,
8762 N_("Can't find external @j\n"),
8763 PROMPT_NONE, PR_FATAL },
8765 /* External journal has bad superblock */
8766 { PR_0_EXT_JOURNAL_BAD_SUPER,
8767 N_("External @j has bad @S\n"),
8768 PROMPT_NONE, PR_FATAL },
8770 /* Superblock has a bad journal UUID */
8771 { PR_0_JOURNAL_BAD_UUID,
8772 N_("External @j does not support this @f\n"),
8773 PROMPT_NONE, PR_FATAL },
8775 /* Journal has an unknown superblock type */
8776 { PR_0_JOURNAL_UNSUPP_SUPER,
8777 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8778 "It is likely that your copy of e2fsck is old and/or doesn't "
8779 "support this @j format.\n"
8780 "It is also possible the @j @S is corrupt.\n"),
8781 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8783 /* Journal superblock is corrupt */
8784 { PR_0_JOURNAL_BAD_SUPER,
8785 N_("Ext3 @j @S is corrupt.\n"),
8786 PROMPT_FIX, PR_PREEN_OK },
8788 /* Superblock flag should be cleared */
8789 { PR_0_JOURNAL_HAS_JOURNAL,
8790 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8791 PROMPT_CLEAR, PR_PREEN_OK },
8793 /* Superblock flag is incorrect */
8794 { PR_0_JOURNAL_RECOVER_SET,
8795 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8796 PROMPT_CLEAR, PR_PREEN_OK },
8798 /* Journal has data, but recovery flag is clear */
8799 { PR_0_JOURNAL_RECOVERY_CLEAR,
8800 N_("ext3 recovery flag is clear, but @j has data.\n"),
8803 /* Ask if we should clear the journal */
8804 { PR_0_JOURNAL_RESET_JOURNAL,
8806 PROMPT_NULL, PR_PREEN_NOMSG },
8808 /* Ask if we should run the journal anyway */
8810 N_("Run @j anyway"),
8813 /* Run the journal by default */
8814 { PR_0_JOURNAL_RUN_DEFAULT,
8815 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8818 /* Clearing orphan inode */
8819 { PR_0_ORPHAN_CLEAR_INODE,
8820 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8823 /* Illegal block found in orphaned inode */
8824 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8825 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8828 /* Already cleared block found in orphaned inode */
8829 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8830 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8833 /* Illegal orphan inode in superblock */
8834 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8835 N_("@I @o @i %i in @S.\n"),
8838 /* Illegal inode in orphaned inode list */
8839 { PR_0_ORPHAN_ILLEGAL_INODE,
8840 N_("@I @i %i in @o @i list.\n"),
8843 /* Filesystem revision is 0, but feature flags are set */
8844 { PR_0_FS_REV_LEVEL,
8845 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8846 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8848 /* Journal superblock has an unknown read-only feature flag set */
8849 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8850 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8853 /* Journal superblock has an unknown incompatible feature flag set */
8854 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8855 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8858 /* Journal has unsupported version number */
8859 { PR_0_JOURNAL_UNSUPP_VERSION,
8860 N_("@j version not supported by this e2fsck.\n"),
8863 /* Moving journal to hidden file */
8864 { PR_0_MOVE_JOURNAL,
8865 N_("Moving @j from /%s to hidden @i.\n\n"),
8868 /* Error moving journal to hidden file */
8869 { PR_0_ERR_MOVE_JOURNAL,
8870 N_("Error moving @j: %m\n\n"),
8873 /* Clearing V2 journal superblock */
8874 { PR_0_CLEAR_V2_JOURNAL,
8875 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8876 "Clearing fields beyond the V1 @j @S...\n\n"),
8879 /* Backup journal inode blocks */
8881 N_("Backing up @j @i @b information.\n\n"),
8884 /* Reserved blocks w/o resize_inode */
8885 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8886 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8887 "is %N; @s zero. "),
8890 /* Resize_inode not enabled, but resize inode is non-zero */
8891 { PR_0_CLEAR_RESIZE_INODE,
8892 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8895 /* Resize inode invalid */
8896 { PR_0_RESIZE_INODE_INVALID,
8897 N_("Resize @i not valid. "),
8898 PROMPT_RECREATE, 0 },
8902 /* Pass 1: Checking inodes, blocks, and sizes */
8904 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8907 /* Root directory is not an inode */
8908 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8911 /* Root directory has dtime set */
8913 N_("@r has dtime set (probably due to old mke2fs). "),
8914 PROMPT_FIX, PR_PREEN_OK },
8916 /* Reserved inode has bad mode */
8917 { PR_1_RESERVED_BAD_MODE,
8918 N_("Reserved @i %i (%Q) has @n mode. "),
8919 PROMPT_CLEAR, PR_PREEN_OK },
8921 /* Deleted inode has zero dtime */
8923 N_("@D @i %i has zero dtime. "),
8924 PROMPT_FIX, PR_PREEN_OK },
8926 /* Inode in use, but dtime set */
8928 N_("@i %i is in use, but has dtime set. "),
8929 PROMPT_FIX, PR_PREEN_OK },
8931 /* Zero-length directory */
8932 { PR_1_ZERO_LENGTH_DIR,
8933 N_("@i %i is a @z @d. "),
8934 PROMPT_CLEAR, PR_PREEN_OK },
8936 /* Block bitmap conflicts with some other fs block */
8938 N_("@g %g's @b @B at %b @C.\n"),
8939 PROMPT_RELOCATE, 0 },
8941 /* Inode bitmap conflicts with some other fs block */
8943 N_("@g %g's @i @B at %b @C.\n"),
8944 PROMPT_RELOCATE, 0 },
8946 /* Inode table conflicts with some other fs block */
8947 { PR_1_ITABLE_CONFLICT,
8948 N_("@g %g's @i table at %b @C.\n"),
8949 PROMPT_RELOCATE, 0 },
8951 /* Block bitmap is on a bad block */
8952 { PR_1_BB_BAD_BLOCK,
8953 N_("@g %g's @b @B (%b) is bad. "),
8954 PROMPT_RELOCATE, 0 },
8956 /* Inode bitmap is on a bad block */
8957 { PR_1_IB_BAD_BLOCK,
8958 N_("@g %g's @i @B (%b) is bad. "),
8959 PROMPT_RELOCATE, 0 },
8961 /* Inode has incorrect i_size */
8963 N_("@i %i, i_size is %Is, @s %N. "),
8964 PROMPT_FIX, PR_PREEN_OK },
8966 /* Inode has incorrect i_blocks */
8967 { PR_1_BAD_I_BLOCKS,
8968 N_("@i %i, i_@bs is %Ib, @s %N. "),
8969 PROMPT_FIX, PR_PREEN_OK },
8971 /* Illegal blocknumber in inode */
8972 { PR_1_ILLEGAL_BLOCK_NUM,
8973 N_("@I @b #%B (%b) in @i %i. "),
8974 PROMPT_CLEAR, PR_LATCH_BLOCK },
8976 /* Block number overlaps fs metadata */
8977 { PR_1_BLOCK_OVERLAPS_METADATA,
8978 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8979 PROMPT_CLEAR, PR_LATCH_BLOCK },
8981 /* Inode has illegal blocks (latch question) */
8982 { PR_1_INODE_BLOCK_LATCH,
8983 N_("@i %i has illegal @b(s). "),
8986 /* Too many bad blocks in inode */
8987 { PR_1_TOO_MANY_BAD_BLOCKS,
8988 N_("Too many illegal @bs in @i %i.\n"),
8989 PROMPT_CLEAR_INODE, PR_NO_OK },
8991 /* Illegal block number in bad block inode */
8992 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8993 N_("@I @b #%B (%b) in bad @b @i. "),
8994 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8996 /* Bad block inode has illegal blocks (latch question) */
8997 { PR_1_INODE_BBLOCK_LATCH,
8998 N_("Bad @b @i has illegal @b(s). "),
9001 /* Duplicate or bad blocks in use! */
9002 { PR_1_DUP_BLOCKS_PREENSTOP,
9003 N_("Duplicate or bad @b in use!\n"),
9006 /* Bad block used as bad block indirect block */
9007 { PR_1_BBINODE_BAD_METABLOCK,
9008 N_("Bad @b %b used as bad @b @i indirect @b. "),
9009 PROMPT_CLEAR, PR_LATCH_BBLOCK },
9011 /* Inconsistency can't be fixed prompt */
9012 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
9013 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
9014 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
9016 PROMPT_CONTINUE, PR_PREEN_NOMSG },
9018 /* Bad primary block */
9019 { PR_1_BAD_PRIMARY_BLOCK,
9020 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
9021 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
9023 /* Bad primary block prompt */
9024 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
9025 N_("You can remove this @b from the bad @b list and hope\n"
9026 "that the @b is really OK. But there are no guarantees.\n\n"),
9027 PROMPT_CLEAR, PR_PREEN_NOMSG },
9029 /* Bad primary superblock */
9030 { PR_1_BAD_PRIMARY_SUPERBLOCK,
9031 N_("The primary @S (%b) is on the bad @b list.\n"),
9032 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9034 /* Bad primary block group descriptors */
9035 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
9036 N_("Block %b in the primary @g descriptors "
9037 "is on the bad @b list\n"),
9038 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
9040 /* Bad superblock in group */
9041 { PR_1_BAD_SUPERBLOCK,
9042 N_("Warning: Group %g's @S (%b) is bad.\n"),
9043 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9045 /* Bad block group descriptors in group */
9046 { PR_1_BAD_GROUP_DESCRIPTORS,
9047 N_("Warning: Group %g's copy of the @g descriptors has a bad "
9049 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9051 /* Block claimed for no reason */
9052 { PR_1_PROGERR_CLAIMED_BLOCK,
9053 N_("Programming error? @b #%b claimed for no reason in "
9054 "process_bad_@b.\n"),
9055 PROMPT_NONE, PR_PREEN_OK },
9057 /* Error allocating blocks for relocating metadata */
9058 { PR_1_RELOC_BLOCK_ALLOCATE,
9059 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
9060 PROMPT_NONE, PR_PREEN_OK },
9062 /* Error allocating block buffer during relocation process */
9063 { PR_1_RELOC_MEMORY_ALLOCATE,
9064 N_("@A @b buffer for relocating %s\n"),
9065 PROMPT_NONE, PR_PREEN_OK },
9067 /* Relocating metadata group information from X to Y */
9068 { PR_1_RELOC_FROM_TO,
9069 N_("Relocating @g %g's %s from %b to %c...\n"),
9070 PROMPT_NONE, PR_PREEN_OK },
9072 /* Relocating metatdata group information to X */
9074 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
9075 PROMPT_NONE, PR_PREEN_OK },
9077 /* Block read error during relocation process */
9078 { PR_1_RELOC_READ_ERR,
9079 N_("Warning: could not read @b %b of %s: %m\n"),
9080 PROMPT_NONE, PR_PREEN_OK },
9082 /* Block write error during relocation process */
9083 { PR_1_RELOC_WRITE_ERR,
9084 N_("Warning: could not write @b %b for %s: %m\n"),
9085 PROMPT_NONE, PR_PREEN_OK },
9087 /* Error allocating inode bitmap */
9088 { PR_1_ALLOCATE_IBITMAP_ERROR,
9089 N_("@A @i @B (%N): %m\n"),
9090 PROMPT_NONE, PR_FATAL },
9092 /* Error allocating block bitmap */
9093 { PR_1_ALLOCATE_BBITMAP_ERROR,
9094 N_("@A @b @B (%N): %m\n"),
9095 PROMPT_NONE, PR_FATAL },
9097 /* Error allocating icount structure */
9098 { PR_1_ALLOCATE_ICOUNT,
9099 N_("@A icount link information: %m\n"),
9100 PROMPT_NONE, PR_FATAL },
9102 /* Error allocating dbcount */
9103 { PR_1_ALLOCATE_DBCOUNT,
9104 N_("@A @d @b array: %m\n"),
9105 PROMPT_NONE, PR_FATAL },
9107 /* Error while scanning inodes */
9109 N_("Error while scanning @is (%i): %m\n"),
9110 PROMPT_NONE, PR_FATAL },
9112 /* Error while iterating over blocks */
9113 { PR_1_BLOCK_ITERATE,
9114 N_("Error while iterating over @bs in @i %i: %m\n"),
9115 PROMPT_NONE, PR_FATAL },
9117 /* Error while storing inode count information */
9118 { PR_1_ICOUNT_STORE,
9119 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
9120 PROMPT_NONE, PR_FATAL },
9122 /* Error while storing directory block information */
9124 N_("Error storing @d @b information "
9125 "(@i=%i, @b=%b, num=%N): %m\n"),
9126 PROMPT_NONE, PR_FATAL },
9128 /* Error while reading inode (for clearing) */
9130 N_("Error reading @i %i: %m\n"),
9131 PROMPT_NONE, PR_FATAL },
9133 /* Suppress messages prompt */
9134 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
9136 /* Imagic flag set on an inode when filesystem doesn't support it */
9138 N_("@i %i has imagic flag set. "),
9141 /* Immutable flag set on a device or socket inode */
9142 { PR_1_SET_IMMUTABLE,
9143 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
9144 "or append-only flag set. "),
9145 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
9147 /* Compression flag set on an inode when filesystem doesn't support it */
9149 N_("@i %i has @cion flag set on @f without @cion support. "),
9152 /* Non-zero size for device, fifo or socket inode */
9153 { PR_1_SET_NONZSIZE,
9154 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
9155 PROMPT_FIX, PR_PREEN_OK },
9157 /* Filesystem revision is 0, but feature flags are set */
9158 { PR_1_FS_REV_LEVEL,
9159 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
9160 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
9162 /* Journal inode is not in use, but contains data */
9163 { PR_1_JOURNAL_INODE_NOT_CLEAR,
9164 N_("@j @i is not in use, but contains data. "),
9165 PROMPT_CLEAR, PR_PREEN_OK },
9167 /* Journal has bad mode */
9168 { PR_1_JOURNAL_BAD_MODE,
9169 N_("@j is not regular file. "),
9170 PROMPT_FIX, PR_PREEN_OK },
9172 /* Deal with inodes that were part of orphan linked list */
9174 N_("@i %i was part of the @o @i list. "),
9175 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
9177 /* Deal with inodes that were part of corrupted orphan linked
9178 list (latch question) */
9179 { PR_1_ORPHAN_LIST_REFUGEES,
9180 N_("@is that were part of a corrupted orphan linked list found. "),
9183 /* Error allocating refcount structure */
9184 { PR_1_ALLOCATE_REFCOUNT,
9185 N_("@A refcount structure (%N): %m\n"),
9186 PROMPT_NONE, PR_FATAL },
9188 /* Error reading extended attribute block */
9189 { PR_1_READ_EA_BLOCK,
9190 N_("Error reading @a @b %b for @i %i. "),
9193 /* Invalid extended attribute block */
9194 { PR_1_BAD_EA_BLOCK,
9195 N_("@i %i has a bad @a @b %b. "),
9198 /* Error reading Extended Attribute block while fixing refcount */
9199 { PR_1_EXTATTR_READ_ABORT,
9200 N_("Error reading @a @b %b (%m). "),
9203 /* Extended attribute reference count incorrect */
9204 { PR_1_EXTATTR_REFCOUNT,
9205 N_("@a @b %b has reference count %B, @s %N. "),
9208 /* Error writing Extended Attribute block while fixing refcount */
9209 { PR_1_EXTATTR_WRITE,
9210 N_("Error writing @a @b %b (%m). "),
9213 /* Multiple EA blocks not supported */
9214 { PR_1_EA_MULTI_BLOCK,
9215 N_("@a @b %b has h_@bs > 1. "),
9218 /* Error allocating EA region allocation structure */
9219 { PR_1_EA_ALLOC_REGION,
9220 N_("@A @a @b %b. "),
9223 /* Error EA allocation collision */
9224 { PR_1_EA_ALLOC_COLLISION,
9225 N_("@a @b %b is corrupt (allocation collision). "),
9228 /* Bad extended attribute name */
9230 N_("@a @b %b is corrupt (@n name). "),
9233 /* Bad extended attribute value */
9234 { PR_1_EA_BAD_VALUE,
9235 N_("@a @b %b is corrupt (@n value). "),
9238 /* Inode too big (latch question) */
9239 { PR_1_INODE_TOOBIG,
9240 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
9242 /* Directory too big */
9244 N_("@b #%B (%b) causes @d to be too big. "),
9245 PROMPT_CLEAR, PR_LATCH_TOOBIG },
9247 /* Regular file too big */
9249 N_("@b #%B (%b) causes file to be too big. "),
9250 PROMPT_CLEAR, PR_LATCH_TOOBIG },
9252 /* Symlink too big */
9253 { PR_1_TOOBIG_SYMLINK,
9254 N_("@b #%B (%b) causes symlink to be too big. "),
9255 PROMPT_CLEAR, PR_LATCH_TOOBIG },
9257 /* INDEX_FL flag set on a non-HTREE filesystem */
9259 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
9260 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9262 /* INDEX_FL flag set on a non-directory */
9264 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
9265 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9267 /* Invalid root node in HTREE directory */
9268 { PR_1_HTREE_BADROOT,
9269 N_("@h %i has an @n root node.\n"),
9270 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9272 /* Unsupported hash version in HTREE directory */
9274 N_("@h %i has an unsupported hash version (%N)\n"),
9275 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9277 /* Incompatible flag in HTREE root node */
9278 { PR_1_HTREE_INCOMPAT,
9279 N_("@h %i uses an incompatible htree root node flag.\n"),
9280 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9282 /* HTREE too deep */
9284 N_("@h %i has a tree depth (%N) which is too big\n"),
9285 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9287 /* Bad block has indirect block that conflicts with filesystem block */
9289 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
9291 PROMPT_CLEAR, PR_LATCH_BBLOCK },
9293 /* Resize inode failed */
9294 { PR_1_RESIZE_INODE_CREATE,
9295 N_("Resize @i (re)creation failed: %m."),
9298 /* invalid inode->i_extra_isize */
9300 N_("@i %i has a extra size (%IS) which is @n\n"),
9301 PROMPT_FIX, PR_PREEN_OK },
9303 /* invalid ea entry->e_name_len */
9304 { PR_1_ATTR_NAME_LEN,
9305 N_("@a in @i %i has a namelen (%N) which is @n\n"),
9306 PROMPT_CLEAR, PR_PREEN_OK },
9308 /* invalid ea entry->e_value_size */
9309 { PR_1_ATTR_VALUE_SIZE,
9310 N_("@a in @i %i has a value size (%N) which is @n\n"),
9311 PROMPT_CLEAR, PR_PREEN_OK },
9313 /* invalid ea entry->e_value_offs */
9314 { PR_1_ATTR_VALUE_OFFSET,
9315 N_("@a in @i %i has a value offset (%N) which is @n\n"),
9316 PROMPT_CLEAR, PR_PREEN_OK },
9318 /* invalid ea entry->e_value_block */
9319 { PR_1_ATTR_VALUE_BLOCK,
9320 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
9321 PROMPT_CLEAR, PR_PREEN_OK },
9323 /* invalid ea entry->e_hash */
9325 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
9326 PROMPT_CLEAR, PR_PREEN_OK },
9328 /* Pass 1b errors */
9330 /* Pass 1B: Rescan for duplicate/bad blocks */
9331 { PR_1B_PASS_HEADER,
9332 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
9333 "Pass 1B: Rescanning for @m @bs\n"),
9336 /* Duplicate/bad block(s) header */
9337 { PR_1B_DUP_BLOCK_HEADER,
9338 N_("@m @b(s) in @i %i:"),
9341 /* Duplicate/bad block(s) in inode */
9344 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
9346 /* Duplicate/bad block(s) end */
9347 { PR_1B_DUP_BLOCK_END,
9349 PROMPT_NONE, PR_PREEN_NOHDR },
9351 /* Error while scanning inodes */
9352 { PR_1B_ISCAN_ERROR,
9353 N_("Error while scanning inodes (%i): %m\n"),
9354 PROMPT_NONE, PR_FATAL },
9356 /* Error allocating inode bitmap */
9357 { PR_1B_ALLOCATE_IBITMAP_ERROR,
9358 N_("@A @i @B (@i_dup_map): %m\n"),
9359 PROMPT_NONE, PR_FATAL },
9361 /* Error while iterating over blocks */
9362 { PR_1B_BLOCK_ITERATE,
9363 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
9366 /* Error adjusting EA refcount */
9367 { PR_1B_ADJ_EA_REFCOUNT,
9368 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9372 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
9373 { PR_1C_PASS_HEADER,
9374 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
9378 /* Pass 1D: Reconciling multiply-claimed blocks */
9379 { PR_1D_PASS_HEADER,
9380 N_("Pass 1D: Reconciling @m @bs\n"),
9383 /* File has duplicate blocks */
9385 N_("File %Q (@i #%i, mod time %IM) \n"
9386 " has %B @m @b(s), shared with %N file(s):\n"),
9389 /* List of files sharing duplicate blocks */
9390 { PR_1D_DUP_FILE_LIST,
9391 N_("\t%Q (@i #%i, mod time %IM)\n"),
9394 /* File sharing blocks with filesystem metadata */
9395 { PR_1D_SHARE_METADATA,
9396 N_("\t<@f metadata>\n"),
9399 /* Report of how many duplicate/bad inodes */
9400 { PR_1D_NUM_DUP_INODES,
9401 N_("(There are %N @is containing @m @bs.)\n\n"),
9404 /* Duplicated blocks already reassigned or cloned. */
9405 { PR_1D_DUP_BLOCKS_DEALT,
9406 N_("@m @bs already reassigned or cloned.\n\n"),
9409 /* Clone duplicate/bad blocks? */
9410 { PR_1D_CLONE_QUESTION,
9411 "", PROMPT_CLONE, PR_NO_OK },
9414 { PR_1D_DELETE_QUESTION,
9415 "", PROMPT_DELETE, 0 },
9417 /* Couldn't clone file (error) */
9418 { PR_1D_CLONE_ERROR,
9419 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
9423 /* Pass 2: Checking directory structure */
9425 N_("Pass 2: Checking @d structure\n"),
9428 /* Bad inode number for '.' */
9429 { PR_2_BAD_INODE_DOT,
9430 N_("@n @i number for '.' in @d @i %i.\n"),
9433 /* Directory entry has bad inode number */
9435 N_("@E has @n @i #: %Di.\n"),
9438 /* Directory entry has deleted or unused inode */
9439 { PR_2_UNUSED_INODE,
9440 N_("@E has @D/unused @i %Di. "),
9441 PROMPT_CLEAR, PR_PREEN_OK },
9443 /* Directry entry is link to '.' */
9445 N_("@E @L to '.' "),
9448 /* Directory entry points to inode now located in a bad block */
9450 N_("@E points to @i (%Di) located in a bad @b.\n"),
9453 /* Directory entry contains a link to a directory */
9455 N_("@E @L to @d %P (%Di).\n"),
9458 /* Directory entry contains a link to the root directry */
9460 N_("@E @L to the @r.\n"),
9463 /* Directory entry has illegal characters in its name */
9465 N_("@E has illegal characters in its name.\n"),
9468 /* Missing '.' in directory inode */
9470 N_("Missing '.' in @d @i %i.\n"),
9473 /* Missing '..' in directory inode */
9474 { PR_2_MISSING_DOT_DOT,
9475 N_("Missing '..' in @d @i %i.\n"),
9478 /* First entry in directory inode doesn't contain '.' */
9480 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9483 /* Second entry in directory inode doesn't contain '..' */
9484 { PR_2_2ND_NOT_DOT_DOT,
9485 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9488 /* i_faddr should be zero */
9490 N_("i_faddr @F %IF, @s zero.\n"),
9493 /* i_file_acl should be zero */
9494 { PR_2_FILE_ACL_ZERO,
9495 N_("i_file_acl @F %If, @s zero.\n"),
9498 /* i_dir_acl should be zero */
9499 { PR_2_DIR_ACL_ZERO,
9500 N_("i_dir_acl @F %Id, @s zero.\n"),
9503 /* i_frag should be zero */
9505 N_("i_frag @F %N, @s zero.\n"),
9508 /* i_fsize should be zero */
9510 N_("i_fsize @F %N, @s zero.\n"),
9513 /* inode has bad mode */
9515 N_("@i %i (%Q) has @n mode (%Im).\n"),
9518 /* directory corrupted */
9519 { PR_2_DIR_CORRUPTED,
9520 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9521 PROMPT_SALVAGE, 0 },
9523 /* filename too long */
9524 { PR_2_FILENAME_LONG,
9525 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9526 PROMPT_TRUNCATE, 0 },
9528 /* Directory inode has a missing block (hole) */
9529 { PR_2_DIRECTORY_HOLE,
9530 N_("@d @i %i has an unallocated @b #%B. "),
9531 PROMPT_ALLOCATE, 0 },
9533 /* '.' is not NULL terminated */
9534 { PR_2_DOT_NULL_TERM,
9535 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9538 /* '..' is not NULL terminated */
9539 { PR_2_DOT_DOT_NULL_TERM,
9540 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9543 /* Illegal character device inode */
9544 { PR_2_BAD_CHAR_DEV,
9545 N_("@i %i (%Q) is an @I character @v.\n"),
9548 /* Illegal block device inode */
9549 { PR_2_BAD_BLOCK_DEV,
9550 N_("@i %i (%Q) is an @I @b @v.\n"),
9553 /* Duplicate '.' entry */
9555 N_("@E is duplicate '.' @e.\n"),
9558 /* Duplicate '..' entry */
9560 N_("@E is duplicate '..' @e.\n"),
9563 /* Internal error: couldn't find dir_info */
9565 N_("Internal error: couldn't find dir_info for %i.\n"),
9566 PROMPT_NONE, PR_FATAL },
9568 /* Final rec_len is wrong */
9569 { PR_2_FINAL_RECLEN,
9570 N_("@E has rec_len of %Dr, @s %N.\n"),
9573 /* Error allocating icount structure */
9574 { PR_2_ALLOCATE_ICOUNT,
9575 N_("@A icount structure: %m\n"),
9576 PROMPT_NONE, PR_FATAL },
9578 /* Error iterating over directory blocks */
9579 { PR_2_DBLIST_ITERATE,
9580 N_("Error iterating over @d @bs: %m\n"),
9581 PROMPT_NONE, PR_FATAL },
9583 /* Error reading directory block */
9584 { PR_2_READ_DIRBLOCK,
9585 N_("Error reading @d @b %b (@i %i): %m\n"),
9586 PROMPT_CONTINUE, 0 },
9588 /* Error writing directory block */
9589 { PR_2_WRITE_DIRBLOCK,
9590 N_("Error writing @d @b %b (@i %i): %m\n"),
9591 PROMPT_CONTINUE, 0 },
9593 /* Error allocating new directory block */
9594 { PR_2_ALLOC_DIRBOCK,
9595 N_("@A new @d @b for @i %i (%s): %m\n"),
9598 /* Error deallocating inode */
9599 { PR_2_DEALLOC_INODE,
9600 N_("Error deallocating @i %i: %m\n"),
9601 PROMPT_NONE, PR_FATAL },
9603 /* Directory entry for '.' is big. Split? */
9605 N_("@d @e for '.' is big. "),
9606 PROMPT_SPLIT, PR_NO_OK },
9608 /* Illegal FIFO inode */
9610 N_("@i %i (%Q) is an @I FIFO.\n"),
9613 /* Illegal socket inode */
9615 N_("@i %i (%Q) is an @I socket.\n"),
9618 /* Directory filetype not set */
9619 { PR_2_SET_FILETYPE,
9620 N_("Setting filetype for @E to %N.\n"),
9621 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9623 /* Directory filetype incorrect */
9624 { PR_2_BAD_FILETYPE,
9625 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9628 /* Directory filetype set on filesystem */
9629 { PR_2_CLEAR_FILETYPE,
9630 N_("@E has filetype set.\n"),
9631 PROMPT_CLEAR, PR_PREEN_OK },
9633 /* Directory filename is null */
9635 N_("@E has a @z name.\n"),
9638 /* Invalid symlink */
9639 { PR_2_INVALID_SYMLINK,
9640 N_("Symlink %Q (@i #%i) is @n.\n"),
9643 /* i_file_acl (extended attribute block) is bad */
9644 { PR_2_FILE_ACL_BAD,
9645 N_("@a @b @F @n (%If).\n"),
9648 /* Filesystem contains large files, but has no such flag in sb */
9649 { PR_2_FEATURE_LARGE_FILES,
9650 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9653 /* Node in HTREE directory not referenced */
9654 { PR_2_HTREE_NOTREF,
9655 N_("@p @h %d: node (%B) not referenced\n"),
9658 /* Node in HTREE directory referenced twice */
9659 { PR_2_HTREE_DUPREF,
9660 N_("@p @h %d: node (%B) referenced twice\n"),
9663 /* Node in HTREE directory has bad min hash */
9664 { PR_2_HTREE_MIN_HASH,
9665 N_("@p @h %d: node (%B) has bad min hash\n"),
9668 /* Node in HTREE directory has bad max hash */
9669 { PR_2_HTREE_MAX_HASH,
9670 N_("@p @h %d: node (%B) has bad max hash\n"),
9673 /* Clear invalid HTREE directory */
9675 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9677 /* Bad block in htree interior node */
9678 { PR_2_HTREE_BADBLK,
9679 N_("@p @h %d (%q): bad @b number %b.\n"),
9680 PROMPT_CLEAR_HTREE, 0 },
9682 /* Error adjusting EA refcount */
9683 { PR_2_ADJ_EA_REFCOUNT,
9684 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9685 PROMPT_NONE, PR_FATAL },
9687 /* Invalid HTREE root node */
9688 { PR_2_HTREE_BAD_ROOT,
9689 N_("@p @h %d: root node is @n\n"),
9690 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9692 /* Invalid HTREE limit */
9693 { PR_2_HTREE_BAD_LIMIT,
9694 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9695 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9697 /* Invalid HTREE count */
9698 { PR_2_HTREE_BAD_COUNT,
9699 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9700 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9702 /* HTREE interior node has out-of-order hashes in table */
9703 { PR_2_HTREE_HASH_ORDER,
9704 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9705 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9707 /* Node in HTREE directory has invalid depth */
9708 { PR_2_HTREE_BAD_DEPTH,
9709 N_("@p @h %d: node (%B) has @n depth\n"),
9712 /* Duplicate directory entry found */
9713 { PR_2_DUPLICATE_DIRENT,
9714 N_("Duplicate @E found. "),
9717 /* Non-unique filename found */
9718 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9719 N_("@E has a non-unique filename.\nRename to %s"),
9722 /* Duplicate directory entry found */
9723 { PR_2_REPORT_DUP_DIRENT,
9724 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9729 /* Pass 3: Checking directory connectivity */
9731 N_("Pass 3: Checking @d connectivity\n"),
9734 /* Root inode not allocated */
9735 { PR_3_NO_ROOT_INODE,
9736 N_("@r not allocated. "),
9737 PROMPT_ALLOCATE, 0 },
9739 /* No room in lost+found */
9740 { PR_3_EXPAND_LF_DIR,
9741 N_("No room in @l @d. "),
9744 /* Unconnected directory inode */
9745 { PR_3_UNCONNECTED_DIR,
9746 N_("Unconnected @d @i %i (%p)\n"),
9747 PROMPT_CONNECT, 0 },
9749 /* /lost+found not found */
9751 N_("/@l not found. "),
9752 PROMPT_CREATE, PR_PREEN_OK },
9754 /* .. entry is incorrect */
9756 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9759 /* Bad or non-existent /lost+found. Cannot reconnect */
9761 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9764 /* Could not expand /lost+found */
9765 { PR_3_CANT_EXPAND_LPF,
9766 N_("Could not expand /@l: %m\n"),
9769 /* Could not reconnect inode */
9770 { PR_3_CANT_RECONNECT,
9771 N_("Could not reconnect %i: %m\n"),
9774 /* Error while trying to find /lost+found */
9775 { PR_3_ERR_FIND_LPF,
9776 N_("Error while trying to find /@l: %m\n"),
9779 /* Error in ext2fs_new_block while creating /lost+found */
9780 { PR_3_ERR_LPF_NEW_BLOCK,
9781 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9784 /* Error in ext2fs_new_inode while creating /lost+found */
9785 { PR_3_ERR_LPF_NEW_INODE,
9786 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9789 /* Error in ext2fs_new_dir_block while creating /lost+found */
9790 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9791 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9794 /* Error while writing directory block for /lost+found */
9795 { PR_3_ERR_LPF_WRITE_BLOCK,
9796 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9799 /* Error while adjusting inode count */
9800 { PR_3_ADJUST_INODE,
9801 N_("Error while adjusting @i count on @i %i\n"),
9804 /* Couldn't fix parent directory -- error */
9805 { PR_3_FIX_PARENT_ERR,
9806 N_("Couldn't fix parent of @i %i: %m\n\n"),
9809 /* Couldn't fix parent directory -- couldn't find it */
9810 { PR_3_FIX_PARENT_NOFIND,
9811 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9814 /* Error allocating inode bitmap */
9815 { PR_3_ALLOCATE_IBITMAP_ERROR,
9816 N_("@A @i @B (%N): %m\n"),
9817 PROMPT_NONE, PR_FATAL },
9819 /* Error creating root directory */
9820 { PR_3_CREATE_ROOT_ERROR,
9821 N_("Error creating root @d (%s): %m\n"),
9822 PROMPT_NONE, PR_FATAL },
9824 /* Error creating lost and found directory */
9825 { PR_3_CREATE_LPF_ERROR,
9826 N_("Error creating /@l @d (%s): %m\n"),
9827 PROMPT_NONE, PR_FATAL },
9829 /* Root inode is not directory; aborting */
9830 { PR_3_ROOT_NOT_DIR_ABORT,
9831 N_("@r is not a @d; aborting.\n"),
9832 PROMPT_NONE, PR_FATAL },
9834 /* Cannot proceed without a root inode. */
9835 { PR_3_NO_ROOT_INODE_ABORT,
9836 N_("Cannot proceed without a @r.\n"),
9837 PROMPT_NONE, PR_FATAL },
9839 /* Internal error: couldn't find dir_info */
9841 N_("Internal error: couldn't find dir_info for %i.\n"),
9842 PROMPT_NONE, PR_FATAL },
9844 /* Lost+found not a directory */
9846 N_("/@l is not a @d (ino=%i)\n"),
9849 /* Pass 3A Directory Optimization */
9851 /* Pass 3A: Optimizing directories */
9852 { PR_3A_PASS_HEADER,
9853 N_("Pass 3A: Optimizing directories\n"),
9854 PROMPT_NONE, PR_PREEN_NOMSG },
9856 /* Error iterating over directories */
9857 { PR_3A_OPTIMIZE_ITER,
9858 N_("Failed to create dirs_to_hash iterator: %m"),
9861 /* Error rehash directory */
9862 { PR_3A_OPTIMIZE_DIR_ERR,
9863 N_("Failed to optimize directory %q (%d): %m"),
9866 /* Rehashing dir header */
9867 { PR_3A_OPTIMIZE_DIR_HEADER,
9868 N_("Optimizing directories: "),
9869 PROMPT_NONE, PR_MSG_ONLY },
9871 /* Rehashing directory %d */
9872 { PR_3A_OPTIMIZE_DIR,
9874 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9876 /* Rehashing dir end */
9877 { PR_3A_OPTIMIZE_DIR_END,
9879 PROMPT_NONE, PR_PREEN_NOHDR },
9883 /* Pass 4: Checking reference counts */
9885 N_("Pass 4: Checking reference counts\n"),
9888 /* Unattached zero-length inode */
9889 { PR_4_ZERO_LEN_INODE,
9890 N_("@u @z @i %i. "),
9891 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9893 /* Unattached inode */
9894 { PR_4_UNATTACHED_INODE,
9896 PROMPT_CONNECT, 0 },
9898 /* Inode ref count wrong */
9899 { PR_4_BAD_REF_COUNT,
9900 N_("@i %i ref count is %Il, @s %N. "),
9901 PROMPT_FIX, PR_PREEN_OK },
9903 { PR_4_INCONSISTENT_COUNT,
9904 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9905 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9906 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9907 "They @s the same!\n"),
9912 /* Pass 5: Checking group summary information */
9914 N_("Pass 5: Checking @g summary information\n"),
9917 /* Padding at end of inode bitmap is not set. */
9918 { PR_5_INODE_BMAP_PADDING,
9919 N_("Padding at end of @i @B is not set. "),
9920 PROMPT_FIX, PR_PREEN_OK },
9922 /* Padding at end of block bitmap is not set. */
9923 { PR_5_BLOCK_BMAP_PADDING,
9924 N_("Padding at end of @b @B is not set. "),
9925 PROMPT_FIX, PR_PREEN_OK },
9927 /* Block bitmap differences header */
9928 { PR_5_BLOCK_BITMAP_HEADER,
9929 N_("@b @B differences: "),
9930 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9932 /* Block not used, but marked in bitmap */
9933 { PR_5_BLOCK_UNUSED,
9935 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9937 /* Block used, but not marked used in bitmap */
9940 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9942 /* Block bitmap differences end */
9943 { PR_5_BLOCK_BITMAP_END,
9945 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9947 /* Inode bitmap differences header */
9948 { PR_5_INODE_BITMAP_HEADER,
9949 N_("@i @B differences: "),
9950 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9952 /* Inode not used, but marked in bitmap */
9953 { PR_5_INODE_UNUSED,
9955 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9957 /* Inode used, but not marked used in bitmap */
9960 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9962 /* Inode bitmap differences end */
9963 { PR_5_INODE_BITMAP_END,
9965 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9967 /* Free inodes count for group wrong */
9968 { PR_5_FREE_INODE_COUNT_GROUP,
9969 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9970 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9972 /* Directories count for group wrong */
9973 { PR_5_FREE_DIR_COUNT_GROUP,
9974 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9975 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9977 /* Free inodes count wrong */
9978 { PR_5_FREE_INODE_COUNT,
9979 N_("Free @is count wrong (%i, counted=%j).\n"),
9980 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9982 /* Free blocks count for group wrong */
9983 { PR_5_FREE_BLOCK_COUNT_GROUP,
9984 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9985 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9987 /* Free blocks count wrong */
9988 { PR_5_FREE_BLOCK_COUNT,
9989 N_("Free @bs count wrong (%b, counted=%c).\n"),
9990 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9992 /* Programming error: bitmap endpoints don't match */
9993 { PR_5_BMAP_ENDPOINTS,
9994 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9995 "match calculated @B endpoints (%i, %j)\n"),
9996 PROMPT_NONE, PR_FATAL },
9998 /* Internal error: fudging end of bitmap */
9999 { PR_5_FUDGE_BITMAP_ERROR,
10000 N_("Internal error: fudging end of bitmap (%N)\n"),
10001 PROMPT_NONE, PR_FATAL },
10003 /* Error copying in replacement inode bitmap */
10004 { PR_5_COPY_IBITMAP_ERROR,
10005 N_("Error copying in replacement @i @B: %m\n"),
10006 PROMPT_NONE, PR_FATAL },
10008 /* Error copying in replacement block bitmap */
10009 { PR_5_COPY_BBITMAP_ERROR,
10010 N_("Error copying in replacement @b @B: %m\n"),
10011 PROMPT_NONE, PR_FATAL },
10013 /* Block range not used, but marked in bitmap */
10014 { PR_5_BLOCK_RANGE_UNUSED,
10016 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10018 /* Block range used, but not marked used in bitmap */
10019 { PR_5_BLOCK_RANGE_USED,
10021 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10023 /* Inode range not used, but marked in bitmap */
10024 { PR_5_INODE_RANGE_UNUSED,
10026 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10028 /* Inode range used, but not marked used in bitmap */
10029 { PR_5_INODE_RANGE_USED,
10031 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
10037 * This is the latch flags register. It allows several problems to be
10038 * "latched" together. This means that the user has to answer but one
10039 * question for the set of problems, and all of the associated
10040 * problems will be either fixed or not fixed.
10042 static struct latch_descr pr_latch_info[] = {
10043 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
10044 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
10045 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
10046 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
10047 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
10048 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
10049 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
10050 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
10051 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
10055 static const struct e2fsck_problem *find_problem(problem_t code)
10059 for (i=0; problem_table[i].e2p_code; i++) {
10060 if (problem_table[i].e2p_code == code)
10061 return &problem_table[i];
10066 static struct latch_descr *find_latch(int code)
10070 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
10071 if (pr_latch_info[i].latch_code == code)
10072 return &pr_latch_info[i];
10077 int end_problem_latch(e2fsck_t ctx, int mask)
10079 struct latch_descr *ldesc;
10080 struct problem_context pctx;
10083 ldesc = find_latch(mask);
10084 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
10085 clear_problem_context(&pctx);
10086 answer = fix_problem(ctx, ldesc->end_message, &pctx);
10088 ldesc->flags &= ~(PRL_VARIABLE);
10092 int set_latch_flags(int mask, int setflags, int clearflags)
10094 struct latch_descr *ldesc;
10096 ldesc = find_latch(mask);
10099 ldesc->flags |= setflags;
10100 ldesc->flags &= ~clearflags;
10104 void clear_problem_context(struct problem_context *ctx)
10106 memset(ctx, 0, sizeof(struct problem_context));
10107 ctx->blkcount = -1;
10111 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
10113 ext2_filsys fs = ctx->fs;
10114 const struct e2fsck_problem *ptr;
10115 struct latch_descr *ldesc = 0;
10116 const char *message;
10117 int def_yn, answer, ans;
10118 int print_answer = 0;
10121 ptr = find_problem(code);
10123 printf(_("Unhandled error code (0x%x)!\n"), code);
10127 if ((ptr->flags & PR_NO_DEFAULT) ||
10128 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
10129 (ctx->options & E2F_OPT_NO))
10133 * Do special latch processing. This is where we ask the
10134 * latch question, if it exists
10136 if (ptr->flags & PR_LATCH_MASK) {
10137 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
10138 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
10139 ans = fix_problem(ctx, ldesc->question, pctx);
10141 ldesc->flags |= PRL_YES;
10143 ldesc->flags |= PRL_NO;
10144 ldesc->flags |= PRL_LATCHED;
10146 if (ldesc->flags & PRL_SUPPRESS)
10149 if ((ptr->flags & PR_PREEN_NOMSG) &&
10150 (ctx->options & E2F_OPT_PREEN))
10152 if ((ptr->flags & PR_NO_NOMSG) &&
10153 (ctx->options & E2F_OPT_NO))
10156 message = ptr->e2p_description;
10157 if ((ctx->options & E2F_OPT_PREEN) &&
10158 !(ptr->flags & PR_PREEN_NOHDR)) {
10159 printf("%s: ", ctx->device_name ?
10160 ctx->device_name : ctx->filesystem_name);
10163 print_e2fsck_message(ctx, _(message), pctx, 1);
10165 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
10168 if (ptr->flags & PR_FATAL)
10169 fatal_error(ctx, 0);
10171 if (ptr->prompt == PROMPT_NONE) {
10172 if (ptr->flags & PR_NOCOLLATE)
10177 if (ctx->options & E2F_OPT_PREEN) {
10179 if (!(ptr->flags & PR_PREEN_NOMSG))
10181 } else if ((ptr->flags & PR_LATCH_MASK) &&
10182 (ldesc->flags & (PRL_YES | PRL_NO))) {
10185 if (ldesc->flags & PRL_YES)
10190 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
10191 if (!answer && !(ptr->flags & PR_NO_OK))
10192 ext2fs_unmark_valid(fs);
10195 printf("%s.\n", answer ?
10196 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
10200 if ((ptr->prompt == PROMPT_ABORT) && answer)
10201 fatal_error(ctx, 0);
10203 if (ptr->flags & PR_AFTER_CODE)
10204 answer = fix_problem(ctx, ptr->second_code, pctx);
10210 * linux/fs/recovery.c
10212 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
10216 * Maintain information about the progress of the recovery job, so that
10217 * the different passes can carry information between them.
10219 struct recovery_info
10221 tid_t start_transaction;
10222 tid_t end_transaction;
10226 int nr_revoke_hits;
10229 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
10230 static int do_one_pass(journal_t *journal,
10231 struct recovery_info *info, enum passtype pass);
10232 static int scan_revoke_records(journal_t *, struct buffer_head *,
10233 tid_t, struct recovery_info *);
10236 * Read a block from the journal
10239 static int jread(struct buffer_head **bhp, journal_t *journal,
10240 unsigned int offset)
10243 unsigned long blocknr;
10244 struct buffer_head *bh;
10248 err = journal_bmap(journal, offset, &blocknr);
10251 printf ("JBD: bad block at offset %u\n", offset);
10255 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
10259 if (!buffer_uptodate(bh)) {
10260 /* If this is a brand new buffer, start readahead.
10261 Otherwise, we assume we are already reading it. */
10262 if (!buffer_req(bh))
10263 do_readahead(journal, offset);
10264 wait_on_buffer(bh);
10267 if (!buffer_uptodate(bh)) {
10268 printf ("JBD: Failed to read block at offset %u\n", offset);
10279 * Count the number of in-use tags in a journal descriptor block.
10282 static int count_tags(struct buffer_head *bh, int size)
10285 journal_block_tag_t * tag;
10288 tagp = &bh->b_data[sizeof(journal_header_t)];
10290 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
10291 tag = (journal_block_tag_t *) tagp;
10294 tagp += sizeof(journal_block_tag_t);
10295 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
10298 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
10306 /* Make sure we wrap around the log correctly! */
10307 #define wrap(journal, var) \
10309 if (var >= (journal)->j_last) \
10310 var -= ((journal)->j_last - (journal)->j_first); \
10314 * int journal_recover(journal_t *journal) - recovers a on-disk journal
10315 * @journal: the journal to recover
10317 * The primary function for recovering the log contents when mounting a
10318 * journaled device.
10320 * Recovery is done in three passes. In the first pass, we look for the
10321 * end of the log. In the second, we assemble the list of revoke
10322 * blocks. In the third and final pass, we replay any un-revoked blocks
10325 int journal_recover(journal_t *journal)
10328 journal_superblock_t * sb;
10330 struct recovery_info info;
10332 memset(&info, 0, sizeof(info));
10333 sb = journal->j_superblock;
10336 * The journal superblock's s_start field (the current log head)
10337 * is always zero if, and only if, the journal was cleanly
10341 if (!sb->s_start) {
10342 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
10346 err = do_one_pass(journal, &info, PASS_SCAN);
10348 err = do_one_pass(journal, &info, PASS_REVOKE);
10350 err = do_one_pass(journal, &info, PASS_REPLAY);
10352 /* Restart the log at the next transaction ID, thus invalidating
10353 * any existing commit records in the log. */
10354 journal->j_transaction_sequence = ++info.end_transaction;
10356 journal_clear_revoke(journal);
10357 sync_blockdev(journal->j_fs_dev);
10361 static int do_one_pass(journal_t *journal,
10362 struct recovery_info *info, enum passtype pass)
10364 unsigned int first_commit_ID, next_commit_ID;
10365 unsigned long next_log_block;
10366 int err, success = 0;
10367 journal_superblock_t * sb;
10368 journal_header_t * tmp;
10369 struct buffer_head * bh;
10370 unsigned int sequence;
10373 /* Precompute the maximum metadata descriptors in a descriptor block */
10374 int MAX_BLOCKS_PER_DESC;
10375 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
10376 / sizeof(journal_block_tag_t));
10379 * First thing is to establish what we expect to find in the log
10380 * (in terms of transaction IDs), and where (in terms of log
10381 * block offsets): query the superblock.
10384 sb = journal->j_superblock;
10385 next_commit_ID = ntohl(sb->s_sequence);
10386 next_log_block = ntohl(sb->s_start);
10388 first_commit_ID = next_commit_ID;
10389 if (pass == PASS_SCAN)
10390 info->start_transaction = first_commit_ID;
10393 * Now we walk through the log, transaction by transaction,
10394 * making sure that each transaction has a commit block in the
10395 * expected place. Each complete transaction gets replayed back
10396 * into the main filesystem.
10402 journal_block_tag_t * tag;
10403 struct buffer_head * obh;
10404 struct buffer_head * nbh;
10406 /* If we already know where to stop the log traversal,
10407 * check right now that we haven't gone past the end of
10410 if (pass != PASS_SCAN)
10411 if (tid_geq(next_commit_ID, info->end_transaction))
10414 /* Skip over each chunk of the transaction looking
10415 * either the next descriptor block or the final commit
10418 err = jread(&bh, journal, next_log_block);
10423 wrap(journal, next_log_block);
10425 /* What kind of buffer is it?
10427 * If it is a descriptor block, check that it has the
10428 * expected sequence number. Otherwise, we're all done
10431 tmp = (journal_header_t *)bh->b_data;
10433 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10438 blocktype = ntohl(tmp->h_blocktype);
10439 sequence = ntohl(tmp->h_sequence);
10441 if (sequence != next_commit_ID) {
10446 /* OK, we have a valid descriptor block which matches
10447 * all of the sequence number checks. What are we going
10448 * to do with it? That depends on the pass... */
10450 switch(blocktype) {
10451 case JFS_DESCRIPTOR_BLOCK:
10452 /* If it is a valid descriptor block, replay it
10453 * in pass REPLAY; otherwise, just skip over the
10454 * blocks it describes. */
10455 if (pass != PASS_REPLAY) {
10457 count_tags(bh, journal->j_blocksize);
10458 wrap(journal, next_log_block);
10463 /* A descriptor block: we can now write all of
10464 * the data blocks. Yay, useful work is finally
10465 * getting done here! */
10467 tagp = &bh->b_data[sizeof(journal_header_t)];
10468 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10469 <= journal->j_blocksize) {
10470 unsigned long io_block;
10472 tag = (journal_block_tag_t *) tagp;
10473 flags = ntohl(tag->t_flags);
10475 io_block = next_log_block++;
10476 wrap(journal, next_log_block);
10477 err = jread(&obh, journal, io_block);
10479 /* Recover what we can, but
10480 * report failure at the end. */
10482 printf ("JBD: IO error %d recovering "
10483 "block %ld in log\n",
10486 unsigned long blocknr;
10488 blocknr = ntohl(tag->t_blocknr);
10490 /* If the block has been
10491 * revoked, then we're all done
10493 if (journal_test_revoke
10497 ++info->nr_revoke_hits;
10501 /* Find a buffer for the new
10502 * data being restored */
10503 nbh = getblk(journal->j_fs_dev,
10505 journal->j_blocksize);
10507 printf ("JBD: Out of memory "
10508 "during recovery.\n");
10516 memcpy(nbh->b_data, obh->b_data,
10517 journal->j_blocksize);
10518 if (flags & JFS_FLAG_ESCAPE) {
10519 *((unsigned int *)bh->b_data) =
10520 htonl(JFS_MAGIC_NUMBER);
10523 mark_buffer_uptodate(nbh, 1);
10524 mark_buffer_dirty(nbh);
10525 ++info->nr_replays;
10526 /* ll_rw_block(WRITE, 1, &nbh); */
10527 unlock_buffer(nbh);
10533 tagp += sizeof(journal_block_tag_t);
10534 if (!(flags & JFS_FLAG_SAME_UUID))
10537 if (flags & JFS_FLAG_LAST_TAG)
10544 case JFS_COMMIT_BLOCK:
10545 /* Found an expected commit block: not much to
10546 * do other than move on to the next sequence
10552 case JFS_REVOKE_BLOCK:
10553 /* If we aren't in the REVOKE pass, then we can
10554 * just skip over this block. */
10555 if (pass != PASS_REVOKE) {
10560 err = scan_revoke_records(journal, bh,
10561 next_commit_ID, info);
10574 * We broke out of the log scan loop: either we came to the
10575 * known end of the log or we found an unexpected block in the
10576 * log. If the latter happened, then we know that the "current"
10577 * transaction marks the end of the valid log.
10580 if (pass == PASS_SCAN)
10581 info->end_transaction = next_commit_ID;
10583 /* It's really bad news if different passes end up at
10584 * different places (but possible due to IO errors). */
10585 if (info->end_transaction != next_commit_ID) {
10586 printf ("JBD: recovery pass %d ended at "
10587 "transaction %u, expected %u\n",
10588 pass, next_commit_ID, info->end_transaction);
10601 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10603 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10604 tid_t sequence, struct recovery_info *info)
10606 journal_revoke_header_t *header;
10609 header = (journal_revoke_header_t *) bh->b_data;
10610 offset = sizeof(journal_revoke_header_t);
10611 max = ntohl(header->r_count);
10613 while (offset < max) {
10614 unsigned long blocknr;
10617 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10619 err = journal_set_revoke(journal, blocknr, sequence);
10622 ++info->nr_revokes;
10629 * rehash.c --- rebuild hash tree directories
10631 * This algorithm is designed for simplicity of implementation and to
10632 * pack the directory as much as possible. It however requires twice
10633 * as much memory as the size of the directory. The maximum size
10634 * directory supported using a 4k blocksize is roughly a gigabyte, and
10635 * so there may very well be problems with machines that don't have
10636 * virtual memory, and obscenely large directories.
10638 * An alternate algorithm which is much more disk intensive could be
10639 * written, and probably will need to be written in the future. The
10640 * design goals of such an algorithm are: (a) use (roughly) constant
10641 * amounts of memory, no matter how large the directory, (b) the
10642 * directory must be safe at all times, even if e2fsck is interrupted
10643 * in the middle, (c) we must use minimal amounts of extra disk
10644 * blocks. This pretty much requires an incremental approach, where
10645 * we are reading from one part of the directory, and inserting into
10646 * the front half. So the algorithm will have to keep track of a
10647 * moving block boundary between the new tree and the old tree, and
10648 * files will need to be moved from the old directory and inserted
10649 * into the new tree. If the new directory requires space which isn't
10650 * yet available, blocks from the beginning part of the old directory
10651 * may need to be moved to the end of the directory to make room for
10654 * --------------------------------------------------------
10655 * | new tree | | old tree |
10656 * --------------------------------------------------------
10658 * tail new head old
10660 * This is going to be a pain in the tuckus to implement, and will
10661 * require a lot more disk accesses. So I'm going to skip it for now;
10662 * it's only really going to be an issue for really, really big
10663 * filesystems (when we reach the level of tens of millions of files
10664 * in a single directory). It will probably be easier to simply
10665 * require that e2fsck use VM first.
10668 struct fill_dir_struct {
10670 struct ext2_inode *inode;
10673 struct hash_entry *harray;
10674 int max_array, num_array;
10680 struct hash_entry {
10681 ext2_dirhash_t hash;
10682 ext2_dirhash_t minor_hash;
10683 struct ext2_dir_entry *dir;
10690 ext2_dirhash_t *hashes;
10693 static int fill_dir_block(ext2_filsys fs,
10695 e2_blkcnt_t blockcnt,
10696 blk_t ref_block FSCK_ATTR((unused)),
10697 int ref_offset FSCK_ATTR((unused)),
10700 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10701 struct hash_entry *new_array, *ent;
10702 struct ext2_dir_entry *dirent;
10704 unsigned int offset, dir_offset;
10709 offset = blockcnt * fs->blocksize;
10710 if (offset + fs->blocksize > fd->inode->i_size) {
10711 fd->err = EXT2_ET_DIR_CORRUPTED;
10712 return BLOCK_ABORT;
10714 dir = (fd->buf+offset);
10715 if (HOLE_BLKADDR(*block_nr)) {
10716 memset(dir, 0, fs->blocksize);
10717 dirent = (struct ext2_dir_entry *) dir;
10718 dirent->rec_len = fs->blocksize;
10720 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10722 return BLOCK_ABORT;
10724 /* While the directory block is "hot", index it. */
10726 while (dir_offset < fs->blocksize) {
10727 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10728 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10729 (dirent->rec_len < 8) ||
10730 ((dirent->rec_len % 4) != 0) ||
10731 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10732 fd->err = EXT2_ET_DIR_CORRUPTED;
10733 return BLOCK_ABORT;
10735 dir_offset += dirent->rec_len;
10736 if (dirent->inode == 0)
10738 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10739 (dirent->name[0] == '.'))
10741 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10742 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10743 fd->parent = dirent->inode;
10746 if (fd->num_array >= fd->max_array) {
10747 new_array = realloc(fd->harray,
10748 sizeof(struct hash_entry) * (fd->max_array+500));
10751 return BLOCK_ABORT;
10753 fd->harray = new_array;
10754 fd->max_array += 500;
10756 ent = fd->harray + fd->num_array++;
10758 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10760 ent->hash = ent->minor_hash = 0;
10762 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10764 dirent->name_len & 0xFF,
10765 fs->super->s_hash_seed,
10766 &ent->hash, &ent->minor_hash);
10768 return BLOCK_ABORT;
10775 /* Used for sorting the hash entry */
10776 static EXT2_QSORT_TYPE name_cmp(const void *a, const void *b)
10778 const struct hash_entry *he_a = (const struct hash_entry *) a;
10779 const struct hash_entry *he_b = (const struct hash_entry *) b;
10783 min_len = he_a->dir->name_len;
10784 if (min_len > he_b->dir->name_len)
10785 min_len = he_b->dir->name_len;
10787 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10789 if (he_a->dir->name_len > he_b->dir->name_len)
10791 else if (he_a->dir->name_len < he_b->dir->name_len)
10794 ret = he_b->dir->inode - he_a->dir->inode;
10799 /* Used for sorting the hash entry */
10800 static EXT2_QSORT_TYPE hash_cmp(const void *a, const void *b)
10802 const struct hash_entry *he_a = (const struct hash_entry *) a;
10803 const struct hash_entry *he_b = (const struct hash_entry *) b;
10806 if (he_a->hash > he_b->hash)
10808 else if (he_a->hash < he_b->hash)
10811 if (he_a->minor_hash > he_b->minor_hash)
10813 else if (he_a->minor_hash < he_b->minor_hash)
10816 ret = name_cmp(a, b);
10821 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10827 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10830 outdir->buf = new_mem;
10831 new_mem = realloc(outdir->hashes,
10832 blocks * sizeof(ext2_dirhash_t));
10835 outdir->hashes = new_mem;
10837 outdir->buf = malloc(blocks * fs->blocksize);
10838 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10841 outdir->max = blocks;
10845 static void free_out_dir(struct out_dir *outdir)
10848 free(outdir->hashes);
10853 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10858 if (outdir->num >= outdir->max) {
10859 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10863 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10864 memset(*ret, 0, fs->blocksize);
10869 * This function is used to make a unique filename. We do this by
10870 * appending ~0, and then incrementing the number. However, we cannot
10871 * expand the length of the filename beyond the padding available in
10872 * the directory entry.
10874 static void mutate_name(char *str, __u16 *len)
10877 __u16 l = *len & 0xFF, h = *len & 0xff00;
10880 * First check to see if it looks the name has been mutated
10883 for (i = l-1; i > 0; i--) {
10884 if (!isdigit(str[i]))
10887 if ((i == l-1) || (str[i] != '~')) {
10888 if (((l-1) & 3) < 2)
10897 for (i = l-1; i >= 0; i--) {
10898 if (isdigit(str[i])) {
10910 else if (str[0] == 'Z') {
10915 } else if (i > 0) {
10928 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10930 struct fill_dir_struct *fd)
10932 struct problem_context pctx;
10933 struct hash_entry *ent, *prev;
10936 char new_name[256];
10939 clear_problem_context(&pctx);
10942 for (i=1; i < fd->num_array; i++) {
10943 ent = fd->harray + i;
10945 if (!ent->dir->inode ||
10946 ((ent->dir->name_len & 0xFF) !=
10947 (prev->dir->name_len & 0xFF)) ||
10948 (strncmp(ent->dir->name, prev->dir->name,
10949 ent->dir->name_len & 0xFF)))
10951 pctx.dirent = ent->dir;
10952 if ((ent->dir->inode == prev->dir->inode) &&
10953 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10954 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10955 ent->dir->inode = 0;
10959 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10960 new_len = ent->dir->name_len;
10961 mutate_name(new_name, &new_len);
10962 for (j=0; j < fd->num_array; j++) {
10964 ((ent->dir->name_len & 0xFF) !=
10965 (fd->harray[j].dir->name_len & 0xFF)) ||
10966 (strncmp(new_name, fd->harray[j].dir->name,
10969 mutate_name(new_name, &new_len);
10973 new_name[new_len & 0xFF] = 0;
10974 pctx.str = new_name;
10975 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10976 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10977 ent->dir->name_len = new_len;
10978 ext2fs_dirhash(fs->super->s_def_hash_version,
10980 ent->dir->name_len & 0xFF,
10981 fs->super->s_hash_seed,
10982 &ent->hash, &ent->minor_hash);
10990 static errcode_t copy_dir_entries(ext2_filsys fs,
10991 struct fill_dir_struct *fd,
10992 struct out_dir *outdir)
10996 struct hash_entry *ent;
10997 struct ext2_dir_entry *dirent;
10998 int i, rec_len, left;
10999 ext2_dirhash_t prev_hash;
11003 retval = alloc_size_dir(fs, outdir,
11004 (fd->dir_size / fs->blocksize) + 2);
11007 outdir->num = fd->compress ? 0 : 1;
11009 outdir->hashes[0] = 0;
11011 if ((retval = get_next_block(fs, outdir, &block_start)))
11013 dirent = (struct ext2_dir_entry *) block_start;
11014 left = fs->blocksize;
11015 for (i=0; i < fd->num_array; i++) {
11016 ent = fd->harray + i;
11017 if (ent->dir->inode == 0)
11019 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
11020 if (rec_len > left) {
11022 dirent->rec_len += left;
11023 if ((retval = get_next_block(fs, outdir,
11028 left = fs->blocksize - offset;
11029 dirent = (struct ext2_dir_entry *) (block_start + offset);
11031 if (ent->hash == prev_hash)
11032 outdir->hashes[outdir->num-1] = ent->hash | 1;
11034 outdir->hashes[outdir->num-1] = ent->hash;
11036 dirent->inode = ent->dir->inode;
11037 dirent->name_len = ent->dir->name_len;
11038 dirent->rec_len = rec_len;
11039 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
11043 dirent->rec_len += left;
11047 prev_hash = ent->hash;
11050 dirent->rec_len += left;
11056 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
11057 ext2_ino_t ino, ext2_ino_t parent)
11059 struct ext2_dir_entry *dir;
11060 struct ext2_dx_root_info *root;
11061 struct ext2_dx_countlimit *limits;
11064 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
11065 filetype = EXT2_FT_DIR << 8;
11067 memset(buf, 0, fs->blocksize);
11068 dir = (struct ext2_dir_entry *) buf;
11070 dir->name[0] = '.';
11071 dir->name_len = 1 | filetype;
11073 dir = (struct ext2_dir_entry *) (buf + 12);
11074 dir->inode = parent;
11075 dir->name[0] = '.';
11076 dir->name[1] = '.';
11077 dir->name_len = 2 | filetype;
11078 dir->rec_len = fs->blocksize - 12;
11080 root = (struct ext2_dx_root_info *) (buf+24);
11081 root->reserved_zero = 0;
11082 root->hash_version = fs->super->s_def_hash_version;
11083 root->info_length = 8;
11084 root->indirect_levels = 0;
11085 root->unused_flags = 0;
11087 limits = (struct ext2_dx_countlimit *) (buf+32);
11088 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
11095 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
11097 struct ext2_dir_entry *dir;
11098 struct ext2_dx_countlimit *limits;
11100 memset(buf, 0, fs->blocksize);
11101 dir = (struct ext2_dir_entry *) buf;
11103 dir->rec_len = fs->blocksize;
11105 limits = (struct ext2_dx_countlimit *) (buf+8);
11106 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
11109 return (struct ext2_dx_entry *) limits;
11113 * This function takes the leaf nodes which have been written in
11114 * outdir, and populates the root node and any necessary interior nodes.
11116 static errcode_t calculate_tree(ext2_filsys fs,
11117 struct out_dir *outdir,
11121 struct ext2_dx_root_info *root_info;
11122 struct ext2_dx_entry *root, *dx_ent = 0;
11123 struct ext2_dx_countlimit *root_limit, *limit;
11125 char * block_start;
11126 int i, c1, c2, nblks;
11127 int limit_offset, root_offset;
11129 root_info = set_root_node(fs, outdir->buf, ino, parent);
11130 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
11131 root_info->info_length;
11132 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11133 c1 = root_limit->limit;
11134 nblks = outdir->num;
11136 /* Write out the pointer blocks */
11137 if (nblks-1 <= c1) {
11138 /* Just write out the root block, and we're done */
11139 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
11140 for (i=1; i < nblks; i++) {
11141 root->block = ext2fs_cpu_to_le32(i);
11144 ext2fs_cpu_to_le32(outdir->hashes[i]);
11151 root_info->indirect_levels = 1;
11152 for (i=1; i < nblks; i++) {
11157 limit->limit = limit->count =
11158 ext2fs_cpu_to_le16(limit->limit);
11159 root = (struct ext2_dx_entry *)
11160 (outdir->buf + root_offset);
11161 root->block = ext2fs_cpu_to_le32(outdir->num);
11164 ext2fs_cpu_to_le32(outdir->hashes[i]);
11165 if ((retval = get_next_block(fs, outdir,
11168 dx_ent = set_int_node(fs, block_start);
11169 limit = (struct ext2_dx_countlimit *) dx_ent;
11171 root_offset += sizeof(struct ext2_dx_entry);
11174 dx_ent->block = ext2fs_cpu_to_le32(i);
11175 if (c2 != limit->limit)
11177 ext2fs_cpu_to_le32(outdir->hashes[i]);
11181 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
11182 limit->limit = ext2fs_cpu_to_le16(limit->limit);
11184 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
11185 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
11186 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
11191 struct write_dir_struct {
11192 struct out_dir *outdir;
11199 * Helper function which writes out a directory block.
11201 static int write_dir_block(ext2_filsys fs,
11203 e2_blkcnt_t blockcnt,
11204 blk_t ref_block FSCK_ATTR((unused)),
11205 int ref_offset FSCK_ATTR((unused)),
11208 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
11212 if (*block_nr == 0)
11214 if (blockcnt >= wd->outdir->num) {
11215 e2fsck_read_bitmaps(wd->ctx);
11217 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
11218 ext2fs_block_alloc_stats(fs, blk, -1);
11221 return BLOCK_CHANGED;
11226 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
11227 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
11229 return BLOCK_ABORT;
11233 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
11234 struct out_dir *outdir,
11235 ext2_ino_t ino, int compress)
11237 struct write_dir_struct wd;
11239 struct ext2_inode inode;
11241 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
11245 wd.outdir = outdir;
11250 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
11251 write_dir_block, &wd);
11257 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
11259 inode.i_flags &= ~EXT2_INDEX_FL;
11261 inode.i_flags |= EXT2_INDEX_FL;
11262 inode.i_size = outdir->num * fs->blocksize;
11263 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
11264 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
11269 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
11271 ext2_filsys fs = ctx->fs;
11273 struct ext2_inode inode;
11275 struct fill_dir_struct fd;
11276 struct out_dir outdir;
11278 outdir.max = outdir.num = 0;
11281 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
11285 dir_buf = malloc(inode.i_size);
11289 fd.max_array = inode.i_size / 32;
11291 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
11301 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
11302 (inode.i_size / fs->blocksize) < 2)
11306 /* Read in the entire directory into memory */
11307 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
11308 fill_dir_block, &fd);
11314 /* Sort the list */
11317 qsort(fd.harray+2, fd.num_array-2,
11318 sizeof(struct hash_entry), name_cmp);
11320 qsort(fd.harray, fd.num_array,
11321 sizeof(struct hash_entry), hash_cmp);
11324 * Look for duplicates
11326 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
11329 if (ctx->options & E2F_OPT_NO) {
11335 * Copy the directory entries. In a htree directory these
11336 * will become the leaf nodes.
11338 retval = copy_dir_entries(fs, &fd, &outdir);
11342 free(dir_buf); dir_buf = 0;
11344 if (!fd.compress) {
11345 /* Calculate the interior nodes */
11346 retval = calculate_tree(fs, &outdir, ino, fd.parent);
11351 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
11357 free_out_dir(&outdir);
11361 void e2fsck_rehash_directories(e2fsck_t ctx)
11363 struct problem_context pctx;
11364 struct dir_info *dir;
11365 ext2_u32_iterate iter;
11368 int i, cur, max, all_dirs, dir_index, first = 1;
11370 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
11372 if (!ctx->dirs_to_hash && !all_dirs)
11375 e2fsck_get_lost_and_found(ctx, 0);
11377 clear_problem_context(&pctx);
11379 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
11383 max = e2fsck_get_num_dirinfo(ctx);
11385 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
11388 pctx.errcode = retval;
11389 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
11392 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
11396 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
11400 if (!ext2fs_u32_list_iterate(iter, &ino))
11403 if (ino == ctx->lost_and_found)
11407 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
11410 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
11411 if (pctx.errcode) {
11412 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11413 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
11415 if (ctx->progress && !ctx->progress_fd)
11416 e2fsck_simple_progress(ctx, "Rebuilding directory",
11417 100.0 * (float) (++cur) / (float) max, ino);
11419 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11421 ext2fs_u32_list_iterate_end(iter);
11423 ext2fs_u32_list_free(ctx->dirs_to_hash);
11424 ctx->dirs_to_hash = 0;
11428 * linux/fs/revoke.c
11430 * Journal revoke routines for the generic filesystem journaling code;
11431 * part of the ext2fs journaling system.
11433 * Revoke is the mechanism used to prevent old log records for deleted
11434 * metadata from being replayed on top of newer data using the same
11435 * blocks. The revoke mechanism is used in two separate places:
11437 * + Commit: during commit we write the entire list of the current
11438 * transaction's revoked blocks to the journal
11440 * + Recovery: during recovery we record the transaction ID of all
11441 * revoked blocks. If there are multiple revoke records in the log
11442 * for a single block, only the last one counts, and if there is a log
11443 * entry for a block beyond the last revoke, then that log entry still
11446 * We can get interactions between revokes and new log data within a
11447 * single transaction:
11449 * Block is revoked and then journaled:
11450 * The desired end result is the journaling of the new block, so we
11451 * cancel the revoke before the transaction commits.
11453 * Block is journaled and then revoked:
11454 * The revoke must take precedence over the write of the block, so we
11455 * need either to cancel the journal entry or to write the revoke
11456 * later in the log than the log block. In this case, we choose the
11457 * latter: journaling a block cancels any revoke record for that block
11458 * in the current transaction, so any revoke for that block in the
11459 * transaction must have happened after the block was journaled and so
11460 * the revoke must take precedence.
11462 * Block is revoked and then written as data:
11463 * The data write is allowed to succeed, but the revoke is _not_
11464 * cancelled. We still need to prevent old log records from
11465 * overwriting the new data. We don't even need to clear the revoke
11468 * Revoke information on buffers is a tri-state value:
11470 * RevokeValid clear: no cached revoke status, need to look it up
11471 * RevokeValid set, Revoked clear:
11472 * buffer has not been revoked, and cancel_revoke
11474 * RevokeValid set, Revoked set:
11475 * buffer has been revoked.
11478 static kmem_cache_t *revoke_record_cache;
11479 static kmem_cache_t *revoke_table_cache;
11481 /* Each revoke record represents one single revoked block. During
11482 journal replay, this involves recording the transaction ID of the
11483 last transaction to revoke this block. */
11485 struct jbd_revoke_record_s
11487 struct list_head hash;
11488 tid_t sequence; /* Used for recovery only */
11489 unsigned long blocknr;
11493 /* The revoke table is just a simple hash table of revoke records. */
11494 struct jbd_revoke_table_s
11496 /* It is conceivable that we might want a larger hash table
11497 * for recovery. Must be a power of two. */
11500 struct list_head *hash_table;
11504 /* Utility functions to maintain the revoke table */
11506 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11507 static inline int hash(journal_t *journal, unsigned long block)
11509 struct jbd_revoke_table_s *table = journal->j_revoke;
11510 int hash_shift = table->hash_shift;
11512 return ((block << (hash_shift - 6)) ^
11514 (block << (hash_shift - 12))) & (table->hash_size - 1);
11517 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11520 struct list_head *hash_list;
11521 struct jbd_revoke_record_s *record;
11523 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11527 record->sequence = seq;
11528 record->blocknr = blocknr;
11529 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11530 list_add(&record->hash, hash_list);
11537 /* Find a revoke record in the journal's hash table. */
11539 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11540 unsigned long blocknr)
11542 struct list_head *hash_list;
11543 struct jbd_revoke_record_s *record;
11545 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11547 record = (struct jbd_revoke_record_s *) hash_list->next;
11548 while (&(record->hash) != hash_list) {
11549 if (record->blocknr == blocknr)
11551 record = (struct jbd_revoke_record_s *) record->hash.next;
11556 int journal_init_revoke_caches(void)
11558 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11559 if (revoke_record_cache == 0)
11562 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11563 if (revoke_table_cache == 0) {
11564 do_cache_destroy(revoke_record_cache);
11565 revoke_record_cache = NULL;
11571 void journal_destroy_revoke_caches(void)
11573 do_cache_destroy(revoke_record_cache);
11574 revoke_record_cache = 0;
11575 do_cache_destroy(revoke_table_cache);
11576 revoke_table_cache = 0;
11579 /* Initialise the revoke table for a given journal to a given size. */
11581 int journal_init_revoke(journal_t *journal, int hash_size)
11585 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11586 if (!journal->j_revoke)
11589 /* Check that the hash_size is a power of two */
11590 journal->j_revoke->hash_size = hash_size;
11594 while((tmp >>= 1UL) != 0UL)
11596 journal->j_revoke->hash_shift = shift;
11598 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11599 if (!journal->j_revoke->hash_table) {
11600 free(journal->j_revoke);
11601 journal->j_revoke = NULL;
11605 for (tmp = 0; tmp < hash_size; tmp++)
11606 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11611 /* Destoy a journal's revoke table. The table must already be empty! */
11613 void journal_destroy_revoke(journal_t *journal)
11615 struct jbd_revoke_table_s *table;
11616 struct list_head *hash_list;
11619 table = journal->j_revoke;
11623 for (i=0; i<table->hash_size; i++) {
11624 hash_list = &table->hash_table[i];
11627 free(table->hash_table);
11629 journal->j_revoke = NULL;
11633 * Revoke support for recovery.
11635 * Recovery needs to be able to:
11637 * record all revoke records, including the tid of the latest instance
11638 * of each revoke in the journal
11640 * check whether a given block in a given transaction should be replayed
11641 * (ie. has not been revoked by a revoke record in that or a subsequent
11644 * empty the revoke table after recovery.
11648 * First, setting revoke records. We create a new revoke record for
11649 * every block ever revoked in the log as we scan it for recovery, and
11650 * we update the existing records if we find multiple revokes for a
11654 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11657 struct jbd_revoke_record_s *record;
11659 record = find_revoke_record(journal, blocknr);
11661 /* If we have multiple occurences, only record the
11662 * latest sequence number in the hashed record */
11663 if (tid_gt(sequence, record->sequence))
11664 record->sequence = sequence;
11667 return insert_revoke_hash(journal, blocknr, sequence);
11671 * Test revoke records. For a given block referenced in the log, has
11672 * that block been revoked? A revoke record with a given transaction
11673 * sequence number revokes all blocks in that transaction and earlier
11674 * ones, but later transactions still need replayed.
11677 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11680 struct jbd_revoke_record_s *record;
11682 record = find_revoke_record(journal, blocknr);
11685 if (tid_gt(sequence, record->sequence))
11691 * Finally, once recovery is over, we need to clear the revoke table so
11692 * that it can be reused by the running filesystem.
11695 void journal_clear_revoke(journal_t *journal)
11698 struct list_head *hash_list;
11699 struct jbd_revoke_record_s *record;
11700 struct jbd_revoke_table_s *revoke_var;
11702 revoke_var = journal->j_revoke;
11704 for (i = 0; i < revoke_var->hash_size; i++) {
11705 hash_list = &revoke_var->hash_table[i];
11706 while (!list_empty(hash_list)) {
11707 record = (struct jbd_revoke_record_s*) hash_list->next;
11708 list_del(&record->hash);
11715 * e2fsck.c - superblock checks
11718 #define MIN_CHECK 1
11719 #define MAX_CHECK 2
11721 static void check_super_value(e2fsck_t ctx, const char *descr,
11722 unsigned long value, int flags,
11723 unsigned long min_val, unsigned long max_val)
11725 struct problem_context pctx;
11727 if (((flags & MIN_CHECK) && (value < min_val)) ||
11728 ((flags & MAX_CHECK) && (value > max_val))) {
11729 clear_problem_context(&pctx);
11732 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11733 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11738 * This routine may get stubbed out in special compilations of the
11741 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11742 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11744 return (ext2fs_get_device_size(ctx->filesystem_name,
11745 EXT2_BLOCK_SIZE(ctx->fs->super),
11746 &ctx->num_blocks));
11751 * helper function to release an inode
11753 struct process_block_struct {
11756 struct problem_context *pctx;
11758 int truncate_offset;
11759 e2_blkcnt_t truncate_block;
11760 int truncated_blocks;
11765 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11766 e2_blkcnt_t blockcnt,
11767 blk_t ref_blk FSCK_ATTR((unused)),
11768 int ref_offset FSCK_ATTR((unused)),
11771 struct process_block_struct *pb;
11773 struct problem_context *pctx;
11774 blk_t blk = *block_nr;
11777 pb = (struct process_block_struct *) priv_data;
11782 pctx->blkcount = blockcnt;
11784 if (HOLE_BLKADDR(blk))
11787 if ((blk < fs->super->s_first_data_block) ||
11788 (blk >= fs->super->s_blocks_count)) {
11789 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11792 return BLOCK_ABORT;
11795 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11796 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11801 * If we are deleting an orphan, then we leave the fields alone.
11802 * If we are truncating an orphan, then update the inode fields
11803 * and clean up any partial block data.
11805 if (pb->truncating) {
11807 * We only remove indirect blocks if they are
11808 * completely empty.
11810 if (blockcnt < 0) {
11814 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11819 limit = fs->blocksize >> 2;
11820 for (i = 0, bp = (blk_t *) pb->buf;
11821 i < limit; i++, bp++)
11826 * We don't remove direct blocks until we've reached
11827 * the truncation block.
11829 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11832 * If part of the last block needs truncating, we do
11835 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11836 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11840 memset(pb->buf + pb->truncate_offset, 0,
11841 fs->blocksize - pb->truncate_offset);
11842 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11847 pb->truncated_blocks++;
11849 retval |= BLOCK_CHANGED;
11852 ext2fs_block_alloc_stats(fs, blk, -1);
11857 * This function releases an inode. Returns 1 if an inconsistency was
11858 * found. If the inode has a link count, then it is being truncated and
11861 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11862 struct ext2_inode *inode, char *block_buf,
11863 struct problem_context *pctx)
11865 struct process_block_struct pb;
11866 ext2_filsys fs = ctx->fs;
11870 if (!ext2fs_inode_has_valid_blocks(inode))
11873 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11878 if (inode->i_links_count) {
11880 pb.truncate_block = (e2_blkcnt_t)
11881 ((((long long)inode->i_size_high << 32) +
11882 inode->i_size + fs->blocksize - 1) /
11884 pb.truncate_offset = inode->i_size % fs->blocksize;
11887 pb.truncate_block = 0;
11888 pb.truncate_offset = 0;
11890 pb.truncated_blocks = 0;
11891 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11892 block_buf, release_inode_block, &pb);
11894 com_err("release_inode_blocks", retval,
11895 _("while calling ext2fs_block_iterate for inode %d"),
11902 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11903 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11905 if (pb.truncated_blocks)
11906 inode->i_blocks -= pb.truncated_blocks *
11907 (fs->blocksize / 512);
11909 if (inode->i_file_acl) {
11910 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11911 block_buf, -1, &count);
11912 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11917 com_err("release_inode_blocks", retval,
11918 _("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11923 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11924 inode->i_file_acl = 0;
11930 * This function releases all of the orphan inodes. It returns 1 if
11931 * it hit some error, and 0 on success.
11933 static int release_orphan_inodes(e2fsck_t ctx)
11935 ext2_filsys fs = ctx->fs;
11936 ext2_ino_t ino, next_ino;
11937 struct ext2_inode inode;
11938 struct problem_context pctx;
11941 if ((ino = fs->super->s_last_orphan) == 0)
11945 * Win or lose, we won't be using the head of the orphan inode
11948 fs->super->s_last_orphan = 0;
11949 ext2fs_mark_super_dirty(fs);
11952 * If the filesystem contains errors, don't run the orphan
11953 * list, since the orphan list can't be trusted; and we're
11954 * going to be running a full e2fsck run anyway...
11956 if (fs->super->s_state & EXT2_ERROR_FS)
11959 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11960 (ino > fs->super->s_inodes_count)) {
11961 clear_problem_context(&pctx);
11963 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11967 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11968 "block iterate buffer");
11969 e2fsck_read_bitmaps(ctx);
11972 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11973 clear_problem_context(&pctx);
11975 pctx.inode = &inode;
11976 pctx.str = inode.i_links_count ? _("Truncating") :
11979 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11981 next_ino = inode.i_dtime;
11983 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11984 (next_ino > fs->super->s_inodes_count))) {
11985 pctx.ino = next_ino;
11986 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11990 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11993 if (!inode.i_links_count) {
11994 ext2fs_inode_alloc_stats2(fs, ino, -1,
11995 LINUX_S_ISDIR(inode.i_mode));
11996 inode.i_dtime = time(0);
12000 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
12003 ext2fs_free_mem(&block_buf);
12006 ext2fs_free_mem(&block_buf);
12011 * Check the resize inode to make sure it is sane. We check both for
12012 * the case where on-line resizing is not enabled (in which case the
12013 * resize inode should be cleared) as well as the case where on-line
12014 * resizing is enabled.
12016 static void check_resize_inode(e2fsck_t ctx)
12018 ext2_filsys fs = ctx->fs;
12019 struct ext2_inode inode;
12020 struct problem_context pctx;
12021 int i, j, gdt_off, ind_off;
12022 blk_t blk, pblk, expect;
12023 __u32 *dind_buf = 0, *ind_buf;
12026 clear_problem_context(&pctx);
12029 * If the resize inode feature isn't set, then
12030 * s_reserved_gdt_blocks must be zero.
12032 if (!(fs->super->s_feature_compat &
12033 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12034 if (fs->super->s_reserved_gdt_blocks) {
12035 pctx.num = fs->super->s_reserved_gdt_blocks;
12036 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
12038 fs->super->s_reserved_gdt_blocks = 0;
12039 ext2fs_mark_super_dirty(fs);
12044 /* Read the resize inode */
12045 pctx.ino = EXT2_RESIZE_INO;
12046 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
12048 if (fs->super->s_feature_compat &
12049 EXT2_FEATURE_COMPAT_RESIZE_INODE)
12050 ctx->flags |= E2F_FLAG_RESIZE_INODE;
12055 * If the resize inode feature isn't set, check to make sure
12056 * the resize inode is cleared; then we're done.
12058 if (!(fs->super->s_feature_compat &
12059 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
12060 for (i=0; i < EXT2_N_BLOCKS; i++) {
12061 if (inode.i_block[i])
12064 if ((i < EXT2_N_BLOCKS) &&
12065 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
12066 memset(&inode, 0, sizeof(inode));
12067 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12074 * The resize inode feature is enabled; check to make sure the
12075 * only block in use is the double indirect block
12077 blk = inode.i_block[EXT2_DIND_BLOCK];
12078 for (i=0; i < EXT2_N_BLOCKS; i++) {
12079 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
12082 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
12083 !(inode.i_mode & LINUX_S_IFREG) ||
12084 (blk < fs->super->s_first_data_block ||
12085 blk >= fs->super->s_blocks_count)) {
12086 resize_inode_invalid:
12087 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
12088 memset(&inode, 0, sizeof(inode));
12089 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
12091 ctx->flags |= E2F_FLAG_RESIZE_INODE;
12093 if (!(ctx->options & E2F_OPT_READONLY)) {
12094 fs->super->s_state &= ~EXT2_VALID_FS;
12095 ext2fs_mark_super_dirty(fs);
12099 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
12100 "resize dind buffer");
12101 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
12103 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
12105 goto resize_inode_invalid;
12107 gdt_off = fs->desc_blocks;
12108 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
12109 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
12110 i++, gdt_off++, pblk++) {
12111 gdt_off %= fs->blocksize/4;
12112 if (dind_buf[gdt_off] != pblk)
12113 goto resize_inode_invalid;
12114 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
12116 goto resize_inode_invalid;
12118 for (j = 1; j < fs->group_desc_count; j++) {
12119 if (!ext2fs_bg_has_super(fs, j))
12121 expect = pblk + (j * fs->super->s_blocks_per_group);
12122 if (ind_buf[ind_off] != expect)
12123 goto resize_inode_invalid;
12129 ext2fs_free_mem(&dind_buf);
12133 static void check_super_block(e2fsck_t ctx)
12135 ext2_filsys fs = ctx->fs;
12136 blk_t first_block, last_block;
12137 struct ext2_super_block *sb = fs->super;
12138 struct ext2_group_desc *gd;
12139 blk_t blocks_per_group = fs->super->s_blocks_per_group;
12141 int inodes_per_block;
12146 struct problem_context pctx;
12147 __u32 free_blocks = 0, free_inodes = 0;
12149 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
12150 ipg_max = inodes_per_block * (blocks_per_group - 4);
12151 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
12152 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
12153 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
12154 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
12155 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
12157 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
12158 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
12159 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
12160 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
12161 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
12162 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
12164 clear_problem_context(&pctx);
12167 * Verify the super block constants...
12169 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
12171 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
12173 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
12174 MAX_CHECK, 0, sb->s_blocks_count);
12175 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
12176 MIN_CHECK | MAX_CHECK, 0,
12177 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
12178 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
12179 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
12180 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
12181 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
12183 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
12184 MIN_CHECK | MAX_CHECK, 8, bpg_max);
12185 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
12186 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
12187 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
12188 MAX_CHECK, 0, sb->s_blocks_count / 2);
12189 check_super_value(ctx, "reserved_gdt_blocks",
12190 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
12192 inode_size = EXT2_INODE_SIZE(sb);
12193 check_super_value(ctx, "inode_size",
12194 inode_size, MIN_CHECK | MAX_CHECK,
12195 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
12196 if (inode_size & (inode_size - 1)) {
12197 pctx.num = inode_size;
12198 pctx.str = "inode_size";
12199 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
12200 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
12204 if (!ctx->num_blocks) {
12205 pctx.errcode = e2fsck_get_device_size(ctx);
12206 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
12207 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
12208 ctx->flags |= E2F_FLAG_ABORT;
12211 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
12212 (ctx->num_blocks < sb->s_blocks_count)) {
12213 pctx.blk = sb->s_blocks_count;
12214 pctx.blk2 = ctx->num_blocks;
12215 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
12216 ctx->flags |= E2F_FLAG_ABORT;
12222 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
12223 pctx.blk = EXT2_BLOCK_SIZE(sb);
12224 pctx.blk2 = EXT2_FRAG_SIZE(sb);
12225 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
12226 ctx->flags |= E2F_FLAG_ABORT;
12230 should_be = sb->s_frags_per_group >>
12231 (sb->s_log_block_size - sb->s_log_frag_size);
12232 if (sb->s_blocks_per_group != should_be) {
12233 pctx.blk = sb->s_blocks_per_group;
12234 pctx.blk2 = should_be;
12235 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
12236 ctx->flags |= E2F_FLAG_ABORT;
12240 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
12241 if (sb->s_first_data_block != should_be) {
12242 pctx.blk = sb->s_first_data_block;
12243 pctx.blk2 = should_be;
12244 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
12245 ctx->flags |= E2F_FLAG_ABORT;
12249 should_be = sb->s_inodes_per_group * fs->group_desc_count;
12250 if (sb->s_inodes_count != should_be) {
12251 pctx.ino = sb->s_inodes_count;
12252 pctx.ino2 = should_be;
12253 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
12254 sb->s_inodes_count = should_be;
12255 ext2fs_mark_super_dirty(fs);
12260 * Verify the group descriptors....
12262 first_block = sb->s_first_data_block;
12263 last_block = first_block + blocks_per_group;
12265 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
12268 if (i == fs->group_desc_count - 1)
12269 last_block = sb->s_blocks_count;
12270 if ((gd->bg_block_bitmap < first_block) ||
12271 (gd->bg_block_bitmap >= last_block)) {
12272 pctx.blk = gd->bg_block_bitmap;
12273 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
12274 gd->bg_block_bitmap = 0;
12276 if (gd->bg_block_bitmap == 0) {
12277 ctx->invalid_block_bitmap_flag[i]++;
12278 ctx->invalid_bitmaps++;
12280 if ((gd->bg_inode_bitmap < first_block) ||
12281 (gd->bg_inode_bitmap >= last_block)) {
12282 pctx.blk = gd->bg_inode_bitmap;
12283 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
12284 gd->bg_inode_bitmap = 0;
12286 if (gd->bg_inode_bitmap == 0) {
12287 ctx->invalid_inode_bitmap_flag[i]++;
12288 ctx->invalid_bitmaps++;
12290 if ((gd->bg_inode_table < first_block) ||
12291 ((gd->bg_inode_table +
12292 fs->inode_blocks_per_group - 1) >= last_block)) {
12293 pctx.blk = gd->bg_inode_table;
12294 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
12295 gd->bg_inode_table = 0;
12297 if (gd->bg_inode_table == 0) {
12298 ctx->invalid_inode_table_flag[i]++;
12299 ctx->invalid_bitmaps++;
12301 free_blocks += gd->bg_free_blocks_count;
12302 free_inodes += gd->bg_free_inodes_count;
12303 first_block += sb->s_blocks_per_group;
12304 last_block += sb->s_blocks_per_group;
12306 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
12307 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
12308 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
12309 ext2fs_unmark_valid(fs);
12314 * Update the global counts from the block group counts. This
12315 * is needed for an experimental patch which eliminates
12316 * locking the entire filesystem when allocating blocks or
12317 * inodes; if the filesystem is not unmounted cleanly, the
12318 * global counts may not be accurate.
12320 if ((free_blocks != sb->s_free_blocks_count) ||
12321 (free_inodes != sb->s_free_inodes_count)) {
12322 if (ctx->options & E2F_OPT_READONLY)
12323 ext2fs_unmark_valid(fs);
12325 sb->s_free_blocks_count = free_blocks;
12326 sb->s_free_inodes_count = free_inodes;
12327 ext2fs_mark_super_dirty(fs);
12331 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
12332 (sb->s_free_inodes_count > sb->s_inodes_count))
12333 ext2fs_unmark_valid(fs);
12337 * If we have invalid bitmaps, set the error state of the
12340 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
12341 sb->s_state &= ~EXT2_VALID_FS;
12342 ext2fs_mark_super_dirty(fs);
12345 clear_problem_context(&pctx);
12348 * If the UUID field isn't assigned, assign it.
12350 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
12351 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
12352 uuid_generate(sb->s_uuid);
12353 ext2fs_mark_super_dirty(fs);
12354 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12358 /* FIXME - HURD support?
12359 * For the Hurd, check to see if the filetype option is set,
12360 * since it doesn't support it.
12362 if (!(ctx->options & E2F_OPT_READONLY) &&
12363 fs->super->s_creator_os == EXT2_OS_HURD &&
12364 (fs->super->s_feature_incompat &
12365 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
12366 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
12367 fs->super->s_feature_incompat &=
12368 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
12369 ext2fs_mark_super_dirty(fs);
12375 * If we have any of the compatibility flags set, we need to have a
12376 * revision 1 filesystem. Most kernels will not check the flags on
12377 * a rev 0 filesystem and we may have corruption issues because of
12378 * the incompatible changes to the filesystem.
12380 if (!(ctx->options & E2F_OPT_READONLY) &&
12381 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
12382 (fs->super->s_feature_compat ||
12383 fs->super->s_feature_ro_compat ||
12384 fs->super->s_feature_incompat) &&
12385 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
12386 ext2fs_update_dynamic_rev(fs);
12387 ext2fs_mark_super_dirty(fs);
12390 check_resize_inode(ctx);
12393 * Clean up any orphan inodes, if present.
12395 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
12396 fs->super->s_state &= ~EXT2_VALID_FS;
12397 ext2fs_mark_super_dirty(fs);
12401 * Move the ext3 journal file, if necessary.
12403 e2fsck_move_ext3_journal(ctx);
12408 * swapfs.c --- byte-swap an ext2 filesystem
12411 #ifdef ENABLE_SWAPFS
12413 struct swap_block_struct {
12418 struct ext2_inode *inode;
12422 * This is a helper function for block_iterate. We mark all of the
12423 * indirect and direct blocks as changed, so that block_iterate will
12426 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
12431 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
12433 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
12434 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
12436 sb->errcode = retval;
12437 return BLOCK_ABORT;
12439 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
12441 sb->errcode = retval;
12442 return BLOCK_ABORT;
12445 if (blockcnt >= 0) {
12446 if (blockcnt < EXT2_NDIR_BLOCKS)
12448 return BLOCK_CHANGED;
12450 if (blockcnt == BLOCK_COUNT_IND) {
12451 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
12453 return BLOCK_CHANGED;
12455 if (blockcnt == BLOCK_COUNT_DIND) {
12456 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12458 return BLOCK_CHANGED;
12460 if (blockcnt == BLOCK_COUNT_TIND) {
12461 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12463 return BLOCK_CHANGED;
12465 return BLOCK_CHANGED;
12469 * This function is responsible for byte-swapping all of the indirect,
12470 * block pointers. It is also responsible for byte-swapping directories.
12472 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12473 struct ext2_inode *inode)
12476 struct swap_block_struct sb;
12480 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12483 if (LINUX_S_ISDIR(inode->i_mode))
12486 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12489 com_err("swap_inode_blocks", retval,
12490 _("while calling ext2fs_block_iterate"));
12491 ctx->flags |= E2F_FLAG_ABORT;
12495 com_err("swap_inode_blocks", sb.errcode,
12496 _("while calling iterator function"));
12497 ctx->flags |= E2F_FLAG_ABORT;
12502 static void swap_inodes(e2fsck_t ctx)
12504 ext2_filsys fs = ctx->fs;
12507 ext2_ino_t ino = 1;
12508 char *buf, *block_buf;
12510 struct ext2_inode * inode;
12512 e2fsck_use_inode_shortcuts(ctx, 1);
12514 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12517 com_err("swap_inodes", retval,
12518 _("while allocating inode buffer"));
12519 ctx->flags |= E2F_FLAG_ABORT;
12522 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12523 "block interate buffer");
12524 for (group = 0; group < fs->group_desc_count; group++) {
12525 retval = io_channel_read_blk(fs->io,
12526 fs->group_desc[group].bg_inode_table,
12527 fs->inode_blocks_per_group, buf);
12529 com_err("swap_inodes", retval,
12530 _("while reading inode table (group %d)"),
12532 ctx->flags |= E2F_FLAG_ABORT;
12535 inode = (struct ext2_inode *) buf;
12536 for (i=0; i < fs->super->s_inodes_per_group;
12537 i++, ino++, inode++) {
12538 ctx->stashed_ino = ino;
12539 ctx->stashed_inode = inode;
12541 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12542 ext2fs_swap_inode(fs, inode, inode, 0);
12545 * Skip deleted files.
12547 if (inode->i_links_count == 0)
12550 if (LINUX_S_ISDIR(inode->i_mode) ||
12551 ((inode->i_block[EXT2_IND_BLOCK] ||
12552 inode->i_block[EXT2_DIND_BLOCK] ||
12553 inode->i_block[EXT2_TIND_BLOCK]) &&
12554 ext2fs_inode_has_valid_blocks(inode)))
12555 swap_inode_blocks(ctx, ino, block_buf, inode);
12557 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12560 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12561 ext2fs_swap_inode(fs, inode, inode, 1);
12563 retval = io_channel_write_blk(fs->io,
12564 fs->group_desc[group].bg_inode_table,
12565 fs->inode_blocks_per_group, buf);
12567 com_err("swap_inodes", retval,
12568 _("while writing inode table (group %d)"),
12570 ctx->flags |= E2F_FLAG_ABORT;
12574 ext2fs_free_mem(&buf);
12575 ext2fs_free_mem(&block_buf);
12576 e2fsck_use_inode_shortcuts(ctx, 0);
12577 ext2fs_flush_icache(fs);
12580 #if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
12582 * On the PowerPC, the big-endian variant of the ext2 filesystem
12583 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12584 * of each word. Thus a bitmap with only bit 0 set would be, as
12585 * a string of bytes, 00 00 00 01 00 ...
12586 * To cope with this, we byte-reverse each word of a bitmap if
12587 * we have a big-endian filesystem, that is, if we are *not*
12588 * byte-swapping other word-sized numbers.
12590 #define EXT2_BIG_ENDIAN_BITMAPS
12593 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12594 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12596 __u32 *p = (__u32 *) bmap->bitmap;
12597 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12599 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12600 *p = ext2fs_swab32(*p);
12605 #ifdef ENABLE_SWAPFS
12606 static void swap_filesys(e2fsck_t ctx)
12608 ext2_filsys fs = ctx->fs;
12609 if (!(ctx->options & E2F_OPT_PREEN))
12610 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12614 if (fs->super->s_mnt_count) {
12615 fprintf(stderr, _("%s: the filesystem must be freshly "
12616 "checked using fsck\n"
12617 "and not mounted before trying to "
12618 "byte-swap it.\n"), ctx->device_name);
12619 ctx->flags |= E2F_FLAG_ABORT;
12622 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12623 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12624 EXT2_FLAG_SWAP_BYTES_WRITE);
12625 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12627 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12628 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12631 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12633 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12634 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12635 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12636 EXT2_FLAG_SWAP_BYTES_WRITE);
12638 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12639 e2fsck_read_bitmaps(ctx);
12640 ext2fs_swap_bitmap(fs->inode_map);
12641 ext2fs_swap_bitmap(fs->block_map);
12642 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12644 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12646 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12648 #endif /* ENABLE_SWAPFS */
12653 * util.c --- miscellaneous utilities
12657 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12658 const char *description)
12663 ret = malloc(size);
12665 sprintf(buf, "Can't allocate %s\n", description);
12666 fatal_error(ctx, buf);
12668 memset(ret, 0, size);
12672 static char *string_copy(const char *str, int len)
12680 ret = malloc(len+1);
12682 strncpy(ret, str, len);
12688 #ifndef HAVE_CONIO_H
12689 static int read_a_char(void)
12696 if (e2fsck_global_ctx &&
12697 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12700 r = read(0, &c, 1);
12710 static int ask_yn(const char * string, int def)
12713 const char *defstr;
12714 static const char short_yes[] = "yY";
12715 static const char short_no[] = "nN";
12717 #ifdef HAVE_TERMIOS_H
12718 struct termios termios, tmp;
12720 tcgetattr (0, &termios);
12722 tmp.c_lflag &= ~(ICANON | ECHO);
12723 tmp.c_cc[VMIN] = 1;
12724 tmp.c_cc[VTIME] = 0;
12725 tcsetattr (0, TCSANOW, &tmp);
12734 printf("%s%s? ", string, defstr);
12737 if ((c = read_a_char()) == EOF)
12740 #ifdef HAVE_TERMIOS_H
12741 tcsetattr (0, TCSANOW, &termios);
12743 if (e2fsck_global_ctx &&
12744 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12746 longjmp(e2fsck_global_ctx->abort_loc, 1);
12748 puts(_("cancelled!\n"));
12751 if (strchr(short_yes, (char) c)) {
12755 else if (strchr(short_no, (char) c)) {
12759 else if ((c == ' ' || c == '\n') && (def != -1))
12766 #ifdef HAVE_TERMIOS_H
12767 tcsetattr (0, TCSANOW, &termios);
12772 int ask (e2fsck_t ctx, const char * string, int def)
12774 if (ctx->options & E2F_OPT_NO) {
12775 printf (_("%s? no\n\n"), string);
12778 if (ctx->options & E2F_OPT_YES) {
12779 printf (_("%s? yes\n\n"), string);
12782 if (ctx->options & E2F_OPT_PREEN) {
12783 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
12786 return ask_yn(string, def);
12789 void e2fsck_read_bitmaps(e2fsck_t ctx)
12791 ext2_filsys fs = ctx->fs;
12794 if (ctx->invalid_bitmaps) {
12795 com_err(ctx->program_name, 0,
12796 _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12798 fatal_error(ctx, 0);
12801 ehandler_operation(_("reading inode and block bitmaps"));
12802 retval = ext2fs_read_bitmaps(fs);
12803 ehandler_operation(0);
12805 com_err(ctx->program_name, retval,
12806 _("while retrying to read bitmaps for %s"),
12808 fatal_error(ctx, 0);
12812 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12814 ext2_filsys fs = ctx->fs;
12817 if (ext2fs_test_bb_dirty(fs)) {
12818 ehandler_operation(_("writing block bitmaps"));
12819 retval = ext2fs_write_block_bitmap(fs);
12820 ehandler_operation(0);
12822 com_err(ctx->program_name, retval,
12823 _("while retrying to write block bitmaps for %s"),
12825 fatal_error(ctx, 0);
12829 if (ext2fs_test_ib_dirty(fs)) {
12830 ehandler_operation(_("writing inode bitmaps"));
12831 retval = ext2fs_write_inode_bitmap(fs);
12832 ehandler_operation(0);
12834 com_err(ctx->program_name, retval,
12835 _("while retrying to write inode bitmaps for %s"),
12837 fatal_error(ctx, 0);
12842 void preenhalt(e2fsck_t ctx)
12844 ext2_filsys fs = ctx->fs;
12846 if (!(ctx->options & E2F_OPT_PREEN))
12848 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12849 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12852 fs->super->s_state |= EXT2_ERROR_FS;
12853 ext2fs_mark_super_dirty(fs);
12856 exit(EXIT_UNCORRECTED);
12859 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12860 struct ext2_inode * inode, const char *proc)
12864 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12866 com_err("ext2fs_read_inode", retval,
12867 _("while reading inode %ld in %s"), ino, proc);
12868 fatal_error(ctx, 0);
12872 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12873 struct ext2_inode * inode, int bufsize,
12878 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12880 com_err("ext2fs_write_inode", retval,
12881 _("while writing inode %ld in %s"), ino, proc);
12882 fatal_error(ctx, 0);
12886 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12887 struct ext2_inode * inode, const char *proc)
12891 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12893 com_err("ext2fs_write_inode", retval,
12894 _("while writing inode %ld in %s"), ino, proc);
12895 fatal_error(ctx, 0);
12899 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12900 io_manager manager)
12902 struct ext2_super_block *sb;
12903 io_channel io = NULL;
12906 blk_t superblock, ret_sb = 8193;
12908 if (fs && fs->super) {
12909 ret_sb = (fs->super->s_blocks_per_group +
12910 fs->super->s_first_data_block);
12912 ctx->superblock = ret_sb;
12913 ctx->blocksize = fs->blocksize;
12919 if (ctx->blocksize) {
12920 ret_sb = ctx->blocksize * 8;
12921 if (ctx->blocksize == 1024)
12923 ctx->superblock = ret_sb;
12926 ctx->superblock = ret_sb;
12927 ctx->blocksize = 1024;
12930 if (!name || !manager)
12933 if (manager->open(name, 0, &io) != 0)
12936 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12938 sb = (struct ext2_super_block *) buf;
12940 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12941 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
12942 superblock = blocksize*8;
12943 if (blocksize == 1024)
12945 io_channel_set_blksize(io, blocksize);
12946 if (io_channel_read_blk(io, superblock,
12947 -SUPERBLOCK_SIZE, buf))
12949 #ifdef EXT2FS_ENABLE_SWAPFS
12950 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12951 ext2fs_swap_super(sb);
12953 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12954 ret_sb = superblock;
12956 ctx->superblock = superblock;
12957 ctx->blocksize = blocksize;
12965 io_channel_close(io);
12966 ext2fs_free_mem(&buf);
12972 * This function runs through the e2fsck passes and calls them all,
12973 * returning restart, abort, or cancel as necessary...
12975 typedef void (*pass_t)(e2fsck_t ctx);
12977 static const pass_t e2fsck_passes[] = {
12978 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12981 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12983 static int e2fsck_run(e2fsck_t ctx)
12986 pass_t e2fsck_pass;
12988 if (setjmp(ctx->abort_loc)) {
12989 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12990 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12992 ctx->flags |= E2F_FLAG_SETJMP_OK;
12994 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12995 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12999 (void) (ctx->progress)(ctx, 0, 0, 0);
13001 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
13003 if (ctx->flags & E2F_FLAG_RUN_RETURN)
13004 return (ctx->flags & E2F_FLAG_RUN_RETURN);
13010 * unix.c - The unix-specific code for e2fsck
13014 /* Command line options */
13016 #ifdef ENABLE_SWAPFS
13017 static int normalize_swapfs;
13019 static int cflag; /* check disk */
13020 static int show_version_only;
13021 static int verbose;
13023 static int replace_bad_blocks;
13024 static int keep_bad_blocks;
13025 static char *bad_blocks_file;
13027 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
13029 static void show_stats(e2fsck_t ctx)
13031 ext2_filsys fs = ctx->fs;
13032 int inodes, inodes_used, blocks, blocks_used;
13034 int num_files, num_links;
13037 dir_links = 2 * ctx->fs_directory_count - 1;
13038 num_files = ctx->fs_total_count - dir_links;
13039 num_links = ctx->fs_links_count - dir_links;
13040 inodes = fs->super->s_inodes_count;
13041 inodes_used = (fs->super->s_inodes_count -
13042 fs->super->s_free_inodes_count);
13043 blocks = fs->super->s_blocks_count;
13044 blocks_used = (fs->super->s_blocks_count -
13045 fs->super->s_free_blocks_count);
13047 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
13048 frag_percent = (frag_percent + 5) / 10;
13051 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
13052 ctx->device_name, inodes_used, inodes,
13053 frag_percent / 10, frag_percent % 10,
13054 blocks_used, blocks);
13057 printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
13058 100 * inodes_used / inodes);
13059 printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
13060 P_E2("", "s", ctx->fs_fragmented),
13061 frag_percent / 10, frag_percent % 10);
13062 printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
13063 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
13064 printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
13065 (int) ((long long) 100 * blocks_used / blocks));
13066 printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count));
13067 printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
13068 printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
13069 printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
13070 printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
13071 printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
13072 printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
13073 printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
13074 printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
13075 printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
13076 printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
13077 printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
13080 static void check_mount(e2fsck_t ctx)
13085 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
13086 &ctx->mount_flags);
13088 com_err("ext2fs_check_if_mount", retval,
13089 _("while determining whether %s is mounted."),
13090 ctx->filesystem_name);
13095 * If the filesystem isn't mounted, or it's the root filesystem
13096 * and it's mounted read-only, then everything's fine.
13098 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
13099 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
13100 (ctx->mount_flags & EXT2_MF_READONLY)))
13103 if (ctx->options & E2F_OPT_READONLY) {
13104 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
13108 printf(_("%s is mounted. "), ctx->filesystem_name);
13109 if (!ctx->interactive)
13110 fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
13111 printf(_("\n\n\007\007\007\007WARNING!!! "
13112 "Running e2fsck on a mounted filesystem may cause\n"
13113 "SEVERE filesystem damage.\007\007\007\n\n"));
13114 cont = ask_yn(_("Do you really want to continue"), -1);
13116 printf (_("check aborted.\n"));
13122 static int is_on_batt(void)
13126 char tmp[80], tmp2[80], fname[80];
13127 unsigned int acflag;
13130 f = fopen("/proc/apm", "r");
13132 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
13135 return (acflag != 1);
13137 d = opendir("/proc/acpi/ac_adapter");
13139 while ((de=readdir(d)) != NULL) {
13140 if (!strncmp(".", de->d_name, 1))
13142 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
13144 f = fopen(fname, "r");
13147 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
13150 if (strncmp(tmp, "off-line", 8) == 0) {
13161 * This routine checks to see if a filesystem can be skipped; if so,
13162 * it will exit with EXIT_OK. Under some conditions it will print a
13163 * message explaining why a check is being forced.
13165 static void check_if_skip(e2fsck_t ctx)
13167 ext2_filsys fs = ctx->fs;
13168 const char *reason = NULL;
13169 unsigned int reason_arg = 0;
13171 int batt = is_on_batt();
13172 time_t now = time(0);
13174 if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
13178 if ((fs->super->s_state & EXT2_ERROR_FS) ||
13179 !ext2fs_test_valid(fs))
13180 reason = _(" contains a file system with errors");
13181 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
13182 reason = _(" was not cleanly unmounted");
13183 else if ((fs->super->s_max_mnt_count > 0) &&
13184 (fs->super->s_mnt_count >=
13185 (unsigned) fs->super->s_max_mnt_count)) {
13186 reason = _(" has been mounted %u times without being checked");
13187 reason_arg = fs->super->s_mnt_count;
13188 if (batt && (fs->super->s_mnt_count <
13189 (unsigned) fs->super->s_max_mnt_count*2))
13191 } else if (fs->super->s_checkinterval &&
13192 ((now - fs->super->s_lastcheck) >=
13193 fs->super->s_checkinterval)) {
13194 reason = _(" has gone %u days without being checked");
13195 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
13196 if (batt && ((now - fs->super->s_lastcheck) <
13197 fs->super->s_checkinterval*2))
13201 fputs(ctx->device_name, stdout);
13202 printf(reason, reason_arg);
13203 fputs(_(", check forced.\n"), stdout);
13206 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
13207 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
13208 fs->super->s_inodes_count,
13209 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
13210 fs->super->s_blocks_count);
13211 next_check = 100000;
13212 if (fs->super->s_max_mnt_count > 0) {
13213 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
13214 if (next_check <= 0)
13217 if (fs->super->s_checkinterval &&
13218 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
13220 if (next_check <= 5) {
13221 if (next_check == 1)
13222 fputs(_(" (check after next mount)"), stdout);
13224 printf(_(" (check in %ld mounts)"), next_check);
13226 fputc('\n', stdout);
13229 e2fsck_free_context(ctx);
13234 * For completion notice
13236 struct percent_tbl {
13240 static const struct percent_tbl e2fsck_tbl = {
13241 5, { 0, 70, 90, 92, 95, 100 }
13244 static char bar[128], spaces[128];
13246 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
13253 if (pass > tbl->max_pass || max == 0)
13255 percent = ((float) curr) / ((float) max);
13256 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
13257 + tbl->table[pass-1]);
13260 void e2fsck_clear_progbar(e2fsck_t ctx)
13262 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
13265 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
13268 ctx->flags &= ~E2F_FLAG_PROG_BAR;
13271 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
13272 unsigned int dpynum)
13274 static const char spinner[] = "\\|/-";
13281 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
13285 * Calculate the new progress position. If the
13286 * percentage hasn't changed, then we skip out right
13289 fixed_percent = (int) ((10 * percent) + 0.5);
13290 if (ctx->progress_last_percent == fixed_percent)
13292 ctx->progress_last_percent = fixed_percent;
13295 * If we've already updated the spinner once within
13296 * the last 1/8th of a second, no point doing it
13299 gettimeofday(&tv, NULL);
13300 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
13301 if ((tick == ctx->progress_last_time) &&
13302 (fixed_percent != 0) && (fixed_percent != 1000))
13304 ctx->progress_last_time = tick;
13307 * Advance the spinner, and note that the progress bar
13308 * will be on the screen
13310 ctx->progress_pos = (ctx->progress_pos+1) & 3;
13311 ctx->flags |= E2F_FLAG_PROG_BAR;
13313 dpywidth = 66 - strlen(label);
13314 dpywidth = 8 * (dpywidth / 8);
13318 i = ((percent * dpywidth) + 50) / 100;
13319 printf("%s%s: |%s%s", ctx->start_meta, label,
13320 bar + (sizeof(bar) - (i+1)),
13321 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
13322 if (fixed_percent == 1000)
13323 fputc('|', stdout);
13325 fputc(spinner[ctx->progress_pos & 3], stdout);
13326 printf(" %4.1f%% ", percent);
13328 printf("%u\r", dpynum);
13330 fputs(" \r", stdout);
13331 fputs(ctx->stop_meta, stdout);
13333 if (fixed_percent == 1000)
13334 e2fsck_clear_progbar(ctx);
13340 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
13341 unsigned long cur, unsigned long max)
13349 if (ctx->progress_fd) {
13350 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
13351 write(ctx->progress_fd, buf, strlen(buf));
13353 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
13354 e2fsck_simple_progress(ctx, ctx->device_name,
13360 static void reserve_stdio_fds(void)
13365 fd = open(bb_dev_null, O_RDWR);
13369 fprintf(stderr, _("ERROR: Couldn't open "
13370 "/dev/null (%s)\n"),
13378 static void signal_progress_on(int sig FSCK_ATTR((unused)))
13380 e2fsck_t ctx = e2fsck_global_ctx;
13385 ctx->progress = e2fsck_update_progress;
13386 ctx->progress_fd = 0;
13389 static void signal_progress_off(int sig FSCK_ATTR((unused)))
13391 e2fsck_t ctx = e2fsck_global_ctx;
13396 e2fsck_clear_progbar(ctx);
13400 static void signal_cancel(int sig FSCK_ATTR((unused)))
13402 e2fsck_t ctx = e2fsck_global_ctx;
13405 exit(FSCK_CANCELED);
13407 ctx->flags |= E2F_FLAG_CANCEL;
13410 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
13412 char *buf, *token, *next, *p, *arg;
13414 int extended_usage = 0;
13416 buf = string_copy(opts, 0);
13417 for (token = buf; token && *token; token = next) {
13418 p = strchr(token, ',');
13424 arg = strchr(token, '=');
13429 if (strcmp(token, "ea_ver") == 0) {
13434 ea_ver = strtoul(arg, &p, 0);
13436 ((ea_ver != 1) && (ea_ver != 2))) {
13438 _("Invalid EA version.\n"));
13442 ctx->ext_attr_ver = ea_ver;
13444 fprintf(stderr, _("Unknown extended option: %s\n"),
13449 if (extended_usage) {
13450 bb_error_msg_and_die(
13451 "Extended options are separated by commas, "
13452 "and may take an argument which\n"
13453 "is set off by an equals ('=') sign. "
13454 "Valid extended options are:\n"
13455 "\tea_ver=<ea_version (1 or 2)>\n\n");
13460 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
13466 struct sigaction sa;
13467 char *extended_opts = 0;
13469 retval = e2fsck_allocate_context(&ctx);
13475 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
13476 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
13477 if (isatty(0) && isatty(1)) {
13478 ctx->interactive = 1;
13480 ctx->start_meta[0] = '\001';
13481 ctx->stop_meta[0] = '\002';
13483 memset(bar, '=', sizeof(bar)-1);
13484 memset(spaces, ' ', sizeof(spaces)-1);
13485 blkid_get_cache(&ctx->blkid, NULL);
13488 ctx->program_name = *argv;
13490 ctx->program_name = "e2fsck";
13491 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13494 ctx->progress = e2fsck_update_progress;
13495 ctx->progress_fd = atoi(optarg);
13496 if (!ctx->progress_fd)
13498 /* Validate the file descriptor to avoid disasters */
13499 fd = dup(ctx->progress_fd);
13502 _("Error validating file descriptor %d: %s\n"),
13504 error_message(errno));
13506 _("Invalid completion information file descriptor"));
13511 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13514 extended_opts = optarg;
13518 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13521 _("Only one the options -p/-a, -n or -y may be specified."));
13523 ctx->options |= E2F_OPT_PREEN;
13526 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13528 ctx->options |= E2F_OPT_NO;
13531 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13533 ctx->options |= E2F_OPT_YES;
13536 /* FIXME - This needs to go away in a future path - will change binary */
13537 fprintf(stderr, _("The -t option is not "
13538 "supported on this version of e2fsck.\n"));
13542 ctx->options |= E2F_OPT_WRITECHECK;
13543 ctx->options |= E2F_OPT_CHECKBLOCKS;
13546 /* What we do by default, anyway! */
13549 ctx->use_superblock = atoi(optarg);
13550 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13553 ctx->blocksize = atoi(optarg);
13556 ctx->inode_buffer_blocks = atoi(optarg);
13559 ctx->journal_name = string_copy(optarg, 0);
13562 ctx->process_inode_size = atoi(optarg);
13565 replace_bad_blocks++;
13567 bad_blocks_file = string_copy(optarg, 0);
13570 ctx->options |= E2F_OPT_DEBUG;
13573 ctx->options |= E2F_OPT_FORCE;
13582 show_version_only = 1;
13585 ctx->device_name = optarg;
13587 #ifdef ENABLE_SWAPFS
13589 normalize_swapfs = 1;
13596 fprintf(stderr, _("Byte-swapping filesystems "
13597 "not compiled in this version "
13607 if (show_version_only)
13609 if (optind != argc - 1)
13611 if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
13612 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13613 ctx->options |= E2F_OPT_READONLY;
13614 ctx->io_options = strchr(argv[optind], '?');
13615 if (ctx->io_options)
13616 *ctx->io_options++ = 0;
13617 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13618 if (!ctx->filesystem_name) {
13619 com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
13621 fatal_error(ctx, 0);
13624 parse_extended_opts(ctx, extended_opts);
13627 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13629 com_err("open", errno,
13630 _("while opening %s for flushing"),
13631 ctx->filesystem_name);
13632 fatal_error(ctx, 0);
13634 if ((retval = ext2fs_sync_device(fd, 1))) {
13635 com_err("ext2fs_sync_device", retval,
13636 _("while trying to flush %s"),
13637 ctx->filesystem_name);
13638 fatal_error(ctx, 0);
13642 #ifdef ENABLE_SWAPFS
13644 if (cflag || bad_blocks_file) {
13645 fprintf(stderr, _("Incompatible options not "
13646 "allowed when byte-swapping.\n"));
13651 if (cflag && bad_blocks_file) {
13652 fprintf(stderr, _("The -c and the -l/-L options may "
13653 "not be both used at the same time.\n"));
13657 * Set up signal action
13659 memset(&sa, 0, sizeof(struct sigaction));
13660 sa.sa_handler = signal_cancel;
13661 sigaction(SIGINT, &sa, 0);
13662 sigaction(SIGTERM, &sa, 0);
13664 sa.sa_flags = SA_RESTART;
13666 e2fsck_global_ctx = ctx;
13667 sa.sa_handler = signal_progress_on;
13668 sigaction(SIGUSR1, &sa, 0);
13669 sa.sa_handler = signal_progress_off;
13670 sigaction(SIGUSR2, &sa, 0);
13672 /* Update our PATH to include /sbin if we need to run badblocks */
13674 e2fs_set_sbin_path();
13678 static const char my_ver_string[] = E2FSPROGS_VERSION;
13679 static const char my_ver_date[] = E2FSPROGS_DATE;
13681 int e2fsck_main (int argc, char *argv[])
13684 int exit_value = EXIT_OK;
13685 ext2_filsys fs = 0;
13687 struct ext2_super_block *sb;
13688 const char *lib_ver_date;
13689 int my_ver, lib_ver;
13691 struct problem_context pctx;
13692 int flags, run_result;
13694 clear_problem_context(&pctx);
13696 my_ver = ext2fs_parse_version_string(my_ver_string);
13697 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13698 if (my_ver > lib_ver) {
13699 fprintf( stderr, _("Error: ext2fs library version "
13700 "out of date!\n"));
13701 show_version_only++;
13704 retval = PRS(argc, argv, &ctx);
13706 com_err("e2fsck", retval,
13707 _("while trying to initialize program"));
13710 reserve_stdio_fds();
13712 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13713 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13716 if (show_version_only) {
13717 fprintf(stderr, _("\tUsing %s, %s\n"),
13718 error_message(EXT2_ET_BASE), lib_ver_date);
13724 if (!(ctx->options & E2F_OPT_PREEN) &&
13725 !(ctx->options & E2F_OPT_NO) &&
13726 !(ctx->options & E2F_OPT_YES)) {
13727 if (!ctx->interactive)
13729 _("need terminal for interactive repairs"));
13731 ctx->superblock = ctx->use_superblock;
13733 #ifdef CONFIG_TESTIO_DEBUG
13734 io_ptr = test_io_manager;
13735 test_io_backing_manager = unix_io_manager;
13737 io_ptr = unix_io_manager;
13740 if ((ctx->options & E2F_OPT_READONLY) == 0)
13741 flags |= EXT2_FLAG_RW;
13743 if (ctx->superblock && ctx->blocksize) {
13744 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13745 flags, ctx->superblock, ctx->blocksize,
13747 } else if (ctx->superblock) {
13749 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13750 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13751 retval = ext2fs_open2(ctx->filesystem_name,
13752 ctx->io_options, flags,
13753 ctx->superblock, blocksize,
13759 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13760 flags, 0, 0, io_ptr, &fs);
13761 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13762 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13763 ((retval == EXT2_ET_BAD_MAGIC) ||
13764 ((retval == 0) && ext2fs_check_desc(fs)))) {
13765 if (!fs || (fs->group_desc_count > 1)) {
13766 printf(_("%s trying backup blocks...\n"),
13767 retval ? _("Couldn't find ext2 superblock,") :
13768 _("Group descriptors look bad..."));
13769 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13776 com_err(ctx->program_name, retval, _("while trying to open %s"),
13777 ctx->filesystem_name);
13778 if (retval == EXT2_ET_REV_TOO_HIGH) {
13779 printf(_("The filesystem revision is apparently "
13780 "too high for this version of e2fsck.\n"
13781 "(Or the filesystem superblock "
13782 "is corrupt)\n\n"));
13783 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13784 } else if (retval == EXT2_ET_SHORT_READ)
13785 printf(_("Could this be a zero-length partition?\n"));
13786 else if ((retval == EPERM) || (retval == EACCES))
13787 printf(_("You must have %s access to the "
13788 "filesystem or be root\n"),
13789 (ctx->options & E2F_OPT_READONLY) ?
13791 else if (retval == ENXIO)
13792 printf(_("Possibly non-existent or swap device?\n"));
13794 else if (retval == EROFS)
13795 printf(_("Disk write-protected; use the -n option "
13796 "to do a read-only\n"
13797 "check of the device.\n"));
13800 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13801 fatal_error(ctx, 0);
13804 fs->priv_data = ctx;
13806 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13807 com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
13808 _("while trying to open %s"),
13809 ctx->filesystem_name);
13811 fatal_error(ctx, _("Get a newer version of e2fsck!"));
13815 * Set the device name, which is used whenever we print error
13816 * or informational messages to the user.
13818 if (ctx->device_name == 0 &&
13819 (sb->s_volume_name[0] != 0)) {
13820 ctx->device_name = string_copy(sb->s_volume_name,
13821 sizeof(sb->s_volume_name));
13823 if (ctx->device_name == 0)
13824 ctx->device_name = ctx->filesystem_name;
13827 * Make sure the ext3 superblock fields are consistent.
13829 retval = e2fsck_check_ext3_journal(ctx);
13831 com_err(ctx->program_name, retval,
13832 _("while checking ext3 journal for %s"),
13834 fatal_error(ctx, 0);
13838 * Check to see if we need to do ext3-style recovery. If so,
13839 * do it, and then restart the fsck.
13841 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13842 if (ctx->options & E2F_OPT_READONLY) {
13843 printf(_("Warning: skipping journal recovery "
13844 "because doing a read-only filesystem "
13846 io_channel_flush(ctx->fs->io);
13848 if (ctx->flags & E2F_FLAG_RESTARTED) {
13850 * Whoops, we attempted to run the
13851 * journal twice. This should never
13852 * happen, unless the hardware or
13853 * device driver is being bogus.
13855 com_err(ctx->program_name, 0,
13856 _("unable to set superblock flags on %s\n"), ctx->device_name);
13857 fatal_error(ctx, 0);
13859 retval = e2fsck_run_ext3_journal(ctx);
13861 com_err(ctx->program_name, retval,
13862 _("while recovering ext3 journal of %s"),
13864 fatal_error(ctx, 0);
13866 ext2fs_close(ctx->fs);
13868 ctx->flags |= E2F_FLAG_RESTARTED;
13874 * Check for compatibility with the feature sets. We need to
13875 * be more stringent than ext2fs_open().
13877 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13878 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13879 com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE,
13880 "(%s)", ctx->device_name);
13883 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13884 com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE,
13885 "(%s)", ctx->device_name);
13888 #ifdef ENABLE_COMPRESSION
13889 /* FIXME - do we support this at all? */
13890 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13891 com_err(ctx->program_name, 0,
13892 _("Warning: compression support is experimental.\n"));
13894 #ifndef ENABLE_HTREE
13895 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13896 com_err(ctx->program_name, 0,
13897 _("E2fsck not compiled with HTREE support,\n\t"
13898 "but filesystem %s has HTREE directories.\n"),
13905 * If the user specified a specific superblock, presumably the
13906 * master superblock has been trashed. So we mark the
13907 * superblock as dirty, so it can be written out.
13909 if (ctx->superblock &&
13910 !(ctx->options & E2F_OPT_READONLY))
13911 ext2fs_mark_super_dirty(fs);
13914 * We only update the master superblock because (a) paranoia;
13915 * we don't want to corrupt the backup superblocks, and (b) we
13916 * don't need to update the mount count and last checked
13917 * fields in the backup superblock (the kernel doesn't
13918 * update the backup superblocks anyway).
13920 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13922 ehandler_init(fs->io);
13924 if (ctx->superblock)
13925 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13926 ext2fs_mark_valid(fs);
13927 check_super_block(ctx);
13928 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13929 fatal_error(ctx, 0);
13930 check_if_skip(ctx);
13931 if (bad_blocks_file)
13932 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
13934 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
13935 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13936 fatal_error(ctx, 0);
13937 #ifdef ENABLE_SWAPFS
13939 #ifdef WORDS_BIGENDIAN
13940 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13942 #define NATIVE_FLAG 0
13946 if (normalize_swapfs) {
13947 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13948 fprintf(stderr, _("%s: Filesystem byte order "
13949 "already normalized.\n"), ctx->device_name);
13950 fatal_error(ctx, 0);
13955 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13956 fatal_error(ctx, 0);
13961 * Mark the system as valid, 'til proven otherwise
13963 ext2fs_mark_valid(fs);
13965 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13967 com_err(ctx->program_name, retval,
13968 _("while reading bad blocks inode"));
13970 printf(_("This doesn't bode well,"
13971 " but we'll try to go on...\n"));
13974 run_result = e2fsck_run(ctx);
13975 e2fsck_clear_progbar(ctx);
13976 if (run_result == E2F_FLAG_RESTART) {
13977 printf(_("Restarting e2fsck from the beginning...\n"));
13978 retval = e2fsck_reset_context(ctx);
13980 com_err(ctx->program_name, retval,
13981 _("while resetting context"));
13982 fatal_error(ctx, 0);
13987 if (run_result & E2F_FLAG_CANCEL) {
13988 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13989 ctx->device_name : ctx->filesystem_name);
13990 exit_value |= FSCK_CANCELED;
13992 if (run_result & E2F_FLAG_ABORT)
13993 fatal_error(ctx, _("aborted"));
13996 if (ext2fs_test_changed(fs)) {
13997 exit_value |= EXIT_NONDESTRUCT;
13998 if (!(ctx->options & E2F_OPT_PREEN))
13999 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
14001 if (ctx->mount_flags & EXT2_MF_ISROOT) {
14002 printf(_("%s: ***** REBOOT LINUX *****\n"),
14004 exit_value |= EXIT_DESTRUCT;
14007 if (!ext2fs_test_valid(fs)) {
14008 printf(_("\n%s: ********** WARNING: Filesystem still has "
14009 "errors **********\n\n"), ctx->device_name);
14010 exit_value |= EXIT_UNCORRECTED;
14011 exit_value &= ~EXIT_NONDESTRUCT;
14013 if (exit_value & FSCK_CANCELED)
14014 exit_value &= ~EXIT_NONDESTRUCT;
14017 if (!(ctx->options & E2F_OPT_READONLY)) {
14018 if (ext2fs_test_valid(fs)) {
14019 if (!(sb->s_state & EXT2_VALID_FS))
14020 exit_value |= EXIT_NONDESTRUCT;
14021 sb->s_state = EXT2_VALID_FS;
14023 sb->s_state &= ~EXT2_VALID_FS;
14024 sb->s_mnt_count = 0;
14025 sb->s_lastcheck = time(NULL);
14026 ext2fs_mark_super_dirty(fs);
14030 e2fsck_write_bitmaps(ctx);
14034 free(ctx->filesystem_name);
14035 free(ctx->journal_name);
14036 e2fsck_free_context(ctx);