1 /* vi: set sw=4 ts=4: */
5 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6 * Copyright (C) 2006 Garrett Kajmowicz
8 * Dictionary Abstract Data Type
9 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
10 * Free Software License:
11 * All rights are reserved by the author, with the following exceptions:
12 * Permission is granted to freely reproduce and distribute this software,
13 * possibly in exchange for a fee, provided that this copyright notice appears
14 * intact. Permission is also granted to adapt this software to produce
15 * derivative works, as long as the modified versions carry this copyright
16 * notice and additional notices stating that the work has been modified.
17 * This source code may be translated into executable form and incorporated
18 * into proprietary software; there is no requirement for such software to
19 * contain a copyright notice related to this source.
21 * linux/fs/recovery and linux/fs/revoke
22 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
24 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
26 * Journal recovery routines for the generic filesystem journaling code;
27 * part of the ext2fs journaling system.
29 * Licensed under GPLv2 or later, see file License in this tarball for details.
33 #define _GNU_SOURCE 1 /* get strnlen() */
36 #include "e2fsck.h" /*Put all of our defines here to clean things up*/
42 * Procedure declarations
45 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
48 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
51 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
52 ext2_ino_t ino, char *buf);
55 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
56 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
57 int num, int gauranteed_size);
58 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
59 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
63 static void e2fsck_rehash_directories(e2fsck_t ctx);
66 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
67 const char *description);
68 static int ask(e2fsck_t ctx, const char * string, int def);
69 static void e2fsck_read_bitmaps(e2fsck_t ctx);
70 static void preenhalt(e2fsck_t ctx);
71 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
72 struct ext2_inode * inode, const char * proc);
73 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
74 struct ext2_inode * inode, const char * proc);
75 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
76 const char *name, io_manager manager);
79 static void e2fsck_clear_progbar(e2fsck_t ctx);
80 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
81 float percent, unsigned int dpynum);
85 * problem.h --- e2fsck problem error codes
88 typedef __u32 problem_t;
90 struct problem_context {
92 ext2_ino_t ino, ino2, dir;
93 struct ext2_inode *inode;
94 struct ext2_dir_entry *dirent;
104 * Function declarations
106 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
107 static int end_problem_latch(e2fsck_t ctx, int mask);
108 static int set_latch_flags(int mask, int setflags, int clearflags);
109 static void clear_problem_context(struct problem_context *ctx);
112 * Dictionary Abstract Data Type
113 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
115 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
123 * Blurb for inclusion into C++ translation units
126 typedef unsigned long dictcount_t;
127 #define DICTCOUNT_T_MAX ULONG_MAX
130 * The dictionary is implemented as a red-black tree
133 typedef enum { dnode_red, dnode_black } dnode_color_t;
135 typedef struct dnode_t {
136 struct dnode_t *dict_left;
137 struct dnode_t *dict_right;
138 struct dnode_t *dict_parent;
139 dnode_color_t dict_color;
140 const void *dict_key;
144 typedef int (*dict_comp_t)(const void *, const void *);
145 typedef void (*dnode_free_t)(dnode_t *);
147 typedef struct dict_t {
148 dnode_t dict_nilnode;
149 dictcount_t dict_nodecount;
150 dictcount_t dict_maxcount;
151 dict_comp_t dict_compare;
152 dnode_free_t dict_freenode;
156 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
158 typedef struct dict_load_t {
159 dict_t *dict_dictptr;
160 dnode_t dict_nilnode;
163 #define dict_count(D) ((D)->dict_nodecount)
164 #define dnode_get(N) ((N)->dict_data)
165 #define dnode_getkey(N) ((N)->dict_key)
170 * Compatibility header file for e2fsck which should be included
171 * instead of linux/jfs.h
173 * Copyright (C) 2000 Stephen C. Tweedie
177 * Pull in the definition of the e2fsck context structure
193 #define K_DEV_JOURNAL 2
195 #define lock_buffer(bh) do {} while (0)
196 #define unlock_buffer(bh) do {} while (0)
197 #define buffer_req(bh) 1
198 #define do_readahead(journal, start) do {} while (0)
200 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
206 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
209 * We use the standard libext2fs portability tricks for inline
213 static kmem_cache_t * do_cache_create(int len)
215 kmem_cache_t *new_cache;
217 new_cache = xmalloc(sizeof(*new_cache));
218 new_cache->object_length = len;
222 static void do_cache_destroy(kmem_cache_t *cache)
229 * Dictionary Abstract Data Type
234 * These macros provide short convenient names for structure members,
235 * which are embellished with dict_ prefixes so that they are
236 * properly confined to the documented namespace. It's legal for a
237 * program which uses dict to define, for instance, a macro called ``parent''.
238 * Such a macro would interfere with the dnode_t struct definition.
239 * In general, highly portable and reusable C modules which expose their
240 * structures need to confine structure member names to well-defined spaces.
241 * The resulting identifiers aren't necessarily convenient to use, nor
242 * readable, in the implementation, however!
245 #define left dict_left
246 #define right dict_right
247 #define parent dict_parent
248 #define color dict_color
250 #define data dict_data
252 #define nilnode dict_nilnode
253 #define maxcount dict_maxcount
254 #define compare dict_compare
255 #define dupes dict_dupes
257 #define dict_root(D) ((D)->nilnode.left)
258 #define dict_nil(D) (&(D)->nilnode)
260 static void dnode_free(dnode_t *node);
263 * Perform a ``left rotation'' adjustment on the tree. The given node P and
264 * its right child C are rearranged so that the P instead becomes the left
265 * child of C. The left subtree of C is inherited as the new right subtree
266 * for P. The ordering of the keys within the tree is thus preserved.
269 static void rotate_left(dnode_t *upper)
271 dnode_t *lower, *lowleft, *upparent;
273 lower = upper->right;
274 upper->right = lowleft = lower->left;
275 lowleft->parent = upper;
277 lower->parent = upparent = upper->parent;
279 /* don't need to check for root node here because root->parent is
280 the sentinel nil node, and root->parent->left points back to root */
282 if (upper == upparent->left) {
283 upparent->left = lower;
285 assert (upper == upparent->right);
286 upparent->right = lower;
290 upper->parent = lower;
294 * This operation is the ``mirror'' image of rotate_left. It is
295 * the same procedure, but with left and right interchanged.
298 static void rotate_right(dnode_t *upper)
300 dnode_t *lower, *lowright, *upparent;
303 upper->left = lowright = lower->right;
304 lowright->parent = upper;
306 lower->parent = upparent = upper->parent;
308 if (upper == upparent->right) {
309 upparent->right = lower;
311 assert (upper == upparent->left);
312 upparent->left = lower;
315 lower->right = upper;
316 upper->parent = lower;
320 * Do a postorder traversal of the tree rooted at the specified
321 * node and free everything under it. Used by dict_free().
324 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
328 free_nodes(dict, node->left, nil);
329 free_nodes(dict, node->right, nil);
330 dict->dict_freenode(node);
334 * Verify that the tree contains the given node. This is done by
335 * traversing all of the nodes and comparing their pointers to the
336 * given pointer. Returns 1 if the node is found, otherwise
337 * returns zero. It is intended for debugging purposes.
340 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
344 || verify_dict_has_node(nil, root->left, node)
345 || verify_dict_has_node(nil, root->right, node);
352 * Select a different set of node allocator routines.
355 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
357 assert(dict_count(dict) == 0);
358 dict->dict_freenode = fr;
362 * Free all the nodes in the dictionary by using the dictionary's
363 * installed free routine. The dictionary is emptied.
366 static void dict_free_nodes(dict_t *dict)
368 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
369 free_nodes(dict, root, nil);
370 dict->dict_nodecount = 0;
371 dict->nilnode.left = &dict->nilnode;
372 dict->nilnode.right = &dict->nilnode;
376 * Initialize a user-supplied dictionary object.
379 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
381 dict->compare = comp;
382 dict->dict_freenode = dnode_free;
383 dict->dict_nodecount = 0;
384 dict->maxcount = maxcount;
385 dict->nilnode.left = &dict->nilnode;
386 dict->nilnode.right = &dict->nilnode;
387 dict->nilnode.parent = &dict->nilnode;
388 dict->nilnode.color = dnode_black;
394 * Locate a node in the dictionary having the given key.
395 * If the node is not found, a null a pointer is returned (rather than
396 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
397 * located node is returned.
400 static dnode_t *dict_lookup(dict_t *dict, const void *key)
402 dnode_t *root = dict_root(dict);
403 dnode_t *nil = dict_nil(dict);
407 /* simple binary search adapted for trees that contain duplicate keys */
409 while (root != nil) {
410 result = dict->compare(key, root->key);
416 if (!dict->dupes) { /* no duplicates, return match */
418 } else { /* could be dupes, find leftmost one */
422 while (root != nil && dict->compare(key, root->key))
424 } while (root != nil);
434 * Insert a node into the dictionary. The node should have been
435 * initialized with a data field. All other fields are ignored.
436 * The behavior is undefined if the user attempts to insert into
437 * a dictionary that is already full (for which the dict_isfull()
438 * function returns true).
441 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
443 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
444 dnode_t *parent = nil, *uncle, *grandpa;
449 /* basic binary tree insert */
451 while (where != nil) {
453 result = dict->compare(key, where->key);
454 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
455 assert(dict->dupes || result != 0);
459 where = where->right;
462 assert(where == nil);
467 parent->right = node;
469 node->parent = parent;
473 dict->dict_nodecount++;
475 /* red black adjustments */
477 node->color = dnode_red;
479 while (parent->color == dnode_red) {
480 grandpa = parent->parent;
481 if (parent == grandpa->left) {
482 uncle = grandpa->right;
483 if (uncle->color == dnode_red) { /* red parent, red uncle */
484 parent->color = dnode_black;
485 uncle->color = dnode_black;
486 grandpa->color = dnode_red;
488 parent = grandpa->parent;
489 } else { /* red parent, black uncle */
490 if (node == parent->right) {
493 assert (grandpa == parent->parent);
494 /* rotation between parent and child preserves grandpa */
496 parent->color = dnode_black;
497 grandpa->color = dnode_red;
498 rotate_right(grandpa);
501 } else { /* symmetric cases: parent == parent->parent->right */
502 uncle = grandpa->left;
503 if (uncle->color == dnode_red) {
504 parent->color = dnode_black;
505 uncle->color = dnode_black;
506 grandpa->color = dnode_red;
508 parent = grandpa->parent;
510 if (node == parent->left) {
511 rotate_right(parent);
513 assert (grandpa == parent->parent);
515 parent->color = dnode_black;
516 grandpa->color = dnode_red;
517 rotate_left(grandpa);
523 dict_root(dict)->color = dnode_black;
528 * Allocate a node using the dictionary's allocator routine, give it
532 static dnode_t *dnode_init(dnode_t *dnode, void *data)
535 dnode->parent = NULL;
541 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
543 dnode_t *node = xmalloc(sizeof(dnode_t));
545 dnode_init(node, data);
546 dict_insert(dict, node, key);
551 * Return the node with the lowest (leftmost) key. If the dictionary is empty
552 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
555 static dnode_t *dict_first(dict_t *dict)
557 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
560 while ((left = root->left) != nil)
563 return (root == nil) ? NULL : root;
567 * Return the given node's successor node---the node which has the
568 * next key in the the left to right ordering. If the node has
569 * no successor, a null pointer is returned rather than a pointer to
573 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
575 dnode_t *nil = dict_nil(dict), *parent, *left;
577 if (curr->right != nil) {
579 while ((left = curr->left) != nil)
584 parent = curr->parent;
586 while (parent != nil && curr == parent->right) {
588 parent = curr->parent;
591 return (parent == nil) ? NULL : parent;
595 static void dnode_free(dnode_t *node)
615 * dirinfo.c --- maintains the directory information table for e2fsck.
619 * This subroutine is called during pass1 to create a directory info
620 * entry. During pass1, the passed-in parent is 0; it will get filled
623 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
625 struct dir_info *dir;
629 unsigned long old_size;
631 if (!ctx->dir_info) {
632 ctx->dir_info_count = 0;
633 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
635 num_dirs = 1024; /* Guess */
636 ctx->dir_info_size = num_dirs + 10;
637 ctx->dir_info = (struct dir_info *)
638 e2fsck_allocate_memory(ctx, ctx->dir_info_size
639 * sizeof (struct dir_info),
643 if (ctx->dir_info_count >= ctx->dir_info_size) {
644 old_size = ctx->dir_info_size * sizeof(struct dir_info);
645 ctx->dir_info_size += 10;
646 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
647 sizeof(struct dir_info),
650 ctx->dir_info_size -= 10;
656 * Normally, add_dir_info is called with each inode in
657 * sequential order; but once in a while (like when pass 3
658 * needs to recreate the root directory or lost+found
659 * directory) it is called out of order. In those cases, we
660 * need to move the dir_info entries down to make room, since
661 * the dir_info array needs to be sorted by inode number for
662 * get_dir_info()'s sake.
664 if (ctx->dir_info_count &&
665 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
666 for (i = ctx->dir_info_count-1; i > 0; i--)
667 if (ctx->dir_info[i-1].ino < ino)
669 dir = &ctx->dir_info[i];
671 for (j = ctx->dir_info_count++; j > i; j--)
672 ctx->dir_info[j] = ctx->dir_info[j-1];
674 dir = &ctx->dir_info[ctx->dir_info_count++];
677 dir->dotdot = parent;
678 dir->parent = parent;
682 * get_dir_info() --- given an inode number, try to find the directory
683 * information entry for it.
685 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
690 high = ctx->dir_info_count-1;
693 if (ino == ctx->dir_info[low].ino)
694 return &ctx->dir_info[low];
695 if (ino == ctx->dir_info[high].ino)
696 return &ctx->dir_info[high];
700 if (mid == low || mid == high)
702 if (ino == ctx->dir_info[mid].ino)
703 return &ctx->dir_info[mid];
704 if (ino < ctx->dir_info[mid].ino)
713 * Free the dir_info structure when it isn't needed any more.
715 static void e2fsck_free_dir_info(e2fsck_t ctx)
717 ext2fs_free_mem(&ctx->dir_info);
718 ctx->dir_info_size = 0;
719 ctx->dir_info_count = 0;
723 * Return the count of number of directories in the dir_info structure
725 static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
727 return ctx->dir_info_count;
731 * A simple interator function
733 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
735 if (*control >= ctx->dir_info_count)
738 return ctx->dir_info + (*control)++;
742 * dirinfo.c --- maintains the directory information table for e2fsck.
749 * This subroutine is called during pass1 to create a directory info
750 * entry. During pass1, the passed-in parent is 0; it will get filled
753 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
755 struct dx_dir_info *dir;
758 unsigned long old_size;
760 if (!ctx->dx_dir_info) {
761 ctx->dx_dir_info_count = 0;
762 ctx->dx_dir_info_size = 100; /* Guess */
763 ctx->dx_dir_info = (struct dx_dir_info *)
764 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
765 * sizeof (struct dx_dir_info),
769 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
770 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
771 ctx->dx_dir_info_size += 10;
772 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
773 sizeof(struct dx_dir_info),
776 ctx->dx_dir_info_size -= 10;
782 * Normally, add_dx_dir_info is called with each inode in
783 * sequential order; but once in a while (like when pass 3
784 * needs to recreate the root directory or lost+found
785 * directory) it is called out of order. In those cases, we
786 * need to move the dx_dir_info entries down to make room, since
787 * the dx_dir_info array needs to be sorted by inode number for
788 * get_dx_dir_info()'s sake.
790 if (ctx->dx_dir_info_count &&
791 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
792 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
793 if (ctx->dx_dir_info[i-1].ino < ino)
795 dir = &ctx->dx_dir_info[i];
797 for (j = ctx->dx_dir_info_count++; j > i; j--)
798 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
800 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
803 dir->numblocks = num_blocks;
804 dir->hashversion = 0;
805 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
806 * sizeof (struct dx_dirblock_info),
807 "dx_block info array");
812 * get_dx_dir_info() --- given an inode number, try to find the directory
813 * information entry for it.
815 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
820 high = ctx->dx_dir_info_count-1;
821 if (!ctx->dx_dir_info)
823 if (ino == ctx->dx_dir_info[low].ino)
824 return &ctx->dx_dir_info[low];
825 if (ino == ctx->dx_dir_info[high].ino)
826 return &ctx->dx_dir_info[high];
830 if (mid == low || mid == high)
832 if (ino == ctx->dx_dir_info[mid].ino)
833 return &ctx->dx_dir_info[mid];
834 if (ino < ctx->dx_dir_info[mid].ino)
843 * Free the dx_dir_info structure when it isn't needed any more.
845 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
848 struct dx_dir_info *dir;
850 if (ctx->dx_dir_info) {
851 dir = ctx->dx_dir_info;
852 for (i=0; i < ctx->dx_dir_info_count; i++) {
853 ext2fs_free_mem(&dir->dx_block);
855 ext2fs_free_mem(&ctx->dx_dir_info);
857 ctx->dx_dir_info_size = 0;
858 ctx->dx_dir_info_count = 0;
862 * A simple interator function
864 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
866 if (*control >= ctx->dx_dir_info_count)
869 return ctx->dx_dir_info + (*control)++;
872 #endif /* ENABLE_HTREE */
874 * e2fsck.c - a consistency checker for the new extended file system.
879 * This function allocates an e2fsck context
881 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
886 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
890 memset(context, 0, sizeof(struct e2fsck_struct));
892 context->process_inode_size = 256;
893 context->ext_attr_ver = 2;
899 struct ea_refcount_el {
908 struct ea_refcount_el *list;
911 static void ea_refcount_free(ext2_refcount_t refcount)
916 ext2fs_free_mem(&refcount->list);
917 ext2fs_free_mem(&refcount);
921 * This function resets an e2fsck context; it is called when e2fsck
922 * needs to be restarted.
924 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
927 ctx->lost_and_found = 0;
928 ctx->bad_lost_and_found = 0;
929 ext2fs_free_inode_bitmap(ctx->inode_used_map);
930 ctx->inode_used_map = 0;
931 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
932 ctx->inode_dir_map = 0;
933 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
934 ctx->inode_reg_map = 0;
935 ext2fs_free_block_bitmap(ctx->block_found_map);
936 ctx->block_found_map = 0;
937 ext2fs_free_icount(ctx->inode_link_info);
938 ctx->inode_link_info = 0;
939 if (ctx->journal_io) {
940 if (ctx->fs && ctx->fs->io != ctx->journal_io)
941 io_channel_close(ctx->journal_io);
945 ext2fs_free_dblist(ctx->fs->dblist);
948 e2fsck_free_dir_info(ctx);
950 e2fsck_free_dx_dir_info(ctx);
952 ea_refcount_free(ctx->refcount);
954 ea_refcount_free(ctx->refcount_extra);
955 ctx->refcount_extra = 0;
956 ext2fs_free_block_bitmap(ctx->block_dup_map);
957 ctx->block_dup_map = 0;
958 ext2fs_free_block_bitmap(ctx->block_ea_map);
959 ctx->block_ea_map = 0;
960 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
961 ctx->inode_bad_map = 0;
962 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
963 ctx->inode_imagic_map = 0;
964 ext2fs_u32_list_free(ctx->dirs_to_hash);
965 ctx->dirs_to_hash = 0;
968 * Clear the array of invalid meta-data flags
970 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
971 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
972 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
974 /* Clear statistic counters */
975 ctx->fs_directory_count = 0;
976 ctx->fs_regular_count = 0;
977 ctx->fs_blockdev_count = 0;
978 ctx->fs_chardev_count = 0;
979 ctx->fs_links_count = 0;
980 ctx->fs_symlinks_count = 0;
981 ctx->fs_fast_symlinks_count = 0;
982 ctx->fs_fifo_count = 0;
983 ctx->fs_total_count = 0;
984 ctx->fs_sockets_count = 0;
985 ctx->fs_ind_count = 0;
986 ctx->fs_dind_count = 0;
987 ctx->fs_tind_count = 0;
988 ctx->fs_fragmented = 0;
989 ctx->large_files = 0;
991 /* Reset the superblock to the user's requested value */
992 ctx->superblock = ctx->use_superblock;
997 static void e2fsck_free_context(e2fsck_t ctx)
1002 e2fsck_reset_context(ctx);
1004 blkid_put_cache(ctx->blkid);
1006 ext2fs_free_mem(&ctx);
1014 * The strategy we use for keeping track of EA refcounts is as
1015 * follows. We keep a sorted array of first EA blocks and its
1016 * reference counts. Once the refcount has dropped to zero, it is
1017 * removed from the array to save memory space. Once the EA block is
1018 * checked, its bit is set in the block_ea_map bitmap.
1022 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1024 ext2_refcount_t refcount;
1028 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1031 memset(refcount, 0, sizeof(struct ea_refcount));
1035 refcount->size = size;
1036 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1038 printf("Refcount allocated %d entries, %d bytes.\n",
1039 refcount->size, bytes);
1041 retval = ext2fs_get_mem(bytes, &refcount->list);
1044 memset(refcount->list, 0, bytes);
1046 refcount->count = 0;
1047 refcount->cursor = 0;
1053 ea_refcount_free(refcount);
1058 * collapse_refcount() --- go through the refcount array, and get rid
1059 * of any count == zero entries
1061 static void refcount_collapse(ext2_refcount_t refcount)
1064 struct ea_refcount_el *list;
1066 list = refcount->list;
1067 for (i = 0, j = 0; i < refcount->count; i++) {
1068 if (list[i].ea_count) {
1074 #if defined(DEBUG) || defined(TEST_PROGRAM)
1075 printf("Refcount_collapse: size was %d, now %d\n",
1076 refcount->count, j);
1078 refcount->count = j;
1083 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1084 * specified position.
1086 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1089 struct ea_refcount_el *el;
1094 if (refcount->count >= refcount->size) {
1095 new_size = refcount->size + 100;
1097 printf("Reallocating refcount %d entries...\n", new_size);
1099 retval = ext2fs_resize_mem((size_t) refcount->size *
1100 sizeof(struct ea_refcount_el),
1102 sizeof(struct ea_refcount_el),
1106 refcount->size = new_size;
1108 num = (int) refcount->count - pos;
1110 return 0; /* should never happen */
1112 memmove(&refcount->list[pos+1], &refcount->list[pos],
1113 sizeof(struct ea_refcount_el) * num);
1116 el = &refcount->list[pos];
1124 * get_refcount_el() --- given an block number, try to find refcount
1125 * information in the sorted list. If the create flag is set,
1126 * and we can't find an entry, create one in the sorted list.
1128 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1129 blk_t blk, int create)
1133 blk_t lowval, highval;
1135 if (!refcount || !refcount->list)
1139 high = (int) refcount->count-1;
1140 if (create && ((refcount->count == 0) ||
1141 (blk > refcount->list[high].ea_blk))) {
1142 if (refcount->count >= refcount->size)
1143 refcount_collapse(refcount);
1145 return insert_refcount_el(refcount, blk,
1146 (unsigned) refcount->count);
1148 if (refcount->count == 0)
1151 if (refcount->cursor >= refcount->count)
1152 refcount->cursor = 0;
1153 if (blk == refcount->list[refcount->cursor].ea_blk)
1154 return &refcount->list[refcount->cursor++];
1156 printf("Non-cursor get_refcount_el: %u\n", blk);
1158 while (low <= high) {
1162 /* Interpolate for efficiency */
1163 lowval = refcount->list[low].ea_blk;
1164 highval = refcount->list[high].ea_blk;
1168 else if (blk > highval)
1171 range = ((float) (blk - lowval)) /
1173 mid = low + ((int) (range * (high-low)));
1176 if (blk == refcount->list[mid].ea_blk) {
1177 refcount->cursor = mid+1;
1178 return &refcount->list[mid];
1180 if (blk < refcount->list[mid].ea_blk)
1186 * If we need to create a new entry, it should be right at
1187 * low (where high will be left at low-1).
1190 if (refcount->count >= refcount->size) {
1191 refcount_collapse(refcount);
1192 if (refcount->count < refcount->size)
1195 return insert_refcount_el(refcount, blk, low);
1201 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1203 struct ea_refcount_el *el;
1205 el = get_refcount_el(refcount, blk, 1);
1207 return EXT2_ET_NO_MEMORY;
1211 *ret = el->ea_count;
1216 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1218 struct ea_refcount_el *el;
1220 el = get_refcount_el(refcount, blk, 0);
1221 if (!el || el->ea_count == 0)
1222 return EXT2_ET_INVALID_ARGUMENT;
1227 *ret = el->ea_count;
1232 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1234 struct ea_refcount_el *el;
1237 * Get the refcount element
1239 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1241 return count ? EXT2_ET_NO_MEMORY : 0;
1242 el->ea_count = count;
1246 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1248 refcount->cursor = 0;
1252 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1254 struct ea_refcount_el *list;
1257 if (refcount->cursor >= refcount->count)
1259 list = refcount->list;
1260 if (list[refcount->cursor].ea_count) {
1262 *ret = list[refcount->cursor].ea_count;
1263 return list[refcount->cursor++].ea_blk;
1271 * ehandler.c --- handle bad block errors which come up during the
1272 * course of an e2fsck session.
1276 static const char *operation;
1279 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1280 void *data, size_t size FSCK_ATTR((unused)),
1281 int actual FSCK_ATTR((unused)), errcode_t error)
1285 ext2_filsys fs = (ext2_filsys) channel->app_data;
1288 ctx = (e2fsck_t) fs->priv_data;
1291 * If more than one block was read, try reading each block
1292 * separately. We could use the actual bytes read to figure
1293 * out where to start, but we don't bother.
1297 for (i=0; i < count; i++, p += channel->block_size, block++) {
1298 error = io_channel_read_blk(channel, block,
1306 printf(_("Error reading block %lu (%s) while %s. "), block,
1307 error_message(error), operation);
1309 printf(_("Error reading block %lu (%s). "), block,
1310 error_message(error));
1312 if (ask(ctx, _("Ignore error"), 1)) {
1313 if (ask(ctx, _("Force rewrite"), 1))
1314 io_channel_write_blk(channel, block, 1, data);
1322 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1323 const void *data, size_t size FSCK_ATTR((unused)),
1324 int actual FSCK_ATTR((unused)), errcode_t error)
1328 ext2_filsys fs = (ext2_filsys) channel->app_data;
1331 ctx = (e2fsck_t) fs->priv_data;
1334 * If more than one block was written, try writing each block
1335 * separately. We could use the actual bytes read to figure
1336 * out where to start, but we don't bother.
1339 p = (const char *) data;
1340 for (i=0; i < count; i++, p += channel->block_size, block++) {
1341 error = io_channel_write_blk(channel, block,
1350 printf(_("Error writing block %lu (%s) while %s. "), block,
1351 error_message(error), operation);
1353 printf(_("Error writing block %lu (%s). "), block,
1354 error_message(error));
1356 if (ask(ctx, _("Ignore error"), 1))
1362 static const char *ehandler_operation(const char *op)
1364 const char *ret = operation;
1370 static void ehandler_init(io_channel channel)
1372 channel->read_error = e2fsck_handle_read_error;
1373 channel->write_error = e2fsck_handle_write_error;
1377 * journal.c --- code for handling the "ext3" journal
1379 * Copyright (C) 2000 Andreas Dilger
1380 * Copyright (C) 2000 Theodore Ts'o
1382 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1383 * Copyright (C) 1999 Red Hat Software
1385 * This file may be redistributed under the terms of the
1386 * GNU General Public License version 2 or at your discretion
1387 * any later version.
1391 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1392 * This creates a larger static binary, and a smaller binary using
1393 * shared libraries. It's also probably slightly less CPU-efficient,
1394 * which is why it's not on by default. But, it's a good way of
1395 * testing the functions in inode_io.c and fileio.c.
1399 /* Kernel compatibility functions for handling the journal. These allow us
1400 * to use the recovery.c file virtually unchanged from the kernel, so we
1401 * don't have to do much to keep kernel and user recovery in sync.
1403 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1409 struct inode *inode = journal->j_inode;
1418 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1419 &inode->i_ext2, NULL, 0, block, &pblk);
1425 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1427 struct buffer_head *bh;
1429 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1433 bh->b_ctx = kdev->k_ctx;
1434 if (kdev->k_dev == K_DEV_FS)
1435 bh->b_io = kdev->k_ctx->fs->io;
1437 bh->b_io = kdev->k_ctx->journal_io;
1438 bh->b_size = blocksize;
1439 bh->b_blocknr = blocknr;
1444 static void sync_blockdev(kdev_t kdev)
1448 if (kdev->k_dev == K_DEV_FS)
1449 io = kdev->k_ctx->fs->io;
1451 io = kdev->k_ctx->journal_io;
1453 io_channel_flush(io);
1456 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1459 struct buffer_head *bh;
1461 for (; nr > 0; --nr) {
1463 if (rw == READ && !bh->b_uptodate) {
1464 retval = io_channel_read_blk(bh->b_io,
1468 bb_error_msg("while reading block %lu",
1469 (unsigned long) bh->b_blocknr);
1474 } else if (rw == WRITE && bh->b_dirty) {
1475 retval = io_channel_write_blk(bh->b_io,
1479 bb_error_msg("while writing block %lu",
1480 (unsigned long) bh->b_blocknr);
1490 static void mark_buffer_dirty(struct buffer_head *bh)
1495 static inline void mark_buffer_clean(struct buffer_head * bh)
1500 static void brelse(struct buffer_head *bh)
1503 ll_rw_block(WRITE, 1, &bh);
1504 ext2fs_free_mem(&bh);
1507 static int buffer_uptodate(struct buffer_head *bh)
1509 return bh->b_uptodate;
1512 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1514 bh->b_uptodate = val;
1517 static void wait_on_buffer(struct buffer_head *bh)
1519 if (!bh->b_uptodate)
1520 ll_rw_block(READ, 1, &bh);
1524 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1526 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1528 /* if we had an error doing journal recovery, we need a full fsck */
1530 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1531 ext2fs_mark_super_dirty(ctx->fs);
1534 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1536 struct ext2_super_block *sb = ctx->fs->super;
1537 struct ext2_super_block jsuper;
1538 struct problem_context pctx;
1539 struct buffer_head *bh;
1540 struct inode *j_inode = NULL;
1541 struct kdev_s *dev_fs = NULL, *dev_journal;
1542 const char *journal_name = NULL;
1543 journal_t *journal = NULL;
1544 errcode_t retval = 0;
1545 io_manager io_ptr = 0;
1546 unsigned long start = 0;
1548 int ext_journal = 0;
1549 int tried_backup_jnl = 0;
1552 clear_problem_context(&pctx);
1554 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1556 return EXT2_ET_NO_MEMORY;
1559 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1561 retval = EXT2_ET_NO_MEMORY;
1564 dev_journal = dev_fs+1;
1566 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1567 dev_fs->k_dev = K_DEV_FS;
1568 dev_journal->k_dev = K_DEV_JOURNAL;
1570 journal->j_dev = dev_journal;
1571 journal->j_fs_dev = dev_fs;
1572 journal->j_inode = NULL;
1573 journal->j_blocksize = ctx->fs->blocksize;
1575 if (uuid_is_null(sb->s_journal_uuid)) {
1576 if (!sb->s_journal_inum)
1577 return EXT2_ET_BAD_INODE_NUM;
1578 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1581 retval = EXT2_ET_NO_MEMORY;
1585 j_inode->i_ctx = ctx;
1586 j_inode->i_ino = sb->s_journal_inum;
1588 if ((retval = ext2fs_read_inode(ctx->fs,
1590 &j_inode->i_ext2))) {
1592 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1595 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1596 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1598 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1599 j_inode->i_ext2.i_links_count = 1;
1600 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1603 if (!j_inode->i_ext2.i_links_count ||
1604 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1605 retval = EXT2_ET_NO_JOURNAL;
1606 goto try_backup_journal;
1608 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1609 JFS_MIN_JOURNAL_BLOCKS) {
1610 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1611 goto try_backup_journal;
1613 for (i=0; i < EXT2_N_BLOCKS; i++) {
1614 blk = j_inode->i_ext2.i_block[i];
1616 if (i < EXT2_NDIR_BLOCKS) {
1617 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1618 goto try_backup_journal;
1622 if (blk < sb->s_first_data_block ||
1623 blk >= sb->s_blocks_count) {
1624 retval = EXT2_ET_BAD_BLOCK_NUM;
1625 goto try_backup_journal;
1628 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1631 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1637 io_ptr = inode_io_manager;
1639 journal->j_inode = j_inode;
1640 ctx->journal_io = ctx->fs->io;
1641 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1646 if (!ctx->journal_name) {
1649 uuid_unparse(sb->s_journal_uuid, uuid);
1650 ctx->journal_name = blkid_get_devname(ctx->blkid,
1652 if (!ctx->journal_name)
1653 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1655 journal_name = ctx->journal_name;
1657 if (!journal_name) {
1658 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1659 return EXT2_ET_LOAD_EXT_JOURNAL;
1662 io_ptr = unix_io_manager;
1665 #ifndef USE_INODE_IO
1668 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1673 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1676 if (ctx->fs->blocksize == 1024)
1678 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1680 retval = EXT2_ET_NO_MEMORY;
1683 ll_rw_block(READ, 1, &bh);
1684 if ((retval = bh->b_err) != 0)
1686 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1690 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1691 ext2fs_swap_super(&jsuper);
1693 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1694 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1695 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1696 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1699 /* Make sure the journal UUID is correct */
1700 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1701 sizeof(jsuper.s_uuid))) {
1702 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1703 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1707 journal->j_maxlen = jsuper.s_blocks_count;
1711 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1712 retval = EXT2_ET_NO_MEMORY;
1716 journal->j_sb_buffer = bh;
1717 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1720 ext2fs_free_mem(&j_inode);
1723 *ret_journal = journal;
1727 ext2fs_free_mem(&dev_fs);
1728 ext2fs_free_mem(&j_inode);
1729 ext2fs_free_mem(&journal);
1734 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1735 struct problem_context *pctx)
1737 struct ext2_super_block *sb = ctx->fs->super;
1738 int recover = ctx->fs->super->s_feature_incompat &
1739 EXT3_FEATURE_INCOMPAT_RECOVER;
1740 int has_journal = ctx->fs->super->s_feature_compat &
1741 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1743 if (has_journal || sb->s_journal_inum) {
1744 /* The journal inode is bogus, remove and force full fsck */
1745 pctx->ino = sb->s_journal_inum;
1746 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1747 if (has_journal && sb->s_journal_inum)
1748 printf("*** ext3 journal has been deleted - "
1749 "filesystem is now ext2 only ***\n\n");
1750 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1751 sb->s_journal_inum = 0;
1752 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1753 e2fsck_clear_recover(ctx, 1);
1756 return EXT2_ET_BAD_INODE_NUM;
1757 } else if (recover) {
1758 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1759 e2fsck_clear_recover(ctx, 1);
1762 return EXT2_ET_UNSUPP_FEATURE;
1767 #define V1_SB_SIZE 0x0024
1768 static void clear_v2_journal_fields(journal_t *journal)
1770 e2fsck_t ctx = journal->j_dev->k_ctx;
1771 struct problem_context pctx;
1773 clear_problem_context(&pctx);
1775 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1778 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1779 ctx->fs->blocksize-V1_SB_SIZE);
1780 mark_buffer_dirty(journal->j_sb_buffer);
1784 static errcode_t e2fsck_journal_load(journal_t *journal)
1786 e2fsck_t ctx = journal->j_dev->k_ctx;
1787 journal_superblock_t *jsb;
1788 struct buffer_head *jbh = journal->j_sb_buffer;
1789 struct problem_context pctx;
1791 clear_problem_context(&pctx);
1793 ll_rw_block(READ, 1, &jbh);
1795 bb_error_msg(_("reading journal superblock"));
1799 jsb = journal->j_superblock;
1800 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1801 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1802 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1804 switch (ntohl(jsb->s_header.h_blocktype)) {
1805 case JFS_SUPERBLOCK_V1:
1806 journal->j_format_version = 1;
1807 if (jsb->s_feature_compat ||
1808 jsb->s_feature_incompat ||
1809 jsb->s_feature_ro_compat ||
1811 clear_v2_journal_fields(journal);
1814 case JFS_SUPERBLOCK_V2:
1815 journal->j_format_version = 2;
1816 if (ntohl(jsb->s_nr_users) > 1 &&
1817 uuid_is_null(ctx->fs->super->s_journal_uuid))
1818 clear_v2_journal_fields(journal);
1819 if (ntohl(jsb->s_nr_users) > 1) {
1820 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1821 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1826 * These should never appear in a journal super block, so if
1827 * they do, the journal is badly corrupted.
1829 case JFS_DESCRIPTOR_BLOCK:
1830 case JFS_COMMIT_BLOCK:
1831 case JFS_REVOKE_BLOCK:
1832 return EXT2_ET_CORRUPT_SUPERBLOCK;
1834 /* If we don't understand the superblock major type, but there
1835 * is a magic number, then it is likely to be a new format we
1836 * just don't understand, so leave it alone. */
1838 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1841 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1842 return EXT2_ET_UNSUPP_FEATURE;
1844 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1845 return EXT2_ET_RO_UNSUPP_FEATURE;
1847 /* We have now checked whether we know enough about the journal
1848 * format to be able to proceed safely, so any other checks that
1849 * fail we should attempt to recover from. */
1850 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1851 bb_error_msg(_("%s: no valid journal superblock found"),
1853 return EXT2_ET_CORRUPT_SUPERBLOCK;
1856 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1857 journal->j_maxlen = ntohl(jsb->s_maxlen);
1858 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1859 bb_error_msg(_("%s: journal too short"),
1861 return EXT2_ET_CORRUPT_SUPERBLOCK;
1864 journal->j_tail_sequence = ntohl(jsb->s_sequence);
1865 journal->j_transaction_sequence = journal->j_tail_sequence;
1866 journal->j_tail = ntohl(jsb->s_start);
1867 journal->j_first = ntohl(jsb->s_first);
1868 journal->j_last = ntohl(jsb->s_maxlen);
1873 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
1884 /* Leave a valid existing V1 superblock signature alone.
1885 * Anything unrecognizable we overwrite with a new V2
1888 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
1889 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
1890 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
1891 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
1894 /* Zero out everything else beyond the superblock header */
1896 p = ((char *) jsb) + sizeof(journal_header_t);
1897 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
1899 jsb->s_blocksize = htonl(ctx->fs->blocksize);
1900 jsb->s_maxlen = htonl(journal->j_maxlen);
1901 jsb->s_first = htonl(1);
1903 /* Initialize the journal sequence number so that there is "no"
1904 * chance we will find old "valid" transactions in the journal.
1905 * This avoids the need to zero the whole journal (slow to do,
1906 * and risky when we are just recovering the filesystem).
1908 uuid_generate(u.uuid);
1909 for (i = 0; i < 4; i ++)
1910 new_seq ^= u.val[i];
1911 jsb->s_sequence = htonl(new_seq);
1913 mark_buffer_dirty(journal->j_sb_buffer);
1914 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
1917 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
1919 struct problem_context *pctx)
1921 struct ext2_super_block *sb = ctx->fs->super;
1922 int recover = ctx->fs->super->s_feature_incompat &
1923 EXT3_FEATURE_INCOMPAT_RECOVER;
1925 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
1926 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
1927 e2fsck_journal_reset_super(ctx, journal->j_superblock,
1929 journal->j_transaction_sequence = 1;
1930 e2fsck_clear_recover(ctx, recover);
1933 return EXT2_ET_CORRUPT_SUPERBLOCK;
1934 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
1935 return EXT2_ET_CORRUPT_SUPERBLOCK;
1940 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
1941 int reset, int drop)
1943 journal_superblock_t *jsb;
1946 mark_buffer_clean(journal->j_sb_buffer);
1947 else if (!(ctx->options & E2F_OPT_READONLY)) {
1948 jsb = journal->j_superblock;
1949 jsb->s_sequence = htonl(journal->j_transaction_sequence);
1951 jsb->s_start = 0; /* this marks the journal as empty */
1952 mark_buffer_dirty(journal->j_sb_buffer);
1954 brelse(journal->j_sb_buffer);
1956 if (ctx->journal_io) {
1957 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1958 io_channel_close(ctx->journal_io);
1959 ctx->journal_io = 0;
1962 #ifndef USE_INODE_IO
1963 ext2fs_free_mem(&journal->j_inode);
1965 ext2fs_free_mem(&journal->j_fs_dev);
1966 ext2fs_free_mem(&journal);
1970 * This function makes sure that the superblock fields regarding the
1971 * journal are consistent.
1973 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
1975 struct ext2_super_block *sb = ctx->fs->super;
1977 int recover = ctx->fs->super->s_feature_incompat &
1978 EXT3_FEATURE_INCOMPAT_RECOVER;
1979 struct problem_context pctx;
1981 int reset = 0, force_fsck = 0;
1984 /* If we don't have any journal features, don't do anything more */
1985 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
1986 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
1987 uuid_is_null(sb->s_journal_uuid))
1990 clear_problem_context(&pctx);
1991 pctx.num = sb->s_journal_inum;
1993 retval = e2fsck_get_journal(ctx, &journal);
1995 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
1996 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
1997 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
1998 (retval == EXT2_ET_NO_JOURNAL))
1999 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2003 retval = e2fsck_journal_load(journal);
2005 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2006 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2007 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2009 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2010 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2012 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2013 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2014 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2016 e2fsck_journal_release(ctx, journal, 0, 1);
2021 * We want to make the flags consistent here. We will not leave with
2022 * needs_recovery set but has_journal clear. We can't get in a loop
2023 * with -y, -n, or -p, only if a user isn't making up their mind.
2026 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2027 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2029 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2031 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2032 goto no_has_journal;
2034 * Need a full fsck if we are releasing a
2035 * journal stored on a reserved inode.
2037 force_fsck = recover ||
2038 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2039 /* Clear all of the journal fields */
2040 sb->s_journal_inum = 0;
2041 sb->s_journal_dev = 0;
2042 memset(sb->s_journal_uuid, 0,
2043 sizeof(sb->s_journal_uuid));
2044 e2fsck_clear_recover(ctx, force_fsck);
2045 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2046 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2047 ext2fs_mark_super_dirty(ctx->fs);
2051 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2052 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2053 journal->j_superblock->s_start != 0) {
2054 /* Print status information */
2055 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2056 if (ctx->superblock)
2057 problem = PR_0_JOURNAL_RUN_DEFAULT;
2059 problem = PR_0_JOURNAL_RUN;
2060 if (fix_problem(ctx, problem, &pctx)) {
2061 ctx->options |= E2F_OPT_FORCE;
2062 sb->s_feature_incompat |=
2063 EXT3_FEATURE_INCOMPAT_RECOVER;
2064 ext2fs_mark_super_dirty(ctx->fs);
2065 } else if (fix_problem(ctx,
2066 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2068 sb->s_state &= ~EXT2_VALID_FS;
2069 ext2fs_mark_super_dirty(ctx->fs);
2072 * If the user answers no to the above question, we
2073 * ignore the fact that journal apparently has data;
2074 * accidentally replaying over valid data would be far
2075 * worse than skipping a questionable recovery.
2077 * XXX should we abort with a fatal error here? What
2078 * will the ext3 kernel code do if a filesystem with
2079 * !NEEDS_RECOVERY but with a non-zero
2080 * journal->j_superblock->s_start is mounted?
2084 e2fsck_journal_release(ctx, journal, reset, 0);
2088 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2093 journal_init_revoke_caches();
2094 retval = e2fsck_get_journal(ctx, &journal);
2098 retval = e2fsck_journal_load(journal);
2102 retval = journal_init_revoke(journal, 1024);
2106 retval = -journal_recover(journal);
2110 if (journal->j_superblock->s_errno) {
2111 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2112 ext2fs_mark_super_dirty(ctx->fs);
2113 journal->j_superblock->s_errno = 0;
2114 mark_buffer_dirty(journal->j_sb_buffer);
2118 journal_destroy_revoke(journal);
2119 journal_destroy_revoke_caches();
2120 e2fsck_journal_release(ctx, journal, 1, 0);
2124 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2126 io_manager io_ptr = ctx->fs->io->manager;
2127 int blocksize = ctx->fs->blocksize;
2128 errcode_t retval, recover_retval;
2130 printf(_("%s: recovering journal\n"), ctx->device_name);
2131 if (ctx->options & E2F_OPT_READONLY) {
2132 printf(_("%s: won't do journal recovery while read-only\n"),
2134 return EXT2_ET_FILE_RO;
2137 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2138 ext2fs_flush(ctx->fs); /* Force out any modifications */
2140 recover_retval = recover_ext3_journal(ctx);
2143 * Reload the filesystem context to get up-to-date data from disk
2144 * because journal recovery will change the filesystem under us.
2146 ext2fs_close(ctx->fs);
2147 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2148 ctx->superblock, blocksize, io_ptr,
2152 bb_error_msg(_("while trying to re-open %s"),
2154 bb_error_msg_and_die(0);
2156 ctx->fs->priv_data = ctx;
2158 /* Set the superblock flags */
2159 e2fsck_clear_recover(ctx, recover_retval);
2160 return recover_retval;
2164 * This function will move the journal inode from a visible file in
2165 * the filesystem directory hierarchy to the reserved inode if necessary.
2167 static const char *const journal_names[] = {
2168 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2170 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2172 struct ext2_super_block *sb = ctx->fs->super;
2173 struct problem_context pctx;
2174 struct ext2_inode inode;
2175 ext2_filsys fs = ctx->fs;
2178 const char *const * cpp;
2179 int group, mount_flags;
2181 clear_problem_context(&pctx);
2184 * If the filesystem is opened read-only, or there is no
2185 * journal, then do nothing.
2187 if ((ctx->options & E2F_OPT_READONLY) ||
2188 (sb->s_journal_inum == 0) ||
2189 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2193 * Read in the journal inode
2195 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2199 * If it's necessary to backup the journal inode, do so.
2201 if ((sb->s_jnl_backup_type == 0) ||
2202 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2203 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2204 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2205 memcpy(sb->s_jnl_blocks, inode.i_block,
2207 sb->s_jnl_blocks[16] = inode.i_size;
2208 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2209 ext2fs_mark_super_dirty(fs);
2210 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2215 * If the journal is already the hidden inode, then do nothing
2217 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2221 * The journal inode had better have only one link and not be readable.
2223 if (inode.i_links_count != 1)
2227 * If the filesystem is mounted, or we can't tell whether
2228 * or not it's mounted, do nothing.
2230 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2231 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2235 * If we can't find the name of the journal inode, then do
2238 for (cpp = journal_names; *cpp; cpp++) {
2239 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2240 strlen(*cpp), 0, &ino);
2241 if ((retval == 0) && (ino == sb->s_journal_inum))
2247 /* We need the inode bitmap to be loaded */
2248 retval = ext2fs_read_bitmaps(fs);
2253 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2257 * OK, we've done all the checks, let's actually move the
2258 * journal inode. Errors at this point mean we need to force
2259 * an ext2 filesystem check.
2261 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2263 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2265 sb->s_journal_inum = EXT2_JOURNAL_INO;
2266 ext2fs_mark_super_dirty(fs);
2267 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2268 inode.i_links_count = 0;
2269 inode.i_dtime = time(NULL);
2270 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2273 group = ext2fs_group_of_ino(fs, ino);
2274 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2275 ext2fs_mark_ib_dirty(fs);
2276 fs->group_desc[group].bg_free_inodes_count++;
2277 fs->super->s_free_inodes_count++;
2281 pctx.errcode = retval;
2282 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2283 fs->super->s_state &= ~EXT2_VALID_FS;
2284 ext2fs_mark_super_dirty(fs);
2288 * message.c --- print e2fsck messages (with compression)
2290 * print_e2fsck_message() prints a message to the user, using
2291 * compression techniques and expansions of abbreviations.
2293 * The following % expansions are supported:
2295 * %b <blk> block number
2296 * %B <blkcount> integer
2297 * %c <blk2> block number
2298 * %Di <dirent>->ino inode number
2299 * %Dn <dirent>->name string
2300 * %Dr <dirent>->rec_len
2301 * %Dl <dirent>->name_len
2302 * %Dt <dirent>->filetype
2303 * %d <dir> inode number
2304 * %g <group> integer
2305 * %i <ino> inode number
2306 * %Is <inode> -> i_size
2307 * %IS <inode> -> i_extra_isize
2308 * %Ib <inode> -> i_blocks
2309 * %Il <inode> -> i_links_count
2310 * %Im <inode> -> i_mode
2311 * %IM <inode> -> i_mtime
2312 * %IF <inode> -> i_faddr
2313 * %If <inode> -> i_file_acl
2314 * %Id <inode> -> i_dir_acl
2315 * %Iu <inode> -> i_uid
2316 * %Ig <inode> -> i_gid
2317 * %j <ino2> inode number
2318 * %m <com_err error message>
2320 * %p ext2fs_get_pathname of directory <ino>
2321 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2322 * the containing directory. (If dirent is NULL
2323 * then return the pathname of directory <ino2>)
2324 * %q ext2fs_get_pathname of directory <dir>
2325 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2326 * the containing directory.
2327 * %s <str> miscellaneous string
2328 * %S backup superblock
2329 * %X <num> hexadecimal format
2331 * The following '@' expansions are supported:
2333 * @a extended attribute
2334 * @A error allocating
2338 * @C conflicts with some other fs block
2342 * @E Entry '%Dn' in %p (%i)
2344 * @F for @i %i (%Q) is
2346 * @h HTREE directory inode
2352 * @m multiply-claimed
2366 * This structure defines the abbreviations used by the text strings
2367 * below. The first character in the string is the index letter. An
2368 * abbreviation of the form '@<i>' is expanded by looking up the index
2369 * letter <i> in the table below.
2371 static const char *const abbrevs[] = {
2372 N_("aextended attribute"),
2373 N_("Aerror allocating"),
2377 N_("Cconflicts with some other fs @b"),
2384 N_("E@e '%Dn' in %p (%i)"),
2386 N_("Ffor @i %i (%Q) is"),
2391 N_("mmultiply-claimed"),
2406 * Give more user friendly names to the "special" inodes.
2408 #define num_special_inodes 11
2409 static const char *const special_inode_name[] =
2411 N_("<The NULL inode>"), /* 0 */
2412 N_("<The bad blocks inode>"), /* 1 */
2414 N_("<The ACL index inode>"), /* 3 */
2415 N_("<The ACL data inode>"), /* 4 */
2416 N_("<The boot loader inode>"), /* 5 */
2417 N_("<The undelete directory inode>"), /* 6 */
2418 N_("<The group descriptor inode>"), /* 7 */
2419 N_("<The journal inode>"), /* 8 */
2420 N_("<Reserved inode 9>"), /* 9 */
2421 N_("<Reserved inode 10>"), /* 10 */
2425 * This function does "safe" printing. It will convert non-printable
2426 * ASCII characters using '^' and M- notation.
2428 static void safe_print(const char *cp, int len)
2438 fputs("M-", stdout);
2441 if ((ch < 32) || (ch == 0x7f)) {
2443 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2451 * This function prints a pathname, using the ext2fs_get_pathname
2454 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2459 if (!dir && (ino < num_special_inodes)) {
2460 fputs(_(special_inode_name[ino]), stdout);
2464 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2466 fputs("???", stdout);
2468 safe_print(path, -1);
2469 ext2fs_free_mem(&path);
2473 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2474 struct problem_context *pctx, int first);
2476 * This function handles the '@' expansion. We allow recursive
2477 * expansion; an @ expression can contain further '@' and '%'
2480 static void expand_at_expression(e2fsck_t ctx, char ch,
2481 struct problem_context *pctx,
2484 const char *const *cpp;
2487 /* Search for the abbreviation */
2488 for (cpp = abbrevs; *cpp; cpp++) {
2494 if (*first && islower(*str)) {
2496 bb_putchar(toupper(*str++));
2498 print_e2fsck_message(ctx, str, pctx, *first);
2504 * This function expands '%IX' expressions
2506 static void expand_inode_expression(char ch,
2507 struct problem_context *ctx)
2509 struct ext2_inode *inode;
2510 struct ext2_inode_large *large_inode;
2515 if (!ctx || !ctx->inode)
2519 large_inode = (struct ext2_inode_large *) inode;
2523 if (LINUX_S_ISDIR(inode->i_mode))
2524 printf("%u", inode->i_size);
2526 printf("%"PRIu64, (inode->i_size |
2527 ((uint64_t) inode->i_size_high << 32)));
2531 printf("%u", large_inode->i_extra_isize);
2534 printf("%u", inode->i_blocks);
2537 printf("%d", inode->i_links_count);
2540 printf("0%o", inode->i_mode);
2543 /* The diet libc doesn't respect the TZ environemnt variable */
2545 time_str = getenv("TZ");
2548 do_gmt = !strcmp(time_str, "GMT");
2551 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2552 printf("%.24s", time_str);
2555 printf("%u", inode->i_faddr);
2558 printf("%u", inode->i_file_acl);
2561 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2562 inode->i_dir_acl : 0));
2565 printf("%d", (inode->i_uid |
2566 (inode->osd2.linux2.l_i_uid_high << 16)));
2569 printf("%d", (inode->i_gid |
2570 (inode->osd2.linux2.l_i_gid_high << 16)));
2574 printf("%%I%c", ch);
2580 * This function expands '%dX' expressions
2582 static void expand_dirent_expression(char ch,
2583 struct problem_context *ctx)
2585 struct ext2_dir_entry *dirent;
2588 if (!ctx || !ctx->dirent)
2591 dirent = ctx->dirent;
2595 printf("%u", dirent->inode);
2598 len = dirent->name_len & 0xFF;
2599 if (len > EXT2_NAME_LEN)
2600 len = EXT2_NAME_LEN;
2601 if (len > dirent->rec_len)
2602 len = dirent->rec_len;
2603 safe_print(dirent->name, len);
2606 printf("%u", dirent->rec_len);
2609 printf("%u", dirent->name_len & 0xFF);
2612 printf("%u", dirent->name_len >> 8);
2616 printf("%%D%c", ch);
2621 static void expand_percent_expression(ext2_filsys fs, char ch,
2622 struct problem_context *ctx)
2632 printf("%u", ctx->blk);
2635 printf("%"PRIi64, ctx->blkcount);
2638 printf("%u", ctx->blk2);
2641 printf("%u", ctx->dir);
2644 printf("%d", ctx->group);
2647 printf("%u", ctx->ino);
2650 printf("%u", ctx->ino2);
2653 fputs(error_message(ctx->errcode), stdout);
2656 printf("%"PRIi64, ctx->num);
2659 print_pathname(fs, ctx->ino, 0);
2662 print_pathname(fs, ctx->ino2,
2663 ctx->dirent ? ctx->dirent->inode : 0);
2666 print_pathname(fs, ctx->dir, 0);
2669 print_pathname(fs, ctx->dir, ctx->ino);
2672 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2675 fputs((ctx->str ? ctx->str : "NULL"), stdout);
2678 printf("0x%"PRIi64, ctx->num);
2688 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2689 struct problem_context *pctx, int first)
2691 ext2_filsys fs = ctx->fs;
2695 e2fsck_clear_progbar(ctx);
2696 for (cp = msg; *cp; cp++) {
2699 expand_at_expression(ctx, *cp, pctx, &first);
2700 } else if (cp[0] == '%' && cp[1] == 'I') {
2702 expand_inode_expression(*cp, pctx);
2703 } else if (cp[0] == '%' && cp[1] == 'D') {
2705 expand_dirent_expression(*cp, pctx);
2706 } else if ((cp[0] == '%')) {
2708 expand_percent_expression(fs, *cp, pctx);
2710 for (i=0; cp[i]; i++)
2711 if ((cp[i] == '@') || cp[i] == '%')
2713 printf("%.*s", i, cp);
2722 * region.c --- code which manages allocations within a region.
2726 region_addr_t start;
2728 struct region_el *next;
2731 struct region_struct {
2734 struct region_el *allocated;
2737 static region_t region_create(region_addr_t min, region_addr_t max)
2741 region = xzalloc(sizeof(struct region_struct));
2747 static void region_free(region_t region)
2749 struct region_el *r, *next;
2751 for (r = region->allocated; r; r = next) {
2755 memset(region, 0, sizeof(struct region_struct));
2759 static int region_allocate(region_t region, region_addr_t start, int n)
2761 struct region_el *r, *new_region, *prev, *next;
2765 if ((start < region->min) || (end > region->max))
2771 * Search through the linked list. If we find that it
2772 * conflicts witih something that's already allocated, return
2773 * 1; if we can find an existing region which we can grow, do
2774 * so. Otherwise, stop when we find the appropriate place
2775 * insert a new region element into the linked list.
2777 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2778 if (((start >= r->start) && (start < r->end)) ||
2779 ((end > r->start) && (end <= r->end)) ||
2780 ((start <= r->start) && (end >= r->end)))
2782 if (end == r->start) {
2786 if (start == r->end) {
2787 if ((next = r->next)) {
2788 if (end > next->start)
2790 if (end == next->start) {
2792 r->next = next->next;
2800 if (start < r->start)
2804 * Insert a new region element structure into the linked list
2806 new_region = xmalloc(sizeof(struct region_el));
2807 new_region->start = start;
2808 new_region->end = start + n;
2809 new_region->next = r;
2811 prev->next = new_region;
2813 region->allocated = new_region;
2818 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2820 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2821 * and applies the following tests to each inode:
2823 * - The mode field of the inode must be legal.
2824 * - The size and block count fields of the inode are correct.
2825 * - A data block must not be used by another inode
2827 * Pass 1 also gathers the collects the following information:
2829 * - A bitmap of which inodes are in use. (inode_used_map)
2830 * - A bitmap of which inodes are directories. (inode_dir_map)
2831 * - A bitmap of which inodes are regular files. (inode_reg_map)
2832 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2833 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2834 * - A bitmap of which blocks are in use. (block_found_map)
2835 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2836 * - The data blocks of the directory inodes. (dir_map)
2838 * Pass 1 is designed to stash away enough information so that the
2839 * other passes should not need to read in the inode information
2840 * during the normal course of a filesystem check. (Althogh if an
2841 * inconsistency is detected, other passes may need to read in an
2844 * Note that pass 1B will be invoked if there are any duplicate blocks
2849 static int process_block(ext2_filsys fs, blk_t *blocknr,
2850 e2_blkcnt_t blockcnt, blk_t ref_blk,
2851 int ref_offset, void *priv_data);
2852 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2853 e2_blkcnt_t blockcnt, blk_t ref_blk,
2854 int ref_offset, void *priv_data);
2855 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2857 static void mark_table_blocks(e2fsck_t ctx);
2858 static void alloc_imagic_map(e2fsck_t ctx);
2859 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2860 static void handle_fs_bad_blocks(e2fsck_t ctx);
2861 static void process_inodes(e2fsck_t ctx, char *block_buf);
2862 static int process_inode_cmp(const void *a, const void *b);
2863 static errcode_t scan_callback(ext2_filsys fs,
2864 dgrp_t group, void * priv_data);
2865 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2866 char *block_buf, int adjust_sign);
2867 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2869 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2870 struct ext2_inode * inode, int bufsize,
2873 struct process_block_struct_1 {
2875 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
2876 fragmented:1, compressed:1, bbcheck:1;
2879 e2_blkcnt_t last_block;
2880 int num_illegal_blocks;
2881 blk_t previous_block;
2882 struct ext2_inode *inode;
2883 struct problem_context *pctx;
2884 ext2fs_block_bitmap fs_meta_blocks;
2888 struct process_inode_block {
2890 struct ext2_inode inode;
2893 struct scan_callback_struct {
2899 * For the inodes to process list.
2901 static struct process_inode_block *inodes_to_process;
2902 static int process_inode_count;
2904 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2905 EXT2_MIN_BLOCK_LOG_SIZE + 1];
2908 * Free all memory allocated by pass1 in preparation for restarting
2911 static void unwind_pass1(void)
2913 ext2fs_free_mem(&inodes_to_process);
2917 * Check to make sure a device inode is real. Returns 1 if the device
2918 * checks out, 0 if not.
2920 * Note: this routine is now also used to check FIFO's and Sockets,
2921 * since they have the same requirement; the i_block fields should be
2925 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2930 * If i_blocks is non-zero, or the index flag is set, then
2931 * this is a bogus device/fifo/socket
2933 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2934 (inode->i_flags & EXT2_INDEX_FL))
2938 * We should be able to do the test below all the time, but
2939 * because the kernel doesn't forcibly clear the device
2940 * inode's additional i_block fields, there are some rare
2941 * occasions when a legitimate device inode will have non-zero
2942 * additional i_block fields. So for now, we only complain
2943 * when the immutable flag is set, which should never happen
2944 * for devices. (And that's when the problem is caused, since
2945 * you can't set or clear immutable flags for devices.) Once
2946 * the kernel has been fixed we can change this...
2948 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2949 for (i=4; i < EXT2_N_BLOCKS; i++)
2950 if (inode->i_block[i])
2957 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2958 * checks out, 0 if not.
2961 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
2967 if ((inode->i_size_high || inode->i_size == 0) ||
2968 (inode->i_flags & EXT2_INDEX_FL))
2971 blocks = ext2fs_inode_data_blocks(fs, inode);
2973 if ((inode->i_size >= fs->blocksize) ||
2974 (blocks != fs->blocksize >> 9) ||
2975 (inode->i_block[0] < fs->super->s_first_data_block) ||
2976 (inode->i_block[0] >= fs->super->s_blocks_count))
2979 for (i = 1; i < EXT2_N_BLOCKS; i++)
2980 if (inode->i_block[i])
2983 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
2986 len = strnlen(buf, fs->blocksize);
2987 if (len == fs->blocksize)
2990 if (inode->i_size >= sizeof(inode->i_block))
2993 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
2994 if (len == sizeof(inode->i_block))
2997 if (len != inode->i_size)
3003 * If the immutable (or append-only) flag is set on the inode, offer
3006 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3007 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3009 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3012 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3015 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3016 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3020 * If device, fifo or socket, check size is zero -- if not offer to
3023 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3025 struct ext2_inode *inode = pctx->inode;
3027 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3030 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3034 inode->i_size_high = 0;
3035 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3038 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3040 struct ext2_super_block *sb = ctx->fs->super;
3041 struct ext2_inode_large *inode;
3042 struct ext2_ext_attr_entry *entry;
3044 int storage_size, remain, offs;
3047 inode = (struct ext2_inode_large *) pctx->inode;
3048 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3049 inode->i_extra_isize;
3050 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3051 inode->i_extra_isize + sizeof(__u32);
3052 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3053 entry = (struct ext2_ext_attr_entry *) start;
3055 /* scan all entry's headers first */
3057 /* take finish entry 0UL into account */
3058 remain = storage_size - sizeof(__u32);
3061 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3063 /* header eats this space */
3064 remain -= sizeof(struct ext2_ext_attr_entry);
3066 /* is attribute name valid? */
3067 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3068 pctx->num = entry->e_name_len;
3069 problem = PR_1_ATTR_NAME_LEN;
3073 /* attribute len eats this space */
3074 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3076 /* check value size */
3077 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3078 pctx->num = entry->e_value_size;
3079 problem = PR_1_ATTR_VALUE_SIZE;
3083 /* check value placement */
3084 if (entry->e_value_offs +
3085 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3086 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3087 pctx->num = entry->e_value_offs;
3088 problem = PR_1_ATTR_VALUE_OFFSET;
3092 /* e_value_block must be 0 in inode's ea */
3093 if (entry->e_value_block != 0) {
3094 pctx->num = entry->e_value_block;
3095 problem = PR_1_ATTR_VALUE_BLOCK;
3099 /* e_hash must be 0 in inode's ea */
3100 if (entry->e_hash != 0) {
3101 pctx->num = entry->e_hash;
3102 problem = PR_1_ATTR_HASH;
3106 remain -= entry->e_value_size;
3107 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3109 entry = EXT2_EXT_ATTR_NEXT(entry);
3113 * it seems like a corruption. it's very unlikely we could repair
3114 * EA(s) in automatic fashion -bzzz
3116 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3119 /* simple remove all possible EA(s) */
3120 *((__u32 *)start) = 0UL;
3121 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3122 EXT2_INODE_SIZE(sb), "pass1");
3125 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3127 struct ext2_super_block *sb = ctx->fs->super;
3128 struct ext2_inode_large *inode;
3132 inode = (struct ext2_inode_large *) pctx->inode;
3133 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3134 /* this isn't large inode. so, nothing to check */
3138 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3139 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3140 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3142 * For now we will allow i_extra_isize to be 0, but really
3143 * implementations should never allow i_extra_isize to be 0
3145 if (inode->i_extra_isize &&
3146 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3147 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3149 inode->i_extra_isize = min;
3150 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3151 EXT2_INODE_SIZE(sb), "pass1");
3155 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3156 inode->i_extra_isize);
3157 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3158 /* it seems inode has an extended attribute(s) in body */
3159 check_ea_in_inode(ctx, pctx);
3163 static void e2fsck_pass1(e2fsck_t ctx)
3167 ext2_filsys fs = ctx->fs;
3169 struct ext2_inode *inode;
3170 ext2_inode_scan scan;
3172 unsigned char frag, fsize;
3173 struct problem_context pctx;
3174 struct scan_callback_struct scan_struct;
3175 struct ext2_super_block *sb = ctx->fs->super;
3177 int busted_fs_time = 0;
3180 clear_problem_context(&pctx);
3182 if (!(ctx->options & E2F_OPT_PREEN))
3183 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3185 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3186 !(ctx->options & E2F_OPT_NO)) {
3187 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3188 ctx->dirs_to_hash = 0;
3193 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3195 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3196 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3197 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3198 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3199 max_sizes = (max_sizes * (1UL << i)) - 1;
3200 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3204 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3207 * Allocate bitmaps structures
3209 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3210 &ctx->inode_used_map);
3213 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3214 ctx->flags |= E2F_FLAG_ABORT;
3217 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3218 _("directory inode map"), &ctx->inode_dir_map);
3221 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3222 ctx->flags |= E2F_FLAG_ABORT;
3225 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3226 _("regular file inode map"), &ctx->inode_reg_map);
3229 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3230 ctx->flags |= E2F_FLAG_ABORT;
3233 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3234 &ctx->block_found_map);
3237 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3238 ctx->flags |= E2F_FLAG_ABORT;
3241 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3242 &ctx->inode_link_info);
3244 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3245 ctx->flags |= E2F_FLAG_ABORT;
3248 inode_size = EXT2_INODE_SIZE(fs->super);
3249 inode = (struct ext2_inode *)
3250 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3252 inodes_to_process = (struct process_inode_block *)
3253 e2fsck_allocate_memory(ctx,
3254 (ctx->process_inode_size *
3255 sizeof(struct process_inode_block)),
3256 "array of inodes to process");
3257 process_inode_count = 0;
3259 pctx.errcode = ext2fs_init_dblist(fs, 0);
3261 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3262 ctx->flags |= E2F_FLAG_ABORT;
3267 * If the last orphan field is set, clear it, since the pass1
3268 * processing will automatically find and clear the orphans.
3269 * In the future, we may want to try using the last_orphan
3270 * linked list ourselves, but for now, we clear it so that the
3271 * ext3 mount code won't get confused.
3273 if (!(ctx->options & E2F_OPT_READONLY)) {
3274 if (fs->super->s_last_orphan) {
3275 fs->super->s_last_orphan = 0;
3276 ext2fs_mark_super_dirty(fs);
3280 mark_table_blocks(ctx);
3281 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3282 "block interate buffer");
3283 e2fsck_use_inode_shortcuts(ctx, 1);
3284 ehandler_operation(_("doing inode scan"));
3285 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3288 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3289 ctx->flags |= E2F_FLAG_ABORT;
3292 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3293 ctx->stashed_inode = inode;
3294 scan_struct.ctx = ctx;
3295 scan_struct.block_buf = block_buf;
3296 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3298 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3300 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3301 (fs->super->s_mtime < fs->super->s_inodes_count))
3305 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3307 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3309 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3313 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3314 ctx->flags |= E2F_FLAG_ABORT;
3321 ctx->stashed_ino = ino;
3322 if (inode->i_links_count) {
3323 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3324 ino, inode->i_links_count);
3326 pctx.num = inode->i_links_count;
3327 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3328 ctx->flags |= E2F_FLAG_ABORT;
3332 if (ino == EXT2_BAD_INO) {
3333 struct process_block_struct_1 pb;
3335 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3336 &pb.fs_meta_blocks);
3339 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3340 ctx->flags |= E2F_FLAG_ABORT;
3343 pb.ino = EXT2_BAD_INO;
3344 pb.num_blocks = pb.last_block = 0;
3345 pb.num_illegal_blocks = 0;
3346 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3347 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3351 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3352 block_buf, process_bad_block, &pb);
3353 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3355 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3356 ctx->flags |= E2F_FLAG_ABORT;
3360 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3361 ctx->flags |= E2F_FLAG_ABORT;
3364 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3365 clear_problem_context(&pctx);
3367 } else if (ino == EXT2_ROOT_INO) {
3369 * Make sure the root inode is a directory; if
3370 * not, offer to clear it. It will be
3371 * regnerated in pass #3.
3373 if (!LINUX_S_ISDIR(inode->i_mode)) {
3374 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3375 inode->i_dtime = time(NULL);
3376 inode->i_links_count = 0;
3377 ext2fs_icount_store(ctx->inode_link_info,
3379 e2fsck_write_inode(ctx, ino, inode,
3385 * If dtime is set, offer to clear it. mke2fs
3386 * version 0.2b created filesystems with the
3387 * dtime field set for the root and lost+found
3388 * directories. We won't worry about
3389 * /lost+found, since that can be regenerated
3390 * easily. But we will fix the root directory
3391 * as a special case.
3393 if (inode->i_dtime && inode->i_links_count) {
3394 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3396 e2fsck_write_inode(ctx, ino, inode,
3400 } else if (ino == EXT2_JOURNAL_INO) {
3401 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3402 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3403 if (!LINUX_S_ISREG(inode->i_mode) &&
3404 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3406 inode->i_mode = LINUX_S_IFREG;
3407 e2fsck_write_inode(ctx, ino, inode,
3410 check_blocks(ctx, &pctx, block_buf);
3413 if ((inode->i_links_count || inode->i_blocks ||
3414 inode->i_blocks || inode->i_block[0]) &&
3415 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3417 memset(inode, 0, inode_size);
3418 ext2fs_icount_store(ctx->inode_link_info,
3420 e2fsck_write_inode_full(ctx, ino, inode,
3421 inode_size, "pass1");
3423 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3426 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3427 if (ino == EXT2_BOOT_LOADER_INO) {
3428 if (LINUX_S_ISDIR(inode->i_mode))
3429 problem = PR_1_RESERVED_BAD_MODE;
3430 } else if (ino == EXT2_RESIZE_INO) {
3431 if (inode->i_mode &&
3432 !LINUX_S_ISREG(inode->i_mode))
3433 problem = PR_1_RESERVED_BAD_MODE;
3435 if (inode->i_mode != 0)
3436 problem = PR_1_RESERVED_BAD_MODE;
3439 if (fix_problem(ctx, problem, &pctx)) {
3441 e2fsck_write_inode(ctx, ino, inode,
3445 check_blocks(ctx, &pctx, block_buf);
3449 * Check for inodes who might have been part of the
3450 * orphaned list linked list. They should have gotten
3451 * dealt with by now, unless the list had somehow been
3454 * FIXME: In the future, inodes which are still in use
3455 * (and which are therefore) pending truncation should
3456 * be handled specially. Right now we just clear the
3457 * dtime field, and the normal e2fsck handling of
3458 * inodes where i_size and the inode blocks are
3459 * inconsistent is to fix i_size, instead of releasing
3460 * the extra blocks. This won't catch the inodes that
3461 * was at the end of the orphan list, but it's better
3462 * than nothing. The right answer is that there
3463 * shouldn't be any bugs in the orphan list handling. :-)
3465 if (inode->i_dtime && !busted_fs_time &&
3466 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3467 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3468 inode->i_dtime = inode->i_links_count ?
3470 e2fsck_write_inode(ctx, ino, inode,
3476 * This code assumes that deleted inodes have
3477 * i_links_count set to 0.
3479 if (!inode->i_links_count) {
3480 if (!inode->i_dtime && inode->i_mode) {
3481 if (fix_problem(ctx,
3482 PR_1_ZERO_DTIME, &pctx)) {
3483 inode->i_dtime = time(NULL);
3484 e2fsck_write_inode(ctx, ino, inode,
3491 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3492 * deleted files. Oops.
3494 * Since all new ext2 implementations get this right,
3495 * we now assume that the case of non-zero
3496 * i_links_count and non-zero dtime means that we
3497 * should keep the file, not delete it.
3500 if (inode->i_dtime) {
3501 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3503 e2fsck_write_inode(ctx, ino, inode, "pass1");
3507 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3508 switch (fs->super->s_creator_os) {
3510 frag = inode->osd2.linux2.l_i_frag;
3511 fsize = inode->osd2.linux2.l_i_fsize;
3514 frag = inode->osd2.hurd2.h_i_frag;
3515 fsize = inode->osd2.hurd2.h_i_fsize;
3518 frag = inode->osd2.masix2.m_i_frag;
3519 fsize = inode->osd2.masix2.m_i_fsize;
3525 if (inode->i_faddr || frag || fsize ||
3526 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3527 mark_inode_bad(ctx, ino);
3528 if (inode->i_flags & EXT2_IMAGIC_FL) {
3530 if (!ctx->inode_imagic_map)
3531 alloc_imagic_map(ctx);
3532 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3535 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3536 inode->i_flags &= ~EXT2_IMAGIC_FL;
3537 e2fsck_write_inode(ctx, ino,
3543 check_inode_extra_space(ctx, &pctx);
3545 if (LINUX_S_ISDIR(inode->i_mode)) {
3546 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3547 e2fsck_add_dir_info(ctx, ino, 0);
3548 ctx->fs_directory_count++;
3549 } else if (LINUX_S_ISREG (inode->i_mode)) {
3550 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3551 ctx->fs_regular_count++;
3552 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3553 e2fsck_pass1_check_device_inode(fs, inode)) {
3554 check_immutable(ctx, &pctx);
3555 check_size(ctx, &pctx);
3556 ctx->fs_chardev_count++;
3557 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3558 e2fsck_pass1_check_device_inode(fs, inode)) {
3559 check_immutable(ctx, &pctx);
3560 check_size(ctx, &pctx);
3561 ctx->fs_blockdev_count++;
3562 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3563 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3564 check_immutable(ctx, &pctx);
3565 ctx->fs_symlinks_count++;
3566 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3567 ctx->fs_fast_symlinks_count++;
3568 check_blocks(ctx, &pctx, block_buf);
3572 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3573 e2fsck_pass1_check_device_inode(fs, inode)) {
3574 check_immutable(ctx, &pctx);
3575 check_size(ctx, &pctx);
3576 ctx->fs_fifo_count++;
3577 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3578 e2fsck_pass1_check_device_inode(fs, inode)) {
3579 check_immutable(ctx, &pctx);
3580 check_size(ctx, &pctx);
3581 ctx->fs_sockets_count++;
3583 mark_inode_bad(ctx, ino);
3584 if (inode->i_block[EXT2_IND_BLOCK])
3585 ctx->fs_ind_count++;
3586 if (inode->i_block[EXT2_DIND_BLOCK])
3587 ctx->fs_dind_count++;
3588 if (inode->i_block[EXT2_TIND_BLOCK])
3589 ctx->fs_tind_count++;
3590 if (inode->i_block[EXT2_IND_BLOCK] ||
3591 inode->i_block[EXT2_DIND_BLOCK] ||
3592 inode->i_block[EXT2_TIND_BLOCK] ||
3593 inode->i_file_acl) {
3594 inodes_to_process[process_inode_count].ino = ino;
3595 inodes_to_process[process_inode_count].inode = *inode;
3596 process_inode_count++;
3598 check_blocks(ctx, &pctx, block_buf);
3600 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3603 if (process_inode_count >= ctx->process_inode_size) {
3604 process_inodes(ctx, block_buf);
3606 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3610 process_inodes(ctx, block_buf);
3611 ext2fs_close_inode_scan(scan);
3612 ehandler_operation(0);
3615 * If any extended attribute blocks' reference counts need to
3616 * be adjusted, either up (ctx->refcount_extra), or down
3617 * (ctx->refcount), then fix them.
3619 if (ctx->refcount) {
3620 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3621 ea_refcount_free(ctx->refcount);
3624 if (ctx->refcount_extra) {
3625 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3627 ea_refcount_free(ctx->refcount_extra);
3628 ctx->refcount_extra = 0;
3631 if (ctx->invalid_bitmaps)
3632 handle_fs_bad_blocks(ctx);
3634 /* We don't need the block_ea_map any more */
3635 ext2fs_free_block_bitmap(ctx->block_ea_map);
3636 ctx->block_ea_map = 0;
3638 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3639 ext2fs_block_bitmap save_bmap;
3641 save_bmap = fs->block_map;
3642 fs->block_map = ctx->block_found_map;
3643 clear_problem_context(&pctx);
3644 pctx.errcode = ext2fs_create_resize_inode(fs);
3646 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3647 /* Should never get here */
3648 ctx->flags |= E2F_FLAG_ABORT;
3651 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3653 inode->i_mtime = time(NULL);
3654 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3656 fs->block_map = save_bmap;
3657 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3660 if (ctx->flags & E2F_FLAG_RESTART) {
3662 * Only the master copy of the superblock and block
3663 * group descriptors are going to be written during a
3664 * restart, so set the superblock to be used to be the
3665 * master superblock.
3667 ctx->use_superblock = 0;
3672 if (ctx->block_dup_map) {
3673 if (ctx->options & E2F_OPT_PREEN) {
3674 clear_problem_context(&pctx);
3675 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3677 e2fsck_pass1_dupblocks(ctx, block_buf);
3679 ext2fs_free_mem(&inodes_to_process);
3681 e2fsck_use_inode_shortcuts(ctx, 0);
3683 ext2fs_free_mem(&block_buf);
3684 ext2fs_free_mem(&inode);
3689 * When the inode_scan routines call this callback at the end of the
3690 * glock group, call process_inodes.
3692 static errcode_t scan_callback(ext2_filsys fs,
3693 dgrp_t group, void * priv_data)
3695 struct scan_callback_struct *scan_struct;
3698 scan_struct = (struct scan_callback_struct *) priv_data;
3699 ctx = scan_struct->ctx;
3701 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3704 if ((ctx->progress)(ctx, 1, group+1,
3705 ctx->fs->group_desc_count))
3706 return EXT2_ET_CANCEL_REQUESTED;
3712 * Process the inodes in the "inodes to process" list.
3714 static void process_inodes(e2fsck_t ctx, char *block_buf)
3717 struct ext2_inode *old_stashed_inode;
3718 ext2_ino_t old_stashed_ino;
3719 const char *old_operation;
3721 struct problem_context pctx;
3723 /* begin process_inodes */
3724 if (process_inode_count == 0)
3726 old_operation = ehandler_operation(0);
3727 old_stashed_inode = ctx->stashed_inode;
3728 old_stashed_ino = ctx->stashed_ino;
3729 qsort(inodes_to_process, process_inode_count,
3730 sizeof(struct process_inode_block), process_inode_cmp);
3731 clear_problem_context(&pctx);
3732 for (i=0; i < process_inode_count; i++) {
3733 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3734 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3735 sprintf(buf, _("reading indirect blocks of inode %u"),
3737 ehandler_operation(buf);
3738 check_blocks(ctx, &pctx, block_buf);
3739 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3742 ctx->stashed_inode = old_stashed_inode;
3743 ctx->stashed_ino = old_stashed_ino;
3744 process_inode_count = 0;
3745 /* end process inodes */
3747 ehandler_operation(old_operation);
3750 static int process_inode_cmp(const void *a, const void *b)
3752 const struct process_inode_block *ib_a =
3753 (const struct process_inode_block *) a;
3754 const struct process_inode_block *ib_b =
3755 (const struct process_inode_block *) b;
3758 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3759 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3761 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3766 * Mark an inode as being bad in some what
3768 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3770 struct problem_context pctx;
3772 if (!ctx->inode_bad_map) {
3773 clear_problem_context(&pctx);
3775 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3776 _("bad inode map"), &ctx->inode_bad_map);
3779 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3780 /* Should never get here */
3781 ctx->flags |= E2F_FLAG_ABORT;
3785 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3790 * This procedure will allocate the inode imagic table
3792 static void alloc_imagic_map(e2fsck_t ctx)
3794 struct problem_context pctx;
3796 clear_problem_context(&pctx);
3797 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3798 _("imagic inode map"),
3799 &ctx->inode_imagic_map);
3802 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3803 /* Should never get here */
3804 ctx->flags |= E2F_FLAG_ABORT;
3810 * Marks a block as in use, setting the dup_map if it's been set
3811 * already. Called by process_block and process_bad_block.
3813 * WARNING: Assumes checks have already been done to make sure block
3814 * is valid. This is true in both process_block and process_bad_block.
3816 static void mark_block_used(e2fsck_t ctx, blk_t block)
3818 struct problem_context pctx;
3820 clear_problem_context(&pctx);
3822 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3823 if (!ctx->block_dup_map) {
3824 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3825 _("multiply claimed block map"),
3826 &ctx->block_dup_map);
3829 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3831 /* Should never get here */
3832 ctx->flags |= E2F_FLAG_ABORT;
3836 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3838 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3843 * Adjust the extended attribute block's reference counts at the end
3844 * of pass 1, either by subtracting out references for EA blocks that
3845 * are still referenced in ctx->refcount, or by adding references for
3846 * EA blocks that had extra references as accounted for in
3847 * ctx->refcount_extra.
3849 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3850 char *block_buf, int adjust_sign)
3852 struct ext2_ext_attr_header *header;
3853 struct problem_context pctx;
3854 ext2_filsys fs = ctx->fs;
3859 clear_problem_context(&pctx);
3861 ea_refcount_intr_begin(refcount);
3863 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3866 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3868 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3871 header = (struct ext2_ext_attr_header *) block_buf;
3872 pctx.blkcount = header->h_refcount;
3873 should_be = header->h_refcount + adjust_sign * count;
3874 pctx.num = should_be;
3875 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3876 header->h_refcount = should_be;
3877 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3880 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3888 * Handle processing the extended attribute blocks
3890 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3893 ext2_filsys fs = ctx->fs;
3894 ext2_ino_t ino = pctx->ino;
3895 struct ext2_inode *inode = pctx->inode;
3898 struct ext2_ext_attr_header *header;
3899 struct ext2_ext_attr_entry *entry;
3903 blk = inode->i_file_acl;
3908 * If the Extended attribute flag isn't set, then a non-zero
3909 * file acl means that the inode is corrupted.
3911 * Or if the extended attribute block is an invalid block,
3912 * then the inode is also corrupted.
3914 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3915 (blk < fs->super->s_first_data_block) ||
3916 (blk >= fs->super->s_blocks_count)) {
3917 mark_inode_bad(ctx, ino);
3921 /* If ea bitmap hasn't been allocated, create it */
3922 if (!ctx->block_ea_map) {
3923 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3924 _("ext attr block map"),
3925 &ctx->block_ea_map);
3926 if (pctx->errcode) {
3928 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3929 ctx->flags |= E2F_FLAG_ABORT;
3934 /* Create the EA refcount structure if necessary */
3935 if (!ctx->refcount) {
3936 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3937 if (pctx->errcode) {
3939 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3940 ctx->flags |= E2F_FLAG_ABORT;
3945 /* Have we seen this EA block before? */
3946 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3947 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3949 /* Ooops, this EA was referenced more than it stated */
3950 if (!ctx->refcount_extra) {
3951 pctx->errcode = ea_refcount_create(0,
3952 &ctx->refcount_extra);
3953 if (pctx->errcode) {
3955 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3956 ctx->flags |= E2F_FLAG_ABORT;
3960 ea_refcount_increment(ctx->refcount_extra, blk, 0);
3965 * OK, we haven't seen this EA block yet. So we need to
3969 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3970 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
3972 header = (struct ext2_ext_attr_header *) block_buf;
3973 pctx->blk = inode->i_file_acl;
3974 if (((ctx->ext_attr_ver == 1) &&
3975 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
3976 ((ctx->ext_attr_ver == 2) &&
3977 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
3978 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
3982 if (header->h_blocks != 1) {
3983 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
3987 region = region_create(0, fs->blocksize);
3989 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
3990 ctx->flags |= E2F_FLAG_ABORT;
3993 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
3994 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
3998 entry = (struct ext2_ext_attr_entry *)(header+1);
3999 end = block_buf + fs->blocksize;
4000 while ((char *)entry < end && *(__u32 *)entry) {
4001 if (region_allocate(region, (char *)entry - (char *)header,
4002 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4003 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4006 if ((ctx->ext_attr_ver == 1 &&
4007 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4008 (ctx->ext_attr_ver == 2 &&
4009 entry->e_name_index == 0)) {
4010 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4013 if (entry->e_value_block != 0) {
4014 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4017 if (entry->e_value_size &&
4018 region_allocate(region, entry->e_value_offs,
4019 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4020 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4023 entry = EXT2_EXT_ATTR_NEXT(entry);
4025 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4026 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4029 region_free(region);
4031 count = header->h_refcount - 1;
4033 ea_refcount_store(ctx->refcount, blk, count);
4034 mark_block_used(ctx, blk);
4035 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4040 inode->i_file_acl = 0;
4041 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4045 /* Returns 1 if bad htree, 0 if OK */
4046 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4047 ext2_ino_t ino FSCK_ATTR((unused)),
4048 struct ext2_inode *inode,
4051 struct ext2_dx_root_info *root;
4052 ext2_filsys fs = ctx->fs;
4056 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4057 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4058 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4059 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4062 blk = inode->i_block[0];
4064 (blk < fs->super->s_first_data_block) ||
4065 (blk >= fs->super->s_blocks_count)) &&
4066 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4069 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4070 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4073 /* XXX should check that beginning matches a directory */
4074 root = (struct ext2_dx_root_info *) (block_buf + 24);
4076 if ((root->reserved_zero || root->info_length < 8) &&
4077 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4080 pctx->num = root->hash_version;
4081 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4082 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4083 (root->hash_version != EXT2_HASH_TEA) &&
4084 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4087 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4088 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4091 pctx->num = root->indirect_levels;
4092 if ((root->indirect_levels > 1) &&
4093 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4100 * This subroutine is called on each inode to account for all of the
4101 * blocks used by that inode.
4103 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4106 ext2_filsys fs = ctx->fs;
4107 struct process_block_struct_1 pb;
4108 ext2_ino_t ino = pctx->ino;
4109 struct ext2_inode *inode = pctx->inode;
4111 int dirty_inode = 0;
4117 pb.num_illegal_blocks = 0;
4118 pb.suppress = 0; pb.clear = 0;
4121 pb.previous_block = 0;
4122 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4123 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4124 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4131 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4132 if (fs->super->s_feature_incompat &
4133 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4136 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4137 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4143 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4146 if (ext2fs_inode_has_valid_blocks(inode))
4147 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4148 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4149 block_buf, process_block, &pb);
4150 end_problem_latch(ctx, PR_LATCH_BLOCK);
4151 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4152 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4155 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4157 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4158 ctx->fs_fragmented++;
4161 inode->i_links_count = 0;
4162 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4163 inode->i_dtime = time(NULL);
4165 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4166 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4167 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4169 * The inode was probably partially accounted for
4170 * before processing was aborted, so we need to
4171 * restart the pass 1 scan.
4173 ctx->flags |= E2F_FLAG_RESTART;
4177 if (inode->i_flags & EXT2_INDEX_FL) {
4178 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4179 inode->i_flags &= ~EXT2_INDEX_FL;
4183 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4187 if (ctx->dirs_to_hash && pb.is_dir &&
4188 !(inode->i_flags & EXT2_INDEX_FL) &&
4189 ((inode->i_size / fs->blocksize) >= 3))
4190 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4192 if (!pb.num_blocks && pb.is_dir) {
4193 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4194 inode->i_links_count = 0;
4195 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4196 inode->i_dtime = time(NULL);
4198 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4199 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4200 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4201 ctx->fs_directory_count--;
4206 pb.num_blocks *= (fs->blocksize / 512);
4209 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4210 if (nblock > (pb.last_block + 1))
4212 else if (nblock < (pb.last_block + 1)) {
4213 if (((pb.last_block + 1) - nblock) >
4214 fs->super->s_prealloc_dir_blocks)
4218 size = EXT2_I_SIZE(inode);
4219 if ((pb.last_block >= 0) &&
4220 (size < (__u64) pb.last_block * fs->blocksize))
4222 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4225 /* i_size for symlinks is checked elsewhere */
4226 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4227 pctx->num = (pb.last_block+1) * fs->blocksize;
4228 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4229 inode->i_size = pctx->num;
4230 if (!LINUX_S_ISDIR(inode->i_mode))
4231 inode->i_size_high = pctx->num >> 32;
4236 if (LINUX_S_ISREG(inode->i_mode) &&
4237 (inode->i_size_high || inode->i_size & 0x80000000UL))
4239 if (pb.num_blocks != inode->i_blocks) {
4240 pctx->num = pb.num_blocks;
4241 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4242 inode->i_blocks = pb.num_blocks;
4249 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4254 * This is a helper function for check_blocks().
4256 static int process_block(ext2_filsys fs,
4258 e2_blkcnt_t blockcnt,
4259 blk_t ref_block FSCK_ATTR((unused)),
4260 int ref_offset FSCK_ATTR((unused)),
4263 struct process_block_struct_1 *p;
4264 struct problem_context *pctx;
4265 blk_t blk = *block_nr;
4270 p = (struct process_block_struct_1 *) priv_data;
4274 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4275 /* todo: Check that the comprblk_fl is high, that the
4276 blkaddr pattern looks right (all non-holes up to
4277 first EXT2FS_COMPRESSED_BLKADDR, then all
4278 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4279 that the feature_incompat bit is high, and that the
4280 inode is a regular file. If we're doing a "full
4281 check" (a concept introduced to e2fsck by e2compr,
4282 meaning that we look at data blocks as well as
4283 metadata) then call some library routine that
4284 checks the compressed data. I'll have to think
4285 about this, because one particularly important
4286 problem to be able to fix is to recalculate the
4287 cluster size if necessary. I think that perhaps
4288 we'd better do most/all e2compr-specific checks
4289 separately, after the non-e2compr checks. If not
4290 doing a full check, it may be useful to test that
4291 the personality is linux; e.g. if it isn't then
4292 perhaps this really is just an illegal block. */
4297 if (p->is_dir == 0) {
4299 * Should never happen, since only directories
4300 * get called with BLOCK_FLAG_HOLE
4303 printf("process_block() called with blk == 0, "
4304 "blockcnt=%d, inode %lu???\n",
4311 if (blockcnt * fs->blocksize < p->inode->i_size) {
4318 * Simplistic fragmentation check. We merely require that the
4319 * file be contiguous. (Which can never be true for really
4320 * big files that are greater than a block group.)
4322 if (!HOLE_BLKADDR(p->previous_block)) {
4323 if (p->previous_block+1 != blk)
4326 p->previous_block = blk;
4328 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4329 problem = PR_1_TOOBIG_DIR;
4330 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4331 problem = PR_1_TOOBIG_REG;
4332 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4333 problem = PR_1_TOOBIG_SYMLINK;
4335 if (blk < fs->super->s_first_data_block ||
4336 blk >= fs->super->s_blocks_count)
4337 problem = PR_1_ILLEGAL_BLOCK_NUM;
4340 p->num_illegal_blocks++;
4341 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4342 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4346 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4348 set_latch_flags(PR_LATCH_BLOCK,
4353 pctx->blkcount = blockcnt;
4354 if (fix_problem(ctx, problem, pctx)) {
4355 blk = *block_nr = 0;
4356 ret_code = BLOCK_CHANGED;
4362 if (p->ino == EXT2_RESIZE_INO) {
4364 * The resize inode has already be sanity checked
4365 * during pass #0 (the superblock checks). All we
4366 * have to do is mark the double indirect block as
4367 * being in use; all of the other blocks are handled
4368 * by mark_table_blocks()).
4370 if (blockcnt == BLOCK_COUNT_DIND)
4371 mark_block_used(ctx, blk);
4373 mark_block_used(ctx, blk);
4376 p->last_block = blockcnt;
4378 if (p->is_dir && (blockcnt >= 0)) {
4379 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4381 if (pctx->errcode) {
4383 pctx->num = blockcnt;
4384 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4385 /* Should never get here */
4386 ctx->flags |= E2F_FLAG_ABORT;
4393 static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4395 e2_blkcnt_t blockcnt,
4396 blk_t ref_block FSCK_ATTR((unused)),
4397 int ref_offset FSCK_ATTR((unused)),
4398 void *priv_data EXT2FS_ATTR((unused)))
4401 * Note: This function processes blocks for the bad blocks
4402 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4405 printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4410 * This routine gets called at the end of pass 1 if bad blocks are
4411 * detected in the superblock, group descriptors, inode_bitmaps, or
4412 * block bitmaps. At this point, all of the blocks have been mapped
4413 * out, so we can try to allocate new block(s) to replace the bad
4416 static void handle_fs_bad_blocks(e2fsck_t ctx)
4418 printf("Bad blocks detected on your filesystem\n"
4419 "You should get your data off as the device will soon die\n");
4423 * This routine marks all blocks which are used by the superblock,
4424 * group descriptors, inode bitmaps, and block bitmaps.
4426 static void mark_table_blocks(e2fsck_t ctx)
4428 ext2_filsys fs = ctx->fs;
4432 struct problem_context pctx;
4434 clear_problem_context(&pctx);
4436 block = fs->super->s_first_data_block;
4437 for (i = 0; i < fs->group_desc_count; i++) {
4440 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4443 * Mark the blocks used for the inode table
4445 if (fs->group_desc[i].bg_inode_table) {
4446 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4447 j < fs->inode_blocks_per_group;
4449 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4452 if (fix_problem(ctx,
4453 PR_1_ITABLE_CONFLICT, &pctx)) {
4454 ctx->invalid_inode_table_flag[i]++;
4455 ctx->invalid_bitmaps++;
4458 ext2fs_mark_block_bitmap(ctx->block_found_map,
4465 * Mark block used for the block bitmap
4467 if (fs->group_desc[i].bg_block_bitmap) {
4468 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4469 fs->group_desc[i].bg_block_bitmap)) {
4470 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4471 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4472 ctx->invalid_block_bitmap_flag[i]++;
4473 ctx->invalid_bitmaps++;
4476 ext2fs_mark_block_bitmap(ctx->block_found_map,
4477 fs->group_desc[i].bg_block_bitmap);
4482 * Mark block used for the inode bitmap
4484 if (fs->group_desc[i].bg_inode_bitmap) {
4485 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4486 fs->group_desc[i].bg_inode_bitmap)) {
4487 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4488 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4489 ctx->invalid_inode_bitmap_flag[i]++;
4490 ctx->invalid_bitmaps++;
4493 ext2fs_mark_block_bitmap(ctx->block_found_map,
4494 fs->group_desc[i].bg_inode_bitmap);
4497 block += fs->super->s_blocks_per_group;
4502 * Thes subroutines short circuits ext2fs_get_blocks and
4503 * ext2fs_check_directory; we use them since we already have the inode
4504 * structure, so there's no point in letting the ext2fs library read
4507 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4510 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4513 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4514 return EXT2_ET_CALLBACK_NOTHANDLED;
4516 for (i=0; i < EXT2_N_BLOCKS; i++)
4517 blocks[i] = ctx->stashed_inode->i_block[i];
4521 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4522 struct ext2_inode *inode)
4524 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4526 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4527 return EXT2_ET_CALLBACK_NOTHANDLED;
4528 *inode = *ctx->stashed_inode;
4532 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4533 struct ext2_inode *inode)
4535 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4537 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4538 *ctx->stashed_inode = *inode;
4539 return EXT2_ET_CALLBACK_NOTHANDLED;
4542 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4544 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4546 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4547 return EXT2_ET_CALLBACK_NOTHANDLED;
4549 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4550 return EXT2_ET_NO_DIRECTORY;
4554 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4556 ext2_filsys fs = ctx->fs;
4559 fs->get_blocks = pass1_get_blocks;
4560 fs->check_directory = pass1_check_directory;
4561 fs->read_inode = pass1_read_inode;
4562 fs->write_inode = pass1_write_inode;
4563 ctx->stashed_ino = 0;
4566 fs->check_directory = 0;
4568 fs->write_inode = 0;
4573 * pass1b.c --- Pass #1b of e2fsck
4575 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4576 * only invoked if pass 1 discovered blocks which are in use by more
4579 * Pass1B scans the data blocks of all the inodes again, generating a
4580 * complete list of duplicate blocks and which inodes have claimed
4583 * Pass1C does a tree-traversal of the filesystem, to determine the
4584 * parent directories of these inodes. This step is necessary so that
4585 * e2fsck can print out the pathnames of affected inodes.
4587 * Pass1D is a reconciliation pass. For each inode with duplicate
4588 * blocks, the user is prompted if s/he would like to clone the file
4589 * (so that the file gets a fresh copy of the duplicated blocks) or
4590 * simply to delete the file.
4595 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4596 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4597 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4599 /* Define an extension to the ext2 library's block count information */
4600 #define BLOCK_COUNT_EXTATTR (-5)
4604 struct block_el *next;
4609 struct inode_el *next;
4614 struct inode_el *inode_list;
4618 * This structure stores information about a particular inode which
4619 * is sharing blocks with other inodes. This information is collected
4620 * to display to the user, so that the user knows what files he or she
4621 * is dealing with, when trying to decide how to resolve the conflict
4622 * of multiply-claimed blocks.
4627 struct ext2_inode inode;
4628 struct block_el *block_list;
4631 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
4632 e2_blkcnt_t blockcnt, blk_t ref_blk,
4633 int ref_offset, void *priv_data);
4634 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4635 struct dup_inode *dp, char *block_buf);
4636 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4637 struct dup_inode *dp, char* block_buf);
4638 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4640 static void pass1b(e2fsck_t ctx, char *block_buf);
4641 static void pass1c(e2fsck_t ctx, char *block_buf);
4642 static void pass1d(e2fsck_t ctx, char *block_buf);
4644 static int dup_inode_count = 0;
4646 static dict_t blk_dict, ino_dict;
4648 static ext2fs_inode_bitmap inode_dup_map;
4650 static int dict_int_cmp(const void *a, const void *b)
4661 * Add a duplicate block record
4663 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4664 struct ext2_inode *inode)
4667 struct dup_block *db;
4668 struct dup_inode *di;
4669 struct block_el *blk_el;
4670 struct inode_el *ino_el;
4672 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4674 db = (struct dup_block *) dnode_get(n);
4676 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4677 sizeof(struct dup_block), "duplicate block header");
4680 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4682 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4683 sizeof(struct inode_el), "inode element");
4684 ino_el->inode = ino;
4685 ino_el->next = db->inode_list;
4686 db->inode_list = ino_el;
4689 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4691 di = (struct dup_inode *) dnode_get(n);
4693 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4694 sizeof(struct dup_inode), "duplicate inode header");
4695 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0;
4696 di->num_dupblocks = 0;
4699 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4701 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4702 sizeof(struct block_el), "block element");
4703 blk_el->block = blk;
4704 blk_el->next = di->block_list;
4705 di->block_list = blk_el;
4706 di->num_dupblocks++;
4710 * Free a duplicate inode record
4712 static void inode_dnode_free(dnode_t *node)
4714 struct dup_inode *di;
4715 struct block_el *p, *next;
4717 di = (struct dup_inode *) dnode_get(node);
4718 for (p = di->block_list; p; p = next) {
4726 * Free a duplicate block record
4728 static void block_dnode_free(dnode_t *node)
4730 struct dup_block *db;
4731 struct inode_el *p, *next;
4733 db = (struct dup_block *) dnode_get(node);
4734 for (p = db->inode_list; p; p = next) {
4743 * Main procedure for handling duplicate blocks
4745 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4747 ext2_filsys fs = ctx->fs;
4748 struct problem_context pctx;
4750 clear_problem_context(&pctx);
4752 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4753 _("multiply claimed inode map"), &inode_dup_map);
4755 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4756 ctx->flags |= E2F_FLAG_ABORT;
4760 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4761 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4762 dict_set_allocator(&ino_dict, inode_dnode_free);
4763 dict_set_allocator(&blk_dict, block_dnode_free);
4765 pass1b(ctx, block_buf);
4766 pass1c(ctx, block_buf);
4767 pass1d(ctx, block_buf);
4770 * Time to free all of the accumulated data structures that we
4771 * don't need anymore.
4773 dict_free_nodes(&ino_dict);
4774 dict_free_nodes(&blk_dict);
4778 * Scan the inodes looking for inodes that contain duplicate blocks.
4780 struct process_block_struct_1b {
4784 struct ext2_inode *inode;
4785 struct problem_context *pctx;
4788 static void pass1b(e2fsck_t ctx, char *block_buf)
4790 ext2_filsys fs = ctx->fs;
4792 struct ext2_inode inode;
4793 ext2_inode_scan scan;
4794 struct process_block_struct_1b pb;
4795 struct problem_context pctx;
4797 clear_problem_context(&pctx);
4799 if (!(ctx->options & E2F_OPT_PREEN))
4800 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4801 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4804 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4805 ctx->flags |= E2F_FLAG_ABORT;
4808 ctx->stashed_inode = &inode;
4811 pctx.str = "pass1b";
4813 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4814 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4817 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4818 ctx->flags |= E2F_FLAG_ABORT;
4823 pctx.ino = ctx->stashed_ino = ino;
4824 if ((ino != EXT2_BAD_INO) &&
4825 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4832 if (ext2fs_inode_has_valid_blocks(&inode) ||
4833 (ino == EXT2_BAD_INO))
4834 pctx.errcode = ext2fs_block_iterate2(fs, ino,
4835 0, block_buf, process_pass1b_block, &pb);
4836 if (inode.i_file_acl)
4837 process_pass1b_block(fs, &inode.i_file_acl,
4838 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4839 if (pb.dup_blocks) {
4840 end_problem_latch(ctx, PR_LATCH_DBLOCK);
4841 if (ino >= EXT2_FIRST_INODE(fs->super) ||
4842 ino == EXT2_ROOT_INO)
4846 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4848 ext2fs_close_inode_scan(scan);
4849 e2fsck_use_inode_shortcuts(ctx, 0);
4852 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4854 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4855 blk_t ref_blk FSCK_ATTR((unused)),
4856 int ref_offset FSCK_ATTR((unused)),
4859 struct process_block_struct_1b *p;
4862 if (HOLE_BLKADDR(*block_nr))
4864 p = (struct process_block_struct_1b *) priv_data;
4867 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4870 /* OK, this is a duplicate block */
4871 if (p->ino != EXT2_BAD_INO) {
4872 p->pctx->blk = *block_nr;
4873 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4876 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4878 add_dupe(ctx, p->ino, *block_nr, p->inode);
4884 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4885 * is used so that we can print pathnames when prompting the user for
4888 struct search_dir_struct {
4890 ext2_ino_t first_inode;
4891 ext2_ino_t max_inode;
4894 static int search_dirent_proc(ext2_ino_t dir, int entry,
4895 struct ext2_dir_entry *dirent,
4896 int offset FSCK_ATTR((unused)),
4897 int blocksize FSCK_ATTR((unused)),
4898 char *buf FSCK_ATTR((unused)),
4901 struct search_dir_struct *sd;
4902 struct dup_inode *p;
4905 sd = (struct search_dir_struct *) priv_data;
4907 if (dirent->inode > sd->max_inode)
4908 /* Should abort this inode, but not everything */
4911 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4912 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4915 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4918 p = (struct dup_inode *) dnode_get(n);
4922 return sd->count ? 0 : DIRENT_ABORT;
4926 static void pass1c(e2fsck_t ctx, char *block_buf)
4928 ext2_filsys fs = ctx->fs;
4929 struct search_dir_struct sd;
4930 struct problem_context pctx;
4932 clear_problem_context(&pctx);
4934 if (!(ctx->options & E2F_OPT_PREEN))
4935 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4938 * Search through all directories to translate inodes to names
4939 * (by searching for the containing directory for that inode.)
4941 sd.count = dup_inode_count;
4942 sd.first_inode = EXT2_FIRST_INODE(fs->super);
4943 sd.max_inode = fs->super->s_inodes_count;
4944 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4945 search_dirent_proc, &sd);
4948 static void pass1d(e2fsck_t ctx, char *block_buf)
4950 ext2_filsys fs = ctx->fs;
4951 struct dup_inode *p, *t;
4952 struct dup_block *q;
4953 ext2_ino_t *shared, ino;
4958 struct problem_context pctx;
4963 clear_problem_context(&pctx);
4965 if (!(ctx->options & E2F_OPT_PREEN))
4966 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
4967 e2fsck_read_bitmaps(ctx);
4969 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
4970 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
4971 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
4972 sizeof(ext2_ino_t) * dict_count(&ino_dict),
4973 "Shared inode list");
4974 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
4975 p = (struct dup_inode *) dnode_get(n);
4978 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
4979 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
4983 * Find all of the inodes which share blocks with this
4984 * one. First we find all of the duplicate blocks
4985 * belonging to this inode, and then search each block
4986 * get the list of inodes, and merge them together.
4988 for (s = p->block_list; s; s = s->next) {
4989 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
4991 continue; /* Should never happen... */
4992 q = (struct dup_block *) dnode_get(m);
4995 if (check_if_fs_block(ctx, s->block)) {
5001 * Add all inodes used by this block to the
5002 * shared[] --- which is a unique list, so
5003 * if an inode is already in shared[], don't
5006 for (r = q->inode_list; r; r = r->next) {
5007 if (r->inode == ino)
5009 for (i = 0; i < shared_len; i++)
5010 if (shared[i] == r->inode)
5012 if (i == shared_len) {
5013 shared[shared_len++] = r->inode;
5019 * Report the inode that we are working on
5021 pctx.inode = &p->inode;
5024 pctx.blkcount = p->num_dupblocks;
5025 pctx.num = meta_data ? shared_len+1 : shared_len;
5026 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5031 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5033 for (i = 0; i < shared_len; i++) {
5034 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5036 continue; /* should never happen */
5037 t = (struct dup_inode *) dnode_get(m);
5039 * Report the inode that we are sharing with
5041 pctx.inode = &t->inode;
5042 pctx.ino = shared[i];
5044 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5047 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5050 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5051 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5053 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5057 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5058 delete_file(ctx, ino, p, block_buf);
5060 ext2fs_unmark_valid(fs);
5062 ext2fs_free_mem(&shared);
5066 * Drop the refcount on the dup_block structure, and clear the entry
5067 * in the block_dup_map if appropriate.
5069 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5072 if (p->num_bad <= 0 ||
5073 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5074 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5077 static int delete_file_block(ext2_filsys fs,
5079 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5080 blk_t ref_block FSCK_ATTR((unused)),
5081 int ref_offset FSCK_ATTR((unused)),
5084 struct process_block_struct_1b *pb;
5085 struct dup_block *p;
5089 pb = (struct process_block_struct_1b *) priv_data;
5092 if (HOLE_BLKADDR(*block_nr))
5095 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5096 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5098 p = (struct dup_block *) dnode_get(n);
5099 decrement_badcount(ctx, *block_nr, p);
5101 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5104 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5105 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5111 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5112 struct dup_inode *dp, char* block_buf)
5114 ext2_filsys fs = ctx->fs;
5115 struct process_block_struct_1b pb;
5116 struct ext2_inode inode;
5117 struct problem_context pctx;
5120 clear_problem_context(&pctx);
5121 pctx.ino = pb.ino = ino;
5122 pb.dup_blocks = dp->num_dupblocks;
5124 pctx.str = "delete_file";
5126 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5127 if (ext2fs_inode_has_valid_blocks(&inode))
5128 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5129 delete_file_block, &pb);
5131 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5132 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5133 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5134 if (ctx->inode_bad_map)
5135 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5136 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5138 /* Inode may have changed by block_iterate, so reread it */
5139 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5140 inode.i_links_count = 0;
5141 inode.i_dtime = time(NULL);
5142 if (inode.i_file_acl &&
5143 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5145 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5146 block_buf, -1, &count);
5147 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5152 pctx.blk = inode.i_file_acl;
5153 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5156 * If the count is zero, then arrange to have the
5157 * block deleted. If the block is in the block_dup_map,
5158 * also call delete_file_block since it will take care
5159 * of keeping the accounting straight.
5162 ext2fs_test_block_bitmap(ctx->block_dup_map,
5164 delete_file_block(fs, &inode.i_file_acl,
5165 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5167 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5170 struct clone_struct {
5177 static int clone_file_block(ext2_filsys fs,
5179 e2_blkcnt_t blockcnt,
5180 blk_t ref_block FSCK_ATTR((unused)),
5181 int ref_offset FSCK_ATTR((unused)),
5184 struct dup_block *p;
5187 struct clone_struct *cs = (struct clone_struct *) priv_data;
5193 if (HOLE_BLKADDR(*block_nr))
5196 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5197 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5199 p = (struct dup_block *) dnode_get(n);
5200 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5203 cs->errcode = retval;
5206 if (cs->dir && (blockcnt >= 0)) {
5207 retval = ext2fs_set_dir_block(fs->dblist,
5208 cs->dir, new_block, blockcnt);
5210 cs->errcode = retval;
5215 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5218 cs->errcode = retval;
5221 retval = io_channel_write_blk(fs->io, new_block, 1,
5224 cs->errcode = retval;
5227 decrement_badcount(ctx, *block_nr, p);
5228 *block_nr = new_block;
5229 ext2fs_mark_block_bitmap(ctx->block_found_map,
5231 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5232 return BLOCK_CHANGED;
5234 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5240 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5241 struct dup_inode *dp, char* block_buf)
5243 ext2_filsys fs = ctx->fs;
5245 struct clone_struct cs;
5246 struct problem_context pctx;
5249 struct inode_el *ino_el;
5250 struct dup_block *db;
5251 struct dup_inode *di;
5253 clear_problem_context(&pctx);
5257 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5261 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5265 pctx.str = "clone_file";
5266 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5267 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5268 clone_file_block, &cs);
5269 ext2fs_mark_bb_dirty(fs);
5271 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5272 retval = pctx.errcode;
5276 bb_error_msg(_("returned from clone_file_block"));
5277 retval = cs.errcode;
5280 /* The inode may have changed on disk, so we have to re-read it */
5281 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5282 blk = dp->inode.i_file_acl;
5283 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5284 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5286 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5288 * If we cloned the EA block, find all other inodes
5289 * which refered to that EA block, and modify
5290 * them to point to the new EA block.
5292 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5293 db = (struct dup_block *) dnode_get(n);
5294 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5295 if (ino_el->inode == ino)
5297 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5298 di = (struct dup_inode *) dnode_get(n);
5299 if (di->inode.i_file_acl == blk) {
5300 di->inode.i_file_acl = dp->inode.i_file_acl;
5301 e2fsck_write_inode(ctx, ino_el->inode,
5302 &di->inode, "clone file EA");
5303 decrement_badcount(ctx, blk, db);
5309 ext2fs_free_mem(&cs.buf);
5314 * This routine returns 1 if a block overlaps with one of the superblocks,
5315 * group descriptors, inode bitmaps, or block bitmaps.
5317 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5319 ext2_filsys fs = ctx->fs;
5323 block = fs->super->s_first_data_block;
5324 for (i = 0; i < fs->group_desc_count; i++) {
5326 /* Check superblocks/block group descriptros */
5327 if (ext2fs_bg_has_super(fs, i)) {
5328 if (test_block >= block &&
5329 (test_block <= block + fs->desc_blocks))
5333 /* Check the inode table */
5334 if ((fs->group_desc[i].bg_inode_table) &&
5335 (test_block >= fs->group_desc[i].bg_inode_table) &&
5336 (test_block < (fs->group_desc[i].bg_inode_table +
5337 fs->inode_blocks_per_group)))
5340 /* Check the bitmap blocks */
5341 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5342 (test_block == fs->group_desc[i].bg_inode_bitmap))
5345 block += fs->super->s_blocks_per_group;
5350 * pass2.c --- check directory structure
5352 * Pass 2 of e2fsck iterates through all active directory inodes, and
5353 * applies to following tests to each directory entry in the directory
5354 * blocks in the inodes:
5356 * - The length of the directory entry (rec_len) should be at
5357 * least 8 bytes, and no more than the remaining space
5358 * left in the directory block.
5359 * - The length of the name in the directory entry (name_len)
5360 * should be less than (rec_len - 8).
5361 * - The inode number in the directory entry should be within
5363 * - The inode number should refer to a in-use inode.
5364 * - The first entry should be '.', and its inode should be
5365 * the inode of the directory.
5366 * - The second entry should be '..'.
5368 * To minimize disk seek time, the directory blocks are processed in
5369 * sorted order of block numbers.
5371 * Pass 2 also collects the following information:
5372 * - The inode numbers of the subdirectories for each directory.
5374 * Pass 2 relies on the following information from previous passes:
5375 * - The directory information collected in pass 1.
5376 * - The inode_used_map bitmap
5377 * - The inode_bad_map bitmap
5378 * - The inode_dir_map bitmap
5380 * Pass 2 frees the following data structures
5381 * - The inode_bad_map bitmap
5382 * - The inode_reg_map bitmap
5386 * Keeps track of how many times an inode is referenced.
5388 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5389 static int check_dir_block(ext2_filsys fs,
5390 struct ext2_db_entry *dir_blocks_info,
5392 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5393 struct problem_context *pctx);
5394 static int update_dir_block(ext2_filsys fs,
5396 e2_blkcnt_t blockcnt,
5400 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5401 static int htree_depth(struct dx_dir_info *dx_dir,
5402 struct dx_dirblock_info *dx_db);
5403 static int special_dir_block_cmp(const void *a, const void *b);
5405 struct check_dir_struct {
5407 struct problem_context pctx;
5412 static void e2fsck_pass2(e2fsck_t ctx)
5414 struct ext2_super_block *sb = ctx->fs->super;
5415 struct problem_context pctx;
5416 ext2_filsys fs = ctx->fs;
5418 struct dir_info *dir;
5419 struct check_dir_struct cd;
5420 struct dx_dir_info *dx_dir;
5421 struct dx_dirblock_info *dx_db, *dx_parent;
5427 clear_problem_context(&cd.pctx);
5431 if (!(ctx->options & E2F_OPT_PREEN))
5432 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5434 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5435 0, ctx->inode_link_info,
5437 if (cd.pctx.errcode) {
5438 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5439 ctx->flags |= E2F_FLAG_ABORT;
5442 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5443 "directory scan buffer");
5446 * Set up the parent pointer for the root directory, if
5447 * present. (If the root directory is not present, we will
5448 * create it in pass 3.)
5450 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5452 dir->parent = EXT2_ROOT_INO;
5457 cd.max = ext2fs_dblist_count(fs->dblist);
5460 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5462 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5463 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5465 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5467 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5469 if (cd.pctx.errcode) {
5470 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5471 ctx->flags |= E2F_FLAG_ABORT;
5476 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5477 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5479 if (dx_dir->numblocks == 0)
5481 clear_problem_context(&pctx);
5483 pctx.dir = dx_dir->ino;
5484 dx_db = dx_dir->dx_block;
5485 if (dx_db->flags & DX_FLAG_REFERENCED)
5486 dx_db->flags |= DX_FLAG_DUP_REF;
5488 dx_db->flags |= DX_FLAG_REFERENCED;
5490 * Find all of the first and last leaf blocks, and
5491 * update their parent's min and max hash values
5493 for (b=0, dx_db = dx_dir->dx_block;
5494 b < dx_dir->numblocks;
5496 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5497 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5499 dx_parent = &dx_dir->dx_block[dx_db->parent];
5501 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5503 if (dx_db->flags & DX_FLAG_FIRST)
5504 dx_parent->min_hash = dx_db->min_hash;
5506 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5508 if (dx_db->flags & DX_FLAG_LAST)
5509 dx_parent->max_hash = dx_db->max_hash;
5512 for (b=0, dx_db = dx_dir->dx_block;
5513 b < dx_dir->numblocks;
5516 pctx.group = dx_db->parent;
5518 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5519 (dx_db->min_hash < dx_db->node_min_hash)) {
5520 pctx.blk = dx_db->min_hash;
5521 pctx.blk2 = dx_db->node_min_hash;
5522 code = PR_2_HTREE_MIN_HASH;
5523 fix_problem(ctx, code, &pctx);
5526 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5527 depth = htree_depth(dx_dir, dx_db);
5528 if (depth != dx_dir->depth) {
5529 code = PR_2_HTREE_BAD_DEPTH;
5530 fix_problem(ctx, code, &pctx);
5535 * This test doesn't apply for the root block
5539 (dx_db->max_hash > dx_db->node_max_hash)) {
5540 pctx.blk = dx_db->max_hash;
5541 pctx.blk2 = dx_db->node_max_hash;
5542 code = PR_2_HTREE_MAX_HASH;
5543 fix_problem(ctx, code, &pctx);
5546 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5547 code = PR_2_HTREE_NOTREF;
5548 fix_problem(ctx, code, &pctx);
5550 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5551 code = PR_2_HTREE_DUPREF;
5552 fix_problem(ctx, code, &pctx);
5558 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5559 clear_htree(ctx, dx_dir->ino);
5560 dx_dir->numblocks = 0;
5564 ext2fs_free_mem(&buf);
5565 ext2fs_free_dblist(fs->dblist);
5567 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5568 ctx->inode_bad_map = 0;
5569 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5570 ctx->inode_reg_map = 0;
5572 clear_problem_context(&pctx);
5573 if (ctx->large_files) {
5574 if (!(sb->s_feature_ro_compat &
5575 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5576 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5577 sb->s_feature_ro_compat |=
5578 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5579 ext2fs_mark_super_dirty(fs);
5581 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5582 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5583 ext2fs_update_dynamic_rev(fs);
5584 ext2fs_mark_super_dirty(fs);
5586 } else if (!ctx->large_files &&
5587 (sb->s_feature_ro_compat &
5588 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5589 if (fs->flags & EXT2_FLAG_RW) {
5590 sb->s_feature_ro_compat &=
5591 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5592 ext2fs_mark_super_dirty(fs);
5598 #define MAX_DEPTH 32000
5599 static int htree_depth(struct dx_dir_info *dx_dir,
5600 struct dx_dirblock_info *dx_db)
5604 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5605 dx_db = &dx_dir->dx_block[dx_db->parent];
5611 static int dict_de_cmp(const void *a, const void *b)
5613 const struct ext2_dir_entry *de_a, *de_b;
5616 de_a = (const struct ext2_dir_entry *) a;
5617 a_len = de_a->name_len & 0xFF;
5618 de_b = (const struct ext2_dir_entry *) b;
5619 b_len = de_b->name_len & 0xFF;
5622 return (a_len - b_len);
5624 return strncmp(de_a->name, de_b->name, a_len);
5628 * This is special sort function that makes sure that directory blocks
5629 * with a dirblock of zero are sorted to the beginning of the list.
5630 * This guarantees that the root node of the htree directories are
5631 * processed first, so we know what hash version to use.
5633 static int special_dir_block_cmp(const void *a, const void *b)
5635 const struct ext2_db_entry *db_a =
5636 (const struct ext2_db_entry *) a;
5637 const struct ext2_db_entry *db_b =
5638 (const struct ext2_db_entry *) b;
5640 if (db_a->blockcnt && !db_b->blockcnt)
5643 if (!db_a->blockcnt && db_b->blockcnt)
5646 if (db_a->blk != db_b->blk)
5647 return (int) (db_a->blk - db_b->blk);
5649 if (db_a->ino != db_b->ino)
5650 return (int) (db_a->ino - db_b->ino);
5652 return (int) (db_a->blockcnt - db_b->blockcnt);
5657 * Make sure the first entry in the directory is '.', and that the
5658 * directory entry is sane.
5660 static int check_dot(e2fsck_t ctx,
5661 struct ext2_dir_entry *dirent,
5662 ext2_ino_t ino, struct problem_context *pctx)
5664 struct ext2_dir_entry *nextdir;
5671 problem = PR_2_MISSING_DOT;
5672 else if (((dirent->name_len & 0xFF) != 1) ||
5673 (dirent->name[0] != '.'))
5674 problem = PR_2_1ST_NOT_DOT;
5675 else if (dirent->name[1] != '\0')
5676 problem = PR_2_DOT_NULL_TERM;
5679 if (fix_problem(ctx, problem, pctx)) {
5680 if (dirent->rec_len < 12)
5681 dirent->rec_len = 12;
5682 dirent->inode = ino;
5683 dirent->name_len = 1;
5684 dirent->name[0] = '.';
5685 dirent->name[1] = '\0';
5690 if (dirent->inode != ino) {
5691 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5692 dirent->inode = ino;
5696 if (dirent->rec_len > 12) {
5697 new_len = dirent->rec_len - 12;
5700 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5701 nextdir = (struct ext2_dir_entry *)
5702 ((char *) dirent + 12);
5703 dirent->rec_len = 12;
5704 nextdir->rec_len = new_len;
5706 nextdir->name_len = 0;
5715 * Make sure the second entry in the directory is '..', and that the
5716 * directory entry is sane. We do not check the inode number of '..'
5717 * here; this gets done in pass 3.
5719 static int check_dotdot(e2fsck_t ctx,
5720 struct ext2_dir_entry *dirent,
5721 struct dir_info *dir, struct problem_context *pctx)
5726 problem = PR_2_MISSING_DOT_DOT;
5727 else if (((dirent->name_len & 0xFF) != 2) ||
5728 (dirent->name[0] != '.') ||
5729 (dirent->name[1] != '.'))
5730 problem = PR_2_2ND_NOT_DOT_DOT;
5731 else if (dirent->name[2] != '\0')
5732 problem = PR_2_DOT_DOT_NULL_TERM;
5735 if (fix_problem(ctx, problem, pctx)) {
5736 if (dirent->rec_len < 12)
5737 dirent->rec_len = 12;
5739 * Note: we don't have the parent inode just
5740 * yet, so we will fill it in with the root
5741 * inode. This will get fixed in pass 3.
5743 dirent->inode = EXT2_ROOT_INO;
5744 dirent->name_len = 2;
5745 dirent->name[0] = '.';
5746 dirent->name[1] = '.';
5747 dirent->name[2] = '\0';
5752 dir->dotdot = dirent->inode;
5757 * Check to make sure a directory entry doesn't contain any illegal
5760 static int check_name(e2fsck_t ctx,
5761 struct ext2_dir_entry *dirent,
5762 struct problem_context *pctx)
5768 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5769 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5771 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5774 dirent->name[i] = '.';
5783 * Check the directory filetype (if present)
5787 * Given a mode, return the ext2 file type
5789 static int ext2_file_type(unsigned int mode)
5791 if (LINUX_S_ISREG(mode))
5792 return EXT2_FT_REG_FILE;
5794 if (LINUX_S_ISDIR(mode))
5797 if (LINUX_S_ISCHR(mode))
5798 return EXT2_FT_CHRDEV;
5800 if (LINUX_S_ISBLK(mode))
5801 return EXT2_FT_BLKDEV;
5803 if (LINUX_S_ISLNK(mode))
5804 return EXT2_FT_SYMLINK;
5806 if (LINUX_S_ISFIFO(mode))
5807 return EXT2_FT_FIFO;
5809 if (LINUX_S_ISSOCK(mode))
5810 return EXT2_FT_SOCK;
5815 static int check_filetype(e2fsck_t ctx,
5816 struct ext2_dir_entry *dirent,
5817 struct problem_context *pctx)
5819 int filetype = dirent->name_len >> 8;
5820 int should_be = EXT2_FT_UNKNOWN;
5821 struct ext2_inode inode;
5823 if (!(ctx->fs->super->s_feature_incompat &
5824 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5825 if (filetype == 0 ||
5826 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5828 dirent->name_len = dirent->name_len & 0xFF;
5832 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5833 should_be = EXT2_FT_DIR;
5834 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5836 should_be = EXT2_FT_REG_FILE;
5837 } else if (ctx->inode_bad_map &&
5838 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5842 e2fsck_read_inode(ctx, dirent->inode, &inode,
5844 should_be = ext2_file_type(inode.i_mode);
5846 if (filetype == should_be)
5848 pctx->num = should_be;
5850 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5854 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5859 static void parse_int_node(ext2_filsys fs,
5860 struct ext2_db_entry *db,
5861 struct check_dir_struct *cd,
5862 struct dx_dir_info *dx_dir,
5865 struct ext2_dx_root_info *root;
5866 struct ext2_dx_entry *ent;
5867 struct ext2_dx_countlimit *limit;
5868 struct dx_dirblock_info *dx_db;
5869 int i, expect_limit, count;
5871 ext2_dirhash_t min_hash = 0xffffffff;
5872 ext2_dirhash_t max_hash = 0;
5873 ext2_dirhash_t hash = 0, prev_hash;
5875 if (db->blockcnt == 0) {
5876 root = (struct ext2_dx_root_info *) (block_buf + 24);
5877 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5879 ent = (struct ext2_dx_entry *) (block_buf+8);
5881 limit = (struct ext2_dx_countlimit *) ent;
5883 count = ext2fs_le16_to_cpu(limit->count);
5884 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5885 sizeof(struct ext2_dx_entry);
5886 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5887 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5888 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5889 goto clear_and_exit;
5891 if (count > expect_limit) {
5892 cd->pctx.num = count;
5893 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5894 goto clear_and_exit;
5895 count = expect_limit;
5898 for (i=0; i < count; i++) {
5900 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5901 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5902 /* Check to make sure the block is valid */
5903 if (blk > (blk_t) dx_dir->numblocks) {
5905 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5907 goto clear_and_exit;
5909 if (hash < prev_hash &&
5910 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5911 goto clear_and_exit;
5912 dx_db = &dx_dir->dx_block[blk];
5913 if (dx_db->flags & DX_FLAG_REFERENCED) {
5914 dx_db->flags |= DX_FLAG_DUP_REF;
5916 dx_db->flags |= DX_FLAG_REFERENCED;
5917 dx_db->parent = db->blockcnt;
5919 if (hash < min_hash)
5921 if (hash > max_hash)
5923 dx_db->node_min_hash = hash;
5925 dx_db->node_max_hash =
5926 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5928 dx_db->node_max_hash = 0xfffffffe;
5929 dx_db->flags |= DX_FLAG_LAST;
5932 dx_db->flags |= DX_FLAG_FIRST;
5934 dx_db = &dx_dir->dx_block[db->blockcnt];
5935 dx_db->min_hash = min_hash;
5936 dx_db->max_hash = max_hash;
5940 clear_htree(cd->ctx, cd->pctx.ino);
5941 dx_dir->numblocks = 0;
5943 #endif /* ENABLE_HTREE */
5946 * Given a busted directory, try to salvage it somehow.
5949 static void salvage_directory(ext2_filsys fs,
5950 struct ext2_dir_entry *dirent,
5951 struct ext2_dir_entry *prev,
5952 unsigned int *offset)
5954 char *cp = (char *) dirent;
5955 int left = fs->blocksize - *offset - dirent->rec_len;
5956 int name_len = dirent->name_len & 0xFF;
5959 * Special case of directory entry of size 8: copy what's left
5960 * of the directory block up to cover up the invalid hole.
5962 if ((left >= 12) && (dirent->rec_len == 8)) {
5963 memmove(cp, cp+8, left);
5964 memset(cp + left, 0, 8);
5968 * If the directory entry overruns the end of the directory
5969 * block, and the name is small enough to fit, then adjust the
5973 (name_len + 8 <= dirent->rec_len + left) &&
5974 dirent->inode <= fs->super->s_inodes_count &&
5975 strnlen(dirent->name, name_len) == name_len) {
5976 dirent->rec_len += left;
5980 * If the directory entry is a multiple of four, so it is
5981 * valid, let the previous directory entry absorb the invalid
5984 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
5985 prev->rec_len += dirent->rec_len;
5986 *offset += dirent->rec_len;
5990 * Default salvage method --- kill all of the directory
5991 * entries for the rest of the block. We will either try to
5992 * absorb it into the previous directory entry, or create a
5993 * new empty directory entry the rest of the directory block.
5996 prev->rec_len += fs->blocksize - *offset;
5997 *offset = fs->blocksize;
5999 dirent->rec_len = fs->blocksize - *offset;
6000 dirent->name_len = 0;
6005 static int check_dir_block(ext2_filsys fs,
6006 struct ext2_db_entry *db,
6009 struct dir_info *subdir, *dir;
6010 struct dx_dir_info *dx_dir;
6012 struct dx_dirblock_info *dx_db = NULL;
6013 #endif /* ENABLE_HTREE */
6014 struct ext2_dir_entry *dirent, *prev;
6015 ext2_dirhash_t hash;
6016 unsigned int offset = 0;
6017 int dir_modified = 0;
6019 blk_t block_nr = db->blk;
6020 ext2_ino_t ino = db->ino;
6022 struct check_dir_struct *cd;
6026 struct ext2_dx_root_info *root;
6027 struct ext2_dx_countlimit *limit;
6028 static dict_t de_dict;
6029 struct problem_context pctx;
6032 cd = (struct check_dir_struct *) priv_data;
6036 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6037 return DIRENT_ABORT;
6039 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6040 return DIRENT_ABORT;
6043 * Make sure the inode is still in use (could have been
6044 * deleted in the duplicate/bad blocks pass.
6046 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6050 cd->pctx.blk = block_nr;
6051 cd->pctx.blkcount = db->blockcnt;
6053 cd->pctx.dirent = 0;
6057 if (allocate_dir_block(ctx, db, &cd->pctx))
6067 if (ctx->dirs_to_hash &&
6068 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6071 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6072 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6073 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6074 if (cd->pctx.errcode) {
6075 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6076 ctx->flags |= E2F_FLAG_ABORT;
6077 return DIRENT_ABORT;
6079 memset(buf, 0, fs->blocksize);
6082 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6083 if (dx_dir && dx_dir->numblocks) {
6084 if (db->blockcnt >= dx_dir->numblocks) {
6085 printf("XXX should never happen!!!\n");
6088 dx_db = &dx_dir->dx_block[db->blockcnt];
6089 dx_db->type = DX_DIRBLOCK_LEAF;
6090 dx_db->phys = block_nr;
6091 dx_db->min_hash = ~0;
6092 dx_db->max_hash = 0;
6094 dirent = (struct ext2_dir_entry *) buf;
6095 limit = (struct ext2_dx_countlimit *) (buf+8);
6096 if (db->blockcnt == 0) {
6097 root = (struct ext2_dx_root_info *) (buf + 24);
6098 dx_db->type = DX_DIRBLOCK_ROOT;
6099 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6100 if ((root->reserved_zero ||
6101 root->info_length < 8 ||
6102 root->indirect_levels > 1) &&
6103 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6104 clear_htree(ctx, ino);
6105 dx_dir->numblocks = 0;
6108 dx_dir->hashversion = root->hash_version;
6109 dx_dir->depth = root->indirect_levels + 1;
6110 } else if ((dirent->inode == 0) &&
6111 (dirent->rec_len == fs->blocksize) &&
6112 (dirent->name_len == 0) &&
6113 (ext2fs_le16_to_cpu(limit->limit) ==
6114 ((fs->blocksize-8) /
6115 sizeof(struct ext2_dx_entry))))
6116 dx_db->type = DX_DIRBLOCK_NODE;
6118 #endif /* ENABLE_HTREE */
6120 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6124 dirent = (struct ext2_dir_entry *) (buf + offset);
6125 cd->pctx.dirent = dirent;
6126 cd->pctx.num = offset;
6127 if (((offset + dirent->rec_len) > fs->blocksize) ||
6128 (dirent->rec_len < 12) ||
6129 ((dirent->rec_len % 4) != 0) ||
6130 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6131 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6132 salvage_directory(fs, dirent, prev, &offset);
6136 goto abort_free_dict;
6138 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6139 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6140 dirent->name_len = EXT2_NAME_LEN;
6145 if (dot_state == 0) {
6146 if (check_dot(ctx, dirent, ino, &cd->pctx))
6148 } else if (dot_state == 1) {
6149 dir = e2fsck_get_dir_info(ctx, ino);
6151 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6152 goto abort_free_dict;
6154 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6156 } else if (dirent->inode == ino) {
6157 problem = PR_2_LINK_DOT;
6158 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6168 * Make sure the inode listed is a legal one.
6170 if (((dirent->inode != EXT2_ROOT_INO) &&
6171 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6172 (dirent->inode > fs->super->s_inodes_count)) {
6173 problem = PR_2_BAD_INO;
6174 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6177 * If the inode is unused, offer to clear it.
6179 problem = PR_2_UNUSED_INODE;
6180 } else if ((dot_state > 1) &&
6181 ((dirent->name_len & 0xFF) == 1) &&
6182 (dirent->name[0] == '.')) {
6184 * If there's a '.' entry in anything other
6185 * than the first directory entry, it's a
6186 * duplicate entry that should be removed.
6188 problem = PR_2_DUP_DOT;
6189 } else if ((dot_state > 1) &&
6190 ((dirent->name_len & 0xFF) == 2) &&
6191 (dirent->name[0] == '.') &&
6192 (dirent->name[1] == '.')) {
6194 * If there's a '..' entry in anything other
6195 * than the second directory entry, it's a
6196 * duplicate entry that should be removed.
6198 problem = PR_2_DUP_DOT_DOT;
6199 } else if ((dot_state > 1) &&
6200 (dirent->inode == EXT2_ROOT_INO)) {
6202 * Don't allow links to the root directory.
6203 * We check this specially to make sure we
6204 * catch this error case even if the root
6205 * directory hasn't been created yet.
6207 problem = PR_2_LINK_ROOT;
6208 } else if ((dot_state > 1) &&
6209 (dirent->name_len & 0xFF) == 0) {
6211 * Don't allow zero-length directory names.
6213 problem = PR_2_NULL_NAME;
6217 if (fix_problem(ctx, problem, &cd->pctx)) {
6222 ext2fs_unmark_valid(fs);
6223 if (problem == PR_2_BAD_INO)
6229 * If the inode was marked as having bad fields in
6230 * pass1, process it and offer to fix/clear it.
6231 * (We wait until now so that we can display the
6232 * pathname to the user.)
6234 if (ctx->inode_bad_map &&
6235 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6237 if (e2fsck_process_bad_inode(ctx, ino,
6239 buf + fs->blocksize)) {
6244 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6245 return DIRENT_ABORT;
6248 if (check_name(ctx, dirent, &cd->pctx))
6251 if (check_filetype(ctx, dirent, &cd->pctx))
6256 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6257 (dirent->name_len & 0xFF),
6258 fs->super->s_hash_seed, &hash, 0);
6259 if (hash < dx_db->min_hash)
6260 dx_db->min_hash = hash;
6261 if (hash > dx_db->max_hash)
6262 dx_db->max_hash = hash;
6267 * If this is a directory, then mark its parent in its
6268 * dir_info structure. If the parent field is already
6269 * filled in, then this directory has more than one
6270 * hard link. We assume the first link is correct,
6271 * and ask the user if he/she wants to clear this one.
6273 if ((dot_state > 1) &&
6274 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6276 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6278 cd->pctx.ino = dirent->inode;
6279 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6280 goto abort_free_dict;
6282 if (subdir->parent) {
6283 cd->pctx.ino2 = subdir->parent;
6284 if (fix_problem(ctx, PR_2_LINK_DIR,
6292 subdir->parent = ino;
6297 } else if (dict_lookup(&de_dict, dirent)) {
6298 clear_problem_context(&pctx);
6300 pctx.dirent = dirent;
6301 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6302 if (!ctx->dirs_to_hash)
6303 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6304 if (ctx->dirs_to_hash)
6305 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6308 dict_alloc_insert(&de_dict, dirent, dirent);
6310 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6313 ctx->fs_links_count++;
6314 ctx->fs_total_count++;
6317 offset += dirent->rec_len;
6319 } while (offset < fs->blocksize);
6322 cd->pctx.dir = cd->pctx.ino;
6323 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6324 (dx_db->type == DX_DIRBLOCK_NODE))
6325 parse_int_node(fs, db, cd, dx_dir, buf);
6327 #endif /* ENABLE_HTREE */
6328 if (offset != fs->blocksize) {
6329 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6330 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6331 dirent->rec_len = cd->pctx.num;
6336 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6337 if (cd->pctx.errcode) {
6338 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6340 goto abort_free_dict;
6342 ext2fs_mark_changed(fs);
6344 dict_free_nodes(&de_dict);
6347 dict_free_nodes(&de_dict);
6348 ctx->flags |= E2F_FLAG_ABORT;
6349 return DIRENT_ABORT;
6353 * This function is called to deallocate a block, and is an interator
6354 * functioned called by deallocate inode via ext2fs_iterate_block().
6356 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6357 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6358 blk_t ref_block FSCK_ATTR((unused)),
6359 int ref_offset FSCK_ATTR((unused)),
6362 e2fsck_t ctx = (e2fsck_t) priv_data;
6364 if (HOLE_BLKADDR(*block_nr))
6366 if ((*block_nr < fs->super->s_first_data_block) ||
6367 (*block_nr >= fs->super->s_blocks_count))
6369 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6370 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6375 * This fuction deallocates an inode
6377 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6379 ext2_filsys fs = ctx->fs;
6380 struct ext2_inode inode;
6381 struct problem_context pctx;
6384 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6385 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6386 inode.i_links_count = 0;
6387 inode.i_dtime = time(NULL);
6388 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6389 clear_problem_context(&pctx);
6393 * Fix up the bitmaps...
6395 e2fsck_read_bitmaps(ctx);
6396 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6397 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6398 if (ctx->inode_bad_map)
6399 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6400 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6402 if (inode.i_file_acl &&
6403 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6404 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6405 block_buf, -1, &count);
6406 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6411 pctx.blk = inode.i_file_acl;
6412 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6413 ctx->flags |= E2F_FLAG_ABORT;
6417 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6419 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6421 inode.i_file_acl = 0;
6424 if (!ext2fs_inode_has_valid_blocks(&inode))
6427 if (LINUX_S_ISREG(inode.i_mode) &&
6428 (inode.i_size_high || inode.i_size & 0x80000000UL))
6431 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6432 deallocate_inode_block, ctx);
6434 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6435 ctx->flags |= E2F_FLAG_ABORT;
6441 * This fuction clears the htree flag on an inode
6443 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6445 struct ext2_inode inode;
6447 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6448 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6449 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6450 if (ctx->dirs_to_hash)
6451 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6455 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6456 ext2_ino_t ino, char *buf)
6458 ext2_filsys fs = ctx->fs;
6459 struct ext2_inode inode;
6460 int inode_modified = 0;
6462 unsigned char *frag, *fsize;
6463 struct problem_context pctx;
6466 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6468 clear_problem_context(&pctx);
6471 pctx.inode = &inode;
6473 if (inode.i_file_acl &&
6474 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6475 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6476 inode.i_file_acl = 0;
6479 * This is a special kludge to deal with long symlinks
6480 * on big endian systems. i_blocks had already been
6481 * decremented earlier in pass 1, but since i_file_acl
6482 * hadn't yet been cleared, ext2fs_read_inode()
6483 * assumed that the file was short symlink and would
6484 * not have byte swapped i_block[0]. Hence, we have
6485 * to byte-swap it here.
6487 if (LINUX_S_ISLNK(inode.i_mode) &&
6488 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6489 (inode.i_blocks == fs->blocksize >> 9))
6490 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6496 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6497 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6498 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6499 !(LINUX_S_ISSOCK(inode.i_mode)))
6500 problem = PR_2_BAD_MODE;
6501 else if (LINUX_S_ISCHR(inode.i_mode)
6502 && !e2fsck_pass1_check_device_inode(fs, &inode))
6503 problem = PR_2_BAD_CHAR_DEV;
6504 else if (LINUX_S_ISBLK(inode.i_mode)
6505 && !e2fsck_pass1_check_device_inode(fs, &inode))
6506 problem = PR_2_BAD_BLOCK_DEV;
6507 else if (LINUX_S_ISFIFO(inode.i_mode)
6508 && !e2fsck_pass1_check_device_inode(fs, &inode))
6509 problem = PR_2_BAD_FIFO;
6510 else if (LINUX_S_ISSOCK(inode.i_mode)
6511 && !e2fsck_pass1_check_device_inode(fs, &inode))
6512 problem = PR_2_BAD_SOCKET;
6513 else if (LINUX_S_ISLNK(inode.i_mode)
6514 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6515 problem = PR_2_INVALID_SYMLINK;
6519 if (fix_problem(ctx, problem, &pctx)) {
6520 deallocate_inode(ctx, ino, 0);
6521 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6529 if (inode.i_faddr) {
6530 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6537 switch (fs->super->s_creator_os) {
6539 frag = &inode.osd2.linux2.l_i_frag;
6540 fsize = &inode.osd2.linux2.l_i_fsize;
6543 frag = &inode.osd2.hurd2.h_i_frag;
6544 fsize = &inode.osd2.hurd2.h_i_fsize;
6547 frag = &inode.osd2.masix2.m_i_frag;
6548 fsize = &inode.osd2.masix2.m_i_fsize;
6553 if (frag && *frag) {
6555 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6562 if (fsize && *fsize) {
6564 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6572 if (inode.i_file_acl &&
6573 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6574 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6575 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6576 inode.i_file_acl = 0;
6581 if (inode.i_dir_acl &&
6582 LINUX_S_ISDIR(inode.i_mode)) {
6583 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6584 inode.i_dir_acl = 0;
6591 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6593 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6599 * allocate_dir_block --- this function allocates a new directory
6600 * block for a particular inode; this is done if a directory has
6601 * a "hole" in it, or if a directory has a illegal block number
6602 * that was zeroed out and now needs to be replaced.
6604 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6605 struct problem_context *pctx)
6607 ext2_filsys fs = ctx->fs;
6610 struct ext2_inode inode;
6612 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6616 * Read the inode and block bitmaps in; we'll be messing with
6619 e2fsck_read_bitmaps(ctx);
6622 * First, find a free block
6624 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6625 if (pctx->errcode) {
6626 pctx->str = "ext2fs_new_block";
6627 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6630 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6631 ext2fs_mark_block_bitmap(fs->block_map, blk);
6632 ext2fs_mark_bb_dirty(fs);
6635 * Now let's create the actual data block for the inode
6638 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6640 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6641 EXT2_ROOT_INO, &block);
6643 if (pctx->errcode) {
6644 pctx->str = "ext2fs_new_dir_block";
6645 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6649 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6650 ext2fs_free_mem(&block);
6651 if (pctx->errcode) {
6652 pctx->str = "ext2fs_write_dir_block";
6653 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6658 * Update the inode block count
6660 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6661 inode.i_blocks += fs->blocksize / 512;
6662 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6663 inode.i_size = (db->blockcnt+1) * fs->blocksize;
6664 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6667 * Finally, update the block pointers for the inode
6670 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6671 0, update_dir_block, db);
6672 if (pctx->errcode) {
6673 pctx->str = "ext2fs_block_iterate";
6674 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6682 * This is a helper function for allocate_dir_block().
6684 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6686 e2_blkcnt_t blockcnt,
6687 blk_t ref_block FSCK_ATTR((unused)),
6688 int ref_offset FSCK_ATTR((unused)),
6691 struct ext2_db_entry *db;
6693 db = (struct ext2_db_entry *) priv_data;
6694 if (db->blockcnt == (int) blockcnt) {
6695 *block_nr = db->blk;
6696 return BLOCK_CHANGED;
6702 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6704 * Pass #3 assures that all directories are connected to the
6705 * filesystem tree, using the following algorithm:
6707 * First, the root directory is checked to make sure it exists; if
6708 * not, e2fsck will offer to create a new one. It is then marked as
6711 * Then, pass3 interates over all directory inodes; for each directory
6712 * it attempts to trace up the filesystem tree, using dirinfo.parent
6713 * until it reaches a directory which has been marked "done". If it
6714 * cannot do so, then the directory must be disconnected, and e2fsck
6715 * will offer to reconnect it to /lost+found. While it is chasing
6716 * parent pointers up the filesystem tree, if pass3 sees a directory
6717 * twice, then it has detected a filesystem loop, and it will again
6718 * offer to reconnect the directory to /lost+found in to break the
6721 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6722 * reconnect inodes to /lost+found; this subroutine is also used by
6723 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6724 * is responsible for creating /lost+found if it does not exist.
6726 * Pass 3 frees the following data structures:
6727 * - The dirinfo directory information cache.
6730 static void check_root(e2fsck_t ctx);
6731 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6732 struct problem_context *pctx);
6733 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6735 static ext2fs_inode_bitmap inode_loop_detect;
6736 static ext2fs_inode_bitmap inode_done_map;
6738 static void e2fsck_pass3(e2fsck_t ctx)
6740 ext2_filsys fs = ctx->fs;
6742 struct problem_context pctx;
6743 struct dir_info *dir;
6744 unsigned long maxdirs, count;
6746 clear_problem_context(&pctx);
6750 if (!(ctx->options & E2F_OPT_PREEN))
6751 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6754 * Allocate some bitmaps to do loop detection.
6756 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6760 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6761 ctx->flags |= E2F_FLAG_ABORT;
6765 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6768 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6770 maxdirs = e2fsck_get_num_dirinfo(ctx);
6774 if ((ctx->progress)(ctx, 3, 0, maxdirs))
6777 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6778 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6780 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6782 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6783 if (check_directory(ctx, dir, &pctx))
6788 * Force the creation of /lost+found if not present
6790 if ((ctx->flags & E2F_OPT_READONLY) == 0)
6791 e2fsck_get_lost_and_found(ctx, 1);
6794 * If there are any directories that need to be indexed or
6795 * optimized, do it here.
6797 e2fsck_rehash_directories(ctx);
6800 e2fsck_free_dir_info(ctx);
6801 ext2fs_free_inode_bitmap(inode_loop_detect);
6802 inode_loop_detect = 0;
6803 ext2fs_free_inode_bitmap(inode_done_map);
6808 * This makes sure the root inode is present; if not, we ask if the
6809 * user wants us to create it. Not creating it is a fatal error.
6811 static void check_root(e2fsck_t ctx)
6813 ext2_filsys fs = ctx->fs;
6815 struct ext2_inode inode;
6817 struct problem_context pctx;
6819 clear_problem_context(&pctx);
6821 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6823 * If the root inode is not a directory, die here. The
6824 * user must have answered 'no' in pass1 when we
6825 * offered to clear it.
6827 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6829 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6830 ctx->flags |= E2F_FLAG_ABORT;
6835 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6836 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6837 ctx->flags |= E2F_FLAG_ABORT;
6841 e2fsck_read_bitmaps(ctx);
6844 * First, find a free block
6846 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6848 pctx.str = "ext2fs_new_block";
6849 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6850 ctx->flags |= E2F_FLAG_ABORT;
6853 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6854 ext2fs_mark_block_bitmap(fs->block_map, blk);
6855 ext2fs_mark_bb_dirty(fs);
6858 * Now let's create the actual data block for the inode
6860 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6863 pctx.str = "ext2fs_new_dir_block";
6864 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6865 ctx->flags |= E2F_FLAG_ABORT;
6869 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6871 pctx.str = "ext2fs_write_dir_block";
6872 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6873 ctx->flags |= E2F_FLAG_ABORT;
6876 ext2fs_free_mem(&block);
6879 * Set up the inode structure
6881 memset(&inode, 0, sizeof(inode));
6882 inode.i_mode = 040755;
6883 inode.i_size = fs->blocksize;
6884 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
6885 inode.i_links_count = 2;
6886 inode.i_blocks = fs->blocksize / 512;
6887 inode.i_block[0] = blk;
6890 * Write out the inode.
6892 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6894 pctx.str = "ext2fs_write_inode";
6895 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6896 ctx->flags |= E2F_FLAG_ABORT;
6901 * Miscellaneous bookkeeping...
6903 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6904 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6905 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6907 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6908 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6909 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6910 ext2fs_mark_ib_dirty(fs);
6914 * This subroutine is responsible for making sure that a particular
6915 * directory is connected to the root; if it isn't we trace it up as
6916 * far as we can go, and then offer to connect the resulting parent to
6917 * the lost+found. We have to do loop detection; if we ever discover
6918 * a loop, we treat that as a disconnected directory and offer to
6919 * reparent it to lost+found.
6921 * However, loop detection is expensive, because for very large
6922 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6923 * is non-trivial. Loops in filesystems are also a rare error case,
6924 * and we shouldn't optimize for error cases. So we try two passes of
6925 * the algorithm. The first time, we ignore loop detection and merely
6926 * increment a counter; if the counter exceeds some extreme threshold,
6927 * then we try again with the loop detection bitmap enabled.
6929 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6930 struct problem_context *pctx)
6932 ext2_filsys fs = ctx->fs;
6933 struct dir_info *p = dir;
6934 int loop_pass = 0, parent_count = 0;
6941 * Mark this inode as being "done"; by the time we
6942 * return from this function, the inode we either be
6943 * verified as being connected to the directory tree,
6944 * or we will have offered to reconnect this to
6947 * If it was marked done already, then we've reached a
6948 * parent we've already checked.
6950 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6954 * If this directory doesn't have a parent, or we've
6955 * seen the parent once already, then offer to
6956 * reparent it to lost+found
6960 (ext2fs_test_inode_bitmap(inode_loop_detect,
6963 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6964 if (e2fsck_reconnect_file(ctx, pctx->ino))
6965 ext2fs_unmark_valid(fs);
6967 p = e2fsck_get_dir_info(ctx, pctx->ino);
6968 p->parent = ctx->lost_and_found;
6969 fix_dotdot(ctx, p, ctx->lost_and_found);
6974 p = e2fsck_get_dir_info(ctx, p->parent);
6976 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
6980 ext2fs_mark_inode_bitmap(inode_loop_detect,
6982 } else if (parent_count++ > 2048) {
6984 * If we've run into a path depth that's
6985 * greater than 2048, try again with the inode
6986 * loop bitmap turned on and start from the
6990 if (inode_loop_detect)
6991 ext2fs_clear_inode_bitmap(inode_loop_detect);
6993 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
6994 if (pctx->errcode) {
6997 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
6998 ctx->flags |= E2F_FLAG_ABORT;
7007 * Make sure that .. and the parent directory are the same;
7008 * offer to fix it if not.
7010 if (dir->parent != dir->dotdot) {
7011 pctx->ino = dir->ino;
7012 pctx->ino2 = dir->dotdot;
7013 pctx->dir = dir->parent;
7014 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7015 fix_dotdot(ctx, dir, dir->parent);
7021 * This routine gets the lost_and_found inode, making it a directory
7024 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7026 ext2_filsys fs = ctx->fs;
7030 struct ext2_inode inode;
7032 static const char name[] = "lost+found";
7033 struct problem_context pctx;
7034 struct dir_info *dirinfo;
7036 if (ctx->lost_and_found)
7037 return ctx->lost_and_found;
7039 clear_problem_context(&pctx);
7041 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7042 sizeof(name)-1, 0, &ino);
7046 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7047 ctx->lost_and_found = ino;
7051 /* Lost+found isn't a directory! */
7055 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7058 /* OK, unlink the old /lost+found file. */
7059 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7061 pctx.str = "ext2fs_unlink";
7062 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7065 dirinfo = e2fsck_get_dir_info(ctx, ino);
7067 dirinfo->parent = 0;
7068 e2fsck_adjust_inode_count(ctx, ino, -1);
7069 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7070 pctx.errcode = retval;
7071 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7073 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7077 * Read the inode and block bitmaps in; we'll be messing with
7080 e2fsck_read_bitmaps(ctx);
7083 * First, find a free block
7085 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7087 pctx.errcode = retval;
7088 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7091 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7092 ext2fs_block_alloc_stats(fs, blk, +1);
7095 * Next find a free inode.
7097 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7098 ctx->inode_used_map, &ino);
7100 pctx.errcode = retval;
7101 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7104 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7105 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7106 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7109 * Now let's create the actual data block for the inode
7111 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7113 pctx.errcode = retval;
7114 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7118 retval = ext2fs_write_dir_block(fs, blk, block);
7119 ext2fs_free_mem(&block);
7121 pctx.errcode = retval;
7122 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7127 * Set up the inode structure
7129 memset(&inode, 0, sizeof(inode));
7130 inode.i_mode = 040700;
7131 inode.i_size = fs->blocksize;
7132 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
7133 inode.i_links_count = 2;
7134 inode.i_blocks = fs->blocksize / 512;
7135 inode.i_block[0] = blk;
7138 * Next, write out the inode.
7140 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7142 pctx.str = "ext2fs_write_inode";
7143 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7147 * Finally, create the directory link
7149 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7151 pctx.str = "ext2fs_link";
7152 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7157 * Miscellaneous bookkeeping that needs to be kept straight.
7159 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7160 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7161 ext2fs_icount_store(ctx->inode_count, ino, 2);
7162 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7163 ctx->lost_and_found = ino;
7168 * This routine will connect a file to lost+found
7170 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7172 ext2_filsys fs = ctx->fs;
7175 struct problem_context pctx;
7176 struct ext2_inode inode;
7179 clear_problem_context(&pctx);
7182 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7183 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7184 ctx->bad_lost_and_found++;
7186 if (ctx->bad_lost_and_found) {
7187 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7191 sprintf(name, "#%u", ino);
7192 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7193 file_type = ext2_file_type(inode.i_mode);
7194 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7195 if (retval == EXT2_ET_DIR_NO_SPACE) {
7196 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7198 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7201 pctx.errcode = retval;
7202 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7205 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7209 pctx.errcode = retval;
7210 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7213 e2fsck_adjust_inode_count(ctx, ino, 1);
7219 * Utility routine to adjust the inode counts on an inode.
7221 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7223 ext2_filsys fs = ctx->fs;
7225 struct ext2_inode inode;
7230 retval = ext2fs_read_inode(fs, ino, &inode);
7235 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7236 if (inode.i_links_count == (__u16) ~0)
7238 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7239 inode.i_links_count++;
7240 } else if (adj == -1) {
7241 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7242 if (inode.i_links_count == 0)
7244 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7245 inode.i_links_count--;
7248 retval = ext2fs_write_inode(fs, ino, &inode);
7256 * Fix parent --- this routine fixes up the parent of a directory.
7258 struct fix_dotdot_struct {
7265 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7266 int offset FSCK_ATTR((unused)),
7267 int blocksize FSCK_ATTR((unused)),
7268 char *buf FSCK_ATTR((unused)),
7271 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7273 struct problem_context pctx;
7275 if ((dirent->name_len & 0xFF) != 2)
7277 if (strncmp(dirent->name, "..", 2))
7280 clear_problem_context(&pctx);
7282 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7284 pctx.errcode = retval;
7285 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7287 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7289 pctx.errcode = retval;
7290 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7292 dirent->inode = fp->parent;
7295 return DIRENT_ABORT | DIRENT_CHANGED;
7298 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7300 ext2_filsys fs = ctx->fs;
7302 struct fix_dotdot_struct fp;
7303 struct problem_context pctx;
7310 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7311 0, fix_dotdot_proc, &fp);
7312 if (retval || !fp.done) {
7313 clear_problem_context(&pctx);
7314 pctx.ino = dir->ino;
7315 pctx.errcode = retval;
7316 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7317 PR_3_FIX_PARENT_NOFIND, &pctx);
7318 ext2fs_unmark_valid(fs);
7320 dir->dotdot = parent;
7324 * These routines are responsible for expanding a /lost+found if it is
7328 struct expand_dir_struct {
7330 int guaranteed_size;
7337 static int expand_dir_proc(ext2_filsys fs,
7339 e2_blkcnt_t blockcnt,
7340 blk_t ref_block FSCK_ATTR((unused)),
7341 int ref_offset FSCK_ATTR((unused)),
7344 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7346 static blk_t last_blk = 0;
7353 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7357 es->last_block = blockcnt;
7359 last_blk = *blocknr;
7362 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7369 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7375 retval = ext2fs_write_dir_block(fs, new_blk, block);
7377 retval = ext2fs_get_mem(fs->blocksize, &block);
7382 memset(block, 0, fs->blocksize);
7383 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7389 ext2fs_free_mem(&block);
7391 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7392 ext2fs_block_alloc_stats(fs, new_blk, +1);
7396 return (BLOCK_CHANGED | BLOCK_ABORT);
7398 return BLOCK_CHANGED;
7401 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7402 int num, int guaranteed_size)
7404 ext2_filsys fs = ctx->fs;
7406 struct expand_dir_struct es;
7407 struct ext2_inode inode;
7409 if (!(fs->flags & EXT2_FLAG_RW))
7410 return EXT2_ET_RO_FILSYS;
7413 * Read the inode and block bitmaps in; we'll be messing with
7416 e2fsck_read_bitmaps(ctx);
7418 retval = ext2fs_check_directory(fs, dir);
7423 es.guaranteed_size = guaranteed_size;
7429 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7430 0, expand_dir_proc, &es);
7436 * Update the size and block count fields in the inode.
7438 retval = ext2fs_read_inode(fs, dir, &inode);
7442 inode.i_size = (es.last_block + 1) * fs->blocksize;
7443 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7445 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7451 * pass4.c -- pass #4 of e2fsck: Check reference counts
7453 * Pass 4 frees the following data structures:
7454 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7458 * This routine is called when an inode is not connected to the
7461 * This subroutine returns 1 then the caller shouldn't bother with the
7462 * rest of the pass 4 tests.
7464 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7466 ext2_filsys fs = ctx->fs;
7467 struct ext2_inode inode;
7468 struct problem_context pctx;
7470 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7471 clear_problem_context(&pctx);
7473 pctx.inode = &inode;
7476 * Offer to delete any zero-length files that does not have
7477 * blocks. If there is an EA block, it might have useful
7478 * information, so we won't prompt to delete it, but let it be
7479 * reconnected to lost+found.
7481 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7482 LINUX_S_ISDIR(inode.i_mode))) {
7483 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7484 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7485 inode.i_links_count = 0;
7486 inode.i_dtime = time(NULL);
7487 e2fsck_write_inode(ctx, i, &inode,
7488 "disconnect_inode");
7490 * Fix up the bitmaps...
7492 e2fsck_read_bitmaps(ctx);
7493 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7494 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7495 ext2fs_inode_alloc_stats2(fs, i, -1,
7496 LINUX_S_ISDIR(inode.i_mode));
7502 * Prompt to reconnect.
7504 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7505 if (e2fsck_reconnect_file(ctx, i))
7506 ext2fs_unmark_valid(fs);
7509 * If we don't attach the inode, then skip the
7510 * i_links_test since there's no point in trying to
7511 * force i_links_count to zero.
7513 ext2fs_unmark_valid(fs);
7520 static void e2fsck_pass4(e2fsck_t ctx)
7522 ext2_filsys fs = ctx->fs;
7524 struct ext2_inode inode;
7525 struct problem_context pctx;
7526 __u16 link_count, link_counted;
7528 int group, maxgroup;
7532 clear_problem_context(&pctx);
7534 if (!(ctx->options & E2F_OPT_PREEN))
7535 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7538 maxgroup = fs->group_desc_count;
7540 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7543 for (i=1; i <= fs->super->s_inodes_count; i++) {
7544 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7546 if ((i % fs->super->s_inodes_per_group) == 0) {
7549 if ((ctx->progress)(ctx, 4, group, maxgroup))
7552 if (i == EXT2_BAD_INO ||
7553 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7555 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7556 (ctx->inode_imagic_map &&
7557 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7559 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7560 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7561 if (link_counted == 0) {
7563 buf = e2fsck_allocate_memory(ctx,
7564 fs->blocksize, "bad_inode buffer");
7565 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7567 if (disconnect_inode(ctx, i))
7569 ext2fs_icount_fetch(ctx->inode_link_info, i,
7571 ext2fs_icount_fetch(ctx->inode_count, i,
7574 if (link_counted != link_count) {
7575 e2fsck_read_inode(ctx, i, &inode, "pass4");
7577 pctx.inode = &inode;
7578 if (link_count != inode.i_links_count) {
7579 pctx.num = link_count;
7581 PR_4_INCONSISTENT_COUNT, &pctx);
7583 pctx.num = link_counted;
7584 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7585 inode.i_links_count = link_counted;
7586 e2fsck_write_inode(ctx, i, &inode, "pass4");
7590 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7591 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7592 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7593 ctx->inode_imagic_map = 0;
7594 ext2fs_free_mem(&buf);
7598 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7601 #define NO_BLK ((blk_t) -1)
7603 static void print_bitmap_problem(e2fsck_t ctx, int problem,
7604 struct problem_context *pctx)
7607 case PR_5_BLOCK_UNUSED:
7608 if (pctx->blk == pctx->blk2)
7611 problem = PR_5_BLOCK_RANGE_UNUSED;
7613 case PR_5_BLOCK_USED:
7614 if (pctx->blk == pctx->blk2)
7617 problem = PR_5_BLOCK_RANGE_USED;
7619 case PR_5_INODE_UNUSED:
7620 if (pctx->ino == pctx->ino2)
7623 problem = PR_5_INODE_RANGE_UNUSED;
7625 case PR_5_INODE_USED:
7626 if (pctx->ino == pctx->ino2)
7629 problem = PR_5_INODE_RANGE_USED;
7632 fix_problem(ctx, problem, pctx);
7633 pctx->blk = pctx->blk2 = NO_BLK;
7634 pctx->ino = pctx->ino2 = 0;
7637 static void check_block_bitmaps(e2fsck_t ctx)
7639 ext2_filsys fs = ctx->fs;
7643 unsigned int blocks = 0;
7644 unsigned int free_blocks = 0;
7647 struct problem_context pctx;
7648 int problem, save_problem, fixit, had_problem;
7651 clear_problem_context(&pctx);
7652 free_array = (int *) e2fsck_allocate_memory(ctx,
7653 fs->group_desc_count * sizeof(int), "free block count array");
7655 if ((fs->super->s_first_data_block <
7656 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7657 (fs->super->s_blocks_count-1 >
7658 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7660 pctx.blk = fs->super->s_first_data_block;
7661 pctx.blk2 = fs->super->s_blocks_count -1;
7662 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7663 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7664 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7666 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7670 if ((fs->super->s_first_data_block <
7671 ext2fs_get_block_bitmap_start(fs->block_map)) ||
7672 (fs->super->s_blocks_count-1 >
7673 ext2fs_get_block_bitmap_end(fs->block_map))) {
7675 pctx.blk = fs->super->s_first_data_block;
7676 pctx.blk2 = fs->super->s_blocks_count -1;
7677 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7678 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7679 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7681 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7688 pctx.blk = pctx.blk2 = NO_BLK;
7689 for (i = fs->super->s_first_data_block;
7690 i < fs->super->s_blocks_count;
7692 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7693 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7695 if (actual == bitmap)
7698 if (!actual && bitmap) {
7700 * Block not used, but marked in use in the bitmap.
7702 problem = PR_5_BLOCK_UNUSED;
7705 * Block used, but not marked in use in the bitmap.
7707 problem = PR_5_BLOCK_USED;
7709 if (pctx.blk == NO_BLK) {
7710 pctx.blk = pctx.blk2 = i;
7711 save_problem = problem;
7713 if ((problem == save_problem) &&
7717 print_bitmap_problem(ctx, save_problem, &pctx);
7718 pctx.blk = pctx.blk2 = i;
7719 save_problem = problem;
7722 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7731 if ((blocks == fs->super->s_blocks_per_group) ||
7732 (i == fs->super->s_blocks_count-1)) {
7733 free_array[group] = group_free;
7738 if ((ctx->progress)(ctx, 5, group,
7739 fs->group_desc_count*2))
7743 if (pctx.blk != NO_BLK)
7744 print_bitmap_problem(ctx, save_problem, &pctx);
7746 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7749 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7752 ext2fs_free_block_bitmap(fs->block_map);
7753 retval = ext2fs_copy_bitmap(ctx->block_found_map,
7756 clear_problem_context(&pctx);
7757 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7758 ctx->flags |= E2F_FLAG_ABORT;
7761 ext2fs_set_bitmap_padding(fs->block_map);
7762 ext2fs_mark_bb_dirty(fs);
7764 /* Redo the counts */
7765 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7766 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7768 } else if (fixit == 0)
7769 ext2fs_unmark_valid(fs);
7771 for (i = 0; i < fs->group_desc_count; i++) {
7772 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7774 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7775 pctx.blk2 = free_array[i];
7777 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7779 fs->group_desc[i].bg_free_blocks_count =
7781 ext2fs_mark_super_dirty(fs);
7783 ext2fs_unmark_valid(fs);
7786 if (free_blocks != fs->super->s_free_blocks_count) {
7788 pctx.blk = fs->super->s_free_blocks_count;
7789 pctx.blk2 = free_blocks;
7791 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7792 fs->super->s_free_blocks_count = free_blocks;
7793 ext2fs_mark_super_dirty(fs);
7795 ext2fs_unmark_valid(fs);
7797 ext2fs_free_mem(&free_array);
7800 static void check_inode_bitmaps(e2fsck_t ctx)
7802 ext2_filsys fs = ctx->fs;
7804 unsigned int free_inodes = 0;
7808 unsigned int inodes = 0;
7813 struct problem_context pctx;
7814 int problem, save_problem, fixit, had_problem;
7816 clear_problem_context(&pctx);
7817 free_array = (int *) e2fsck_allocate_memory(ctx,
7818 fs->group_desc_count * sizeof(int), "free inode count array");
7820 dir_array = (int *) e2fsck_allocate_memory(ctx,
7821 fs->group_desc_count * sizeof(int), "directory count array");
7823 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7824 (fs->super->s_inodes_count >
7825 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7828 pctx.blk2 = fs->super->s_inodes_count;
7829 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7830 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7831 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7833 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7836 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7837 (fs->super->s_inodes_count >
7838 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7841 pctx.blk2 = fs->super->s_inodes_count;
7842 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7843 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7844 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7846 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7853 pctx.ino = pctx.ino2 = 0;
7854 for (i = 1; i <= fs->super->s_inodes_count; i++) {
7855 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7856 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7858 if (actual == bitmap)
7861 if (!actual && bitmap) {
7863 * Inode wasn't used, but marked in bitmap
7865 problem = PR_5_INODE_UNUSED;
7866 } else /* if (actual && !bitmap) */ {
7868 * Inode used, but not in bitmap
7870 problem = PR_5_INODE_USED;
7872 if (pctx.ino == 0) {
7873 pctx.ino = pctx.ino2 = i;
7874 save_problem = problem;
7876 if ((problem == save_problem) &&
7880 print_bitmap_problem(ctx, save_problem, &pctx);
7881 pctx.ino = pctx.ino2 = i;
7882 save_problem = problem;
7885 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7893 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7897 if ((inodes == fs->super->s_inodes_per_group) ||
7898 (i == fs->super->s_inodes_count)) {
7899 free_array[group] = group_free;
7900 dir_array[group] = dirs_count;
7906 if ((ctx->progress)(ctx, 5,
7907 group + fs->group_desc_count,
7908 fs->group_desc_count*2))
7913 print_bitmap_problem(ctx, save_problem, &pctx);
7916 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7919 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7922 ext2fs_free_inode_bitmap(fs->inode_map);
7923 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7926 clear_problem_context(&pctx);
7927 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7928 ctx->flags |= E2F_FLAG_ABORT;
7931 ext2fs_set_bitmap_padding(fs->inode_map);
7932 ext2fs_mark_ib_dirty(fs);
7935 inodes = 0; free_inodes = 0; group_free = 0;
7936 dirs_count = 0; group = 0;
7937 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7938 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7940 } else if (fixit == 0)
7941 ext2fs_unmark_valid(fs);
7943 for (i = 0; i < fs->group_desc_count; i++) {
7944 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7946 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7947 pctx.ino2 = free_array[i];
7948 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7950 fs->group_desc[i].bg_free_inodes_count =
7952 ext2fs_mark_super_dirty(fs);
7954 ext2fs_unmark_valid(fs);
7956 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7958 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7959 pctx.ino2 = dir_array[i];
7961 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7963 fs->group_desc[i].bg_used_dirs_count =
7965 ext2fs_mark_super_dirty(fs);
7967 ext2fs_unmark_valid(fs);
7970 if (free_inodes != fs->super->s_free_inodes_count) {
7972 pctx.ino = fs->super->s_free_inodes_count;
7973 pctx.ino2 = free_inodes;
7975 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
7976 fs->super->s_free_inodes_count = free_inodes;
7977 ext2fs_mark_super_dirty(fs);
7979 ext2fs_unmark_valid(fs);
7981 ext2fs_free_mem(&free_array);
7982 ext2fs_free_mem(&dir_array);
7985 static void check_inode_end(e2fsck_t ctx)
7987 ext2_filsys fs = ctx->fs;
7988 ext2_ino_t end, save_inodes_count, i;
7989 struct problem_context pctx;
7991 clear_problem_context(&pctx);
7993 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
7994 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
7995 &save_inodes_count);
7998 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
7999 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8002 if (save_inodes_count == end)
8005 for (i = save_inodes_count + 1; i <= end; i++) {
8006 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8007 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8008 for (i = save_inodes_count + 1; i <= end; i++)
8009 ext2fs_mark_inode_bitmap(fs->inode_map,
8011 ext2fs_mark_ib_dirty(fs);
8013 ext2fs_unmark_valid(fs);
8018 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8019 save_inodes_count, 0);
8022 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8023 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8028 static void check_block_end(e2fsck_t ctx)
8030 ext2_filsys fs = ctx->fs;
8031 blk_t end, save_blocks_count, i;
8032 struct problem_context pctx;
8034 clear_problem_context(&pctx);
8036 end = fs->block_map->start +
8037 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8038 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8039 &save_blocks_count);
8042 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8043 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8046 if (save_blocks_count == end)
8049 for (i = save_blocks_count + 1; i <= end; i++) {
8050 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8051 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8052 for (i = save_blocks_count + 1; i <= end; i++)
8053 ext2fs_mark_block_bitmap(fs->block_map,
8055 ext2fs_mark_bb_dirty(fs);
8057 ext2fs_unmark_valid(fs);
8062 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8063 save_blocks_count, 0);
8066 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8067 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8072 static void e2fsck_pass5(e2fsck_t ctx)
8074 struct problem_context pctx;
8078 clear_problem_context(&pctx);
8080 if (!(ctx->options & E2F_OPT_PREEN))
8081 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8084 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8087 e2fsck_read_bitmaps(ctx);
8089 check_block_bitmaps(ctx);
8090 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8092 check_inode_bitmaps(ctx);
8093 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8095 check_inode_end(ctx);
8096 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8098 check_block_end(ctx);
8099 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8102 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8103 ctx->inode_used_map = 0;
8104 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8105 ctx->inode_dir_map = 0;
8106 ext2fs_free_block_bitmap(ctx->block_found_map);
8107 ctx->block_found_map = 0;
8111 * problem.c --- report filesystem problems to the user
8114 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8115 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8116 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8117 #define PR_MSG_ONLY 0x000008 /* Print message only */
8119 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8121 #define PR_FATAL 0x001000 /* Fatal error */
8122 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8124 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8125 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8126 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8127 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8128 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8131 #define PROMPT_NONE 0
8132 #define PROMPT_FIX 1
8133 #define PROMPT_CLEAR 2
8134 #define PROMPT_RELOCATE 3
8135 #define PROMPT_ALLOCATE 4
8136 #define PROMPT_EXPAND 5
8137 #define PROMPT_CONNECT 6
8138 #define PROMPT_CREATE 7
8139 #define PROMPT_SALVAGE 8
8140 #define PROMPT_TRUNCATE 9
8141 #define PROMPT_CLEAR_INODE 10
8142 #define PROMPT_ABORT 11
8143 #define PROMPT_SPLIT 12
8144 #define PROMPT_CONTINUE 13
8145 #define PROMPT_CLONE 14
8146 #define PROMPT_DELETE 15
8147 #define PROMPT_SUPPRESS 16
8148 #define PROMPT_UNLINK 17
8149 #define PROMPT_CLEAR_HTREE 18
8150 #define PROMPT_RECREATE 19
8151 #define PROMPT_NULL 20
8153 struct e2fsck_problem {
8155 const char * e2p_description;
8158 problem_t second_code;
8161 struct latch_descr {
8164 problem_t end_message;
8169 * These are the prompts which are used to ask the user if they want
8172 static const char *const prompt[] = {
8173 N_("(no prompt)"), /* 0 */
8175 N_("Clear"), /* 2 */
8176 N_("Relocate"), /* 3 */
8177 N_("Allocate"), /* 4 */
8178 N_("Expand"), /* 5 */
8179 N_("Connect to /lost+found"), /* 6 */
8180 N_("Create"), /* 7 */
8181 N_("Salvage"), /* 8 */
8182 N_("Truncate"), /* 9 */
8183 N_("Clear inode"), /* 10 */
8184 N_("Abort"), /* 11 */
8185 N_("Split"), /* 12 */
8186 N_("Continue"), /* 13 */
8187 N_("Clone multiply-claimed blocks"), /* 14 */
8188 N_("Delete file"), /* 15 */
8189 N_("Suppress messages"),/* 16 */
8190 N_("Unlink"), /* 17 */
8191 N_("Clear HTree index"),/* 18 */
8192 N_("Recreate"), /* 19 */
8197 * These messages are printed when we are preen mode and we will be
8198 * automatically fixing the problem.
8200 static const char *const preen_msg[] = {
8201 N_("(NONE)"), /* 0 */
8202 N_("FIXED"), /* 1 */
8203 N_("CLEARED"), /* 2 */
8204 N_("RELOCATED"), /* 3 */
8205 N_("ALLOCATED"), /* 4 */
8206 N_("EXPANDED"), /* 5 */
8207 N_("RECONNECTED"), /* 6 */
8208 N_("CREATED"), /* 7 */
8209 N_("SALVAGED"), /* 8 */
8210 N_("TRUNCATED"), /* 9 */
8211 N_("INODE CLEARED"), /* 10 */
8212 N_("ABORTED"), /* 11 */
8213 N_("SPLIT"), /* 12 */
8214 N_("CONTINUING"), /* 13 */
8215 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8216 N_("FILE DELETED"), /* 15 */
8217 N_("SUPPRESSED"), /* 16 */
8218 N_("UNLINKED"), /* 17 */
8219 N_("HTREE INDEX CLEARED"),/* 18 */
8220 N_("WILL RECREATE"), /* 19 */
8224 static const struct e2fsck_problem problem_table[] = {
8226 /* Pre-Pass 1 errors */
8228 /* Block bitmap not in group */
8229 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8230 PROMPT_RELOCATE, PR_LATCH_RELOC },
8232 /* Inode bitmap not in group */
8233 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8234 PROMPT_RELOCATE, PR_LATCH_RELOC },
8236 /* Inode table not in group */
8237 { PR_0_ITABLE_NOT_GROUP,
8238 N_("@i table for @g %g is not in @g. (@b %b)\n"
8239 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8240 PROMPT_RELOCATE, PR_LATCH_RELOC },
8242 /* Superblock corrupt */
8244 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8245 "@f. If the @v is valid and it really contains an ext2\n"
8246 "@f (and not swap or ufs or something else), then the @S\n"
8247 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8248 " e2fsck -b %S <@v>\n\n"),
8249 PROMPT_NONE, PR_FATAL },
8251 /* Filesystem size is wrong */
8252 { PR_0_FS_SIZE_WRONG,
8253 N_("The @f size (according to the @S) is %b @bs\n"
8254 "The physical size of the @v is %c @bs\n"
8255 "Either the @S or the partition table is likely to be corrupt!\n"),
8258 /* Fragments not supported */
8259 { PR_0_NO_FRAGMENTS,
8260 N_("@S @b_size = %b, fragsize = %c.\n"
8261 "This version of e2fsck does not support fragment sizes different\n"
8262 "from the @b size.\n"),
8263 PROMPT_NONE, PR_FATAL },
8265 /* Bad blocks_per_group */
8266 { PR_0_BLOCKS_PER_GROUP,
8267 N_("@S @bs_per_group = %b, should have been %c\n"),
8268 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8270 /* Bad first_data_block */
8271 { PR_0_FIRST_DATA_BLOCK,
8272 N_("@S first_data_@b = %b, should have been %c\n"),
8273 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8275 /* Adding UUID to filesystem */
8277 N_("@f did not have a UUID; generating one.\n\n"),
8281 { PR_0_RELOCATE_HINT,
8282 N_("Note: if several inode or block bitmap blocks or part\n"
8283 "of the inode table require relocation, you may wish to try\n"
8284 "running e2fsck with the '-b %S' option first. The problem\n"
8285 "may lie only with the primary block group descriptors, and\n"
8286 "the backup block group descriptors may be OK.\n\n"),
8287 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8289 /* Miscellaneous superblock corruption */
8290 { PR_0_MISC_CORRUPT_SUPER,
8291 N_("Corruption found in @S. (%s = %N).\n"),
8292 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8294 /* Error determing physical device size of filesystem */
8295 { PR_0_GETSIZE_ERROR,
8296 N_("Error determining size of the physical @v: %m\n"),
8297 PROMPT_NONE, PR_FATAL },
8299 /* Inode count in superblock is incorrect */
8300 { PR_0_INODE_COUNT_WRONG,
8301 N_("@i count in @S is %i, @s %j.\n"),
8304 { PR_0_HURD_CLEAR_FILETYPE,
8305 N_("The Hurd does not support the filetype feature.\n"),
8308 /* Journal inode is invalid */
8309 { PR_0_JOURNAL_BAD_INODE,
8310 N_("@S has an @n ext3 @j (@i %i).\n"),
8311 PROMPT_CLEAR, PR_PREEN_OK },
8313 /* The external journal has (unsupported) multiple filesystems */
8314 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8315 N_("External @j has multiple @f users (unsupported).\n"),
8316 PROMPT_NONE, PR_FATAL },
8318 /* Can't find external journal */
8319 { PR_0_CANT_FIND_JOURNAL,
8320 N_("Can't find external @j\n"),
8321 PROMPT_NONE, PR_FATAL },
8323 /* External journal has bad superblock */
8324 { PR_0_EXT_JOURNAL_BAD_SUPER,
8325 N_("External @j has bad @S\n"),
8326 PROMPT_NONE, PR_FATAL },
8328 /* Superblock has a bad journal UUID */
8329 { PR_0_JOURNAL_BAD_UUID,
8330 N_("External @j does not support this @f\n"),
8331 PROMPT_NONE, PR_FATAL },
8333 /* Journal has an unknown superblock type */
8334 { PR_0_JOURNAL_UNSUPP_SUPER,
8335 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8336 "It is likely that your copy of e2fsck is old and/or doesn't "
8337 "support this @j format.\n"
8338 "It is also possible the @j @S is corrupt.\n"),
8339 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8341 /* Journal superblock is corrupt */
8342 { PR_0_JOURNAL_BAD_SUPER,
8343 N_("Ext3 @j @S is corrupt.\n"),
8344 PROMPT_FIX, PR_PREEN_OK },
8346 /* Superblock flag should be cleared */
8347 { PR_0_JOURNAL_HAS_JOURNAL,
8348 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8349 PROMPT_CLEAR, PR_PREEN_OK },
8351 /* Superblock flag is incorrect */
8352 { PR_0_JOURNAL_RECOVER_SET,
8353 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8354 PROMPT_CLEAR, PR_PREEN_OK },
8356 /* Journal has data, but recovery flag is clear */
8357 { PR_0_JOURNAL_RECOVERY_CLEAR,
8358 N_("ext3 recovery flag is clear, but @j has data.\n"),
8361 /* Ask if we should clear the journal */
8362 { PR_0_JOURNAL_RESET_JOURNAL,
8364 PROMPT_NULL, PR_PREEN_NOMSG },
8366 /* Ask if we should run the journal anyway */
8368 N_("Run @j anyway"),
8371 /* Run the journal by default */
8372 { PR_0_JOURNAL_RUN_DEFAULT,
8373 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8376 /* Clearing orphan inode */
8377 { PR_0_ORPHAN_CLEAR_INODE,
8378 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8381 /* Illegal block found in orphaned inode */
8382 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8383 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8386 /* Already cleared block found in orphaned inode */
8387 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8388 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8391 /* Illegal orphan inode in superblock */
8392 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8393 N_("@I @o @i %i in @S.\n"),
8396 /* Illegal inode in orphaned inode list */
8397 { PR_0_ORPHAN_ILLEGAL_INODE,
8398 N_("@I @i %i in @o @i list.\n"),
8401 /* Filesystem revision is 0, but feature flags are set */
8402 { PR_0_FS_REV_LEVEL,
8403 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8404 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8406 /* Journal superblock has an unknown read-only feature flag set */
8407 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8408 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8411 /* Journal superblock has an unknown incompatible feature flag set */
8412 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8413 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8416 /* Journal has unsupported version number */
8417 { PR_0_JOURNAL_UNSUPP_VERSION,
8418 N_("@j version not supported by this e2fsck.\n"),
8421 /* Moving journal to hidden file */
8422 { PR_0_MOVE_JOURNAL,
8423 N_("Moving @j from /%s to hidden @i.\n\n"),
8426 /* Error moving journal to hidden file */
8427 { PR_0_ERR_MOVE_JOURNAL,
8428 N_("Error moving @j: %m\n\n"),
8431 /* Clearing V2 journal superblock */
8432 { PR_0_CLEAR_V2_JOURNAL,
8433 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8434 "Clearing fields beyond the V1 @j @S...\n\n"),
8437 /* Backup journal inode blocks */
8439 N_("Backing up @j @i @b information.\n\n"),
8442 /* Reserved blocks w/o resize_inode */
8443 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8444 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8445 "is %N; @s zero. "),
8448 /* Resize_inode not enabled, but resize inode is non-zero */
8449 { PR_0_CLEAR_RESIZE_INODE,
8450 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8453 /* Resize inode invalid */
8454 { PR_0_RESIZE_INODE_INVALID,
8455 N_("Resize @i not valid. "),
8456 PROMPT_RECREATE, 0 },
8460 /* Pass 1: Checking inodes, blocks, and sizes */
8462 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8465 /* Root directory is not an inode */
8466 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8469 /* Root directory has dtime set */
8471 N_("@r has dtime set (probably due to old mke2fs). "),
8472 PROMPT_FIX, PR_PREEN_OK },
8474 /* Reserved inode has bad mode */
8475 { PR_1_RESERVED_BAD_MODE,
8476 N_("Reserved @i %i (%Q) has @n mode. "),
8477 PROMPT_CLEAR, PR_PREEN_OK },
8479 /* Deleted inode has zero dtime */
8481 N_("@D @i %i has zero dtime. "),
8482 PROMPT_FIX, PR_PREEN_OK },
8484 /* Inode in use, but dtime set */
8486 N_("@i %i is in use, but has dtime set. "),
8487 PROMPT_FIX, PR_PREEN_OK },
8489 /* Zero-length directory */
8490 { PR_1_ZERO_LENGTH_DIR,
8491 N_("@i %i is a @z @d. "),
8492 PROMPT_CLEAR, PR_PREEN_OK },
8494 /* Block bitmap conflicts with some other fs block */
8496 N_("@g %g's @b @B at %b @C.\n"),
8497 PROMPT_RELOCATE, 0 },
8499 /* Inode bitmap conflicts with some other fs block */
8501 N_("@g %g's @i @B at %b @C.\n"),
8502 PROMPT_RELOCATE, 0 },
8504 /* Inode table conflicts with some other fs block */
8505 { PR_1_ITABLE_CONFLICT,
8506 N_("@g %g's @i table at %b @C.\n"),
8507 PROMPT_RELOCATE, 0 },
8509 /* Block bitmap is on a bad block */
8510 { PR_1_BB_BAD_BLOCK,
8511 N_("@g %g's @b @B (%b) is bad. "),
8512 PROMPT_RELOCATE, 0 },
8514 /* Inode bitmap is on a bad block */
8515 { PR_1_IB_BAD_BLOCK,
8516 N_("@g %g's @i @B (%b) is bad. "),
8517 PROMPT_RELOCATE, 0 },
8519 /* Inode has incorrect i_size */
8521 N_("@i %i, i_size is %Is, @s %N. "),
8522 PROMPT_FIX, PR_PREEN_OK },
8524 /* Inode has incorrect i_blocks */
8525 { PR_1_BAD_I_BLOCKS,
8526 N_("@i %i, i_@bs is %Ib, @s %N. "),
8527 PROMPT_FIX, PR_PREEN_OK },
8529 /* Illegal blocknumber in inode */
8530 { PR_1_ILLEGAL_BLOCK_NUM,
8531 N_("@I @b #%B (%b) in @i %i. "),
8532 PROMPT_CLEAR, PR_LATCH_BLOCK },
8534 /* Block number overlaps fs metadata */
8535 { PR_1_BLOCK_OVERLAPS_METADATA,
8536 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8537 PROMPT_CLEAR, PR_LATCH_BLOCK },
8539 /* Inode has illegal blocks (latch question) */
8540 { PR_1_INODE_BLOCK_LATCH,
8541 N_("@i %i has illegal @b(s). "),
8544 /* Too many bad blocks in inode */
8545 { PR_1_TOO_MANY_BAD_BLOCKS,
8546 N_("Too many illegal @bs in @i %i.\n"),
8547 PROMPT_CLEAR_INODE, PR_NO_OK },
8549 /* Illegal block number in bad block inode */
8550 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8551 N_("@I @b #%B (%b) in bad @b @i. "),
8552 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8554 /* Bad block inode has illegal blocks (latch question) */
8555 { PR_1_INODE_BBLOCK_LATCH,
8556 N_("Bad @b @i has illegal @b(s). "),
8559 /* Duplicate or bad blocks in use! */
8560 { PR_1_DUP_BLOCKS_PREENSTOP,
8561 N_("Duplicate or bad @b in use!\n"),
8564 /* Bad block used as bad block indirect block */
8565 { PR_1_BBINODE_BAD_METABLOCK,
8566 N_("Bad @b %b used as bad @b @i indirect @b. "),
8567 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8569 /* Inconsistency can't be fixed prompt */
8570 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8571 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8572 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8574 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8576 /* Bad primary block */
8577 { PR_1_BAD_PRIMARY_BLOCK,
8578 N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
8579 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8581 /* Bad primary block prompt */
8582 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8583 N_("You can remove this @b from the bad @b list and hope\n"
8584 "that the @b is really OK. But there are no guarantees.\n\n"),
8585 PROMPT_CLEAR, PR_PREEN_NOMSG },
8587 /* Bad primary superblock */
8588 { PR_1_BAD_PRIMARY_SUPERBLOCK,
8589 N_("The primary @S (%b) is on the bad @b list.\n"),
8590 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8592 /* Bad primary block group descriptors */
8593 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8594 N_("Block %b in the primary @g descriptors "
8595 "is on the bad @b list\n"),
8596 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8598 /* Bad superblock in group */
8599 { PR_1_BAD_SUPERBLOCK,
8600 N_("Warning: Group %g's @S (%b) is bad.\n"),
8601 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8603 /* Bad block group descriptors in group */
8604 { PR_1_BAD_GROUP_DESCRIPTORS,
8605 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8607 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8609 /* Block claimed for no reason */
8610 { PR_1_PROGERR_CLAIMED_BLOCK,
8611 N_("Programming error? @b #%b claimed for no reason in "
8612 "process_bad_@b.\n"),
8613 PROMPT_NONE, PR_PREEN_OK },
8615 /* Error allocating blocks for relocating metadata */
8616 { PR_1_RELOC_BLOCK_ALLOCATE,
8617 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8618 PROMPT_NONE, PR_PREEN_OK },
8620 /* Error allocating block buffer during relocation process */
8621 { PR_1_RELOC_MEMORY_ALLOCATE,
8622 N_("@A @b buffer for relocating %s\n"),
8623 PROMPT_NONE, PR_PREEN_OK },
8625 /* Relocating metadata group information from X to Y */
8626 { PR_1_RELOC_FROM_TO,
8627 N_("Relocating @g %g's %s from %b to %c...\n"),
8628 PROMPT_NONE, PR_PREEN_OK },
8630 /* Relocating metatdata group information to X */
8632 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8633 PROMPT_NONE, PR_PREEN_OK },
8635 /* Block read error during relocation process */
8636 { PR_1_RELOC_READ_ERR,
8637 N_("Warning: could not read @b %b of %s: %m\n"),
8638 PROMPT_NONE, PR_PREEN_OK },
8640 /* Block write error during relocation process */
8641 { PR_1_RELOC_WRITE_ERR,
8642 N_("Warning: could not write @b %b for %s: %m\n"),
8643 PROMPT_NONE, PR_PREEN_OK },
8645 /* Error allocating inode bitmap */
8646 { PR_1_ALLOCATE_IBITMAP_ERROR,
8647 N_("@A @i @B (%N): %m\n"),
8648 PROMPT_NONE, PR_FATAL },
8650 /* Error allocating block bitmap */
8651 { PR_1_ALLOCATE_BBITMAP_ERROR,
8652 N_("@A @b @B (%N): %m\n"),
8653 PROMPT_NONE, PR_FATAL },
8655 /* Error allocating icount structure */
8656 { PR_1_ALLOCATE_ICOUNT,
8657 N_("@A icount link information: %m\n"),
8658 PROMPT_NONE, PR_FATAL },
8660 /* Error allocating dbcount */
8661 { PR_1_ALLOCATE_DBCOUNT,
8662 N_("@A @d @b array: %m\n"),
8663 PROMPT_NONE, PR_FATAL },
8665 /* Error while scanning inodes */
8667 N_("Error while scanning @is (%i): %m\n"),
8668 PROMPT_NONE, PR_FATAL },
8670 /* Error while iterating over blocks */
8671 { PR_1_BLOCK_ITERATE,
8672 N_("Error while iterating over @bs in @i %i: %m\n"),
8673 PROMPT_NONE, PR_FATAL },
8675 /* Error while storing inode count information */
8676 { PR_1_ICOUNT_STORE,
8677 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8678 PROMPT_NONE, PR_FATAL },
8680 /* Error while storing directory block information */
8682 N_("Error storing @d @b information "
8683 "(@i=%i, @b=%b, num=%N): %m\n"),
8684 PROMPT_NONE, PR_FATAL },
8686 /* Error while reading inode (for clearing) */
8688 N_("Error reading @i %i: %m\n"),
8689 PROMPT_NONE, PR_FATAL },
8691 /* Suppress messages prompt */
8692 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8694 /* Imagic flag set on an inode when filesystem doesn't support it */
8696 N_("@i %i has imagic flag set. "),
8699 /* Immutable flag set on a device or socket inode */
8700 { PR_1_SET_IMMUTABLE,
8701 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8702 "or append-only flag set. "),
8703 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8705 /* Compression flag set on an inode when filesystem doesn't support it */
8707 N_("@i %i has @cion flag set on @f without @cion support. "),
8710 /* Non-zero size for device, fifo or socket inode */
8711 { PR_1_SET_NONZSIZE,
8712 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8713 PROMPT_FIX, PR_PREEN_OK },
8715 /* Filesystem revision is 0, but feature flags are set */
8716 { PR_1_FS_REV_LEVEL,
8717 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8718 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8720 /* Journal inode is not in use, but contains data */
8721 { PR_1_JOURNAL_INODE_NOT_CLEAR,
8722 N_("@j @i is not in use, but contains data. "),
8723 PROMPT_CLEAR, PR_PREEN_OK },
8725 /* Journal has bad mode */
8726 { PR_1_JOURNAL_BAD_MODE,
8727 N_("@j is not regular file. "),
8728 PROMPT_FIX, PR_PREEN_OK },
8730 /* Deal with inodes that were part of orphan linked list */
8732 N_("@i %i was part of the @o @i list. "),
8733 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8735 /* Deal with inodes that were part of corrupted orphan linked
8736 list (latch question) */
8737 { PR_1_ORPHAN_LIST_REFUGEES,
8738 N_("@is that were part of a corrupted orphan linked list found. "),
8741 /* Error allocating refcount structure */
8742 { PR_1_ALLOCATE_REFCOUNT,
8743 N_("@A refcount structure (%N): %m\n"),
8744 PROMPT_NONE, PR_FATAL },
8746 /* Error reading extended attribute block */
8747 { PR_1_READ_EA_BLOCK,
8748 N_("Error reading @a @b %b for @i %i. "),
8751 /* Invalid extended attribute block */
8752 { PR_1_BAD_EA_BLOCK,
8753 N_("@i %i has a bad @a @b %b. "),
8756 /* Error reading Extended Attribute block while fixing refcount */
8757 { PR_1_EXTATTR_READ_ABORT,
8758 N_("Error reading @a @b %b (%m). "),
8761 /* Extended attribute reference count incorrect */
8762 { PR_1_EXTATTR_REFCOUNT,
8763 N_("@a @b %b has reference count %B, @s %N. "),
8766 /* Error writing Extended Attribute block while fixing refcount */
8767 { PR_1_EXTATTR_WRITE,
8768 N_("Error writing @a @b %b (%m). "),
8771 /* Multiple EA blocks not supported */
8772 { PR_1_EA_MULTI_BLOCK,
8773 N_("@a @b %b has h_@bs > 1. "),
8776 /* Error allocating EA region allocation structure */
8777 { PR_1_EA_ALLOC_REGION,
8778 N_("@A @a @b %b. "),
8781 /* Error EA allocation collision */
8782 { PR_1_EA_ALLOC_COLLISION,
8783 N_("@a @b %b is corrupt (allocation collision). "),
8786 /* Bad extended attribute name */
8788 N_("@a @b %b is corrupt (@n name). "),
8791 /* Bad extended attribute value */
8792 { PR_1_EA_BAD_VALUE,
8793 N_("@a @b %b is corrupt (@n value). "),
8796 /* Inode too big (latch question) */
8797 { PR_1_INODE_TOOBIG,
8798 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
8800 /* Directory too big */
8802 N_("@b #%B (%b) causes @d to be too big. "),
8803 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8805 /* Regular file too big */
8807 N_("@b #%B (%b) causes file to be too big. "),
8808 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8810 /* Symlink too big */
8811 { PR_1_TOOBIG_SYMLINK,
8812 N_("@b #%B (%b) causes symlink to be too big. "),
8813 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8815 /* INDEX_FL flag set on a non-HTREE filesystem */
8817 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8818 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8820 /* INDEX_FL flag set on a non-directory */
8822 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8823 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8825 /* Invalid root node in HTREE directory */
8826 { PR_1_HTREE_BADROOT,
8827 N_("@h %i has an @n root node.\n"),
8828 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8830 /* Unsupported hash version in HTREE directory */
8832 N_("@h %i has an unsupported hash version (%N)\n"),
8833 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8835 /* Incompatible flag in HTREE root node */
8836 { PR_1_HTREE_INCOMPAT,
8837 N_("@h %i uses an incompatible htree root node flag.\n"),
8838 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8840 /* HTREE too deep */
8842 N_("@h %i has a tree depth (%N) which is too big\n"),
8843 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8845 /* Bad block has indirect block that conflicts with filesystem block */
8847 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8849 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8851 /* Resize inode failed */
8852 { PR_1_RESIZE_INODE_CREATE,
8853 N_("Resize @i (re)creation failed: %m."),
8856 /* invalid inode->i_extra_isize */
8858 N_("@i %i has a extra size (%IS) which is @n\n"),
8859 PROMPT_FIX, PR_PREEN_OK },
8861 /* invalid ea entry->e_name_len */
8862 { PR_1_ATTR_NAME_LEN,
8863 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8864 PROMPT_CLEAR, PR_PREEN_OK },
8866 /* invalid ea entry->e_value_size */
8867 { PR_1_ATTR_VALUE_SIZE,
8868 N_("@a in @i %i has a value size (%N) which is @n\n"),
8869 PROMPT_CLEAR, PR_PREEN_OK },
8871 /* invalid ea entry->e_value_offs */
8872 { PR_1_ATTR_VALUE_OFFSET,
8873 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8874 PROMPT_CLEAR, PR_PREEN_OK },
8876 /* invalid ea entry->e_value_block */
8877 { PR_1_ATTR_VALUE_BLOCK,
8878 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8879 PROMPT_CLEAR, PR_PREEN_OK },
8881 /* invalid ea entry->e_hash */
8883 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8884 PROMPT_CLEAR, PR_PREEN_OK },
8886 /* Pass 1b errors */
8888 /* Pass 1B: Rescan for duplicate/bad blocks */
8889 { PR_1B_PASS_HEADER,
8890 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8891 "Pass 1B: Rescanning for @m @bs\n"),
8894 /* Duplicate/bad block(s) header */
8895 { PR_1B_DUP_BLOCK_HEADER,
8896 N_("@m @b(s) in @i %i:"),
8899 /* Duplicate/bad block(s) in inode */
8902 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8904 /* Duplicate/bad block(s) end */
8905 { PR_1B_DUP_BLOCK_END,
8907 PROMPT_NONE, PR_PREEN_NOHDR },
8909 /* Error while scanning inodes */
8910 { PR_1B_ISCAN_ERROR,
8911 N_("Error while scanning inodes (%i): %m\n"),
8912 PROMPT_NONE, PR_FATAL },
8914 /* Error allocating inode bitmap */
8915 { PR_1B_ALLOCATE_IBITMAP_ERROR,
8916 N_("@A @i @B (@i_dup_map): %m\n"),
8917 PROMPT_NONE, PR_FATAL },
8919 /* Error while iterating over blocks */
8920 { PR_1B_BLOCK_ITERATE,
8921 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8924 /* Error adjusting EA refcount */
8925 { PR_1B_ADJ_EA_REFCOUNT,
8926 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8930 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8931 { PR_1C_PASS_HEADER,
8932 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8936 /* Pass 1D: Reconciling multiply-claimed blocks */
8937 { PR_1D_PASS_HEADER,
8938 N_("Pass 1D: Reconciling @m @bs\n"),
8941 /* File has duplicate blocks */
8943 N_("File %Q (@i #%i, mod time %IM)\n"
8944 " has %B @m @b(s), shared with %N file(s):\n"),
8947 /* List of files sharing duplicate blocks */
8948 { PR_1D_DUP_FILE_LIST,
8949 N_("\t%Q (@i #%i, mod time %IM)\n"),
8952 /* File sharing blocks with filesystem metadata */
8953 { PR_1D_SHARE_METADATA,
8954 N_("\t<@f metadata>\n"),
8957 /* Report of how many duplicate/bad inodes */
8958 { PR_1D_NUM_DUP_INODES,
8959 N_("(There are %N @is containing @m @bs.)\n\n"),
8962 /* Duplicated blocks already reassigned or cloned. */
8963 { PR_1D_DUP_BLOCKS_DEALT,
8964 N_("@m @bs already reassigned or cloned.\n\n"),
8967 /* Clone duplicate/bad blocks? */
8968 { PR_1D_CLONE_QUESTION,
8969 "", PROMPT_CLONE, PR_NO_OK },
8972 { PR_1D_DELETE_QUESTION,
8973 "", PROMPT_DELETE, 0 },
8975 /* Couldn't clone file (error) */
8976 { PR_1D_CLONE_ERROR,
8977 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
8981 /* Pass 2: Checking directory structure */
8983 N_("Pass 2: Checking @d structure\n"),
8986 /* Bad inode number for '.' */
8987 { PR_2_BAD_INODE_DOT,
8988 N_("@n @i number for '.' in @d @i %i.\n"),
8991 /* Directory entry has bad inode number */
8993 N_("@E has @n @i #: %Di.\n"),
8996 /* Directory entry has deleted or unused inode */
8997 { PR_2_UNUSED_INODE,
8998 N_("@E has @D/unused @i %Di. "),
8999 PROMPT_CLEAR, PR_PREEN_OK },
9001 /* Directry entry is link to '.' */
9003 N_("@E @L to '.' "),
9006 /* Directory entry points to inode now located in a bad block */
9008 N_("@E points to @i (%Di) located in a bad @b.\n"),
9011 /* Directory entry contains a link to a directory */
9013 N_("@E @L to @d %P (%Di).\n"),
9016 /* Directory entry contains a link to the root directry */
9018 N_("@E @L to the @r.\n"),
9021 /* Directory entry has illegal characters in its name */
9023 N_("@E has illegal characters in its name.\n"),
9026 /* Missing '.' in directory inode */
9028 N_("Missing '.' in @d @i %i.\n"),
9031 /* Missing '..' in directory inode */
9032 { PR_2_MISSING_DOT_DOT,
9033 N_("Missing '..' in @d @i %i.\n"),
9036 /* First entry in directory inode doesn't contain '.' */
9038 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9041 /* Second entry in directory inode doesn't contain '..' */
9042 { PR_2_2ND_NOT_DOT_DOT,
9043 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9046 /* i_faddr should be zero */
9048 N_("i_faddr @F %IF, @s zero.\n"),
9051 /* i_file_acl should be zero */
9052 { PR_2_FILE_ACL_ZERO,
9053 N_("i_file_acl @F %If, @s zero.\n"),
9056 /* i_dir_acl should be zero */
9057 { PR_2_DIR_ACL_ZERO,
9058 N_("i_dir_acl @F %Id, @s zero.\n"),
9061 /* i_frag should be zero */
9063 N_("i_frag @F %N, @s zero.\n"),
9066 /* i_fsize should be zero */
9068 N_("i_fsize @F %N, @s zero.\n"),
9071 /* inode has bad mode */
9073 N_("@i %i (%Q) has @n mode (%Im).\n"),
9076 /* directory corrupted */
9077 { PR_2_DIR_CORRUPTED,
9078 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9079 PROMPT_SALVAGE, 0 },
9081 /* filename too long */
9082 { PR_2_FILENAME_LONG,
9083 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9084 PROMPT_TRUNCATE, 0 },
9086 /* Directory inode has a missing block (hole) */
9087 { PR_2_DIRECTORY_HOLE,
9088 N_("@d @i %i has an unallocated @b #%B. "),
9089 PROMPT_ALLOCATE, 0 },
9091 /* '.' is not NULL terminated */
9092 { PR_2_DOT_NULL_TERM,
9093 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9096 /* '..' is not NULL terminated */
9097 { PR_2_DOT_DOT_NULL_TERM,
9098 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9101 /* Illegal character device inode */
9102 { PR_2_BAD_CHAR_DEV,
9103 N_("@i %i (%Q) is an @I character @v.\n"),
9106 /* Illegal block device inode */
9107 { PR_2_BAD_BLOCK_DEV,
9108 N_("@i %i (%Q) is an @I @b @v.\n"),
9111 /* Duplicate '.' entry */
9113 N_("@E is duplicate '.' @e.\n"),
9116 /* Duplicate '..' entry */
9118 N_("@E is duplicate '..' @e.\n"),
9121 /* Internal error: couldn't find dir_info */
9123 N_("Internal error: cannot find dir_info for %i.\n"),
9124 PROMPT_NONE, PR_FATAL },
9126 /* Final rec_len is wrong */
9127 { PR_2_FINAL_RECLEN,
9128 N_("@E has rec_len of %Dr, @s %N.\n"),
9131 /* Error allocating icount structure */
9132 { PR_2_ALLOCATE_ICOUNT,
9133 N_("@A icount structure: %m\n"),
9134 PROMPT_NONE, PR_FATAL },
9136 /* Error iterating over directory blocks */
9137 { PR_2_DBLIST_ITERATE,
9138 N_("Error iterating over @d @bs: %m\n"),
9139 PROMPT_NONE, PR_FATAL },
9141 /* Error reading directory block */
9142 { PR_2_READ_DIRBLOCK,
9143 N_("Error reading @d @b %b (@i %i): %m\n"),
9144 PROMPT_CONTINUE, 0 },
9146 /* Error writing directory block */
9147 { PR_2_WRITE_DIRBLOCK,
9148 N_("Error writing @d @b %b (@i %i): %m\n"),
9149 PROMPT_CONTINUE, 0 },
9151 /* Error allocating new directory block */
9152 { PR_2_ALLOC_DIRBOCK,
9153 N_("@A new @d @b for @i %i (%s): %m\n"),
9156 /* Error deallocating inode */
9157 { PR_2_DEALLOC_INODE,
9158 N_("Error deallocating @i %i: %m\n"),
9159 PROMPT_NONE, PR_FATAL },
9161 /* Directory entry for '.' is big. Split? */
9163 N_("@d @e for '.' is big. "),
9164 PROMPT_SPLIT, PR_NO_OK },
9166 /* Illegal FIFO inode */
9168 N_("@i %i (%Q) is an @I FIFO.\n"),
9171 /* Illegal socket inode */
9173 N_("@i %i (%Q) is an @I socket.\n"),
9176 /* Directory filetype not set */
9177 { PR_2_SET_FILETYPE,
9178 N_("Setting filetype for @E to %N.\n"),
9179 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9181 /* Directory filetype incorrect */
9182 { PR_2_BAD_FILETYPE,
9183 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9186 /* Directory filetype set on filesystem */
9187 { PR_2_CLEAR_FILETYPE,
9188 N_("@E has filetype set.\n"),
9189 PROMPT_CLEAR, PR_PREEN_OK },
9191 /* Directory filename is null */
9193 N_("@E has a @z name.\n"),
9196 /* Invalid symlink */
9197 { PR_2_INVALID_SYMLINK,
9198 N_("Symlink %Q (@i #%i) is @n.\n"),
9201 /* i_file_acl (extended attribute block) is bad */
9202 { PR_2_FILE_ACL_BAD,
9203 N_("@a @b @F @n (%If).\n"),
9206 /* Filesystem contains large files, but has no such flag in sb */
9207 { PR_2_FEATURE_LARGE_FILES,
9208 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9211 /* Node in HTREE directory not referenced */
9212 { PR_2_HTREE_NOTREF,
9213 N_("@p @h %d: node (%B) not referenced\n"),
9216 /* Node in HTREE directory referenced twice */
9217 { PR_2_HTREE_DUPREF,
9218 N_("@p @h %d: node (%B) referenced twice\n"),
9221 /* Node in HTREE directory has bad min hash */
9222 { PR_2_HTREE_MIN_HASH,
9223 N_("@p @h %d: node (%B) has bad min hash\n"),
9226 /* Node in HTREE directory has bad max hash */
9227 { PR_2_HTREE_MAX_HASH,
9228 N_("@p @h %d: node (%B) has bad max hash\n"),
9231 /* Clear invalid HTREE directory */
9233 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9235 /* Bad block in htree interior node */
9236 { PR_2_HTREE_BADBLK,
9237 N_("@p @h %d (%q): bad @b number %b.\n"),
9238 PROMPT_CLEAR_HTREE, 0 },
9240 /* Error adjusting EA refcount */
9241 { PR_2_ADJ_EA_REFCOUNT,
9242 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9243 PROMPT_NONE, PR_FATAL },
9245 /* Invalid HTREE root node */
9246 { PR_2_HTREE_BAD_ROOT,
9247 N_("@p @h %d: root node is @n\n"),
9248 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9250 /* Invalid HTREE limit */
9251 { PR_2_HTREE_BAD_LIMIT,
9252 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9253 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9255 /* Invalid HTREE count */
9256 { PR_2_HTREE_BAD_COUNT,
9257 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9258 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9260 /* HTREE interior node has out-of-order hashes in table */
9261 { PR_2_HTREE_HASH_ORDER,
9262 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9263 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9265 /* Node in HTREE directory has invalid depth */
9266 { PR_2_HTREE_BAD_DEPTH,
9267 N_("@p @h %d: node (%B) has @n depth\n"),
9270 /* Duplicate directory entry found */
9271 { PR_2_DUPLICATE_DIRENT,
9272 N_("Duplicate @E found. "),
9275 /* Non-unique filename found */
9276 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9277 N_("@E has a non-unique filename.\nRename to %s"),
9280 /* Duplicate directory entry found */
9281 { PR_2_REPORT_DUP_DIRENT,
9282 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9287 /* Pass 3: Checking directory connectivity */
9289 N_("Pass 3: Checking @d connectivity\n"),
9292 /* Root inode not allocated */
9293 { PR_3_NO_ROOT_INODE,
9294 N_("@r not allocated. "),
9295 PROMPT_ALLOCATE, 0 },
9297 /* No room in lost+found */
9298 { PR_3_EXPAND_LF_DIR,
9299 N_("No room in @l @d. "),
9302 /* Unconnected directory inode */
9303 { PR_3_UNCONNECTED_DIR,
9304 N_("Unconnected @d @i %i (%p)\n"),
9305 PROMPT_CONNECT, 0 },
9307 /* /lost+found not found */
9309 N_("/@l not found. "),
9310 PROMPT_CREATE, PR_PREEN_OK },
9312 /* .. entry is incorrect */
9314 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9317 /* Bad or non-existent /lost+found. Cannot reconnect */
9319 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9322 /* Could not expand /lost+found */
9323 { PR_3_CANT_EXPAND_LPF,
9324 N_("Could not expand /@l: %m\n"),
9327 /* Could not reconnect inode */
9328 { PR_3_CANT_RECONNECT,
9329 N_("Could not reconnect %i: %m\n"),
9332 /* Error while trying to find /lost+found */
9333 { PR_3_ERR_FIND_LPF,
9334 N_("Error while trying to find /@l: %m\n"),
9337 /* Error in ext2fs_new_block while creating /lost+found */
9338 { PR_3_ERR_LPF_NEW_BLOCK,
9339 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9342 /* Error in ext2fs_new_inode while creating /lost+found */
9343 { PR_3_ERR_LPF_NEW_INODE,
9344 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9347 /* Error in ext2fs_new_dir_block while creating /lost+found */
9348 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9349 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9352 /* Error while writing directory block for /lost+found */
9353 { PR_3_ERR_LPF_WRITE_BLOCK,
9354 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9357 /* Error while adjusting inode count */
9358 { PR_3_ADJUST_INODE,
9359 N_("Error while adjusting @i count on @i %i\n"),
9362 /* Couldn't fix parent directory -- error */
9363 { PR_3_FIX_PARENT_ERR,
9364 N_("Couldn't fix parent of @i %i: %m\n\n"),
9367 /* Couldn't fix parent directory -- couldn't find it */
9368 { PR_3_FIX_PARENT_NOFIND,
9369 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9372 /* Error allocating inode bitmap */
9373 { PR_3_ALLOCATE_IBITMAP_ERROR,
9374 N_("@A @i @B (%N): %m\n"),
9375 PROMPT_NONE, PR_FATAL },
9377 /* Error creating root directory */
9378 { PR_3_CREATE_ROOT_ERROR,
9379 N_("Error creating root @d (%s): %m\n"),
9380 PROMPT_NONE, PR_FATAL },
9382 /* Error creating lost and found directory */
9383 { PR_3_CREATE_LPF_ERROR,
9384 N_("Error creating /@l @d (%s): %m\n"),
9385 PROMPT_NONE, PR_FATAL },
9387 /* Root inode is not directory; aborting */
9388 { PR_3_ROOT_NOT_DIR_ABORT,
9389 N_("@r is not a @d; aborting.\n"),
9390 PROMPT_NONE, PR_FATAL },
9392 /* Cannot proceed without a root inode. */
9393 { PR_3_NO_ROOT_INODE_ABORT,
9394 N_("can't proceed without a @r.\n"),
9395 PROMPT_NONE, PR_FATAL },
9397 /* Internal error: couldn't find dir_info */
9399 N_("Internal error: cannot find dir_info for %i.\n"),
9400 PROMPT_NONE, PR_FATAL },
9402 /* Lost+found not a directory */
9404 N_("/@l is not a @d (ino=%i)\n"),
9407 /* Pass 3A Directory Optimization */
9409 /* Pass 3A: Optimizing directories */
9410 { PR_3A_PASS_HEADER,
9411 N_("Pass 3A: Optimizing directories\n"),
9412 PROMPT_NONE, PR_PREEN_NOMSG },
9414 /* Error iterating over directories */
9415 { PR_3A_OPTIMIZE_ITER,
9416 N_("Failed to create dirs_to_hash iterator: %m"),
9419 /* Error rehash directory */
9420 { PR_3A_OPTIMIZE_DIR_ERR,
9421 N_("Failed to optimize directory %q (%d): %m"),
9424 /* Rehashing dir header */
9425 { PR_3A_OPTIMIZE_DIR_HEADER,
9426 N_("Optimizing directories: "),
9427 PROMPT_NONE, PR_MSG_ONLY },
9429 /* Rehashing directory %d */
9430 { PR_3A_OPTIMIZE_DIR,
9432 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9434 /* Rehashing dir end */
9435 { PR_3A_OPTIMIZE_DIR_END,
9437 PROMPT_NONE, PR_PREEN_NOHDR },
9441 /* Pass 4: Checking reference counts */
9443 N_("Pass 4: Checking reference counts\n"),
9446 /* Unattached zero-length inode */
9447 { PR_4_ZERO_LEN_INODE,
9448 N_("@u @z @i %i. "),
9449 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9451 /* Unattached inode */
9452 { PR_4_UNATTACHED_INODE,
9454 PROMPT_CONNECT, 0 },
9456 /* Inode ref count wrong */
9457 { PR_4_BAD_REF_COUNT,
9458 N_("@i %i ref count is %Il, @s %N. "),
9459 PROMPT_FIX, PR_PREEN_OK },
9461 { PR_4_INCONSISTENT_COUNT,
9462 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9463 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9464 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9465 "They @s the same!\n"),
9470 /* Pass 5: Checking group summary information */
9472 N_("Pass 5: Checking @g summary information\n"),
9475 /* Padding at end of inode bitmap is not set. */
9476 { PR_5_INODE_BMAP_PADDING,
9477 N_("Padding at end of @i @B is not set. "),
9478 PROMPT_FIX, PR_PREEN_OK },
9480 /* Padding at end of block bitmap is not set. */
9481 { PR_5_BLOCK_BMAP_PADDING,
9482 N_("Padding at end of @b @B is not set. "),
9483 PROMPT_FIX, PR_PREEN_OK },
9485 /* Block bitmap differences header */
9486 { PR_5_BLOCK_BITMAP_HEADER,
9487 N_("@b @B differences: "),
9488 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9490 /* Block not used, but marked in bitmap */
9491 { PR_5_BLOCK_UNUSED,
9493 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9495 /* Block used, but not marked used in bitmap */
9498 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9500 /* Block bitmap differences end */
9501 { PR_5_BLOCK_BITMAP_END,
9503 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9505 /* Inode bitmap differences header */
9506 { PR_5_INODE_BITMAP_HEADER,
9507 N_("@i @B differences: "),
9508 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9510 /* Inode not used, but marked in bitmap */
9511 { PR_5_INODE_UNUSED,
9513 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9515 /* Inode used, but not marked used in bitmap */
9518 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9520 /* Inode bitmap differences end */
9521 { PR_5_INODE_BITMAP_END,
9523 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9525 /* Free inodes count for group wrong */
9526 { PR_5_FREE_INODE_COUNT_GROUP,
9527 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9528 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9530 /* Directories count for group wrong */
9531 { PR_5_FREE_DIR_COUNT_GROUP,
9532 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9533 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9535 /* Free inodes count wrong */
9536 { PR_5_FREE_INODE_COUNT,
9537 N_("Free @is count wrong (%i, counted=%j).\n"),
9538 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9540 /* Free blocks count for group wrong */
9541 { PR_5_FREE_BLOCK_COUNT_GROUP,
9542 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9543 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9545 /* Free blocks count wrong */
9546 { PR_5_FREE_BLOCK_COUNT,
9547 N_("Free @bs count wrong (%b, counted=%c).\n"),
9548 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9550 /* Programming error: bitmap endpoints don't match */
9551 { PR_5_BMAP_ENDPOINTS,
9552 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9553 "match calculated @B endpoints (%i, %j)\n"),
9554 PROMPT_NONE, PR_FATAL },
9556 /* Internal error: fudging end of bitmap */
9557 { PR_5_FUDGE_BITMAP_ERROR,
9558 N_("Internal error: fudging end of bitmap (%N)\n"),
9559 PROMPT_NONE, PR_FATAL },
9561 /* Error copying in replacement inode bitmap */
9562 { PR_5_COPY_IBITMAP_ERROR,
9563 N_("Error copying in replacement @i @B: %m\n"),
9564 PROMPT_NONE, PR_FATAL },
9566 /* Error copying in replacement block bitmap */
9567 { PR_5_COPY_BBITMAP_ERROR,
9568 N_("Error copying in replacement @b @B: %m\n"),
9569 PROMPT_NONE, PR_FATAL },
9571 /* Block range not used, but marked in bitmap */
9572 { PR_5_BLOCK_RANGE_UNUSED,
9574 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9576 /* Block range used, but not marked used in bitmap */
9577 { PR_5_BLOCK_RANGE_USED,
9579 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9581 /* Inode range not used, but marked in bitmap */
9582 { PR_5_INODE_RANGE_UNUSED,
9584 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9586 /* Inode range used, but not marked used in bitmap */
9587 { PR_5_INODE_RANGE_USED,
9589 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9595 * This is the latch flags register. It allows several problems to be
9596 * "latched" together. This means that the user has to answer but one
9597 * question for the set of problems, and all of the associated
9598 * problems will be either fixed or not fixed.
9600 static struct latch_descr pr_latch_info[] = {
9601 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9602 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9603 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9604 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9605 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9606 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9607 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9608 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9609 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9613 static const struct e2fsck_problem *find_problem(problem_t code)
9617 for (i=0; problem_table[i].e2p_code; i++) {
9618 if (problem_table[i].e2p_code == code)
9619 return &problem_table[i];
9624 static struct latch_descr *find_latch(int code)
9628 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9629 if (pr_latch_info[i].latch_code == code)
9630 return &pr_latch_info[i];
9635 int end_problem_latch(e2fsck_t ctx, int mask)
9637 struct latch_descr *ldesc;
9638 struct problem_context pctx;
9641 ldesc = find_latch(mask);
9642 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9643 clear_problem_context(&pctx);
9644 answer = fix_problem(ctx, ldesc->end_message, &pctx);
9646 ldesc->flags &= ~(PRL_VARIABLE);
9650 int set_latch_flags(int mask, int setflags, int clearflags)
9652 struct latch_descr *ldesc;
9654 ldesc = find_latch(mask);
9657 ldesc->flags |= setflags;
9658 ldesc->flags &= ~clearflags;
9662 void clear_problem_context(struct problem_context *ctx)
9664 memset(ctx, 0, sizeof(struct problem_context));
9669 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9671 ext2_filsys fs = ctx->fs;
9672 const struct e2fsck_problem *ptr;
9673 struct latch_descr *ldesc = NULL;
9674 const char *message;
9675 int def_yn, answer, ans;
9676 int print_answer = 0;
9679 ptr = find_problem(code);
9681 printf(_("Unhandled error code (0x%x)!\n"), code);
9685 if ((ptr->flags & PR_NO_DEFAULT) ||
9686 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9687 (ctx->options & E2F_OPT_NO))
9691 * Do special latch processing. This is where we ask the
9692 * latch question, if it exists
9694 if (ptr->flags & PR_LATCH_MASK) {
9695 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9696 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9697 ans = fix_problem(ctx, ldesc->question, pctx);
9699 ldesc->flags |= PRL_YES;
9701 ldesc->flags |= PRL_NO;
9702 ldesc->flags |= PRL_LATCHED;
9704 if (ldesc->flags & PRL_SUPPRESS)
9707 if ((ptr->flags & PR_PREEN_NOMSG) &&
9708 (ctx->options & E2F_OPT_PREEN))
9710 if ((ptr->flags & PR_NO_NOMSG) &&
9711 (ctx->options & E2F_OPT_NO))
9714 message = ptr->e2p_description;
9715 if ((ctx->options & E2F_OPT_PREEN) &&
9716 !(ptr->flags & PR_PREEN_NOHDR)) {
9717 printf("%s: ", ctx->device_name ?
9718 ctx->device_name : ctx->filesystem_name);
9721 print_e2fsck_message(ctx, _(message), pctx, 1);
9723 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9726 if (ptr->flags & PR_FATAL)
9727 bb_error_msg_and_die(0);
9729 if (ptr->prompt == PROMPT_NONE) {
9730 if (ptr->flags & PR_NOCOLLATE)
9735 if (ctx->options & E2F_OPT_PREEN) {
9737 if (!(ptr->flags & PR_PREEN_NOMSG))
9739 } else if ((ptr->flags & PR_LATCH_MASK) &&
9740 (ldesc->flags & (PRL_YES | PRL_NO))) {
9743 if (ldesc->flags & PRL_YES)
9748 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9749 if (!answer && !(ptr->flags & PR_NO_OK))
9750 ext2fs_unmark_valid(fs);
9753 printf("%s.\n", answer ?
9754 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9758 if ((ptr->prompt == PROMPT_ABORT) && answer)
9759 bb_error_msg_and_die(0);
9761 if (ptr->flags & PR_AFTER_CODE)
9762 answer = fix_problem(ctx, ptr->second_code, pctx);
9768 * linux/fs/recovery.c
9770 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9774 * Maintain information about the progress of the recovery job, so that
9775 * the different passes can carry information between them.
9777 struct recovery_info
9779 tid_t start_transaction;
9780 tid_t end_transaction;
9787 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9788 static int do_one_pass(journal_t *journal,
9789 struct recovery_info *info, enum passtype pass);
9790 static int scan_revoke_records(journal_t *, struct buffer_head *,
9791 tid_t, struct recovery_info *);
9794 * Read a block from the journal
9797 static int jread(struct buffer_head **bhp, journal_t *journal,
9798 unsigned int offset)
9801 unsigned long blocknr;
9802 struct buffer_head *bh;
9806 err = journal_bmap(journal, offset, &blocknr);
9809 printf("JBD: bad block at offset %u\n", offset);
9813 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9817 if (!buffer_uptodate(bh)) {
9818 /* If this is a brand new buffer, start readahead.
9819 Otherwise, we assume we are already reading it. */
9820 if (!buffer_req(bh))
9821 do_readahead(journal, offset);
9825 if (!buffer_uptodate(bh)) {
9826 printf("JBD: Failed to read block at offset %u\n", offset);
9837 * Count the number of in-use tags in a journal descriptor block.
9840 static int count_tags(struct buffer_head *bh, int size)
9843 journal_block_tag_t * tag;
9846 tagp = &bh->b_data[sizeof(journal_header_t)];
9848 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9849 tag = (journal_block_tag_t *) tagp;
9852 tagp += sizeof(journal_block_tag_t);
9853 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9856 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9864 /* Make sure we wrap around the log correctly! */
9865 #define wrap(journal, var) \
9867 if (var >= (journal)->j_last) \
9868 var -= ((journal)->j_last - (journal)->j_first); \
9872 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9873 * @journal: the journal to recover
9875 * The primary function for recovering the log contents when mounting a
9878 * Recovery is done in three passes. In the first pass, we look for the
9879 * end of the log. In the second, we assemble the list of revoke
9880 * blocks. In the third and final pass, we replay any un-revoked blocks
9883 int journal_recover(journal_t *journal)
9886 journal_superblock_t * sb;
9888 struct recovery_info info;
9890 memset(&info, 0, sizeof(info));
9891 sb = journal->j_superblock;
9894 * The journal superblock's s_start field (the current log head)
9895 * is always zero if, and only if, the journal was cleanly
9900 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9904 err = do_one_pass(journal, &info, PASS_SCAN);
9906 err = do_one_pass(journal, &info, PASS_REVOKE);
9908 err = do_one_pass(journal, &info, PASS_REPLAY);
9910 /* Restart the log at the next transaction ID, thus invalidating
9911 * any existing commit records in the log. */
9912 journal->j_transaction_sequence = ++info.end_transaction;
9914 journal_clear_revoke(journal);
9915 sync_blockdev(journal->j_fs_dev);
9919 static int do_one_pass(journal_t *journal,
9920 struct recovery_info *info, enum passtype pass)
9922 unsigned int first_commit_ID, next_commit_ID;
9923 unsigned long next_log_block;
9924 int err, success = 0;
9925 journal_superblock_t * sb;
9926 journal_header_t * tmp;
9927 struct buffer_head * bh;
9928 unsigned int sequence;
9931 /* Precompute the maximum metadata descriptors in a descriptor block */
9932 int MAX_BLOCKS_PER_DESC;
9933 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9934 / sizeof(journal_block_tag_t));
9937 * First thing is to establish what we expect to find in the log
9938 * (in terms of transaction IDs), and where (in terms of log
9939 * block offsets): query the superblock.
9942 sb = journal->j_superblock;
9943 next_commit_ID = ntohl(sb->s_sequence);
9944 next_log_block = ntohl(sb->s_start);
9946 first_commit_ID = next_commit_ID;
9947 if (pass == PASS_SCAN)
9948 info->start_transaction = first_commit_ID;
9951 * Now we walk through the log, transaction by transaction,
9952 * making sure that each transaction has a commit block in the
9953 * expected place. Each complete transaction gets replayed back
9954 * into the main filesystem.
9960 journal_block_tag_t * tag;
9961 struct buffer_head * obh;
9962 struct buffer_head * nbh;
9964 /* If we already know where to stop the log traversal,
9965 * check right now that we haven't gone past the end of
9968 if (pass != PASS_SCAN)
9969 if (tid_geq(next_commit_ID, info->end_transaction))
9972 /* Skip over each chunk of the transaction looking
9973 * either the next descriptor block or the final commit
9976 err = jread(&bh, journal, next_log_block);
9981 wrap(journal, next_log_block);
9983 /* What kind of buffer is it?
9985 * If it is a descriptor block, check that it has the
9986 * expected sequence number. Otherwise, we're all done
9989 tmp = (journal_header_t *)bh->b_data;
9991 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
9996 blocktype = ntohl(tmp->h_blocktype);
9997 sequence = ntohl(tmp->h_sequence);
9999 if (sequence != next_commit_ID) {
10004 /* OK, we have a valid descriptor block which matches
10005 * all of the sequence number checks. What are we going
10006 * to do with it? That depends on the pass... */
10008 switch (blocktype) {
10009 case JFS_DESCRIPTOR_BLOCK:
10010 /* If it is a valid descriptor block, replay it
10011 * in pass REPLAY; otherwise, just skip over the
10012 * blocks it describes. */
10013 if (pass != PASS_REPLAY) {
10015 count_tags(bh, journal->j_blocksize);
10016 wrap(journal, next_log_block);
10021 /* A descriptor block: we can now write all of
10022 * the data blocks. Yay, useful work is finally
10023 * getting done here! */
10025 tagp = &bh->b_data[sizeof(journal_header_t)];
10026 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10027 <= journal->j_blocksize) {
10028 unsigned long io_block;
10030 tag = (journal_block_tag_t *) tagp;
10031 flags = ntohl(tag->t_flags);
10033 io_block = next_log_block++;
10034 wrap(journal, next_log_block);
10035 err = jread(&obh, journal, io_block);
10037 /* Recover what we can, but
10038 * report failure at the end. */
10040 printf("JBD: IO error %d recovering "
10041 "block %ld in log\n",
10044 unsigned long blocknr;
10046 blocknr = ntohl(tag->t_blocknr);
10048 /* If the block has been
10049 * revoked, then we're all done
10051 if (journal_test_revoke
10055 ++info->nr_revoke_hits;
10059 /* Find a buffer for the new
10060 * data being restored */
10061 nbh = getblk(journal->j_fs_dev,
10063 journal->j_blocksize);
10065 printf("JBD: Out of memory "
10066 "during recovery.\n");
10074 memcpy(nbh->b_data, obh->b_data,
10075 journal->j_blocksize);
10076 if (flags & JFS_FLAG_ESCAPE) {
10077 *((unsigned int *)bh->b_data) =
10078 htonl(JFS_MAGIC_NUMBER);
10081 mark_buffer_uptodate(nbh, 1);
10082 mark_buffer_dirty(nbh);
10083 ++info->nr_replays;
10084 /* ll_rw_block(WRITE, 1, &nbh); */
10085 unlock_buffer(nbh);
10091 tagp += sizeof(journal_block_tag_t);
10092 if (!(flags & JFS_FLAG_SAME_UUID))
10095 if (flags & JFS_FLAG_LAST_TAG)
10102 case JFS_COMMIT_BLOCK:
10103 /* Found an expected commit block: not much to
10104 * do other than move on to the next sequence
10110 case JFS_REVOKE_BLOCK:
10111 /* If we aren't in the REVOKE pass, then we can
10112 * just skip over this block. */
10113 if (pass != PASS_REVOKE) {
10118 err = scan_revoke_records(journal, bh,
10119 next_commit_ID, info);
10132 * We broke out of the log scan loop: either we came to the
10133 * known end of the log or we found an unexpected block in the
10134 * log. If the latter happened, then we know that the "current"
10135 * transaction marks the end of the valid log.
10138 if (pass == PASS_SCAN)
10139 info->end_transaction = next_commit_ID;
10141 /* It's really bad news if different passes end up at
10142 * different places (but possible due to IO errors). */
10143 if (info->end_transaction != next_commit_ID) {
10144 printf("JBD: recovery pass %d ended at "
10145 "transaction %u, expected %u\n",
10146 pass, next_commit_ID, info->end_transaction);
10159 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10161 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10162 tid_t sequence, struct recovery_info *info)
10164 journal_revoke_header_t *header;
10167 header = (journal_revoke_header_t *) bh->b_data;
10168 offset = sizeof(journal_revoke_header_t);
10169 max = ntohl(header->r_count);
10171 while (offset < max) {
10172 unsigned long blocknr;
10175 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10177 err = journal_set_revoke(journal, blocknr, sequence);
10180 ++info->nr_revokes;
10187 * rehash.c --- rebuild hash tree directories
10189 * This algorithm is designed for simplicity of implementation and to
10190 * pack the directory as much as possible. It however requires twice
10191 * as much memory as the size of the directory. The maximum size
10192 * directory supported using a 4k blocksize is roughly a gigabyte, and
10193 * so there may very well be problems with machines that don't have
10194 * virtual memory, and obscenely large directories.
10196 * An alternate algorithm which is much more disk intensive could be
10197 * written, and probably will need to be written in the future. The
10198 * design goals of such an algorithm are: (a) use (roughly) constant
10199 * amounts of memory, no matter how large the directory, (b) the
10200 * directory must be safe at all times, even if e2fsck is interrupted
10201 * in the middle, (c) we must use minimal amounts of extra disk
10202 * blocks. This pretty much requires an incremental approach, where
10203 * we are reading from one part of the directory, and inserting into
10204 * the front half. So the algorithm will have to keep track of a
10205 * moving block boundary between the new tree and the old tree, and
10206 * files will need to be moved from the old directory and inserted
10207 * into the new tree. If the new directory requires space which isn't
10208 * yet available, blocks from the beginning part of the old directory
10209 * may need to be moved to the end of the directory to make room for
10212 * --------------------------------------------------------
10213 * | new tree | | old tree |
10214 * --------------------------------------------------------
10216 * tail new head old
10218 * This is going to be a pain in the tuckus to implement, and will
10219 * require a lot more disk accesses. So I'm going to skip it for now;
10220 * it's only really going to be an issue for really, really big
10221 * filesystems (when we reach the level of tens of millions of files
10222 * in a single directory). It will probably be easier to simply
10223 * require that e2fsck use VM first.
10226 struct fill_dir_struct {
10228 struct ext2_inode *inode;
10231 struct hash_entry *harray;
10232 int max_array, num_array;
10238 struct hash_entry {
10239 ext2_dirhash_t hash;
10240 ext2_dirhash_t minor_hash;
10241 struct ext2_dir_entry *dir;
10248 ext2_dirhash_t *hashes;
10251 static int fill_dir_block(ext2_filsys fs,
10253 e2_blkcnt_t blockcnt,
10254 blk_t ref_block FSCK_ATTR((unused)),
10255 int ref_offset FSCK_ATTR((unused)),
10258 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10259 struct hash_entry *new_array, *ent;
10260 struct ext2_dir_entry *dirent;
10262 unsigned int offset, dir_offset;
10267 offset = blockcnt * fs->blocksize;
10268 if (offset + fs->blocksize > fd->inode->i_size) {
10269 fd->err = EXT2_ET_DIR_CORRUPTED;
10270 return BLOCK_ABORT;
10272 dir = (fd->buf+offset);
10273 if (HOLE_BLKADDR(*block_nr)) {
10274 memset(dir, 0, fs->blocksize);
10275 dirent = (struct ext2_dir_entry *) dir;
10276 dirent->rec_len = fs->blocksize;
10278 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10280 return BLOCK_ABORT;
10282 /* While the directory block is "hot", index it. */
10284 while (dir_offset < fs->blocksize) {
10285 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10286 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10287 (dirent->rec_len < 8) ||
10288 ((dirent->rec_len % 4) != 0) ||
10289 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10290 fd->err = EXT2_ET_DIR_CORRUPTED;
10291 return BLOCK_ABORT;
10293 dir_offset += dirent->rec_len;
10294 if (dirent->inode == 0)
10296 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10297 (dirent->name[0] == '.'))
10299 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10300 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10301 fd->parent = dirent->inode;
10304 if (fd->num_array >= fd->max_array) {
10305 new_array = xrealloc(fd->harray,
10306 sizeof(struct hash_entry) * (fd->max_array+500));
10307 fd->harray = new_array;
10308 fd->max_array += 500;
10310 ent = fd->harray + fd->num_array++;
10312 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10314 ent->hash = ent->minor_hash = 0;
10316 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10318 dirent->name_len & 0xFF,
10319 fs->super->s_hash_seed,
10320 &ent->hash, &ent->minor_hash);
10322 return BLOCK_ABORT;
10329 /* Used for sorting the hash entry */
10330 static int name_cmp(const void *a, const void *b)
10332 const struct hash_entry *he_a = (const struct hash_entry *) a;
10333 const struct hash_entry *he_b = (const struct hash_entry *) b;
10337 min_len = he_a->dir->name_len;
10338 if (min_len > he_b->dir->name_len)
10339 min_len = he_b->dir->name_len;
10341 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10343 if (he_a->dir->name_len > he_b->dir->name_len)
10345 else if (he_a->dir->name_len < he_b->dir->name_len)
10348 ret = he_b->dir->inode - he_a->dir->inode;
10353 /* Used for sorting the hash entry */
10354 static int hash_cmp(const void *a, const void *b)
10356 const struct hash_entry *he_a = (const struct hash_entry *) a;
10357 const struct hash_entry *he_b = (const struct hash_entry *) b;
10360 if (he_a->hash > he_b->hash)
10362 else if (he_a->hash < he_b->hash)
10365 if (he_a->minor_hash > he_b->minor_hash)
10367 else if (he_a->minor_hash < he_b->minor_hash)
10370 ret = name_cmp(a, b);
10375 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10381 new_mem = xrealloc(outdir->buf, blocks * fs->blocksize);
10382 outdir->buf = new_mem;
10383 new_mem = xrealloc(outdir->hashes,
10384 blocks * sizeof(ext2_dirhash_t));
10385 outdir->hashes = new_mem;
10387 outdir->buf = xmalloc(blocks * fs->blocksize);
10388 outdir->hashes = xmalloc(blocks * sizeof(ext2_dirhash_t));
10391 outdir->max = blocks;
10395 static void free_out_dir(struct out_dir *outdir)
10398 free(outdir->hashes);
10403 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10408 if (outdir->num >= outdir->max) {
10409 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10413 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10414 memset(*ret, 0, fs->blocksize);
10419 * This function is used to make a unique filename. We do this by
10420 * appending ~0, and then incrementing the number. However, we cannot
10421 * expand the length of the filename beyond the padding available in
10422 * the directory entry.
10424 static void mutate_name(char *str, __u16 *len)
10427 __u16 l = *len & 0xFF, h = *len & 0xff00;
10430 * First check to see if it looks the name has been mutated
10433 for (i = l-1; i > 0; i--) {
10434 if (!isdigit(str[i]))
10437 if ((i == l-1) || (str[i] != '~')) {
10438 if (((l-1) & 3) < 2)
10447 for (i = l-1; i >= 0; i--) {
10448 if (isdigit(str[i])) {
10460 else if (str[0] == 'Z') {
10465 } else if (i > 0) {
10478 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10480 struct fill_dir_struct *fd)
10482 struct problem_context pctx;
10483 struct hash_entry *ent, *prev;
10486 char new_name[256];
10489 clear_problem_context(&pctx);
10492 for (i=1; i < fd->num_array; i++) {
10493 ent = fd->harray + i;
10495 if (!ent->dir->inode ||
10496 ((ent->dir->name_len & 0xFF) !=
10497 (prev->dir->name_len & 0xFF)) ||
10498 (strncmp(ent->dir->name, prev->dir->name,
10499 ent->dir->name_len & 0xFF)))
10501 pctx.dirent = ent->dir;
10502 if ((ent->dir->inode == prev->dir->inode) &&
10503 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10504 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10505 ent->dir->inode = 0;
10509 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10510 new_len = ent->dir->name_len;
10511 mutate_name(new_name, &new_len);
10512 for (j=0; j < fd->num_array; j++) {
10514 ((ent->dir->name_len & 0xFF) !=
10515 (fd->harray[j].dir->name_len & 0xFF)) ||
10516 (strncmp(new_name, fd->harray[j].dir->name,
10519 mutate_name(new_name, &new_len);
10523 new_name[new_len & 0xFF] = 0;
10524 pctx.str = new_name;
10525 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10526 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10527 ent->dir->name_len = new_len;
10528 ext2fs_dirhash(fs->super->s_def_hash_version,
10530 ent->dir->name_len & 0xFF,
10531 fs->super->s_hash_seed,
10532 &ent->hash, &ent->minor_hash);
10540 static errcode_t copy_dir_entries(ext2_filsys fs,
10541 struct fill_dir_struct *fd,
10542 struct out_dir *outdir)
10546 struct hash_entry *ent;
10547 struct ext2_dir_entry *dirent;
10548 int i, rec_len, left;
10549 ext2_dirhash_t prev_hash;
10553 retval = alloc_size_dir(fs, outdir,
10554 (fd->dir_size / fs->blocksize) + 2);
10557 outdir->num = fd->compress ? 0 : 1;
10559 outdir->hashes[0] = 0;
10561 if ((retval = get_next_block(fs, outdir, &block_start)))
10563 dirent = (struct ext2_dir_entry *) block_start;
10564 left = fs->blocksize;
10565 for (i=0; i < fd->num_array; i++) {
10566 ent = fd->harray + i;
10567 if (ent->dir->inode == 0)
10569 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10570 if (rec_len > left) {
10572 dirent->rec_len += left;
10573 if ((retval = get_next_block(fs, outdir,
10578 left = fs->blocksize - offset;
10579 dirent = (struct ext2_dir_entry *) (block_start + offset);
10581 if (ent->hash == prev_hash)
10582 outdir->hashes[outdir->num-1] = ent->hash | 1;
10584 outdir->hashes[outdir->num-1] = ent->hash;
10586 dirent->inode = ent->dir->inode;
10587 dirent->name_len = ent->dir->name_len;
10588 dirent->rec_len = rec_len;
10589 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10593 dirent->rec_len += left;
10597 prev_hash = ent->hash;
10600 dirent->rec_len += left;
10606 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10607 ext2_ino_t ino, ext2_ino_t parent)
10609 struct ext2_dir_entry *dir;
10610 struct ext2_dx_root_info *root;
10611 struct ext2_dx_countlimit *limits;
10614 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10615 filetype = EXT2_FT_DIR << 8;
10617 memset(buf, 0, fs->blocksize);
10618 dir = (struct ext2_dir_entry *) buf;
10620 dir->name[0] = '.';
10621 dir->name_len = 1 | filetype;
10623 dir = (struct ext2_dir_entry *) (buf + 12);
10624 dir->inode = parent;
10625 dir->name[0] = '.';
10626 dir->name[1] = '.';
10627 dir->name_len = 2 | filetype;
10628 dir->rec_len = fs->blocksize - 12;
10630 root = (struct ext2_dx_root_info *) (buf+24);
10631 root->reserved_zero = 0;
10632 root->hash_version = fs->super->s_def_hash_version;
10633 root->info_length = 8;
10634 root->indirect_levels = 0;
10635 root->unused_flags = 0;
10637 limits = (struct ext2_dx_countlimit *) (buf+32);
10638 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10645 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10647 struct ext2_dir_entry *dir;
10648 struct ext2_dx_countlimit *limits;
10650 memset(buf, 0, fs->blocksize);
10651 dir = (struct ext2_dir_entry *) buf;
10653 dir->rec_len = fs->blocksize;
10655 limits = (struct ext2_dx_countlimit *) (buf+8);
10656 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10659 return (struct ext2_dx_entry *) limits;
10663 * This function takes the leaf nodes which have been written in
10664 * outdir, and populates the root node and any necessary interior nodes.
10666 static errcode_t calculate_tree(ext2_filsys fs,
10667 struct out_dir *outdir,
10671 struct ext2_dx_root_info *root_info;
10672 struct ext2_dx_entry *root, *dx_ent = NULL;
10673 struct ext2_dx_countlimit *root_limit, *limit;
10675 char * block_start;
10676 int i, c1, c2, nblks;
10677 int limit_offset, root_offset;
10679 root_info = set_root_node(fs, outdir->buf, ino, parent);
10680 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10681 root_info->info_length;
10682 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10683 c1 = root_limit->limit;
10684 nblks = outdir->num;
10686 /* Write out the pointer blocks */
10687 if (nblks-1 <= c1) {
10688 /* Just write out the root block, and we're done */
10689 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10690 for (i=1; i < nblks; i++) {
10691 root->block = ext2fs_cpu_to_le32(i);
10694 ext2fs_cpu_to_le32(outdir->hashes[i]);
10701 root_info->indirect_levels = 1;
10702 for (i=1; i < nblks; i++) {
10707 limit->limit = limit->count =
10708 ext2fs_cpu_to_le16(limit->limit);
10709 root = (struct ext2_dx_entry *)
10710 (outdir->buf + root_offset);
10711 root->block = ext2fs_cpu_to_le32(outdir->num);
10714 ext2fs_cpu_to_le32(outdir->hashes[i]);
10715 if ((retval = get_next_block(fs, outdir,
10718 dx_ent = set_int_node(fs, block_start);
10719 limit = (struct ext2_dx_countlimit *) dx_ent;
10721 root_offset += sizeof(struct ext2_dx_entry);
10724 dx_ent->block = ext2fs_cpu_to_le32(i);
10725 if (c2 != limit->limit)
10727 ext2fs_cpu_to_le32(outdir->hashes[i]);
10731 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10732 limit->limit = ext2fs_cpu_to_le16(limit->limit);
10734 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10735 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10736 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10741 struct write_dir_struct {
10742 struct out_dir *outdir;
10749 * Helper function which writes out a directory block.
10751 static int write_dir_block(ext2_filsys fs,
10753 e2_blkcnt_t blockcnt,
10754 blk_t ref_block FSCK_ATTR((unused)),
10755 int ref_offset FSCK_ATTR((unused)),
10758 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10762 if (*block_nr == 0)
10764 if (blockcnt >= wd->outdir->num) {
10765 e2fsck_read_bitmaps(wd->ctx);
10767 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10768 ext2fs_block_alloc_stats(fs, blk, -1);
10771 return BLOCK_CHANGED;
10776 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10777 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10779 return BLOCK_ABORT;
10783 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10784 struct out_dir *outdir,
10785 ext2_ino_t ino, int compress)
10787 struct write_dir_struct wd;
10789 struct ext2_inode inode;
10791 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10795 wd.outdir = outdir;
10800 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10801 write_dir_block, &wd);
10807 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10809 inode.i_flags &= ~EXT2_INDEX_FL;
10811 inode.i_flags |= EXT2_INDEX_FL;
10812 inode.i_size = outdir->num * fs->blocksize;
10813 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10814 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10819 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10821 ext2_filsys fs = ctx->fs;
10823 struct ext2_inode inode;
10824 char *dir_buf = NULL;
10825 struct fill_dir_struct fd;
10826 struct out_dir outdir;
10828 outdir.max = outdir.num = 0;
10831 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10835 dir_buf = xmalloc(inode.i_size);
10837 fd.max_array = inode.i_size / 32;
10839 fd.harray = xmalloc(fd.max_array * sizeof(struct hash_entry));
10847 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10848 (inode.i_size / fs->blocksize) < 2)
10852 /* Read in the entire directory into memory */
10853 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10854 fill_dir_block, &fd);
10860 /* Sort the list */
10863 qsort(fd.harray+2, fd.num_array-2,
10864 sizeof(struct hash_entry), name_cmp);
10866 qsort(fd.harray, fd.num_array,
10867 sizeof(struct hash_entry), hash_cmp);
10870 * Look for duplicates
10872 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10875 if (ctx->options & E2F_OPT_NO) {
10881 * Copy the directory entries. In a htree directory these
10882 * will become the leaf nodes.
10884 retval = copy_dir_entries(fs, &fd, &outdir);
10888 free(dir_buf); dir_buf = 0;
10890 if (!fd.compress) {
10891 /* Calculate the interior nodes */
10892 retval = calculate_tree(fs, &outdir, ino, fd.parent);
10897 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10903 free_out_dir(&outdir);
10907 void e2fsck_rehash_directories(e2fsck_t ctx)
10909 struct problem_context pctx;
10910 struct dir_info *dir;
10911 ext2_u32_iterate iter;
10914 int i, cur, max, all_dirs, dir_index, first = 1;
10916 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10918 if (!ctx->dirs_to_hash && !all_dirs)
10921 e2fsck_get_lost_and_found(ctx, 0);
10923 clear_problem_context(&pctx);
10925 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10929 max = e2fsck_get_num_dirinfo(ctx);
10931 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10934 pctx.errcode = retval;
10935 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10938 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10942 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10946 if (!ext2fs_u32_list_iterate(iter, &ino))
10949 if (ino == ctx->lost_and_found)
10953 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
10956 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
10957 if (pctx.errcode) {
10958 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10959 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
10961 if (ctx->progress && !ctx->progress_fd)
10962 e2fsck_simple_progress(ctx, "Rebuilding directory",
10963 100.0 * (float) (++cur) / (float) max, ino);
10965 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10967 ext2fs_u32_list_iterate_end(iter);
10969 ext2fs_u32_list_free(ctx->dirs_to_hash);
10970 ctx->dirs_to_hash = 0;
10974 * linux/fs/revoke.c
10976 * Journal revoke routines for the generic filesystem journaling code;
10977 * part of the ext2fs journaling system.
10979 * Revoke is the mechanism used to prevent old log records for deleted
10980 * metadata from being replayed on top of newer data using the same
10981 * blocks. The revoke mechanism is used in two separate places:
10983 * + Commit: during commit we write the entire list of the current
10984 * transaction's revoked blocks to the journal
10986 * + Recovery: during recovery we record the transaction ID of all
10987 * revoked blocks. If there are multiple revoke records in the log
10988 * for a single block, only the last one counts, and if there is a log
10989 * entry for a block beyond the last revoke, then that log entry still
10992 * We can get interactions between revokes and new log data within a
10993 * single transaction:
10995 * Block is revoked and then journaled:
10996 * The desired end result is the journaling of the new block, so we
10997 * cancel the revoke before the transaction commits.
10999 * Block is journaled and then revoked:
11000 * The revoke must take precedence over the write of the block, so we
11001 * need either to cancel the journal entry or to write the revoke
11002 * later in the log than the log block. In this case, we choose the
11003 * latter: journaling a block cancels any revoke record for that block
11004 * in the current transaction, so any revoke for that block in the
11005 * transaction must have happened after the block was journaled and so
11006 * the revoke must take precedence.
11008 * Block is revoked and then written as data:
11009 * The data write is allowed to succeed, but the revoke is _not_
11010 * cancelled. We still need to prevent old log records from
11011 * overwriting the new data. We don't even need to clear the revoke
11014 * Revoke information on buffers is a tri-state value:
11016 * RevokeValid clear: no cached revoke status, need to look it up
11017 * RevokeValid set, Revoked clear:
11018 * buffer has not been revoked, and cancel_revoke
11020 * RevokeValid set, Revoked set:
11021 * buffer has been revoked.
11024 static kmem_cache_t *revoke_record_cache;
11025 static kmem_cache_t *revoke_table_cache;
11027 /* Each revoke record represents one single revoked block. During
11028 journal replay, this involves recording the transaction ID of the
11029 last transaction to revoke this block. */
11031 struct jbd_revoke_record_s
11033 struct list_head hash;
11034 tid_t sequence; /* Used for recovery only */
11035 unsigned long blocknr;
11039 /* The revoke table is just a simple hash table of revoke records. */
11040 struct jbd_revoke_table_s
11042 /* It is conceivable that we might want a larger hash table
11043 * for recovery. Must be a power of two. */
11046 struct list_head *hash_table;
11050 /* Utility functions to maintain the revoke table */
11052 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11053 static int hash(journal_t *journal, unsigned long block)
11055 struct jbd_revoke_table_s *table = journal->j_revoke;
11056 int hash_shift = table->hash_shift;
11058 return ((block << (hash_shift - 6)) ^
11060 (block << (hash_shift - 12))) & (table->hash_size - 1);
11063 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11066 struct list_head *hash_list;
11067 struct jbd_revoke_record_s *record;
11069 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11073 record->sequence = seq;
11074 record->blocknr = blocknr;
11075 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11076 list_add(&record->hash, hash_list);
11083 /* Find a revoke record in the journal's hash table. */
11085 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11086 unsigned long blocknr)
11088 struct list_head *hash_list;
11089 struct jbd_revoke_record_s *record;
11091 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11093 record = (struct jbd_revoke_record_s *) hash_list->next;
11094 while (&(record->hash) != hash_list) {
11095 if (record->blocknr == blocknr)
11097 record = (struct jbd_revoke_record_s *) record->hash.next;
11102 int journal_init_revoke_caches(void)
11104 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11105 if (revoke_record_cache == 0)
11108 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11109 if (revoke_table_cache == 0) {
11110 do_cache_destroy(revoke_record_cache);
11111 revoke_record_cache = NULL;
11117 void journal_destroy_revoke_caches(void)
11119 do_cache_destroy(revoke_record_cache);
11120 revoke_record_cache = 0;
11121 do_cache_destroy(revoke_table_cache);
11122 revoke_table_cache = 0;
11125 /* Initialise the revoke table for a given journal to a given size. */
11127 int journal_init_revoke(journal_t *journal, int hash_size)
11131 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11132 if (!journal->j_revoke)
11135 /* Check that the hash_size is a power of two */
11136 journal->j_revoke->hash_size = hash_size;
11140 while ((tmp >>= 1UL) != 0UL)
11142 journal->j_revoke->hash_shift = shift;
11144 journal->j_revoke->hash_table = xmalloc(hash_size * sizeof(struct list_head));
11146 for (tmp = 0; tmp < hash_size; tmp++)
11147 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11152 /* Destoy a journal's revoke table. The table must already be empty! */
11154 void journal_destroy_revoke(journal_t *journal)
11156 struct jbd_revoke_table_s *table;
11157 struct list_head *hash_list;
11160 table = journal->j_revoke;
11164 for (i=0; i<table->hash_size; i++) {
11165 hash_list = &table->hash_table[i];
11168 free(table->hash_table);
11170 journal->j_revoke = NULL;
11174 * Revoke support for recovery.
11176 * Recovery needs to be able to:
11178 * record all revoke records, including the tid of the latest instance
11179 * of each revoke in the journal
11181 * check whether a given block in a given transaction should be replayed
11182 * (ie. has not been revoked by a revoke record in that or a subsequent
11185 * empty the revoke table after recovery.
11189 * First, setting revoke records. We create a new revoke record for
11190 * every block ever revoked in the log as we scan it for recovery, and
11191 * we update the existing records if we find multiple revokes for a
11195 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11198 struct jbd_revoke_record_s *record;
11200 record = find_revoke_record(journal, blocknr);
11202 /* If we have multiple occurences, only record the
11203 * latest sequence number in the hashed record */
11204 if (tid_gt(sequence, record->sequence))
11205 record->sequence = sequence;
11208 return insert_revoke_hash(journal, blocknr, sequence);
11212 * Test revoke records. For a given block referenced in the log, has
11213 * that block been revoked? A revoke record with a given transaction
11214 * sequence number revokes all blocks in that transaction and earlier
11215 * ones, but later transactions still need replayed.
11218 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11221 struct jbd_revoke_record_s *record;
11223 record = find_revoke_record(journal, blocknr);
11226 if (tid_gt(sequence, record->sequence))
11232 * Finally, once recovery is over, we need to clear the revoke table so
11233 * that it can be reused by the running filesystem.
11236 void journal_clear_revoke(journal_t *journal)
11239 struct list_head *hash_list;
11240 struct jbd_revoke_record_s *record;
11241 struct jbd_revoke_table_s *revoke_var;
11243 revoke_var = journal->j_revoke;
11245 for (i = 0; i < revoke_var->hash_size; i++) {
11246 hash_list = &revoke_var->hash_table[i];
11247 while (!list_empty(hash_list)) {
11248 record = (struct jbd_revoke_record_s*) hash_list->next;
11249 list_del(&record->hash);
11256 * e2fsck.c - superblock checks
11259 #define MIN_CHECK 1
11260 #define MAX_CHECK 2
11262 static void check_super_value(e2fsck_t ctx, const char *descr,
11263 unsigned long value, int flags,
11264 unsigned long min_val, unsigned long max_val)
11266 struct problem_context pctx;
11268 if (((flags & MIN_CHECK) && (value < min_val)) ||
11269 ((flags & MAX_CHECK) && (value > max_val))) {
11270 clear_problem_context(&pctx);
11273 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11274 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11279 * This routine may get stubbed out in special compilations of the
11282 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11283 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11285 return (ext2fs_get_device_size(ctx->filesystem_name,
11286 EXT2_BLOCK_SIZE(ctx->fs->super),
11287 &ctx->num_blocks));
11292 * helper function to release an inode
11294 struct process_block_struct {
11297 struct problem_context *pctx;
11299 int truncate_offset;
11300 e2_blkcnt_t truncate_block;
11301 int truncated_blocks;
11306 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11307 e2_blkcnt_t blockcnt,
11308 blk_t ref_blk FSCK_ATTR((unused)),
11309 int ref_offset FSCK_ATTR((unused)),
11312 struct process_block_struct *pb;
11314 struct problem_context *pctx;
11315 blk_t blk = *block_nr;
11318 pb = (struct process_block_struct *) priv_data;
11323 pctx->blkcount = blockcnt;
11325 if (HOLE_BLKADDR(blk))
11328 if ((blk < fs->super->s_first_data_block) ||
11329 (blk >= fs->super->s_blocks_count)) {
11330 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11333 return BLOCK_ABORT;
11336 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11337 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11342 * If we are deleting an orphan, then we leave the fields alone.
11343 * If we are truncating an orphan, then update the inode fields
11344 * and clean up any partial block data.
11346 if (pb->truncating) {
11348 * We only remove indirect blocks if they are
11349 * completely empty.
11351 if (blockcnt < 0) {
11355 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11360 limit = fs->blocksize >> 2;
11361 for (i = 0, bp = (blk_t *) pb->buf;
11362 i < limit; i++, bp++)
11367 * We don't remove direct blocks until we've reached
11368 * the truncation block.
11370 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11373 * If part of the last block needs truncating, we do
11376 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11377 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11381 memset(pb->buf + pb->truncate_offset, 0,
11382 fs->blocksize - pb->truncate_offset);
11383 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11388 pb->truncated_blocks++;
11390 retval |= BLOCK_CHANGED;
11393 ext2fs_block_alloc_stats(fs, blk, -1);
11398 * This function releases an inode. Returns 1 if an inconsistency was
11399 * found. If the inode has a link count, then it is being truncated and
11402 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11403 struct ext2_inode *inode, char *block_buf,
11404 struct problem_context *pctx)
11406 struct process_block_struct pb;
11407 ext2_filsys fs = ctx->fs;
11411 if (!ext2fs_inode_has_valid_blocks(inode))
11414 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11419 if (inode->i_links_count) {
11421 pb.truncate_block = (e2_blkcnt_t)
11422 ((((long long)inode->i_size_high << 32) +
11423 inode->i_size + fs->blocksize - 1) /
11425 pb.truncate_offset = inode->i_size % fs->blocksize;
11428 pb.truncate_block = 0;
11429 pb.truncate_offset = 0;
11431 pb.truncated_blocks = 0;
11432 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11433 block_buf, release_inode_block, &pb);
11435 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11442 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11443 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11445 if (pb.truncated_blocks)
11446 inode->i_blocks -= pb.truncated_blocks *
11447 (fs->blocksize / 512);
11449 if (inode->i_file_acl) {
11450 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11451 block_buf, -1, &count);
11452 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11457 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11462 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11463 inode->i_file_acl = 0;
11469 * This function releases all of the orphan inodes. It returns 1 if
11470 * it hit some error, and 0 on success.
11472 static int release_orphan_inodes(e2fsck_t ctx)
11474 ext2_filsys fs = ctx->fs;
11475 ext2_ino_t ino, next_ino;
11476 struct ext2_inode inode;
11477 struct problem_context pctx;
11480 if ((ino = fs->super->s_last_orphan) == 0)
11484 * Win or lose, we won't be using the head of the orphan inode
11487 fs->super->s_last_orphan = 0;
11488 ext2fs_mark_super_dirty(fs);
11491 * If the filesystem contains errors, don't run the orphan
11492 * list, since the orphan list can't be trusted; and we're
11493 * going to be running a full e2fsck run anyway...
11495 if (fs->super->s_state & EXT2_ERROR_FS)
11498 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11499 (ino > fs->super->s_inodes_count)) {
11500 clear_problem_context(&pctx);
11502 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11506 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11507 "block iterate buffer");
11508 e2fsck_read_bitmaps(ctx);
11511 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11512 clear_problem_context(&pctx);
11514 pctx.inode = &inode;
11515 pctx.str = inode.i_links_count ? _("Truncating") :
11518 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11520 next_ino = inode.i_dtime;
11522 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11523 (next_ino > fs->super->s_inodes_count))) {
11524 pctx.ino = next_ino;
11525 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11529 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11532 if (!inode.i_links_count) {
11533 ext2fs_inode_alloc_stats2(fs, ino, -1,
11534 LINUX_S_ISDIR(inode.i_mode));
11535 inode.i_dtime = time(NULL);
11539 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11542 ext2fs_free_mem(&block_buf);
11545 ext2fs_free_mem(&block_buf);
11550 * Check the resize inode to make sure it is sane. We check both for
11551 * the case where on-line resizing is not enabled (in which case the
11552 * resize inode should be cleared) as well as the case where on-line
11553 * resizing is enabled.
11555 static void check_resize_inode(e2fsck_t ctx)
11557 ext2_filsys fs = ctx->fs;
11558 struct ext2_inode inode;
11559 struct problem_context pctx;
11560 int i, j, gdt_off, ind_off;
11561 blk_t blk, pblk, expect;
11562 __u32 *dind_buf = NULL, *ind_buf;
11565 clear_problem_context(&pctx);
11568 * If the resize inode feature isn't set, then
11569 * s_reserved_gdt_blocks must be zero.
11571 if (!(fs->super->s_feature_compat &
11572 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11573 if (fs->super->s_reserved_gdt_blocks) {
11574 pctx.num = fs->super->s_reserved_gdt_blocks;
11575 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11577 fs->super->s_reserved_gdt_blocks = 0;
11578 ext2fs_mark_super_dirty(fs);
11583 /* Read the resize inode */
11584 pctx.ino = EXT2_RESIZE_INO;
11585 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11587 if (fs->super->s_feature_compat &
11588 EXT2_FEATURE_COMPAT_RESIZE_INODE)
11589 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11594 * If the resize inode feature isn't set, check to make sure
11595 * the resize inode is cleared; then we're done.
11597 if (!(fs->super->s_feature_compat &
11598 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11599 for (i=0; i < EXT2_N_BLOCKS; i++) {
11600 if (inode.i_block[i])
11603 if ((i < EXT2_N_BLOCKS) &&
11604 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11605 memset(&inode, 0, sizeof(inode));
11606 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11613 * The resize inode feature is enabled; check to make sure the
11614 * only block in use is the double indirect block
11616 blk = inode.i_block[EXT2_DIND_BLOCK];
11617 for (i=0; i < EXT2_N_BLOCKS; i++) {
11618 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11621 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11622 !(inode.i_mode & LINUX_S_IFREG) ||
11623 (blk < fs->super->s_first_data_block ||
11624 blk >= fs->super->s_blocks_count)) {
11625 resize_inode_invalid:
11626 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11627 memset(&inode, 0, sizeof(inode));
11628 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11630 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11632 if (!(ctx->options & E2F_OPT_READONLY)) {
11633 fs->super->s_state &= ~EXT2_VALID_FS;
11634 ext2fs_mark_super_dirty(fs);
11638 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11639 "resize dind buffer");
11640 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11642 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11644 goto resize_inode_invalid;
11646 gdt_off = fs->desc_blocks;
11647 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11648 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11649 i++, gdt_off++, pblk++) {
11650 gdt_off %= fs->blocksize/4;
11651 if (dind_buf[gdt_off] != pblk)
11652 goto resize_inode_invalid;
11653 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11655 goto resize_inode_invalid;
11657 for (j = 1; j < fs->group_desc_count; j++) {
11658 if (!ext2fs_bg_has_super(fs, j))
11660 expect = pblk + (j * fs->super->s_blocks_per_group);
11661 if (ind_buf[ind_off] != expect)
11662 goto resize_inode_invalid;
11668 ext2fs_free_mem(&dind_buf);
11672 static void check_super_block(e2fsck_t ctx)
11674 ext2_filsys fs = ctx->fs;
11675 blk_t first_block, last_block;
11676 struct ext2_super_block *sb = fs->super;
11677 struct ext2_group_desc *gd;
11678 blk_t blocks_per_group = fs->super->s_blocks_per_group;
11680 int inodes_per_block;
11685 struct problem_context pctx;
11686 __u32 free_blocks = 0, free_inodes = 0;
11688 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11689 ipg_max = inodes_per_block * (blocks_per_group - 4);
11690 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11691 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11692 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11693 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11694 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11696 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11697 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11698 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11699 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11700 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11701 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11703 clear_problem_context(&pctx);
11706 * Verify the super block constants...
11708 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11710 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11712 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11713 MAX_CHECK, 0, sb->s_blocks_count);
11714 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11715 MIN_CHECK | MAX_CHECK, 0,
11716 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11717 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11718 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11719 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11720 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11722 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11723 MIN_CHECK | MAX_CHECK, 8, bpg_max);
11724 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11725 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11726 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11727 MAX_CHECK, 0, sb->s_blocks_count / 2);
11728 check_super_value(ctx, "reserved_gdt_blocks",
11729 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11731 inode_size = EXT2_INODE_SIZE(sb);
11732 check_super_value(ctx, "inode_size",
11733 inode_size, MIN_CHECK | MAX_CHECK,
11734 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11735 if (inode_size & (inode_size - 1)) {
11736 pctx.num = inode_size;
11737 pctx.str = "inode_size";
11738 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11739 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11743 if (!ctx->num_blocks) {
11744 pctx.errcode = e2fsck_get_device_size(ctx);
11745 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11746 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11747 ctx->flags |= E2F_FLAG_ABORT;
11750 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11751 (ctx->num_blocks < sb->s_blocks_count)) {
11752 pctx.blk = sb->s_blocks_count;
11753 pctx.blk2 = ctx->num_blocks;
11754 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11755 ctx->flags |= E2F_FLAG_ABORT;
11761 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11762 pctx.blk = EXT2_BLOCK_SIZE(sb);
11763 pctx.blk2 = EXT2_FRAG_SIZE(sb);
11764 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11765 ctx->flags |= E2F_FLAG_ABORT;
11769 should_be = sb->s_frags_per_group >>
11770 (sb->s_log_block_size - sb->s_log_frag_size);
11771 if (sb->s_blocks_per_group != should_be) {
11772 pctx.blk = sb->s_blocks_per_group;
11773 pctx.blk2 = should_be;
11774 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11775 ctx->flags |= E2F_FLAG_ABORT;
11779 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11780 if (sb->s_first_data_block != should_be) {
11781 pctx.blk = sb->s_first_data_block;
11782 pctx.blk2 = should_be;
11783 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11784 ctx->flags |= E2F_FLAG_ABORT;
11788 should_be = sb->s_inodes_per_group * fs->group_desc_count;
11789 if (sb->s_inodes_count != should_be) {
11790 pctx.ino = sb->s_inodes_count;
11791 pctx.ino2 = should_be;
11792 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11793 sb->s_inodes_count = should_be;
11794 ext2fs_mark_super_dirty(fs);
11799 * Verify the group descriptors....
11801 first_block = sb->s_first_data_block;
11802 last_block = first_block + blocks_per_group;
11804 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11807 if (i == fs->group_desc_count - 1)
11808 last_block = sb->s_blocks_count;
11809 if ((gd->bg_block_bitmap < first_block) ||
11810 (gd->bg_block_bitmap >= last_block)) {
11811 pctx.blk = gd->bg_block_bitmap;
11812 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11813 gd->bg_block_bitmap = 0;
11815 if (gd->bg_block_bitmap == 0) {
11816 ctx->invalid_block_bitmap_flag[i]++;
11817 ctx->invalid_bitmaps++;
11819 if ((gd->bg_inode_bitmap < first_block) ||
11820 (gd->bg_inode_bitmap >= last_block)) {
11821 pctx.blk = gd->bg_inode_bitmap;
11822 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11823 gd->bg_inode_bitmap = 0;
11825 if (gd->bg_inode_bitmap == 0) {
11826 ctx->invalid_inode_bitmap_flag[i]++;
11827 ctx->invalid_bitmaps++;
11829 if ((gd->bg_inode_table < first_block) ||
11830 ((gd->bg_inode_table +
11831 fs->inode_blocks_per_group - 1) >= last_block)) {
11832 pctx.blk = gd->bg_inode_table;
11833 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11834 gd->bg_inode_table = 0;
11836 if (gd->bg_inode_table == 0) {
11837 ctx->invalid_inode_table_flag[i]++;
11838 ctx->invalid_bitmaps++;
11840 free_blocks += gd->bg_free_blocks_count;
11841 free_inodes += gd->bg_free_inodes_count;
11842 first_block += sb->s_blocks_per_group;
11843 last_block += sb->s_blocks_per_group;
11845 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11846 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11847 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11848 ext2fs_unmark_valid(fs);
11853 * Update the global counts from the block group counts. This
11854 * is needed for an experimental patch which eliminates
11855 * locking the entire filesystem when allocating blocks or
11856 * inodes; if the filesystem is not unmounted cleanly, the
11857 * global counts may not be accurate.
11859 if ((free_blocks != sb->s_free_blocks_count) ||
11860 (free_inodes != sb->s_free_inodes_count)) {
11861 if (ctx->options & E2F_OPT_READONLY)
11862 ext2fs_unmark_valid(fs);
11864 sb->s_free_blocks_count = free_blocks;
11865 sb->s_free_inodes_count = free_inodes;
11866 ext2fs_mark_super_dirty(fs);
11870 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11871 (sb->s_free_inodes_count > sb->s_inodes_count))
11872 ext2fs_unmark_valid(fs);
11876 * If we have invalid bitmaps, set the error state of the
11879 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11880 sb->s_state &= ~EXT2_VALID_FS;
11881 ext2fs_mark_super_dirty(fs);
11884 clear_problem_context(&pctx);
11887 * If the UUID field isn't assigned, assign it.
11889 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11890 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11891 uuid_generate(sb->s_uuid);
11892 ext2fs_mark_super_dirty(fs);
11893 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11897 /* FIXME - HURD support?
11898 * For the Hurd, check to see if the filetype option is set,
11899 * since it doesn't support it.
11901 if (!(ctx->options & E2F_OPT_READONLY) &&
11902 fs->super->s_creator_os == EXT2_OS_HURD &&
11903 (fs->super->s_feature_incompat &
11904 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11905 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11906 fs->super->s_feature_incompat &=
11907 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11908 ext2fs_mark_super_dirty(fs);
11914 * If we have any of the compatibility flags set, we need to have a
11915 * revision 1 filesystem. Most kernels will not check the flags on
11916 * a rev 0 filesystem and we may have corruption issues because of
11917 * the incompatible changes to the filesystem.
11919 if (!(ctx->options & E2F_OPT_READONLY) &&
11920 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11921 (fs->super->s_feature_compat ||
11922 fs->super->s_feature_ro_compat ||
11923 fs->super->s_feature_incompat) &&
11924 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11925 ext2fs_update_dynamic_rev(fs);
11926 ext2fs_mark_super_dirty(fs);
11929 check_resize_inode(ctx);
11932 * Clean up any orphan inodes, if present.
11934 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11935 fs->super->s_state &= ~EXT2_VALID_FS;
11936 ext2fs_mark_super_dirty(fs);
11940 * Move the ext3 journal file, if necessary.
11942 e2fsck_move_ext3_journal(ctx);
11946 * swapfs.c --- byte-swap an ext2 filesystem
11949 #ifdef ENABLE_SWAPFS
11951 struct swap_block_struct {
11956 struct ext2_inode *inode;
11960 * This is a helper function for block_iterate. We mark all of the
11961 * indirect and direct blocks as changed, so that block_iterate will
11964 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
11969 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
11971 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
11972 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
11974 sb->errcode = retval;
11975 return BLOCK_ABORT;
11977 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
11979 sb->errcode = retval;
11980 return BLOCK_ABORT;
11983 if (blockcnt >= 0) {
11984 if (blockcnt < EXT2_NDIR_BLOCKS)
11986 return BLOCK_CHANGED;
11988 if (blockcnt == BLOCK_COUNT_IND) {
11989 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
11991 return BLOCK_CHANGED;
11993 if (blockcnt == BLOCK_COUNT_DIND) {
11994 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
11996 return BLOCK_CHANGED;
11998 if (blockcnt == BLOCK_COUNT_TIND) {
11999 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12001 return BLOCK_CHANGED;
12003 return BLOCK_CHANGED;
12007 * This function is responsible for byte-swapping all of the indirect,
12008 * block pointers. It is also responsible for byte-swapping directories.
12010 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12011 struct ext2_inode *inode)
12014 struct swap_block_struct sb;
12018 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12021 if (LINUX_S_ISDIR(inode->i_mode))
12024 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12027 bb_error_msg(_("while calling ext2fs_block_iterate"));
12028 ctx->flags |= E2F_FLAG_ABORT;
12032 bb_error_msg(_("while calling iterator function"));
12033 ctx->flags |= E2F_FLAG_ABORT;
12038 static void swap_inodes(e2fsck_t ctx)
12040 ext2_filsys fs = ctx->fs;
12043 ext2_ino_t ino = 1;
12044 char *buf, *block_buf;
12046 struct ext2_inode * inode;
12048 e2fsck_use_inode_shortcuts(ctx, 1);
12050 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12053 bb_error_msg(_("while allocating inode buffer"));
12054 ctx->flags |= E2F_FLAG_ABORT;
12057 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12058 "block interate buffer");
12059 for (group = 0; group < fs->group_desc_count; group++) {
12060 retval = io_channel_read_blk(fs->io,
12061 fs->group_desc[group].bg_inode_table,
12062 fs->inode_blocks_per_group, buf);
12064 bb_error_msg(_("while reading inode table (group %d)"),
12066 ctx->flags |= E2F_FLAG_ABORT;
12069 inode = (struct ext2_inode *) buf;
12070 for (i=0; i < fs->super->s_inodes_per_group;
12071 i++, ino++, inode++) {
12072 ctx->stashed_ino = ino;
12073 ctx->stashed_inode = inode;
12075 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12076 ext2fs_swap_inode(fs, inode, inode, 0);
12079 * Skip deleted files.
12081 if (inode->i_links_count == 0)
12084 if (LINUX_S_ISDIR(inode->i_mode) ||
12085 ((inode->i_block[EXT2_IND_BLOCK] ||
12086 inode->i_block[EXT2_DIND_BLOCK] ||
12087 inode->i_block[EXT2_TIND_BLOCK]) &&
12088 ext2fs_inode_has_valid_blocks(inode)))
12089 swap_inode_blocks(ctx, ino, block_buf, inode);
12091 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12094 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12095 ext2fs_swap_inode(fs, inode, inode, 1);
12097 retval = io_channel_write_blk(fs->io,
12098 fs->group_desc[group].bg_inode_table,
12099 fs->inode_blocks_per_group, buf);
12101 bb_error_msg(_("while writing inode table (group %d)"),
12103 ctx->flags |= E2F_FLAG_ABORT;
12107 ext2fs_free_mem(&buf);
12108 ext2fs_free_mem(&block_buf);
12109 e2fsck_use_inode_shortcuts(ctx, 0);
12110 ext2fs_flush_icache(fs);
12113 #if defined(__powerpc__) && BB_BIG_ENDIAN
12115 * On the PowerPC, the big-endian variant of the ext2 filesystem
12116 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12117 * of each word. Thus a bitmap with only bit 0 set would be, as
12118 * a string of bytes, 00 00 00 01 00 ...
12119 * To cope with this, we byte-reverse each word of a bitmap if
12120 * we have a big-endian filesystem, that is, if we are *not*
12121 * byte-swapping other word-sized numbers.
12123 #define EXT2_BIG_ENDIAN_BITMAPS
12126 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12127 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12129 __u32 *p = (__u32 *) bmap->bitmap;
12130 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12132 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12133 *p = ext2fs_swab32(*p);
12138 #ifdef ENABLE_SWAPFS
12139 static void swap_filesys(e2fsck_t ctx)
12141 ext2_filsys fs = ctx->fs;
12142 if (!(ctx->options & E2F_OPT_PREEN))
12143 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12147 if (fs->super->s_mnt_count) {
12148 fprintf(stderr, _("%s: the filesystem must be freshly "
12149 "checked using fsck\n"
12150 "and not mounted before trying to "
12151 "byte-swap it.\n"), ctx->device_name);
12152 ctx->flags |= E2F_FLAG_ABORT;
12155 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12156 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12157 EXT2_FLAG_SWAP_BYTES_WRITE);
12158 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12160 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12161 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12164 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12166 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12167 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12168 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12169 EXT2_FLAG_SWAP_BYTES_WRITE);
12171 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12172 e2fsck_read_bitmaps(ctx);
12173 ext2fs_swap_bitmap(fs->inode_map);
12174 ext2fs_swap_bitmap(fs->block_map);
12175 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12177 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12179 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12181 #endif /* ENABLE_SWAPFS */
12186 * util.c --- miscellaneous utilities
12190 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12191 const char *description)
12196 ret = xzalloc(size);
12200 static char *string_copy(const char *str, int len)
12208 ret = xmalloc(len+1);
12209 strncpy(ret, str, len);
12214 #ifndef HAVE_CONIO_H
12215 static int read_a_char(void)
12222 if (e2fsck_global_ctx &&
12223 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12226 r = read(0, &c, 1);
12236 static int ask_yn(const char * string, int def)
12239 const char *defstr;
12240 static const char short_yes[] = "yY";
12241 static const char short_no[] = "nN";
12243 #ifdef HAVE_TERMIOS_H
12244 struct termios termios, tmp;
12246 tcgetattr (0, &termios);
12248 tmp.c_lflag &= ~(ICANON | ECHO);
12249 tmp.c_cc[VMIN] = 1;
12250 tmp.c_cc[VTIME] = 0;
12251 tcsetattr_stdin_TCSANOW(&tmp);
12260 printf("%s%s? ", string, defstr);
12263 if ((c = read_a_char()) == EOF)
12266 #ifdef HAVE_TERMIOS_H
12267 tcsetattr_stdin_TCSANOW(&termios);
12269 if (e2fsck_global_ctx &&
12270 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12272 longjmp(e2fsck_global_ctx->abort_loc, 1);
12274 puts(_("cancelled!\n"));
12277 if (strchr(short_yes, (char) c)) {
12281 else if (strchr(short_no, (char) c)) {
12285 else if ((c == ' ' || c == '\n') && (def != -1))
12292 #ifdef HAVE_TERMIOS_H
12293 tcsetattr_stdin_TCSANOW(&termios);
12298 int ask (e2fsck_t ctx, const char * string, int def)
12300 if (ctx->options & E2F_OPT_NO) {
12301 printf(_("%s? no\n\n"), string);
12304 if (ctx->options & E2F_OPT_YES) {
12305 printf(_("%s? yes\n\n"), string);
12308 if (ctx->options & E2F_OPT_PREEN) {
12309 printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
12312 return ask_yn(string, def);
12315 void e2fsck_read_bitmaps(e2fsck_t ctx)
12317 ext2_filsys fs = ctx->fs;
12320 if (ctx->invalid_bitmaps) {
12321 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12323 bb_error_msg_and_die(0);
12326 ehandler_operation(_("reading inode and block bitmaps"));
12327 retval = ext2fs_read_bitmaps(fs);
12328 ehandler_operation(0);
12330 bb_error_msg(_("while retrying to read bitmaps for %s"),
12332 bb_error_msg_and_die(0);
12336 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12338 ext2_filsys fs = ctx->fs;
12341 if (ext2fs_test_bb_dirty(fs)) {
12342 ehandler_operation(_("writing block bitmaps"));
12343 retval = ext2fs_write_block_bitmap(fs);
12344 ehandler_operation(0);
12346 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12348 bb_error_msg_and_die(0);
12352 if (ext2fs_test_ib_dirty(fs)) {
12353 ehandler_operation(_("writing inode bitmaps"));
12354 retval = ext2fs_write_inode_bitmap(fs);
12355 ehandler_operation(0);
12357 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12359 bb_error_msg_and_die(0);
12364 void preenhalt(e2fsck_t ctx)
12366 ext2_filsys fs = ctx->fs;
12368 if (!(ctx->options & E2F_OPT_PREEN))
12370 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12371 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12374 fs->super->s_state |= EXT2_ERROR_FS;
12375 ext2fs_mark_super_dirty(fs);
12378 exit(EXIT_UNCORRECTED);
12381 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12382 struct ext2_inode * inode, const char *proc)
12386 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12388 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12389 bb_error_msg_and_die(0);
12393 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12394 struct ext2_inode * inode, int bufsize,
12399 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12401 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12402 bb_error_msg_and_die(0);
12406 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12407 struct ext2_inode * inode, const char *proc)
12411 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12413 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12414 bb_error_msg_and_die(0);
12418 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12419 io_manager manager)
12421 struct ext2_super_block *sb;
12422 io_channel io = NULL;
12425 blk_t superblock, ret_sb = 8193;
12427 if (fs && fs->super) {
12428 ret_sb = (fs->super->s_blocks_per_group +
12429 fs->super->s_first_data_block);
12431 ctx->superblock = ret_sb;
12432 ctx->blocksize = fs->blocksize;
12438 if (ctx->blocksize) {
12439 ret_sb = ctx->blocksize * 8;
12440 if (ctx->blocksize == 1024)
12442 ctx->superblock = ret_sb;
12445 ctx->superblock = ret_sb;
12446 ctx->blocksize = 1024;
12449 if (!name || !manager)
12452 if (manager->open(name, 0, &io) != 0)
12455 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12457 sb = (struct ext2_super_block *) buf;
12459 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12460 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
12461 superblock = blocksize*8;
12462 if (blocksize == 1024)
12464 io_channel_set_blksize(io, blocksize);
12465 if (io_channel_read_blk(io, superblock,
12466 -SUPERBLOCK_SIZE, buf))
12469 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12470 ext2fs_swap_super(sb);
12472 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12473 ret_sb = superblock;
12475 ctx->superblock = superblock;
12476 ctx->blocksize = blocksize;
12484 io_channel_close(io);
12485 ext2fs_free_mem(&buf);
12491 * This function runs through the e2fsck passes and calls them all,
12492 * returning restart, abort, or cancel as necessary...
12494 typedef void (*pass_t)(e2fsck_t ctx);
12496 static const pass_t e2fsck_passes[] = {
12497 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12500 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12502 static int e2fsck_run(e2fsck_t ctx)
12505 pass_t e2fsck_pass;
12507 if (setjmp(ctx->abort_loc)) {
12508 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12509 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12511 ctx->flags |= E2F_FLAG_SETJMP_OK;
12513 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12514 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12518 (void) (ctx->progress)(ctx, 0, 0, 0);
12520 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12522 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12523 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12529 * unix.c - The unix-specific code for e2fsck
12533 /* Command line options */
12535 #ifdef ENABLE_SWAPFS
12536 static int normalize_swapfs;
12538 static int cflag; /* check disk */
12539 static int show_version_only;
12540 static int verbose;
12542 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12544 static void show_stats(e2fsck_t ctx)
12546 ext2_filsys fs = ctx->fs;
12547 int inodes, inodes_used, blocks, blocks_used;
12549 int num_files, num_links;
12552 dir_links = 2 * ctx->fs_directory_count - 1;
12553 num_files = ctx->fs_total_count - dir_links;
12554 num_links = ctx->fs_links_count - dir_links;
12555 inodes = fs->super->s_inodes_count;
12556 inodes_used = (fs->super->s_inodes_count -
12557 fs->super->s_free_inodes_count);
12558 blocks = fs->super->s_blocks_count;
12559 blocks_used = (fs->super->s_blocks_count -
12560 fs->super->s_free_blocks_count);
12562 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12563 frag_percent = (frag_percent + 5) / 10;
12566 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12567 ctx->device_name, inodes_used, inodes,
12568 frag_percent / 10, frag_percent % 10,
12569 blocks_used, blocks);
12572 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12573 100 * inodes_used / inodes);
12574 printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12575 P_E2("", "s", ctx->fs_fragmented),
12576 frag_percent / 10, frag_percent % 10);
12577 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12578 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12579 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12580 (int) ((long long) 100 * blocks_used / blocks));
12581 printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12582 printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12583 printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12584 printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12585 printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12586 printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12587 printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12588 printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12589 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12590 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12591 printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12594 static void check_mount(e2fsck_t ctx)
12599 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12600 &ctx->mount_flags);
12602 bb_error_msg(_("while determining whether %s is mounted"),
12603 ctx->filesystem_name);
12608 * If the filesystem isn't mounted, or it's the root filesystem
12609 * and it's mounted read-only, then everything's fine.
12611 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12612 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12613 (ctx->mount_flags & EXT2_MF_READONLY)))
12616 if (ctx->options & E2F_OPT_READONLY) {
12617 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
12621 printf(_("%s is mounted. "), ctx->filesystem_name);
12622 if (!ctx->interactive)
12623 bb_error_msg_and_die(_("can't continue, aborting"));
12624 printf(_("\n\n\007\007\007\007WARNING!!! "
12625 "Running e2fsck on a mounted filesystem may cause\n"
12626 "SEVERE filesystem damage.\007\007\007\n\n"));
12627 cont = ask_yn(_("Do you really want to continue"), -1);
12629 printf(_("check aborted.\n"));
12634 static int is_on_batt(void)
12638 char tmp[80], tmp2[80], fname[80];
12639 unsigned int acflag;
12642 f = fopen_for_read("/proc/apm");
12644 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12647 return (acflag != 1);
12649 d = opendir("/proc/acpi/ac_adapter");
12651 while ((de=readdir(d)) != NULL) {
12652 if (!strncmp(".", de->d_name, 1))
12654 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12656 f = fopen_for_read(fname);
12659 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12662 if (strncmp(tmp, "off-line", 8) == 0) {
12673 * This routine checks to see if a filesystem can be skipped; if so,
12674 * it will exit with EXIT_OK. Under some conditions it will print a
12675 * message explaining why a check is being forced.
12677 static void check_if_skip(e2fsck_t ctx)
12679 ext2_filsys fs = ctx->fs;
12680 const char *reason = NULL;
12681 unsigned int reason_arg = 0;
12683 int batt = is_on_batt();
12684 time_t now = time(NULL);
12686 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12689 if ((fs->super->s_state & EXT2_ERROR_FS) ||
12690 !ext2fs_test_valid(fs))
12691 reason = _(" contains a file system with errors");
12692 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12693 reason = _(" was not cleanly unmounted");
12694 else if ((fs->super->s_max_mnt_count > 0) &&
12695 (fs->super->s_mnt_count >=
12696 (unsigned) fs->super->s_max_mnt_count)) {
12697 reason = _(" has been mounted %u times without being checked");
12698 reason_arg = fs->super->s_mnt_count;
12699 if (batt && (fs->super->s_mnt_count <
12700 (unsigned) fs->super->s_max_mnt_count*2))
12702 } else if (fs->super->s_checkinterval &&
12703 ((now - fs->super->s_lastcheck) >=
12704 fs->super->s_checkinterval)) {
12705 reason = _(" has gone %u days without being checked");
12706 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12707 if (batt && ((now - fs->super->s_lastcheck) <
12708 fs->super->s_checkinterval*2))
12712 fputs(ctx->device_name, stdout);
12713 printf(reason, reason_arg);
12714 fputs(_(", check forced.\n"), stdout);
12717 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12718 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12719 fs->super->s_inodes_count,
12720 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12721 fs->super->s_blocks_count);
12722 next_check = 100000;
12723 if (fs->super->s_max_mnt_count > 0) {
12724 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12725 if (next_check <= 0)
12728 if (fs->super->s_checkinterval &&
12729 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12731 if (next_check <= 5) {
12732 if (next_check == 1)
12733 fputs(_(" (check after next mount)"), stdout);
12735 printf(_(" (check in %ld mounts)"), next_check);
12740 e2fsck_free_context(ctx);
12745 * For completion notice
12747 struct percent_tbl {
12751 static const struct percent_tbl e2fsck_tbl = {
12752 5, { 0, 70, 90, 92, 95, 100 }
12755 static char bar[128], spaces[128];
12757 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12764 if (pass > tbl->max_pass || max == 0)
12766 percent = ((float) curr) / ((float) max);
12767 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12768 + tbl->table[pass-1]);
12771 void e2fsck_clear_progbar(e2fsck_t ctx)
12773 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12776 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12779 ctx->flags &= ~E2F_FLAG_PROG_BAR;
12782 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12783 unsigned int dpynum)
12785 static const char spinner[] = "\\|/-";
12792 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12796 * Calculate the new progress position. If the
12797 * percentage hasn't changed, then we skip out right
12800 fixed_percent = (int) ((10 * percent) + 0.5);
12801 if (ctx->progress_last_percent == fixed_percent)
12803 ctx->progress_last_percent = fixed_percent;
12806 * If we've already updated the spinner once within
12807 * the last 1/8th of a second, no point doing it
12810 gettimeofday(&tv, NULL);
12811 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12812 if ((tick == ctx->progress_last_time) &&
12813 (fixed_percent != 0) && (fixed_percent != 1000))
12815 ctx->progress_last_time = tick;
12818 * Advance the spinner, and note that the progress bar
12819 * will be on the screen
12821 ctx->progress_pos = (ctx->progress_pos+1) & 3;
12822 ctx->flags |= E2F_FLAG_PROG_BAR;
12824 dpywidth = 66 - strlen(label);
12825 dpywidth = 8 * (dpywidth / 8);
12829 i = ((percent * dpywidth) + 50) / 100;
12830 printf("%s%s: |%s%s", ctx->start_meta, label,
12831 bar + (sizeof(bar) - (i+1)),
12832 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12833 if (fixed_percent == 1000)
12836 bb_putchar(spinner[ctx->progress_pos & 3]);
12837 printf(" %4.1f%% ", percent);
12839 printf("%u\r", dpynum);
12841 fputs(" \r", stdout);
12842 fputs(ctx->stop_meta, stdout);
12844 if (fixed_percent == 1000)
12845 e2fsck_clear_progbar(ctx);
12851 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12852 unsigned long cur, unsigned long max)
12860 if (ctx->progress_fd) {
12861 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12862 xwrite_str(ctx->progress_fd, buf);
12864 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12865 e2fsck_simple_progress(ctx, ctx->device_name,
12871 static void reserve_stdio_fds(void)
12876 fd = open(bb_dev_null, O_RDWR);
12880 fprintf(stderr, _("ERROR: Cannot open "
12881 "/dev/null (%s)\n"),
12889 static void signal_progress_on(int sig FSCK_ATTR((unused)))
12891 e2fsck_t ctx = e2fsck_global_ctx;
12896 ctx->progress = e2fsck_update_progress;
12897 ctx->progress_fd = 0;
12900 static void signal_progress_off(int sig FSCK_ATTR((unused)))
12902 e2fsck_t ctx = e2fsck_global_ctx;
12907 e2fsck_clear_progbar(ctx);
12911 static void signal_cancel(int sig FSCK_ATTR((unused)))
12913 e2fsck_t ctx = e2fsck_global_ctx;
12916 exit(FSCK_CANCELED);
12918 ctx->flags |= E2F_FLAG_CANCEL;
12921 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12923 char *buf, *token, *next, *p, *arg;
12925 int extended_usage = 0;
12927 buf = string_copy(opts, 0);
12928 for (token = buf; token && *token; token = next) {
12929 p = strchr(token, ',');
12935 arg = strchr(token, '=');
12940 if (strcmp(token, "ea_ver") == 0) {
12945 ea_ver = strtoul(arg, &p, 0);
12947 ((ea_ver != 1) && (ea_ver != 2))) {
12949 _("Invalid EA version.\n"));
12953 ctx->ext_attr_ver = ea_ver;
12955 fprintf(stderr, _("Unknown extended option: %s\n"),
12960 if (extended_usage) {
12961 bb_error_msg_and_die(
12962 "Extended options are separated by commas, "
12963 "and may take an argument which\n"
12964 "is set off by an equals ('=') sign. "
12965 "Valid extended options are:\n"
12966 "\tea_ver=<ea_version (1 or 2)>\n\n");
12971 static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx)
12977 struct sigaction sa;
12978 char *extended_opts = NULL;
12980 retval = e2fsck_allocate_context(&ctx);
12986 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
12987 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
12988 if (isatty(0) && isatty(1)) {
12989 ctx->interactive = 1;
12991 ctx->start_meta[0] = '\001';
12992 ctx->stop_meta[0] = '\002';
12994 memset(bar, '=', sizeof(bar)-1);
12995 memset(spaces, ' ', sizeof(spaces)-1);
12996 blkid_get_cache(&ctx->blkid, NULL);
12999 ctx->program_name = *argv;
13001 ctx->program_name = "e2fsck";
13002 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13005 ctx->progress = e2fsck_update_progress;
13006 ctx->progress_fd = atoi(optarg);
13007 if (!ctx->progress_fd)
13009 /* Validate the file descriptor to avoid disasters */
13010 fd = dup(ctx->progress_fd);
13013 _("Error validating file descriptor %d: %s\n"),
13015 error_message(errno));
13016 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13021 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13024 extended_opts = optarg;
13028 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13030 bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
13032 ctx->options |= E2F_OPT_PREEN;
13035 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13037 ctx->options |= E2F_OPT_NO;
13040 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13042 ctx->options |= E2F_OPT_YES;
13045 /* FIXME - This needs to go away in a future path - will change binary */
13046 fprintf(stderr, _("The -t option is not "
13047 "supported on this version of e2fsck.\n"));
13051 ctx->options |= E2F_OPT_WRITECHECK;
13052 ctx->options |= E2F_OPT_CHECKBLOCKS;
13055 /* What we do by default, anyway! */
13058 ctx->use_superblock = atoi(optarg);
13059 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13062 ctx->blocksize = atoi(optarg);
13065 ctx->inode_buffer_blocks = atoi(optarg);
13068 ctx->journal_name = string_copy(optarg, 0);
13071 ctx->process_inode_size = atoi(optarg);
13074 ctx->options |= E2F_OPT_DEBUG;
13077 ctx->options |= E2F_OPT_FORCE;
13086 show_version_only = 1;
13089 ctx->device_name = optarg;
13091 #ifdef ENABLE_SWAPFS
13093 normalize_swapfs = 1;
13100 fprintf(stderr, _("Byte-swapping filesystems "
13101 "not compiled in this version "
13108 if (show_version_only)
13110 if (optind != argc - 1)
13112 if ((ctx->options & E2F_OPT_NO) &&
13113 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13114 ctx->options |= E2F_OPT_READONLY;
13115 ctx->io_options = strchr(argv[optind], '?');
13116 if (ctx->io_options)
13117 *ctx->io_options++ = 0;
13118 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13119 if (!ctx->filesystem_name) {
13120 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13121 bb_error_msg_and_die(0);
13124 parse_extended_opts(ctx, extended_opts);
13127 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13129 bb_error_msg(_("while opening %s for flushing"),
13130 ctx->filesystem_name);
13131 bb_error_msg_and_die(0);
13133 if ((retval = ext2fs_sync_device(fd, 1))) {
13134 bb_error_msg(_("while trying to flush %s"),
13135 ctx->filesystem_name);
13136 bb_error_msg_and_die(0);
13140 #ifdef ENABLE_SWAPFS
13141 if (swapfs && cflag) {
13142 fprintf(stderr, _("Incompatible options not "
13143 "allowed when byte-swapping.\n"));
13148 * Set up signal action
13150 memset(&sa, 0, sizeof(struct sigaction));
13151 sa.sa_handler = signal_cancel;
13152 sigaction(SIGINT, &sa, 0);
13153 sigaction(SIGTERM, &sa, 0);
13155 sa.sa_flags = SA_RESTART;
13157 e2fsck_global_ctx = ctx;
13158 sa.sa_handler = signal_progress_on;
13159 sigaction(SIGUSR1, &sa, 0);
13160 sa.sa_handler = signal_progress_off;
13161 sigaction(SIGUSR2, &sa, 0);
13163 /* Update our PATH to include /sbin if we need to run badblocks */
13165 e2fs_set_sbin_path();
13169 static const char my_ver_string[] = E2FSPROGS_VERSION;
13170 static const char my_ver_date[] = E2FSPROGS_DATE;
13172 int e2fsck_main (int argc, char **argv);
13173 int e2fsck_main (int argc, char **argv)
13176 int exit_value = EXIT_OK;
13177 ext2_filsys fs = 0;
13179 struct ext2_super_block *sb;
13180 const char *lib_ver_date;
13181 int my_ver, lib_ver;
13183 struct problem_context pctx;
13184 int flags, run_result;
13186 clear_problem_context(&pctx);
13188 my_ver = ext2fs_parse_version_string(my_ver_string);
13189 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13190 if (my_ver > lib_ver) {
13191 fprintf( stderr, _("Error: ext2fs library version "
13192 "out of date!\n"));
13193 show_version_only++;
13196 retval = PRS(argc, argv, &ctx);
13198 bb_error_msg(_("while trying to initialize program"));
13201 reserve_stdio_fds();
13203 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13204 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13207 if (show_version_only) {
13208 fprintf(stderr, _("\tUsing %s, %s\n"),
13209 error_message(EXT2_ET_BASE), lib_ver_date);
13215 if (!(ctx->options & E2F_OPT_PREEN) &&
13216 !(ctx->options & E2F_OPT_NO) &&
13217 !(ctx->options & E2F_OPT_YES)) {
13218 if (!ctx->interactive)
13219 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13221 ctx->superblock = ctx->use_superblock;
13223 #ifdef CONFIG_TESTIO_DEBUG
13224 io_ptr = test_io_manager;
13225 test_io_backing_manager = unix_io_manager;
13227 io_ptr = unix_io_manager;
13230 if ((ctx->options & E2F_OPT_READONLY) == 0)
13231 flags |= EXT2_FLAG_RW;
13233 if (ctx->superblock && ctx->blocksize) {
13234 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13235 flags, ctx->superblock, ctx->blocksize,
13237 } else if (ctx->superblock) {
13239 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13240 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13241 retval = ext2fs_open2(ctx->filesystem_name,
13242 ctx->io_options, flags,
13243 ctx->superblock, blocksize,
13249 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13250 flags, 0, 0, io_ptr, &fs);
13251 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13252 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13253 ((retval == EXT2_ET_BAD_MAGIC) ||
13254 ((retval == 0) && ext2fs_check_desc(fs)))) {
13255 if (!fs || (fs->group_desc_count > 1)) {
13256 printf(_("%s trying backup blocks...\n"),
13257 retval ? _("Couldn't find ext2 superblock,") :
13258 _("Group descriptors look bad..."));
13259 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13266 bb_error_msg(_("while trying to open %s"),
13267 ctx->filesystem_name);
13268 if (retval == EXT2_ET_REV_TOO_HIGH) {
13269 printf(_("The filesystem revision is apparently "
13270 "too high for this version of e2fsck.\n"
13271 "(Or the filesystem superblock "
13272 "is corrupt)\n\n"));
13273 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13274 } else if (retval == EXT2_ET_SHORT_READ)
13275 printf(_("Could this be a zero-length partition?\n"));
13276 else if ((retval == EPERM) || (retval == EACCES))
13277 printf(_("You must have %s access to the "
13278 "filesystem or be root\n"),
13279 (ctx->options & E2F_OPT_READONLY) ?
13281 else if (retval == ENXIO)
13282 printf(_("Possibly non-existent or swap device?\n"));
13284 else if (retval == EROFS)
13285 printf(_("Disk write-protected; use the -n option "
13286 "to do a read-only\n"
13287 "check of the device.\n"));
13290 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13291 bb_error_msg_and_die(0);
13294 fs->priv_data = ctx;
13296 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13297 bb_error_msg(_("while trying to open %s"),
13298 ctx->filesystem_name);
13300 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13304 * Set the device name, which is used whenever we print error
13305 * or informational messages to the user.
13307 if (ctx->device_name == 0 &&
13308 (sb->s_volume_name[0] != 0)) {
13309 ctx->device_name = string_copy(sb->s_volume_name,
13310 sizeof(sb->s_volume_name));
13312 if (ctx->device_name == 0)
13313 ctx->device_name = ctx->filesystem_name;
13316 * Make sure the ext3 superblock fields are consistent.
13318 retval = e2fsck_check_ext3_journal(ctx);
13320 bb_error_msg(_("while checking ext3 journal for %s"),
13322 bb_error_msg_and_die(0);
13326 * Check to see if we need to do ext3-style recovery. If so,
13327 * do it, and then restart the fsck.
13329 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13330 if (ctx->options & E2F_OPT_READONLY) {
13331 printf(_("Warning: skipping journal recovery "
13332 "because doing a read-only filesystem "
13334 io_channel_flush(ctx->fs->io);
13336 if (ctx->flags & E2F_FLAG_RESTARTED) {
13338 * Whoops, we attempted to run the
13339 * journal twice. This should never
13340 * happen, unless the hardware or
13341 * device driver is being bogus.
13343 bb_error_msg(_("can't set superblock flags on %s"), ctx->device_name);
13344 bb_error_msg_and_die(0);
13346 retval = e2fsck_run_ext3_journal(ctx);
13348 bb_error_msg(_("while recovering ext3 journal of %s"),
13350 bb_error_msg_and_die(0);
13352 ext2fs_close(ctx->fs);
13354 ctx->flags |= E2F_FLAG_RESTARTED;
13360 * Check for compatibility with the feature sets. We need to
13361 * be more stringent than ext2fs_open().
13363 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13364 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13365 bb_error_msg("(%s)", ctx->device_name);
13368 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13369 bb_error_msg("(%s)", ctx->device_name);
13372 #ifdef ENABLE_COMPRESSION
13373 /* FIXME - do we support this at all? */
13374 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13375 bb_error_msg(_("warning: compression support is experimental"));
13377 #ifndef ENABLE_HTREE
13378 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13379 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13380 "but filesystem %s has HTREE directories."),
13387 * If the user specified a specific superblock, presumably the
13388 * master superblock has been trashed. So we mark the
13389 * superblock as dirty, so it can be written out.
13391 if (ctx->superblock &&
13392 !(ctx->options & E2F_OPT_READONLY))
13393 ext2fs_mark_super_dirty(fs);
13396 * We only update the master superblock because (a) paranoia;
13397 * we don't want to corrupt the backup superblocks, and (b) we
13398 * don't need to update the mount count and last checked
13399 * fields in the backup superblock (the kernel doesn't
13400 * update the backup superblocks anyway).
13402 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13404 ehandler_init(fs->io);
13406 if (ctx->superblock)
13407 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13408 ext2fs_mark_valid(fs);
13409 check_super_block(ctx);
13410 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13411 bb_error_msg_and_die(0);
13412 check_if_skip(ctx);
13413 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13414 bb_error_msg_and_die(0);
13415 #ifdef ENABLE_SWAPFS
13417 #ifdef WORDS_BIGENDIAN
13418 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13420 #define NATIVE_FLAG 0
13424 if (normalize_swapfs) {
13425 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13426 fprintf(stderr, _("%s: Filesystem byte order "
13427 "already normalized.\n"), ctx->device_name);
13428 bb_error_msg_and_die(0);
13433 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13434 bb_error_msg_and_die(0);
13439 * Mark the system as valid, 'til proven otherwise
13441 ext2fs_mark_valid(fs);
13443 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13445 bb_error_msg(_("while reading bad blocks inode"));
13447 printf(_("This doesn't bode well,"
13448 " but we'll try to go on...\n"));
13451 run_result = e2fsck_run(ctx);
13452 e2fsck_clear_progbar(ctx);
13453 if (run_result == E2F_FLAG_RESTART) {
13454 printf(_("Restarting e2fsck from the beginning...\n"));
13455 retval = e2fsck_reset_context(ctx);
13457 bb_error_msg(_("while resetting context"));
13458 bb_error_msg_and_die(0);
13463 if (run_result & E2F_FLAG_CANCEL) {
13464 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13465 ctx->device_name : ctx->filesystem_name);
13466 exit_value |= FSCK_CANCELED;
13468 if (run_result & E2F_FLAG_ABORT)
13469 bb_error_msg_and_die(_("aborted"));
13472 if (ext2fs_test_changed(fs)) {
13473 exit_value |= EXIT_NONDESTRUCT;
13474 if (!(ctx->options & E2F_OPT_PREEN))
13475 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13477 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13478 printf(_("%s: ***** REBOOT LINUX *****\n"),
13480 exit_value |= EXIT_DESTRUCT;
13483 if (!ext2fs_test_valid(fs)) {
13484 printf(_("\n%s: ********** WARNING: Filesystem still has "
13485 "errors **********\n\n"), ctx->device_name);
13486 exit_value |= EXIT_UNCORRECTED;
13487 exit_value &= ~EXIT_NONDESTRUCT;
13489 if (exit_value & FSCK_CANCELED)
13490 exit_value &= ~EXIT_NONDESTRUCT;
13493 if (!(ctx->options & E2F_OPT_READONLY)) {
13494 if (ext2fs_test_valid(fs)) {
13495 if (!(sb->s_state & EXT2_VALID_FS))
13496 exit_value |= EXIT_NONDESTRUCT;
13497 sb->s_state = EXT2_VALID_FS;
13499 sb->s_state &= ~EXT2_VALID_FS;
13500 sb->s_mnt_count = 0;
13501 sb->s_lastcheck = time(NULL);
13502 ext2fs_mark_super_dirty(fs);
13506 e2fsck_write_bitmaps(ctx);
13510 free(ctx->filesystem_name);
13511 free(ctx->journal_name);
13512 e2fsck_free_context(ctx);