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 = malloc(sizeof(*new_cache));
219 new_cache->object_length = len;
223 static void do_cache_destroy(kmem_cache_t *cache)
230 * Dictionary Abstract Data Type
235 * These macros provide short convenient names for structure members,
236 * which are embellished with dict_ prefixes so that they are
237 * properly confined to the documented namespace. It's legal for a
238 * program which uses dict to define, for instance, a macro called ``parent''.
239 * Such a macro would interfere with the dnode_t struct definition.
240 * In general, highly portable and reusable C modules which expose their
241 * structures need to confine structure member names to well-defined spaces.
242 * The resulting identifiers aren't necessarily convenient to use, nor
243 * readable, in the implementation, however!
246 #define left dict_left
247 #define right dict_right
248 #define parent dict_parent
249 #define color dict_color
251 #define data dict_data
253 #define nilnode dict_nilnode
254 #define maxcount dict_maxcount
255 #define compare dict_compare
256 #define dupes dict_dupes
258 #define dict_root(D) ((D)->nilnode.left)
259 #define dict_nil(D) (&(D)->nilnode)
261 static void dnode_free(dnode_t *node);
264 * Perform a ``left rotation'' adjustment on the tree. The given node P and
265 * its right child C are rearranged so that the P instead becomes the left
266 * child of C. The left subtree of C is inherited as the new right subtree
267 * for P. The ordering of the keys within the tree is thus preserved.
270 static void rotate_left(dnode_t *upper)
272 dnode_t *lower, *lowleft, *upparent;
274 lower = upper->right;
275 upper->right = lowleft = lower->left;
276 lowleft->parent = upper;
278 lower->parent = upparent = upper->parent;
280 /* don't need to check for root node here because root->parent is
281 the sentinel nil node, and root->parent->left points back to root */
283 if (upper == upparent->left) {
284 upparent->left = lower;
286 assert (upper == upparent->right);
287 upparent->right = lower;
291 upper->parent = lower;
295 * This operation is the ``mirror'' image of rotate_left. It is
296 * the same procedure, but with left and right interchanged.
299 static void rotate_right(dnode_t *upper)
301 dnode_t *lower, *lowright, *upparent;
304 upper->left = lowright = lower->right;
305 lowright->parent = upper;
307 lower->parent = upparent = upper->parent;
309 if (upper == upparent->right) {
310 upparent->right = lower;
312 assert (upper == upparent->left);
313 upparent->left = lower;
316 lower->right = upper;
317 upper->parent = lower;
321 * Do a postorder traversal of the tree rooted at the specified
322 * node and free everything under it. Used by dict_free().
325 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
329 free_nodes(dict, node->left, nil);
330 free_nodes(dict, node->right, nil);
331 dict->dict_freenode(node);
335 * Verify that the tree contains the given node. This is done by
336 * traversing all of the nodes and comparing their pointers to the
337 * given pointer. Returns 1 if the node is found, otherwise
338 * returns zero. It is intended for debugging purposes.
341 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
345 || verify_dict_has_node(nil, root->left, node)
346 || verify_dict_has_node(nil, root->right, node);
353 * Select a different set of node allocator routines.
356 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
358 assert (dict_count(dict) == 0);
359 dict->dict_freenode = fr;
363 * Free all the nodes in the dictionary by using the dictionary's
364 * installed free routine. The dictionary is emptied.
367 static void dict_free_nodes(dict_t *dict)
369 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
370 free_nodes(dict, root, nil);
371 dict->dict_nodecount = 0;
372 dict->nilnode.left = &dict->nilnode;
373 dict->nilnode.right = &dict->nilnode;
377 * Initialize a user-supplied dictionary object.
380 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
382 dict->compare = comp;
383 dict->dict_freenode = dnode_free;
384 dict->dict_nodecount = 0;
385 dict->maxcount = maxcount;
386 dict->nilnode.left = &dict->nilnode;
387 dict->nilnode.right = &dict->nilnode;
388 dict->nilnode.parent = &dict->nilnode;
389 dict->nilnode.color = dnode_black;
395 * Locate a node in the dictionary having the given key.
396 * If the node is not found, a null a pointer is returned (rather than
397 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
398 * located node is returned.
401 static dnode_t *dict_lookup(dict_t *dict, const void *key)
403 dnode_t *root = dict_root(dict);
404 dnode_t *nil = dict_nil(dict);
408 /* simple binary search adapted for trees that contain duplicate keys */
410 while (root != nil) {
411 result = dict->compare(key, root->key);
417 if (!dict->dupes) { /* no duplicates, return match */
419 } else { /* could be dupes, find leftmost one */
423 while (root != nil && dict->compare(key, root->key))
425 } while (root != nil);
435 * Insert a node into the dictionary. The node should have been
436 * initialized with a data field. All other fields are ignored.
437 * The behavior is undefined if the user attempts to insert into
438 * a dictionary that is already full (for which the dict_isfull()
439 * function returns true).
442 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
444 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
445 dnode_t *parent = nil, *uncle, *grandpa;
450 /* basic binary tree insert */
452 while (where != nil) {
454 result = dict->compare(key, where->key);
455 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
456 assert (dict->dupes || result != 0);
460 where = where->right;
463 assert (where == nil);
468 parent->right = node;
470 node->parent = parent;
474 dict->dict_nodecount++;
476 /* red black adjustments */
478 node->color = dnode_red;
480 while (parent->color == dnode_red) {
481 grandpa = parent->parent;
482 if (parent == grandpa->left) {
483 uncle = grandpa->right;
484 if (uncle->color == dnode_red) { /* red parent, red uncle */
485 parent->color = dnode_black;
486 uncle->color = dnode_black;
487 grandpa->color = dnode_red;
489 parent = grandpa->parent;
490 } else { /* red parent, black uncle */
491 if (node == parent->right) {
494 assert (grandpa == parent->parent);
495 /* rotation between parent and child preserves grandpa */
497 parent->color = dnode_black;
498 grandpa->color = dnode_red;
499 rotate_right(grandpa);
502 } else { /* symmetric cases: parent == parent->parent->right */
503 uncle = grandpa->left;
504 if (uncle->color == dnode_red) {
505 parent->color = dnode_black;
506 uncle->color = dnode_black;
507 grandpa->color = dnode_red;
509 parent = grandpa->parent;
511 if (node == parent->left) {
512 rotate_right(parent);
514 assert (grandpa == parent->parent);
516 parent->color = dnode_black;
517 grandpa->color = dnode_red;
518 rotate_left(grandpa);
524 dict_root(dict)->color = dnode_black;
529 * Allocate a node using the dictionary's allocator routine, give it
533 static dnode_t *dnode_init(dnode_t *dnode, void *data)
536 dnode->parent = NULL;
542 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
544 dnode_t *node = malloc(sizeof(dnode_t));
547 dnode_init(node, data);
548 dict_insert(dict, node, key);
555 * Return the node with the lowest (leftmost) key. If the dictionary is empty
556 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
559 static dnode_t *dict_first(dict_t *dict)
561 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
564 while ((left = root->left) != nil)
567 return (root == nil) ? NULL : root;
571 * Return the given node's successor node---the node which has the
572 * next key in the the left to right ordering. If the node has
573 * no successor, a null pointer is returned rather than a pointer to
577 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
579 dnode_t *nil = dict_nil(dict), *parent, *left;
581 if (curr->right != nil) {
583 while ((left = curr->left) != nil)
588 parent = curr->parent;
590 while (parent != nil && curr == parent->right) {
592 parent = curr->parent;
595 return (parent == nil) ? NULL : parent;
599 static void dnode_free(dnode_t *node)
619 * dirinfo.c --- maintains the directory information table for e2fsck.
623 * This subroutine is called during pass1 to create a directory info
624 * entry. During pass1, the passed-in parent is 0; it will get filled
627 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
629 struct dir_info *dir;
633 unsigned long old_size;
635 if (!ctx->dir_info) {
636 ctx->dir_info_count = 0;
637 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
639 num_dirs = 1024; /* Guess */
640 ctx->dir_info_size = num_dirs + 10;
641 ctx->dir_info = (struct dir_info *)
642 e2fsck_allocate_memory(ctx, ctx->dir_info_size
643 * sizeof (struct dir_info),
647 if (ctx->dir_info_count >= ctx->dir_info_size) {
648 old_size = ctx->dir_info_size * sizeof(struct dir_info);
649 ctx->dir_info_size += 10;
650 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
651 sizeof(struct dir_info),
654 ctx->dir_info_size -= 10;
660 * Normally, add_dir_info is called with each inode in
661 * sequential order; but once in a while (like when pass 3
662 * needs to recreate the root directory or lost+found
663 * directory) it is called out of order. In those cases, we
664 * need to move the dir_info entries down to make room, since
665 * the dir_info array needs to be sorted by inode number for
666 * get_dir_info()'s sake.
668 if (ctx->dir_info_count &&
669 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
670 for (i = ctx->dir_info_count-1; i > 0; i--)
671 if (ctx->dir_info[i-1].ino < ino)
673 dir = &ctx->dir_info[i];
675 for (j = ctx->dir_info_count++; j > i; j--)
676 ctx->dir_info[j] = ctx->dir_info[j-1];
678 dir = &ctx->dir_info[ctx->dir_info_count++];
681 dir->dotdot = parent;
682 dir->parent = parent;
686 * get_dir_info() --- given an inode number, try to find the directory
687 * information entry for it.
689 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
694 high = ctx->dir_info_count-1;
697 if (ino == ctx->dir_info[low].ino)
698 return &ctx->dir_info[low];
699 if (ino == ctx->dir_info[high].ino)
700 return &ctx->dir_info[high];
704 if (mid == low || mid == high)
706 if (ino == ctx->dir_info[mid].ino)
707 return &ctx->dir_info[mid];
708 if (ino < ctx->dir_info[mid].ino)
717 * Free the dir_info structure when it isn't needed any more.
719 static void e2fsck_free_dir_info(e2fsck_t ctx)
721 ext2fs_free_mem(&ctx->dir_info);
722 ctx->dir_info_size = 0;
723 ctx->dir_info_count = 0;
727 * Return the count of number of directories in the dir_info structure
729 static int e2fsck_get_num_dirinfo(e2fsck_t ctx)
731 return ctx->dir_info_count;
735 * A simple interator function
737 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
739 if (*control >= ctx->dir_info_count)
742 return ctx->dir_info + (*control)++;
746 * dirinfo.c --- maintains the directory information table for e2fsck.
753 * This subroutine is called during pass1 to create a directory info
754 * entry. During pass1, the passed-in parent is 0; it will get filled
757 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
759 struct dx_dir_info *dir;
762 unsigned long old_size;
764 if (!ctx->dx_dir_info) {
765 ctx->dx_dir_info_count = 0;
766 ctx->dx_dir_info_size = 100; /* Guess */
767 ctx->dx_dir_info = (struct dx_dir_info *)
768 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
769 * sizeof (struct dx_dir_info),
773 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
774 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
775 ctx->dx_dir_info_size += 10;
776 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
777 sizeof(struct dx_dir_info),
780 ctx->dx_dir_info_size -= 10;
786 * Normally, add_dx_dir_info is called with each inode in
787 * sequential order; but once in a while (like when pass 3
788 * needs to recreate the root directory or lost+found
789 * directory) it is called out of order. In those cases, we
790 * need to move the dx_dir_info entries down to make room, since
791 * the dx_dir_info array needs to be sorted by inode number for
792 * get_dx_dir_info()'s sake.
794 if (ctx->dx_dir_info_count &&
795 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
796 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
797 if (ctx->dx_dir_info[i-1].ino < ino)
799 dir = &ctx->dx_dir_info[i];
801 for (j = ctx->dx_dir_info_count++; j > i; j--)
802 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
804 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
807 dir->numblocks = num_blocks;
808 dir->hashversion = 0;
809 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
810 * sizeof (struct dx_dirblock_info),
811 "dx_block info array");
816 * get_dx_dir_info() --- given an inode number, try to find the directory
817 * information entry for it.
819 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
824 high = ctx->dx_dir_info_count-1;
825 if (!ctx->dx_dir_info)
827 if (ino == ctx->dx_dir_info[low].ino)
828 return &ctx->dx_dir_info[low];
829 if (ino == ctx->dx_dir_info[high].ino)
830 return &ctx->dx_dir_info[high];
834 if (mid == low || mid == high)
836 if (ino == ctx->dx_dir_info[mid].ino)
837 return &ctx->dx_dir_info[mid];
838 if (ino < ctx->dx_dir_info[mid].ino)
847 * Free the dx_dir_info structure when it isn't needed any more.
849 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
852 struct dx_dir_info *dir;
854 if (ctx->dx_dir_info) {
855 dir = ctx->dx_dir_info;
856 for (i=0; i < ctx->dx_dir_info_count; i++) {
857 ext2fs_free_mem(&dir->dx_block);
859 ext2fs_free_mem(&ctx->dx_dir_info);
861 ctx->dx_dir_info_size = 0;
862 ctx->dx_dir_info_count = 0;
866 * A simple interator function
868 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
870 if (*control >= ctx->dx_dir_info_count)
873 return ctx->dx_dir_info + (*control)++;
876 #endif /* ENABLE_HTREE */
878 * e2fsck.c - a consistency checker for the new extended file system.
883 * This function allocates an e2fsck context
885 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
890 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
894 memset(context, 0, sizeof(struct e2fsck_struct));
896 context->process_inode_size = 256;
897 context->ext_attr_ver = 2;
903 struct ea_refcount_el {
912 struct ea_refcount_el *list;
915 static void ea_refcount_free(ext2_refcount_t refcount)
920 ext2fs_free_mem(&refcount->list);
921 ext2fs_free_mem(&refcount);
925 * This function resets an e2fsck context; it is called when e2fsck
926 * needs to be restarted.
928 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
931 ctx->lost_and_found = 0;
932 ctx->bad_lost_and_found = 0;
933 ext2fs_free_inode_bitmap(ctx->inode_used_map);
934 ctx->inode_used_map = 0;
935 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
936 ctx->inode_dir_map = 0;
937 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
938 ctx->inode_reg_map = 0;
939 ext2fs_free_block_bitmap(ctx->block_found_map);
940 ctx->block_found_map = 0;
941 ext2fs_free_icount(ctx->inode_link_info);
942 ctx->inode_link_info = 0;
943 if (ctx->journal_io) {
944 if (ctx->fs && ctx->fs->io != ctx->journal_io)
945 io_channel_close(ctx->journal_io);
949 ext2fs_free_dblist(ctx->fs->dblist);
952 e2fsck_free_dir_info(ctx);
954 e2fsck_free_dx_dir_info(ctx);
956 ea_refcount_free(ctx->refcount);
958 ea_refcount_free(ctx->refcount_extra);
959 ctx->refcount_extra = 0;
960 ext2fs_free_block_bitmap(ctx->block_dup_map);
961 ctx->block_dup_map = 0;
962 ext2fs_free_block_bitmap(ctx->block_ea_map);
963 ctx->block_ea_map = 0;
964 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
965 ctx->inode_bad_map = 0;
966 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
967 ctx->inode_imagic_map = 0;
968 ext2fs_u32_list_free(ctx->dirs_to_hash);
969 ctx->dirs_to_hash = 0;
972 * Clear the array of invalid meta-data flags
974 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
975 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
976 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
978 /* Clear statistic counters */
979 ctx->fs_directory_count = 0;
980 ctx->fs_regular_count = 0;
981 ctx->fs_blockdev_count = 0;
982 ctx->fs_chardev_count = 0;
983 ctx->fs_links_count = 0;
984 ctx->fs_symlinks_count = 0;
985 ctx->fs_fast_symlinks_count = 0;
986 ctx->fs_fifo_count = 0;
987 ctx->fs_total_count = 0;
988 ctx->fs_sockets_count = 0;
989 ctx->fs_ind_count = 0;
990 ctx->fs_dind_count = 0;
991 ctx->fs_tind_count = 0;
992 ctx->fs_fragmented = 0;
993 ctx->large_files = 0;
995 /* Reset the superblock to the user's requested value */
996 ctx->superblock = ctx->use_superblock;
1001 static void e2fsck_free_context(e2fsck_t ctx)
1006 e2fsck_reset_context(ctx);
1008 blkid_put_cache(ctx->blkid);
1010 ext2fs_free_mem(&ctx);
1018 * The strategy we use for keeping track of EA refcounts is as
1019 * follows. We keep a sorted array of first EA blocks and its
1020 * reference counts. Once the refcount has dropped to zero, it is
1021 * removed from the array to save memory space. Once the EA block is
1022 * checked, its bit is set in the block_ea_map bitmap.
1026 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1028 ext2_refcount_t refcount;
1032 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1035 memset(refcount, 0, sizeof(struct ea_refcount));
1039 refcount->size = size;
1040 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1042 printf("Refcount allocated %d entries, %d bytes.\n",
1043 refcount->size, bytes);
1045 retval = ext2fs_get_mem(bytes, &refcount->list);
1048 memset(refcount->list, 0, bytes);
1050 refcount->count = 0;
1051 refcount->cursor = 0;
1057 ea_refcount_free(refcount);
1062 * collapse_refcount() --- go through the refcount array, and get rid
1063 * of any count == zero entries
1065 static void refcount_collapse(ext2_refcount_t refcount)
1068 struct ea_refcount_el *list;
1070 list = refcount->list;
1071 for (i = 0, j = 0; i < refcount->count; i++) {
1072 if (list[i].ea_count) {
1078 #if defined(DEBUG) || defined(TEST_PROGRAM)
1079 printf("Refcount_collapse: size was %d, now %d\n",
1080 refcount->count, j);
1082 refcount->count = j;
1087 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1088 * specified position.
1090 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1093 struct ea_refcount_el *el;
1098 if (refcount->count >= refcount->size) {
1099 new_size = refcount->size + 100;
1101 printf("Reallocating refcount %d entries...\n", new_size);
1103 retval = ext2fs_resize_mem((size_t) refcount->size *
1104 sizeof(struct ea_refcount_el),
1106 sizeof(struct ea_refcount_el),
1110 refcount->size = new_size;
1112 num = (int) refcount->count - pos;
1114 return 0; /* should never happen */
1116 memmove(&refcount->list[pos+1], &refcount->list[pos],
1117 sizeof(struct ea_refcount_el) * num);
1120 el = &refcount->list[pos];
1128 * get_refcount_el() --- given an block number, try to find refcount
1129 * information in the sorted list. If the create flag is set,
1130 * and we can't find an entry, create one in the sorted list.
1132 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1133 blk_t blk, int create)
1137 blk_t lowval, highval;
1139 if (!refcount || !refcount->list)
1143 high = (int) refcount->count-1;
1144 if (create && ((refcount->count == 0) ||
1145 (blk > refcount->list[high].ea_blk))) {
1146 if (refcount->count >= refcount->size)
1147 refcount_collapse(refcount);
1149 return insert_refcount_el(refcount, blk,
1150 (unsigned) refcount->count);
1152 if (refcount->count == 0)
1155 if (refcount->cursor >= refcount->count)
1156 refcount->cursor = 0;
1157 if (blk == refcount->list[refcount->cursor].ea_blk)
1158 return &refcount->list[refcount->cursor++];
1160 printf("Non-cursor get_refcount_el: %u\n", blk);
1162 while (low <= high) {
1166 /* Interpolate for efficiency */
1167 lowval = refcount->list[low].ea_blk;
1168 highval = refcount->list[high].ea_blk;
1172 else if (blk > highval)
1175 range = ((float) (blk - lowval)) /
1177 mid = low + ((int) (range * (high-low)));
1180 if (blk == refcount->list[mid].ea_blk) {
1181 refcount->cursor = mid+1;
1182 return &refcount->list[mid];
1184 if (blk < refcount->list[mid].ea_blk)
1190 * If we need to create a new entry, it should be right at
1191 * low (where high will be left at low-1).
1194 if (refcount->count >= refcount->size) {
1195 refcount_collapse(refcount);
1196 if (refcount->count < refcount->size)
1199 return insert_refcount_el(refcount, blk, low);
1205 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1207 struct ea_refcount_el *el;
1209 el = get_refcount_el(refcount, blk, 1);
1211 return EXT2_ET_NO_MEMORY;
1215 *ret = el->ea_count;
1220 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1222 struct ea_refcount_el *el;
1224 el = get_refcount_el(refcount, blk, 0);
1225 if (!el || el->ea_count == 0)
1226 return EXT2_ET_INVALID_ARGUMENT;
1231 *ret = el->ea_count;
1236 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1238 struct ea_refcount_el *el;
1241 * Get the refcount element
1243 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1245 return count ? EXT2_ET_NO_MEMORY : 0;
1246 el->ea_count = count;
1250 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1252 refcount->cursor = 0;
1256 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1258 struct ea_refcount_el *list;
1261 if (refcount->cursor >= refcount->count)
1263 list = refcount->list;
1264 if (list[refcount->cursor].ea_count) {
1266 *ret = list[refcount->cursor].ea_count;
1267 return list[refcount->cursor++].ea_blk;
1275 * ehandler.c --- handle bad block errors which come up during the
1276 * course of an e2fsck session.
1280 static const char *operation;
1283 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1284 void *data, size_t size FSCK_ATTR((unused)),
1285 int actual FSCK_ATTR((unused)), errcode_t error)
1289 ext2_filsys fs = (ext2_filsys) channel->app_data;
1292 ctx = (e2fsck_t) fs->priv_data;
1295 * If more than one block was read, try reading each block
1296 * separately. We could use the actual bytes read to figure
1297 * out where to start, but we don't bother.
1301 for (i=0; i < count; i++, p += channel->block_size, block++) {
1302 error = io_channel_read_blk(channel, block,
1310 printf(_("Error reading block %lu (%s) while %s. "), block,
1311 error_message(error), operation);
1313 printf(_("Error reading block %lu (%s). "), block,
1314 error_message(error));
1316 if (ask(ctx, _("Ignore error"), 1)) {
1317 if (ask(ctx, _("Force rewrite"), 1))
1318 io_channel_write_blk(channel, block, 1, data);
1326 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1327 const void *data, size_t size FSCK_ATTR((unused)),
1328 int actual FSCK_ATTR((unused)), errcode_t error)
1332 ext2_filsys fs = (ext2_filsys) channel->app_data;
1335 ctx = (e2fsck_t) fs->priv_data;
1338 * If more than one block was written, try writing each block
1339 * separately. We could use the actual bytes read to figure
1340 * out where to start, but we don't bother.
1343 p = (const char *) data;
1344 for (i=0; i < count; i++, p += channel->block_size, block++) {
1345 error = io_channel_write_blk(channel, block,
1354 printf(_("Error writing block %lu (%s) while %s. "), block,
1355 error_message(error), operation);
1357 printf(_("Error writing block %lu (%s). "), block,
1358 error_message(error));
1360 if (ask(ctx, _("Ignore error"), 1))
1366 static const char *ehandler_operation(const char *op)
1368 const char *ret = operation;
1374 static void ehandler_init(io_channel channel)
1376 channel->read_error = e2fsck_handle_read_error;
1377 channel->write_error = e2fsck_handle_write_error;
1381 * journal.c --- code for handling the "ext3" journal
1383 * Copyright (C) 2000 Andreas Dilger
1384 * Copyright (C) 2000 Theodore Ts'o
1386 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1387 * Copyright (C) 1999 Red Hat Software
1389 * This file may be redistributed under the terms of the
1390 * GNU General Public License version 2 or at your discretion
1391 * any later version.
1395 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1396 * This creates a larger static binary, and a smaller binary using
1397 * shared libraries. It's also probably slightly less CPU-efficient,
1398 * which is why it's not on by default. But, it's a good way of
1399 * testing the functions in inode_io.c and fileio.c.
1403 /* Kernel compatibility functions for handling the journal. These allow us
1404 * to use the recovery.c file virtually unchanged from the kernel, so we
1405 * don't have to do much to keep kernel and user recovery in sync.
1407 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1413 struct inode *inode = journal->j_inode;
1422 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1423 &inode->i_ext2, NULL, 0, block, &pblk);
1429 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1431 struct buffer_head *bh;
1433 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1437 bh->b_ctx = kdev->k_ctx;
1438 if (kdev->k_dev == K_DEV_FS)
1439 bh->b_io = kdev->k_ctx->fs->io;
1441 bh->b_io = kdev->k_ctx->journal_io;
1442 bh->b_size = blocksize;
1443 bh->b_blocknr = blocknr;
1448 static void sync_blockdev(kdev_t kdev)
1452 if (kdev->k_dev == K_DEV_FS)
1453 io = kdev->k_ctx->fs->io;
1455 io = kdev->k_ctx->journal_io;
1457 io_channel_flush(io);
1460 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1463 struct buffer_head *bh;
1465 for (; nr > 0; --nr) {
1467 if (rw == READ && !bh->b_uptodate) {
1468 retval = io_channel_read_blk(bh->b_io,
1472 bb_error_msg("while reading block %lu",
1473 (unsigned long) bh->b_blocknr);
1478 } else if (rw == WRITE && bh->b_dirty) {
1479 retval = io_channel_write_blk(bh->b_io,
1483 bb_error_msg("while writing block %lu",
1484 (unsigned long) bh->b_blocknr);
1494 static void mark_buffer_dirty(struct buffer_head *bh)
1499 static inline void mark_buffer_clean(struct buffer_head * bh)
1504 static void brelse(struct buffer_head *bh)
1507 ll_rw_block(WRITE, 1, &bh);
1508 ext2fs_free_mem(&bh);
1511 static int buffer_uptodate(struct buffer_head *bh)
1513 return bh->b_uptodate;
1516 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1518 bh->b_uptodate = val;
1521 static void wait_on_buffer(struct buffer_head *bh)
1523 if (!bh->b_uptodate)
1524 ll_rw_block(READ, 1, &bh);
1528 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1530 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1532 /* if we had an error doing journal recovery, we need a full fsck */
1534 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1535 ext2fs_mark_super_dirty(ctx->fs);
1538 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1540 struct ext2_super_block *sb = ctx->fs->super;
1541 struct ext2_super_block jsuper;
1542 struct problem_context pctx;
1543 struct buffer_head *bh;
1544 struct inode *j_inode = NULL;
1545 struct kdev_s *dev_fs = NULL, *dev_journal;
1546 const char *journal_name = 0;
1547 journal_t *journal = NULL;
1548 errcode_t retval = 0;
1549 io_manager io_ptr = 0;
1550 unsigned long start = 0;
1552 int ext_journal = 0;
1553 int tried_backup_jnl = 0;
1556 clear_problem_context(&pctx);
1558 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1560 return EXT2_ET_NO_MEMORY;
1563 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1565 retval = EXT2_ET_NO_MEMORY;
1568 dev_journal = dev_fs+1;
1570 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1571 dev_fs->k_dev = K_DEV_FS;
1572 dev_journal->k_dev = K_DEV_JOURNAL;
1574 journal->j_dev = dev_journal;
1575 journal->j_fs_dev = dev_fs;
1576 journal->j_inode = NULL;
1577 journal->j_blocksize = ctx->fs->blocksize;
1579 if (uuid_is_null(sb->s_journal_uuid)) {
1580 if (!sb->s_journal_inum)
1581 return EXT2_ET_BAD_INODE_NUM;
1582 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1585 retval = EXT2_ET_NO_MEMORY;
1589 j_inode->i_ctx = ctx;
1590 j_inode->i_ino = sb->s_journal_inum;
1592 if ((retval = ext2fs_read_inode(ctx->fs,
1594 &j_inode->i_ext2))) {
1596 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1599 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1600 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1602 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1603 j_inode->i_ext2.i_links_count = 1;
1604 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1607 if (!j_inode->i_ext2.i_links_count ||
1608 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1609 retval = EXT2_ET_NO_JOURNAL;
1610 goto try_backup_journal;
1612 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1613 JFS_MIN_JOURNAL_BLOCKS) {
1614 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1615 goto try_backup_journal;
1617 for (i=0; i < EXT2_N_BLOCKS; i++) {
1618 blk = j_inode->i_ext2.i_block[i];
1620 if (i < EXT2_NDIR_BLOCKS) {
1621 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1622 goto try_backup_journal;
1626 if (blk < sb->s_first_data_block ||
1627 blk >= sb->s_blocks_count) {
1628 retval = EXT2_ET_BAD_BLOCK_NUM;
1629 goto try_backup_journal;
1632 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1635 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1641 io_ptr = inode_io_manager;
1643 journal->j_inode = j_inode;
1644 ctx->journal_io = ctx->fs->io;
1645 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1650 if (!ctx->journal_name) {
1653 uuid_unparse(sb->s_journal_uuid, uuid);
1654 ctx->journal_name = blkid_get_devname(ctx->blkid,
1656 if (!ctx->journal_name)
1657 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1659 journal_name = ctx->journal_name;
1661 if (!journal_name) {
1662 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1663 return EXT2_ET_LOAD_EXT_JOURNAL;
1666 io_ptr = unix_io_manager;
1669 #ifndef USE_INODE_IO
1672 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1677 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1680 if (ctx->fs->blocksize == 1024)
1682 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1684 retval = EXT2_ET_NO_MEMORY;
1687 ll_rw_block(READ, 1, &bh);
1688 if ((retval = bh->b_err) != 0)
1690 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1694 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1695 ext2fs_swap_super(&jsuper);
1697 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1698 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1699 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1700 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1703 /* Make sure the journal UUID is correct */
1704 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1705 sizeof(jsuper.s_uuid))) {
1706 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1707 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1711 journal->j_maxlen = jsuper.s_blocks_count;
1715 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1716 retval = EXT2_ET_NO_MEMORY;
1720 journal->j_sb_buffer = bh;
1721 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1724 ext2fs_free_mem(&j_inode);
1727 *ret_journal = journal;
1731 ext2fs_free_mem(&dev_fs);
1732 ext2fs_free_mem(&j_inode);
1733 ext2fs_free_mem(&journal);
1738 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1739 struct problem_context *pctx)
1741 struct ext2_super_block *sb = ctx->fs->super;
1742 int recover = ctx->fs->super->s_feature_incompat &
1743 EXT3_FEATURE_INCOMPAT_RECOVER;
1744 int has_journal = ctx->fs->super->s_feature_compat &
1745 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1747 if (has_journal || sb->s_journal_inum) {
1748 /* The journal inode is bogus, remove and force full fsck */
1749 pctx->ino = sb->s_journal_inum;
1750 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1751 if (has_journal && sb->s_journal_inum)
1752 printf("*** ext3 journal has been deleted - "
1753 "filesystem is now ext2 only ***\n\n");
1754 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1755 sb->s_journal_inum = 0;
1756 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1757 e2fsck_clear_recover(ctx, 1);
1760 return EXT2_ET_BAD_INODE_NUM;
1761 } else if (recover) {
1762 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1763 e2fsck_clear_recover(ctx, 1);
1766 return EXT2_ET_UNSUPP_FEATURE;
1771 #define V1_SB_SIZE 0x0024
1772 static void clear_v2_journal_fields(journal_t *journal)
1774 e2fsck_t ctx = journal->j_dev->k_ctx;
1775 struct problem_context pctx;
1777 clear_problem_context(&pctx);
1779 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1782 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1783 ctx->fs->blocksize-V1_SB_SIZE);
1784 mark_buffer_dirty(journal->j_sb_buffer);
1788 static errcode_t e2fsck_journal_load(journal_t *journal)
1790 e2fsck_t ctx = journal->j_dev->k_ctx;
1791 journal_superblock_t *jsb;
1792 struct buffer_head *jbh = journal->j_sb_buffer;
1793 struct problem_context pctx;
1795 clear_problem_context(&pctx);
1797 ll_rw_block(READ, 1, &jbh);
1799 bb_error_msg(_("reading journal superblock"));
1803 jsb = journal->j_superblock;
1804 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1805 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1806 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1808 switch (ntohl(jsb->s_header.h_blocktype)) {
1809 case JFS_SUPERBLOCK_V1:
1810 journal->j_format_version = 1;
1811 if (jsb->s_feature_compat ||
1812 jsb->s_feature_incompat ||
1813 jsb->s_feature_ro_compat ||
1815 clear_v2_journal_fields(journal);
1818 case JFS_SUPERBLOCK_V2:
1819 journal->j_format_version = 2;
1820 if (ntohl(jsb->s_nr_users) > 1 &&
1821 uuid_is_null(ctx->fs->super->s_journal_uuid))
1822 clear_v2_journal_fields(journal);
1823 if (ntohl(jsb->s_nr_users) > 1) {
1824 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1825 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1830 * These should never appear in a journal super block, so if
1831 * they do, the journal is badly corrupted.
1833 case JFS_DESCRIPTOR_BLOCK:
1834 case JFS_COMMIT_BLOCK:
1835 case JFS_REVOKE_BLOCK:
1836 return EXT2_ET_CORRUPT_SUPERBLOCK;
1838 /* If we don't understand the superblock major type, but there
1839 * is a magic number, then it is likely to be a new format we
1840 * just don't understand, so leave it alone. */
1842 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1845 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1846 return EXT2_ET_UNSUPP_FEATURE;
1848 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1849 return EXT2_ET_RO_UNSUPP_FEATURE;
1851 /* We have now checked whether we know enough about the journal
1852 * format to be able to proceed safely, so any other checks that
1853 * fail we should attempt to recover from. */
1854 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1855 bb_error_msg(_("%s: no valid journal superblock found"),
1857 return EXT2_ET_CORRUPT_SUPERBLOCK;
1860 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1861 journal->j_maxlen = ntohl(jsb->s_maxlen);
1862 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1863 bb_error_msg(_("%s: journal too short"),
1865 return EXT2_ET_CORRUPT_SUPERBLOCK;
1868 journal->j_tail_sequence = ntohl(jsb->s_sequence);
1869 journal->j_transaction_sequence = journal->j_tail_sequence;
1870 journal->j_tail = ntohl(jsb->s_start);
1871 journal->j_first = ntohl(jsb->s_first);
1872 journal->j_last = ntohl(jsb->s_maxlen);
1877 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
1888 /* Leave a valid existing V1 superblock signature alone.
1889 * Anything unrecognizable we overwrite with a new V2
1892 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
1893 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
1894 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
1895 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
1898 /* Zero out everything else beyond the superblock header */
1900 p = ((char *) jsb) + sizeof(journal_header_t);
1901 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
1903 jsb->s_blocksize = htonl(ctx->fs->blocksize);
1904 jsb->s_maxlen = htonl(journal->j_maxlen);
1905 jsb->s_first = htonl(1);
1907 /* Initialize the journal sequence number so that there is "no"
1908 * chance we will find old "valid" transactions in the journal.
1909 * This avoids the need to zero the whole journal (slow to do,
1910 * and risky when we are just recovering the filesystem).
1912 uuid_generate(u.uuid);
1913 for (i = 0; i < 4; i ++)
1914 new_seq ^= u.val[i];
1915 jsb->s_sequence = htonl(new_seq);
1917 mark_buffer_dirty(journal->j_sb_buffer);
1918 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
1921 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
1923 struct problem_context *pctx)
1925 struct ext2_super_block *sb = ctx->fs->super;
1926 int recover = ctx->fs->super->s_feature_incompat &
1927 EXT3_FEATURE_INCOMPAT_RECOVER;
1929 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
1930 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
1931 e2fsck_journal_reset_super(ctx, journal->j_superblock,
1933 journal->j_transaction_sequence = 1;
1934 e2fsck_clear_recover(ctx, recover);
1937 return EXT2_ET_CORRUPT_SUPERBLOCK;
1938 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
1939 return EXT2_ET_CORRUPT_SUPERBLOCK;
1944 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
1945 int reset, int drop)
1947 journal_superblock_t *jsb;
1950 mark_buffer_clean(journal->j_sb_buffer);
1951 else if (!(ctx->options & E2F_OPT_READONLY)) {
1952 jsb = journal->j_superblock;
1953 jsb->s_sequence = htonl(journal->j_transaction_sequence);
1955 jsb->s_start = 0; /* this marks the journal as empty */
1956 mark_buffer_dirty(journal->j_sb_buffer);
1958 brelse(journal->j_sb_buffer);
1960 if (ctx->journal_io) {
1961 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1962 io_channel_close(ctx->journal_io);
1963 ctx->journal_io = 0;
1966 #ifndef USE_INODE_IO
1967 ext2fs_free_mem(&journal->j_inode);
1969 ext2fs_free_mem(&journal->j_fs_dev);
1970 ext2fs_free_mem(&journal);
1974 * This function makes sure that the superblock fields regarding the
1975 * journal are consistent.
1977 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
1979 struct ext2_super_block *sb = ctx->fs->super;
1981 int recover = ctx->fs->super->s_feature_incompat &
1982 EXT3_FEATURE_INCOMPAT_RECOVER;
1983 struct problem_context pctx;
1985 int reset = 0, force_fsck = 0;
1988 /* If we don't have any journal features, don't do anything more */
1989 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
1990 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
1991 uuid_is_null(sb->s_journal_uuid))
1994 clear_problem_context(&pctx);
1995 pctx.num = sb->s_journal_inum;
1997 retval = e2fsck_get_journal(ctx, &journal);
1999 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2000 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2001 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2002 (retval == EXT2_ET_NO_JOURNAL))
2003 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2007 retval = e2fsck_journal_load(journal);
2009 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2010 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2011 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2013 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2014 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2016 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2017 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2018 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2020 e2fsck_journal_release(ctx, journal, 0, 1);
2025 * We want to make the flags consistent here. We will not leave with
2026 * needs_recovery set but has_journal clear. We can't get in a loop
2027 * with -y, -n, or -p, only if a user isn't making up their mind.
2030 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2031 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2033 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2035 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2036 goto no_has_journal;
2038 * Need a full fsck if we are releasing a
2039 * journal stored on a reserved inode.
2041 force_fsck = recover ||
2042 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2043 /* Clear all of the journal fields */
2044 sb->s_journal_inum = 0;
2045 sb->s_journal_dev = 0;
2046 memset(sb->s_journal_uuid, 0,
2047 sizeof(sb->s_journal_uuid));
2048 e2fsck_clear_recover(ctx, force_fsck);
2049 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2050 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2051 ext2fs_mark_super_dirty(ctx->fs);
2055 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2056 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2057 journal->j_superblock->s_start != 0) {
2058 /* Print status information */
2059 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2060 if (ctx->superblock)
2061 problem = PR_0_JOURNAL_RUN_DEFAULT;
2063 problem = PR_0_JOURNAL_RUN;
2064 if (fix_problem(ctx, problem, &pctx)) {
2065 ctx->options |= E2F_OPT_FORCE;
2066 sb->s_feature_incompat |=
2067 EXT3_FEATURE_INCOMPAT_RECOVER;
2068 ext2fs_mark_super_dirty(ctx->fs);
2069 } else if (fix_problem(ctx,
2070 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2072 sb->s_state &= ~EXT2_VALID_FS;
2073 ext2fs_mark_super_dirty(ctx->fs);
2076 * If the user answers no to the above question, we
2077 * ignore the fact that journal apparently has data;
2078 * accidentally replaying over valid data would be far
2079 * worse than skipping a questionable recovery.
2081 * XXX should we abort with a fatal error here? What
2082 * will the ext3 kernel code do if a filesystem with
2083 * !NEEDS_RECOVERY but with a non-zero
2084 * journal->j_superblock->s_start is mounted?
2088 e2fsck_journal_release(ctx, journal, reset, 0);
2092 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2097 journal_init_revoke_caches();
2098 retval = e2fsck_get_journal(ctx, &journal);
2102 retval = e2fsck_journal_load(journal);
2106 retval = journal_init_revoke(journal, 1024);
2110 retval = -journal_recover(journal);
2114 if (journal->j_superblock->s_errno) {
2115 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2116 ext2fs_mark_super_dirty(ctx->fs);
2117 journal->j_superblock->s_errno = 0;
2118 mark_buffer_dirty(journal->j_sb_buffer);
2122 journal_destroy_revoke(journal);
2123 journal_destroy_revoke_caches();
2124 e2fsck_journal_release(ctx, journal, 1, 0);
2128 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2130 io_manager io_ptr = ctx->fs->io->manager;
2131 int blocksize = ctx->fs->blocksize;
2132 errcode_t retval, recover_retval;
2134 printf(_("%s: recovering journal\n"), ctx->device_name);
2135 if (ctx->options & E2F_OPT_READONLY) {
2136 printf(_("%s: won't do journal recovery while read-only\n"),
2138 return EXT2_ET_FILE_RO;
2141 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2142 ext2fs_flush(ctx->fs); /* Force out any modifications */
2144 recover_retval = recover_ext3_journal(ctx);
2147 * Reload the filesystem context to get up-to-date data from disk
2148 * because journal recovery will change the filesystem under us.
2150 ext2fs_close(ctx->fs);
2151 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2152 ctx->superblock, blocksize, io_ptr,
2156 bb_error_msg(_("while trying to re-open %s"),
2158 bb_error_msg_and_die(0);
2160 ctx->fs->priv_data = ctx;
2162 /* Set the superblock flags */
2163 e2fsck_clear_recover(ctx, recover_retval);
2164 return recover_retval;
2168 * This function will move the journal inode from a visible file in
2169 * the filesystem directory hierarchy to the reserved inode if necessary.
2171 static const char *const journal_names[] = {
2172 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2174 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2176 struct ext2_super_block *sb = ctx->fs->super;
2177 struct problem_context pctx;
2178 struct ext2_inode inode;
2179 ext2_filsys fs = ctx->fs;
2182 const char *const * cpp;
2183 int group, mount_flags;
2185 clear_problem_context(&pctx);
2188 * If the filesystem is opened read-only, or there is no
2189 * journal, then do nothing.
2191 if ((ctx->options & E2F_OPT_READONLY) ||
2192 (sb->s_journal_inum == 0) ||
2193 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2197 * Read in the journal inode
2199 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2203 * If it's necessary to backup the journal inode, do so.
2205 if ((sb->s_jnl_backup_type == 0) ||
2206 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2207 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2208 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2209 memcpy(sb->s_jnl_blocks, inode.i_block,
2211 sb->s_jnl_blocks[16] = inode.i_size;
2212 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2213 ext2fs_mark_super_dirty(fs);
2214 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2219 * If the journal is already the hidden inode, then do nothing
2221 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2225 * The journal inode had better have only one link and not be readable.
2227 if (inode.i_links_count != 1)
2231 * If the filesystem is mounted, or we can't tell whether
2232 * or not it's mounted, do nothing.
2234 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2235 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2239 * If we can't find the name of the journal inode, then do
2242 for (cpp = journal_names; *cpp; cpp++) {
2243 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2244 strlen(*cpp), 0, &ino);
2245 if ((retval == 0) && (ino == sb->s_journal_inum))
2251 /* We need the inode bitmap to be loaded */
2252 retval = ext2fs_read_bitmaps(fs);
2257 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2261 * OK, we've done all the checks, let's actually move the
2262 * journal inode. Errors at this point mean we need to force
2263 * an ext2 filesystem check.
2265 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2267 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2269 sb->s_journal_inum = EXT2_JOURNAL_INO;
2270 ext2fs_mark_super_dirty(fs);
2271 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2272 inode.i_links_count = 0;
2273 inode.i_dtime = time(NULL);
2274 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2277 group = ext2fs_group_of_ino(fs, ino);
2278 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2279 ext2fs_mark_ib_dirty(fs);
2280 fs->group_desc[group].bg_free_inodes_count++;
2281 fs->super->s_free_inodes_count++;
2285 pctx.errcode = retval;
2286 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2287 fs->super->s_state &= ~EXT2_VALID_FS;
2288 ext2fs_mark_super_dirty(fs);
2292 * message.c --- print e2fsck messages (with compression)
2294 * print_e2fsck_message() prints a message to the user, using
2295 * compression techniques and expansions of abbreviations.
2297 * The following % expansions are supported:
2299 * %b <blk> block number
2300 * %B <blkcount> integer
2301 * %c <blk2> block number
2302 * %Di <dirent>->ino inode number
2303 * %Dn <dirent>->name string
2304 * %Dr <dirent>->rec_len
2305 * %Dl <dirent>->name_len
2306 * %Dt <dirent>->filetype
2307 * %d <dir> inode number
2308 * %g <group> integer
2309 * %i <ino> inode number
2310 * %Is <inode> -> i_size
2311 * %IS <inode> -> i_extra_isize
2312 * %Ib <inode> -> i_blocks
2313 * %Il <inode> -> i_links_count
2314 * %Im <inode> -> i_mode
2315 * %IM <inode> -> i_mtime
2316 * %IF <inode> -> i_faddr
2317 * %If <inode> -> i_file_acl
2318 * %Id <inode> -> i_dir_acl
2319 * %Iu <inode> -> i_uid
2320 * %Ig <inode> -> i_gid
2321 * %j <ino2> inode number
2322 * %m <com_err error message>
2324 * %p ext2fs_get_pathname of directory <ino>
2325 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2326 * the containing directory. (If dirent is NULL
2327 * then return the pathname of directory <ino2>)
2328 * %q ext2fs_get_pathname of directory <dir>
2329 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2330 * the containing directory.
2331 * %s <str> miscellaneous string
2332 * %S backup superblock
2333 * %X <num> hexadecimal format
2335 * The following '@' expansions are supported:
2337 * @a extended attribute
2338 * @A error allocating
2342 * @C conflicts with some other fs block
2346 * @E Entry '%Dn' in %p (%i)
2348 * @F for @i %i (%Q) is
2350 * @h HTREE directory inode
2356 * @m multiply-claimed
2370 * This structure defines the abbreviations used by the text strings
2371 * below. The first character in the string is the index letter. An
2372 * abbreviation of the form '@<i>' is expanded by looking up the index
2373 * letter <i> in the table below.
2375 static const char *const abbrevs[] = {
2376 N_("aextended attribute"),
2377 N_("Aerror allocating"),
2381 N_("Cconflicts with some other fs @b"),
2388 N_("E@e '%Dn' in %p (%i)"),
2390 N_("Ffor @i %i (%Q) is"),
2395 N_("mmultiply-claimed"),
2410 * Give more user friendly names to the "special" inodes.
2412 #define num_special_inodes 11
2413 static const char *const special_inode_name[] =
2415 N_("<The NULL inode>"), /* 0 */
2416 N_("<The bad blocks inode>"), /* 1 */
2418 N_("<The ACL index inode>"), /* 3 */
2419 N_("<The ACL data inode>"), /* 4 */
2420 N_("<The boot loader inode>"), /* 5 */
2421 N_("<The undelete directory inode>"), /* 6 */
2422 N_("<The group descriptor inode>"), /* 7 */
2423 N_("<The journal inode>"), /* 8 */
2424 N_("<Reserved inode 9>"), /* 9 */
2425 N_("<Reserved inode 10>"), /* 10 */
2429 * This function does "safe" printing. It will convert non-printable
2430 * ASCII characters using '^' and M- notation.
2432 static void safe_print(const char *cp, int len)
2442 fputs("M-", stdout);
2445 if ((ch < 32) || (ch == 0x7f)) {
2447 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2455 * This function prints a pathname, using the ext2fs_get_pathname
2458 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2463 if (!dir && (ino < num_special_inodes)) {
2464 fputs(_(special_inode_name[ino]), stdout);
2468 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2470 fputs("???", stdout);
2472 safe_print(path, -1);
2473 ext2fs_free_mem(&path);
2477 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2478 struct problem_context *pctx, int first);
2480 * This function handles the '@' expansion. We allow recursive
2481 * expansion; an @ expression can contain further '@' and '%'
2484 static void expand_at_expression(e2fsck_t ctx, char ch,
2485 struct problem_context *pctx,
2488 const char *const *cpp;
2491 /* Search for the abbreviation */
2492 for (cpp = abbrevs; *cpp; cpp++) {
2498 if (*first && islower(*str)) {
2500 bb_putchar(toupper(*str++));
2502 print_e2fsck_message(ctx, str, pctx, *first);
2508 * This function expands '%IX' expressions
2510 static void expand_inode_expression(char ch,
2511 struct problem_context *ctx)
2513 struct ext2_inode *inode;
2514 struct ext2_inode_large *large_inode;
2519 if (!ctx || !ctx->inode)
2523 large_inode = (struct ext2_inode_large *) inode;
2527 if (LINUX_S_ISDIR(inode->i_mode))
2528 printf("%u", inode->i_size);
2530 printf("%"PRIu64, (inode->i_size |
2531 ((uint64_t) inode->i_size_high << 32)));
2535 printf("%u", large_inode->i_extra_isize);
2538 printf("%u", inode->i_blocks);
2541 printf("%d", inode->i_links_count);
2544 printf("0%o", inode->i_mode);
2547 /* The diet libc doesn't respect the TZ environemnt variable */
2549 time_str = getenv("TZ");
2552 do_gmt = !strcmp(time_str, "GMT");
2555 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2556 printf("%.24s", time_str);
2559 printf("%u", inode->i_faddr);
2562 printf("%u", inode->i_file_acl);
2565 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2566 inode->i_dir_acl : 0));
2569 printf("%d", (inode->i_uid |
2570 (inode->osd2.linux2.l_i_uid_high << 16)));
2573 printf("%d", (inode->i_gid |
2574 (inode->osd2.linux2.l_i_gid_high << 16)));
2578 printf("%%I%c", ch);
2584 * This function expands '%dX' expressions
2586 static void expand_dirent_expression(char ch,
2587 struct problem_context *ctx)
2589 struct ext2_dir_entry *dirent;
2592 if (!ctx || !ctx->dirent)
2595 dirent = ctx->dirent;
2599 printf("%u", dirent->inode);
2602 len = dirent->name_len & 0xFF;
2603 if (len > EXT2_NAME_LEN)
2604 len = EXT2_NAME_LEN;
2605 if (len > dirent->rec_len)
2606 len = dirent->rec_len;
2607 safe_print(dirent->name, len);
2610 printf("%u", dirent->rec_len);
2613 printf("%u", dirent->name_len & 0xFF);
2616 printf("%u", dirent->name_len >> 8);
2620 printf("%%D%c", ch);
2625 static void expand_percent_expression(ext2_filsys fs, char ch,
2626 struct problem_context *ctx)
2636 printf("%u", ctx->blk);
2639 printf("%"PRIi64, ctx->blkcount);
2642 printf("%u", ctx->blk2);
2645 printf("%u", ctx->dir);
2648 printf("%d", ctx->group);
2651 printf("%u", ctx->ino);
2654 printf("%u", ctx->ino2);
2657 fputs(error_message(ctx->errcode), stdout);
2660 printf("%"PRIi64, ctx->num);
2663 print_pathname(fs, ctx->ino, 0);
2666 print_pathname(fs, ctx->ino2,
2667 ctx->dirent ? ctx->dirent->inode : 0);
2670 print_pathname(fs, ctx->dir, 0);
2673 print_pathname(fs, ctx->dir, ctx->ino);
2676 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2679 fputs((ctx->str ? ctx->str : "NULL"), stdout);
2682 printf("0x%"PRIi64, ctx->num);
2692 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2693 struct problem_context *pctx, int first)
2695 ext2_filsys fs = ctx->fs;
2699 e2fsck_clear_progbar(ctx);
2700 for (cp = msg; *cp; cp++) {
2703 expand_at_expression(ctx, *cp, pctx, &first);
2704 } else if (cp[0] == '%' && cp[1] == 'I') {
2706 expand_inode_expression(*cp, pctx);
2707 } else if (cp[0] == '%' && cp[1] == 'D') {
2709 expand_dirent_expression(*cp, pctx);
2710 } else if ((cp[0] == '%')) {
2712 expand_percent_expression(fs, *cp, pctx);
2714 for (i=0; cp[i]; i++)
2715 if ((cp[i] == '@') || cp[i] == '%')
2717 printf("%.*s", i, cp);
2726 * region.c --- code which manages allocations within a region.
2730 region_addr_t start;
2732 struct region_el *next;
2735 struct region_struct {
2738 struct region_el *allocated;
2741 static region_t region_create(region_addr_t min, region_addr_t max)
2745 region = malloc(sizeof(struct region_struct));
2748 memset(region, 0, sizeof(struct region_struct));
2754 static void region_free(region_t region)
2756 struct region_el *r, *next;
2758 for (r = region->allocated; r; r = next) {
2762 memset(region, 0, sizeof(struct region_struct));
2766 static int region_allocate(region_t region, region_addr_t start, int n)
2768 struct region_el *r, *new_region, *prev, *next;
2772 if ((start < region->min) || (end > region->max))
2778 * Search through the linked list. If we find that it
2779 * conflicts witih something that's already allocated, return
2780 * 1; if we can find an existing region which we can grow, do
2781 * so. Otherwise, stop when we find the appropriate place
2782 * insert a new region element into the linked list.
2784 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2785 if (((start >= r->start) && (start < r->end)) ||
2786 ((end > r->start) && (end <= r->end)) ||
2787 ((start <= r->start) && (end >= r->end)))
2789 if (end == r->start) {
2793 if (start == r->end) {
2794 if ((next = r->next)) {
2795 if (end > next->start)
2797 if (end == next->start) {
2799 r->next = next->next;
2807 if (start < r->start)
2811 * Insert a new region element structure into the linked list
2813 new_region = malloc(sizeof(struct region_el));
2816 new_region->start = start;
2817 new_region->end = start + n;
2818 new_region->next = r;
2820 prev->next = new_region;
2822 region->allocated = new_region;
2827 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2829 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2830 * and applies the following tests to each inode:
2832 * - The mode field of the inode must be legal.
2833 * - The size and block count fields of the inode are correct.
2834 * - A data block must not be used by another inode
2836 * Pass 1 also gathers the collects the following information:
2838 * - A bitmap of which inodes are in use. (inode_used_map)
2839 * - A bitmap of which inodes are directories. (inode_dir_map)
2840 * - A bitmap of which inodes are regular files. (inode_reg_map)
2841 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2842 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2843 * - A bitmap of which blocks are in use. (block_found_map)
2844 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2845 * - The data blocks of the directory inodes. (dir_map)
2847 * Pass 1 is designed to stash away enough information so that the
2848 * other passes should not need to read in the inode information
2849 * during the normal course of a filesystem check. (Althogh if an
2850 * inconsistency is detected, other passes may need to read in an
2853 * Note that pass 1B will be invoked if there are any duplicate blocks
2858 static int process_block(ext2_filsys fs, blk_t *blocknr,
2859 e2_blkcnt_t blockcnt, blk_t ref_blk,
2860 int ref_offset, void *priv_data);
2861 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2862 e2_blkcnt_t blockcnt, blk_t ref_blk,
2863 int ref_offset, void *priv_data);
2864 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2866 static void mark_table_blocks(e2fsck_t ctx);
2867 static void alloc_imagic_map(e2fsck_t ctx);
2868 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2869 static void handle_fs_bad_blocks(e2fsck_t ctx);
2870 static void process_inodes(e2fsck_t ctx, char *block_buf);
2871 static int process_inode_cmp(const void *a, const void *b);
2872 static errcode_t scan_callback(ext2_filsys fs,
2873 dgrp_t group, void * priv_data);
2874 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2875 char *block_buf, int adjust_sign);
2876 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2878 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2879 struct ext2_inode * inode, int bufsize,
2882 struct process_block_struct_1 {
2884 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
2885 fragmented:1, compressed:1, bbcheck:1;
2888 e2_blkcnt_t last_block;
2889 int num_illegal_blocks;
2890 blk_t previous_block;
2891 struct ext2_inode *inode;
2892 struct problem_context *pctx;
2893 ext2fs_block_bitmap fs_meta_blocks;
2897 struct process_inode_block {
2899 struct ext2_inode inode;
2902 struct scan_callback_struct {
2908 * For the inodes to process list.
2910 static struct process_inode_block *inodes_to_process;
2911 static int process_inode_count;
2913 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2914 EXT2_MIN_BLOCK_LOG_SIZE + 1];
2917 * Free all memory allocated by pass1 in preparation for restarting
2920 static void unwind_pass1(void)
2922 ext2fs_free_mem(&inodes_to_process);
2926 * Check to make sure a device inode is real. Returns 1 if the device
2927 * checks out, 0 if not.
2929 * Note: this routine is now also used to check FIFO's and Sockets,
2930 * since they have the same requirement; the i_block fields should be
2934 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2939 * If i_blocks is non-zero, or the index flag is set, then
2940 * this is a bogus device/fifo/socket
2942 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2943 (inode->i_flags & EXT2_INDEX_FL))
2947 * We should be able to do the test below all the time, but
2948 * because the kernel doesn't forcibly clear the device
2949 * inode's additional i_block fields, there are some rare
2950 * occasions when a legitimate device inode will have non-zero
2951 * additional i_block fields. So for now, we only complain
2952 * when the immutable flag is set, which should never happen
2953 * for devices. (And that's when the problem is caused, since
2954 * you can't set or clear immutable flags for devices.) Once
2955 * the kernel has been fixed we can change this...
2957 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2958 for (i=4; i < EXT2_N_BLOCKS; i++)
2959 if (inode->i_block[i])
2966 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2967 * checks out, 0 if not.
2970 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
2976 if ((inode->i_size_high || inode->i_size == 0) ||
2977 (inode->i_flags & EXT2_INDEX_FL))
2980 blocks = ext2fs_inode_data_blocks(fs, inode);
2982 if ((inode->i_size >= fs->blocksize) ||
2983 (blocks != fs->blocksize >> 9) ||
2984 (inode->i_block[0] < fs->super->s_first_data_block) ||
2985 (inode->i_block[0] >= fs->super->s_blocks_count))
2988 for (i = 1; i < EXT2_N_BLOCKS; i++)
2989 if (inode->i_block[i])
2992 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
2995 len = strnlen(buf, fs->blocksize);
2996 if (len == fs->blocksize)
2999 if (inode->i_size >= sizeof(inode->i_block))
3002 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3003 if (len == sizeof(inode->i_block))
3006 if (len != inode->i_size)
3012 * If the immutable (or append-only) flag is set on the inode, offer
3015 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3016 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3018 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3021 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3024 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3025 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3029 * If device, fifo or socket, check size is zero -- if not offer to
3032 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3034 struct ext2_inode *inode = pctx->inode;
3036 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3039 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3043 inode->i_size_high = 0;
3044 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3047 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3049 struct ext2_super_block *sb = ctx->fs->super;
3050 struct ext2_inode_large *inode;
3051 struct ext2_ext_attr_entry *entry;
3053 int storage_size, remain, offs;
3056 inode = (struct ext2_inode_large *) pctx->inode;
3057 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3058 inode->i_extra_isize;
3059 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3060 inode->i_extra_isize + sizeof(__u32);
3061 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3062 entry = (struct ext2_ext_attr_entry *) start;
3064 /* scan all entry's headers first */
3066 /* take finish entry 0UL into account */
3067 remain = storage_size - sizeof(__u32);
3070 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3072 /* header eats this space */
3073 remain -= sizeof(struct ext2_ext_attr_entry);
3075 /* is attribute name valid? */
3076 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3077 pctx->num = entry->e_name_len;
3078 problem = PR_1_ATTR_NAME_LEN;
3082 /* attribute len eats this space */
3083 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3085 /* check value size */
3086 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3087 pctx->num = entry->e_value_size;
3088 problem = PR_1_ATTR_VALUE_SIZE;
3092 /* check value placement */
3093 if (entry->e_value_offs +
3094 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3095 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3096 pctx->num = entry->e_value_offs;
3097 problem = PR_1_ATTR_VALUE_OFFSET;
3101 /* e_value_block must be 0 in inode's ea */
3102 if (entry->e_value_block != 0) {
3103 pctx->num = entry->e_value_block;
3104 problem = PR_1_ATTR_VALUE_BLOCK;
3108 /* e_hash must be 0 in inode's ea */
3109 if (entry->e_hash != 0) {
3110 pctx->num = entry->e_hash;
3111 problem = PR_1_ATTR_HASH;
3115 remain -= entry->e_value_size;
3116 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3118 entry = EXT2_EXT_ATTR_NEXT(entry);
3122 * it seems like a corruption. it's very unlikely we could repair
3123 * EA(s) in automatic fashion -bzzz
3125 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3128 /* simple remove all possible EA(s) */
3129 *((__u32 *)start) = 0UL;
3130 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3131 EXT2_INODE_SIZE(sb), "pass1");
3134 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3136 struct ext2_super_block *sb = ctx->fs->super;
3137 struct ext2_inode_large *inode;
3141 inode = (struct ext2_inode_large *) pctx->inode;
3142 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3143 /* this isn't large inode. so, nothing to check */
3147 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3148 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3149 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3151 * For now we will allow i_extra_isize to be 0, but really
3152 * implementations should never allow i_extra_isize to be 0
3154 if (inode->i_extra_isize &&
3155 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3156 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3158 inode->i_extra_isize = min;
3159 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3160 EXT2_INODE_SIZE(sb), "pass1");
3164 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3165 inode->i_extra_isize);
3166 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3167 /* it seems inode has an extended attribute(s) in body */
3168 check_ea_in_inode(ctx, pctx);
3172 static void e2fsck_pass1(e2fsck_t ctx)
3176 ext2_filsys fs = ctx->fs;
3178 struct ext2_inode *inode;
3179 ext2_inode_scan scan;
3181 unsigned char frag, fsize;
3182 struct problem_context pctx;
3183 struct scan_callback_struct scan_struct;
3184 struct ext2_super_block *sb = ctx->fs->super;
3186 int busted_fs_time = 0;
3189 clear_problem_context(&pctx);
3191 if (!(ctx->options & E2F_OPT_PREEN))
3192 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3194 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3195 !(ctx->options & E2F_OPT_NO)) {
3196 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3197 ctx->dirs_to_hash = 0;
3202 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3204 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3205 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3206 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3207 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3208 max_sizes = (max_sizes * (1UL << i)) - 1;
3209 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3213 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3216 * Allocate bitmaps structures
3218 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3219 &ctx->inode_used_map);
3222 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3223 ctx->flags |= E2F_FLAG_ABORT;
3226 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3227 _("directory inode map"), &ctx->inode_dir_map);
3230 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3231 ctx->flags |= E2F_FLAG_ABORT;
3234 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3235 _("regular file inode map"), &ctx->inode_reg_map);
3238 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3239 ctx->flags |= E2F_FLAG_ABORT;
3242 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3243 &ctx->block_found_map);
3246 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3247 ctx->flags |= E2F_FLAG_ABORT;
3250 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3251 &ctx->inode_link_info);
3253 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3254 ctx->flags |= E2F_FLAG_ABORT;
3257 inode_size = EXT2_INODE_SIZE(fs->super);
3258 inode = (struct ext2_inode *)
3259 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3261 inodes_to_process = (struct process_inode_block *)
3262 e2fsck_allocate_memory(ctx,
3263 (ctx->process_inode_size *
3264 sizeof(struct process_inode_block)),
3265 "array of inodes to process");
3266 process_inode_count = 0;
3268 pctx.errcode = ext2fs_init_dblist(fs, 0);
3270 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3271 ctx->flags |= E2F_FLAG_ABORT;
3276 * If the last orphan field is set, clear it, since the pass1
3277 * processing will automatically find and clear the orphans.
3278 * In the future, we may want to try using the last_orphan
3279 * linked list ourselves, but for now, we clear it so that the
3280 * ext3 mount code won't get confused.
3282 if (!(ctx->options & E2F_OPT_READONLY)) {
3283 if (fs->super->s_last_orphan) {
3284 fs->super->s_last_orphan = 0;
3285 ext2fs_mark_super_dirty(fs);
3289 mark_table_blocks(ctx);
3290 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3291 "block interate buffer");
3292 e2fsck_use_inode_shortcuts(ctx, 1);
3293 ehandler_operation(_("doing inode scan"));
3294 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3297 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3298 ctx->flags |= E2F_FLAG_ABORT;
3301 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3302 ctx->stashed_inode = inode;
3303 scan_struct.ctx = ctx;
3304 scan_struct.block_buf = block_buf;
3305 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3307 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3309 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3310 (fs->super->s_mtime < fs->super->s_inodes_count))
3314 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3316 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3318 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3322 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3323 ctx->flags |= E2F_FLAG_ABORT;
3330 ctx->stashed_ino = ino;
3331 if (inode->i_links_count) {
3332 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3333 ino, inode->i_links_count);
3335 pctx.num = inode->i_links_count;
3336 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3337 ctx->flags |= E2F_FLAG_ABORT;
3341 if (ino == EXT2_BAD_INO) {
3342 struct process_block_struct_1 pb;
3344 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3345 &pb.fs_meta_blocks);
3348 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3349 ctx->flags |= E2F_FLAG_ABORT;
3352 pb.ino = EXT2_BAD_INO;
3353 pb.num_blocks = pb.last_block = 0;
3354 pb.num_illegal_blocks = 0;
3355 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3356 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3360 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3361 block_buf, process_bad_block, &pb);
3362 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3364 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3365 ctx->flags |= E2F_FLAG_ABORT;
3369 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3370 ctx->flags |= E2F_FLAG_ABORT;
3373 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3374 clear_problem_context(&pctx);
3376 } else if (ino == EXT2_ROOT_INO) {
3378 * Make sure the root inode is a directory; if
3379 * not, offer to clear it. It will be
3380 * regnerated in pass #3.
3382 if (!LINUX_S_ISDIR(inode->i_mode)) {
3383 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3384 inode->i_dtime = time(NULL);
3385 inode->i_links_count = 0;
3386 ext2fs_icount_store(ctx->inode_link_info,
3388 e2fsck_write_inode(ctx, ino, inode,
3394 * If dtime is set, offer to clear it. mke2fs
3395 * version 0.2b created filesystems with the
3396 * dtime field set for the root and lost+found
3397 * directories. We won't worry about
3398 * /lost+found, since that can be regenerated
3399 * easily. But we will fix the root directory
3400 * as a special case.
3402 if (inode->i_dtime && inode->i_links_count) {
3403 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3405 e2fsck_write_inode(ctx, ino, inode,
3409 } else if (ino == EXT2_JOURNAL_INO) {
3410 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3411 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3412 if (!LINUX_S_ISREG(inode->i_mode) &&
3413 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3415 inode->i_mode = LINUX_S_IFREG;
3416 e2fsck_write_inode(ctx, ino, inode,
3419 check_blocks(ctx, &pctx, block_buf);
3422 if ((inode->i_links_count || inode->i_blocks ||
3423 inode->i_blocks || inode->i_block[0]) &&
3424 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3426 memset(inode, 0, inode_size);
3427 ext2fs_icount_store(ctx->inode_link_info,
3429 e2fsck_write_inode_full(ctx, ino, inode,
3430 inode_size, "pass1");
3432 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3435 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3436 if (ino == EXT2_BOOT_LOADER_INO) {
3437 if (LINUX_S_ISDIR(inode->i_mode))
3438 problem = PR_1_RESERVED_BAD_MODE;
3439 } else if (ino == EXT2_RESIZE_INO) {
3440 if (inode->i_mode &&
3441 !LINUX_S_ISREG(inode->i_mode))
3442 problem = PR_1_RESERVED_BAD_MODE;
3444 if (inode->i_mode != 0)
3445 problem = PR_1_RESERVED_BAD_MODE;
3448 if (fix_problem(ctx, problem, &pctx)) {
3450 e2fsck_write_inode(ctx, ino, inode,
3454 check_blocks(ctx, &pctx, block_buf);
3458 * Check for inodes who might have been part of the
3459 * orphaned list linked list. They should have gotten
3460 * dealt with by now, unless the list had somehow been
3463 * FIXME: In the future, inodes which are still in use
3464 * (and which are therefore) pending truncation should
3465 * be handled specially. Right now we just clear the
3466 * dtime field, and the normal e2fsck handling of
3467 * inodes where i_size and the inode blocks are
3468 * inconsistent is to fix i_size, instead of releasing
3469 * the extra blocks. This won't catch the inodes that
3470 * was at the end of the orphan list, but it's better
3471 * than nothing. The right answer is that there
3472 * shouldn't be any bugs in the orphan list handling. :-)
3474 if (inode->i_dtime && !busted_fs_time &&
3475 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3476 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3477 inode->i_dtime = inode->i_links_count ?
3479 e2fsck_write_inode(ctx, ino, inode,
3485 * This code assumes that deleted inodes have
3486 * i_links_count set to 0.
3488 if (!inode->i_links_count) {
3489 if (!inode->i_dtime && inode->i_mode) {
3490 if (fix_problem(ctx,
3491 PR_1_ZERO_DTIME, &pctx)) {
3492 inode->i_dtime = time(NULL);
3493 e2fsck_write_inode(ctx, ino, inode,
3500 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3501 * deleted files. Oops.
3503 * Since all new ext2 implementations get this right,
3504 * we now assume that the case of non-zero
3505 * i_links_count and non-zero dtime means that we
3506 * should keep the file, not delete it.
3509 if (inode->i_dtime) {
3510 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3512 e2fsck_write_inode(ctx, ino, inode, "pass1");
3516 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3517 switch (fs->super->s_creator_os) {
3519 frag = inode->osd2.linux2.l_i_frag;
3520 fsize = inode->osd2.linux2.l_i_fsize;
3523 frag = inode->osd2.hurd2.h_i_frag;
3524 fsize = inode->osd2.hurd2.h_i_fsize;
3527 frag = inode->osd2.masix2.m_i_frag;
3528 fsize = inode->osd2.masix2.m_i_fsize;
3534 if (inode->i_faddr || frag || fsize ||
3535 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3536 mark_inode_bad(ctx, ino);
3537 if (inode->i_flags & EXT2_IMAGIC_FL) {
3539 if (!ctx->inode_imagic_map)
3540 alloc_imagic_map(ctx);
3541 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3544 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3545 inode->i_flags &= ~EXT2_IMAGIC_FL;
3546 e2fsck_write_inode(ctx, ino,
3552 check_inode_extra_space(ctx, &pctx);
3554 if (LINUX_S_ISDIR(inode->i_mode)) {
3555 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3556 e2fsck_add_dir_info(ctx, ino, 0);
3557 ctx->fs_directory_count++;
3558 } else if (LINUX_S_ISREG (inode->i_mode)) {
3559 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3560 ctx->fs_regular_count++;
3561 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3562 e2fsck_pass1_check_device_inode(fs, inode)) {
3563 check_immutable(ctx, &pctx);
3564 check_size(ctx, &pctx);
3565 ctx->fs_chardev_count++;
3566 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3567 e2fsck_pass1_check_device_inode(fs, inode)) {
3568 check_immutable(ctx, &pctx);
3569 check_size(ctx, &pctx);
3570 ctx->fs_blockdev_count++;
3571 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3572 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3573 check_immutable(ctx, &pctx);
3574 ctx->fs_symlinks_count++;
3575 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3576 ctx->fs_fast_symlinks_count++;
3577 check_blocks(ctx, &pctx, block_buf);
3581 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3582 e2fsck_pass1_check_device_inode(fs, inode)) {
3583 check_immutable(ctx, &pctx);
3584 check_size(ctx, &pctx);
3585 ctx->fs_fifo_count++;
3586 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3587 e2fsck_pass1_check_device_inode(fs, inode)) {
3588 check_immutable(ctx, &pctx);
3589 check_size(ctx, &pctx);
3590 ctx->fs_sockets_count++;
3592 mark_inode_bad(ctx, ino);
3593 if (inode->i_block[EXT2_IND_BLOCK])
3594 ctx->fs_ind_count++;
3595 if (inode->i_block[EXT2_DIND_BLOCK])
3596 ctx->fs_dind_count++;
3597 if (inode->i_block[EXT2_TIND_BLOCK])
3598 ctx->fs_tind_count++;
3599 if (inode->i_block[EXT2_IND_BLOCK] ||
3600 inode->i_block[EXT2_DIND_BLOCK] ||
3601 inode->i_block[EXT2_TIND_BLOCK] ||
3602 inode->i_file_acl) {
3603 inodes_to_process[process_inode_count].ino = ino;
3604 inodes_to_process[process_inode_count].inode = *inode;
3605 process_inode_count++;
3607 check_blocks(ctx, &pctx, block_buf);
3609 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3612 if (process_inode_count >= ctx->process_inode_size) {
3613 process_inodes(ctx, block_buf);
3615 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3619 process_inodes(ctx, block_buf);
3620 ext2fs_close_inode_scan(scan);
3621 ehandler_operation(0);
3624 * If any extended attribute blocks' reference counts need to
3625 * be adjusted, either up (ctx->refcount_extra), or down
3626 * (ctx->refcount), then fix them.
3628 if (ctx->refcount) {
3629 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3630 ea_refcount_free(ctx->refcount);
3633 if (ctx->refcount_extra) {
3634 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3636 ea_refcount_free(ctx->refcount_extra);
3637 ctx->refcount_extra = 0;
3640 if (ctx->invalid_bitmaps)
3641 handle_fs_bad_blocks(ctx);
3643 /* We don't need the block_ea_map any more */
3644 ext2fs_free_block_bitmap(ctx->block_ea_map);
3645 ctx->block_ea_map = 0;
3647 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3648 ext2fs_block_bitmap save_bmap;
3650 save_bmap = fs->block_map;
3651 fs->block_map = ctx->block_found_map;
3652 clear_problem_context(&pctx);
3653 pctx.errcode = ext2fs_create_resize_inode(fs);
3655 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3656 /* Should never get here */
3657 ctx->flags |= E2F_FLAG_ABORT;
3660 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3662 inode->i_mtime = time(NULL);
3663 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3665 fs->block_map = save_bmap;
3666 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3669 if (ctx->flags & E2F_FLAG_RESTART) {
3671 * Only the master copy of the superblock and block
3672 * group descriptors are going to be written during a
3673 * restart, so set the superblock to be used to be the
3674 * master superblock.
3676 ctx->use_superblock = 0;
3681 if (ctx->block_dup_map) {
3682 if (ctx->options & E2F_OPT_PREEN) {
3683 clear_problem_context(&pctx);
3684 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3686 e2fsck_pass1_dupblocks(ctx, block_buf);
3688 ext2fs_free_mem(&inodes_to_process);
3690 e2fsck_use_inode_shortcuts(ctx, 0);
3692 ext2fs_free_mem(&block_buf);
3693 ext2fs_free_mem(&inode);
3698 * When the inode_scan routines call this callback at the end of the
3699 * glock group, call process_inodes.
3701 static errcode_t scan_callback(ext2_filsys fs,
3702 dgrp_t group, void * priv_data)
3704 struct scan_callback_struct *scan_struct;
3707 scan_struct = (struct scan_callback_struct *) priv_data;
3708 ctx = scan_struct->ctx;
3710 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3713 if ((ctx->progress)(ctx, 1, group+1,
3714 ctx->fs->group_desc_count))
3715 return EXT2_ET_CANCEL_REQUESTED;
3721 * Process the inodes in the "inodes to process" list.
3723 static void process_inodes(e2fsck_t ctx, char *block_buf)
3726 struct ext2_inode *old_stashed_inode;
3727 ext2_ino_t old_stashed_ino;
3728 const char *old_operation;
3730 struct problem_context pctx;
3732 /* begin process_inodes */
3733 if (process_inode_count == 0)
3735 old_operation = ehandler_operation(0);
3736 old_stashed_inode = ctx->stashed_inode;
3737 old_stashed_ino = ctx->stashed_ino;
3738 qsort(inodes_to_process, process_inode_count,
3739 sizeof(struct process_inode_block), process_inode_cmp);
3740 clear_problem_context(&pctx);
3741 for (i=0; i < process_inode_count; i++) {
3742 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3743 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3744 sprintf(buf, _("reading indirect blocks of inode %u"),
3746 ehandler_operation(buf);
3747 check_blocks(ctx, &pctx, block_buf);
3748 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3751 ctx->stashed_inode = old_stashed_inode;
3752 ctx->stashed_ino = old_stashed_ino;
3753 process_inode_count = 0;
3754 /* end process inodes */
3756 ehandler_operation(old_operation);
3759 static int process_inode_cmp(const void *a, const void *b)
3761 const struct process_inode_block *ib_a =
3762 (const struct process_inode_block *) a;
3763 const struct process_inode_block *ib_b =
3764 (const struct process_inode_block *) b;
3767 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3768 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3770 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3775 * Mark an inode as being bad in some what
3777 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3779 struct problem_context pctx;
3781 if (!ctx->inode_bad_map) {
3782 clear_problem_context(&pctx);
3784 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3785 _("bad inode map"), &ctx->inode_bad_map);
3788 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3789 /* Should never get here */
3790 ctx->flags |= E2F_FLAG_ABORT;
3794 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3799 * This procedure will allocate the inode imagic table
3801 static void alloc_imagic_map(e2fsck_t ctx)
3803 struct problem_context pctx;
3805 clear_problem_context(&pctx);
3806 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3807 _("imagic inode map"),
3808 &ctx->inode_imagic_map);
3811 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3812 /* Should never get here */
3813 ctx->flags |= E2F_FLAG_ABORT;
3819 * Marks a block as in use, setting the dup_map if it's been set
3820 * already. Called by process_block and process_bad_block.
3822 * WARNING: Assumes checks have already been done to make sure block
3823 * is valid. This is true in both process_block and process_bad_block.
3825 static void mark_block_used(e2fsck_t ctx, blk_t block)
3827 struct problem_context pctx;
3829 clear_problem_context(&pctx);
3831 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3832 if (!ctx->block_dup_map) {
3833 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3834 _("multiply claimed block map"),
3835 &ctx->block_dup_map);
3838 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3840 /* Should never get here */
3841 ctx->flags |= E2F_FLAG_ABORT;
3845 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3847 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3852 * Adjust the extended attribute block's reference counts at the end
3853 * of pass 1, either by subtracting out references for EA blocks that
3854 * are still referenced in ctx->refcount, or by adding references for
3855 * EA blocks that had extra references as accounted for in
3856 * ctx->refcount_extra.
3858 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3859 char *block_buf, int adjust_sign)
3861 struct ext2_ext_attr_header *header;
3862 struct problem_context pctx;
3863 ext2_filsys fs = ctx->fs;
3868 clear_problem_context(&pctx);
3870 ea_refcount_intr_begin(refcount);
3872 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3875 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3877 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3880 header = (struct ext2_ext_attr_header *) block_buf;
3881 pctx.blkcount = header->h_refcount;
3882 should_be = header->h_refcount + adjust_sign * count;
3883 pctx.num = should_be;
3884 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3885 header->h_refcount = should_be;
3886 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3889 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3897 * Handle processing the extended attribute blocks
3899 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3902 ext2_filsys fs = ctx->fs;
3903 ext2_ino_t ino = pctx->ino;
3904 struct ext2_inode *inode = pctx->inode;
3907 struct ext2_ext_attr_header *header;
3908 struct ext2_ext_attr_entry *entry;
3912 blk = inode->i_file_acl;
3917 * If the Extended attribute flag isn't set, then a non-zero
3918 * file acl means that the inode is corrupted.
3920 * Or if the extended attribute block is an invalid block,
3921 * then the inode is also corrupted.
3923 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3924 (blk < fs->super->s_first_data_block) ||
3925 (blk >= fs->super->s_blocks_count)) {
3926 mark_inode_bad(ctx, ino);
3930 /* If ea bitmap hasn't been allocated, create it */
3931 if (!ctx->block_ea_map) {
3932 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3933 _("ext attr block map"),
3934 &ctx->block_ea_map);
3935 if (pctx->errcode) {
3937 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3938 ctx->flags |= E2F_FLAG_ABORT;
3943 /* Create the EA refcount structure if necessary */
3944 if (!ctx->refcount) {
3945 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3946 if (pctx->errcode) {
3948 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3949 ctx->flags |= E2F_FLAG_ABORT;
3954 /* Have we seen this EA block before? */
3955 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3956 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3958 /* Ooops, this EA was referenced more than it stated */
3959 if (!ctx->refcount_extra) {
3960 pctx->errcode = ea_refcount_create(0,
3961 &ctx->refcount_extra);
3962 if (pctx->errcode) {
3964 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3965 ctx->flags |= E2F_FLAG_ABORT;
3969 ea_refcount_increment(ctx->refcount_extra, blk, 0);
3974 * OK, we haven't seen this EA block yet. So we need to
3978 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3979 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
3981 header = (struct ext2_ext_attr_header *) block_buf;
3982 pctx->blk = inode->i_file_acl;
3983 if (((ctx->ext_attr_ver == 1) &&
3984 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
3985 ((ctx->ext_attr_ver == 2) &&
3986 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
3987 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
3991 if (header->h_blocks != 1) {
3992 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
3996 region = region_create(0, fs->blocksize);
3998 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
3999 ctx->flags |= E2F_FLAG_ABORT;
4002 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4003 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4007 entry = (struct ext2_ext_attr_entry *)(header+1);
4008 end = block_buf + fs->blocksize;
4009 while ((char *)entry < end && *(__u32 *)entry) {
4010 if (region_allocate(region, (char *)entry - (char *)header,
4011 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4012 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4015 if ((ctx->ext_attr_ver == 1 &&
4016 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4017 (ctx->ext_attr_ver == 2 &&
4018 entry->e_name_index == 0)) {
4019 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4022 if (entry->e_value_block != 0) {
4023 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4026 if (entry->e_value_size &&
4027 region_allocate(region, entry->e_value_offs,
4028 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4029 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4032 entry = EXT2_EXT_ATTR_NEXT(entry);
4034 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4035 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4038 region_free(region);
4040 count = header->h_refcount - 1;
4042 ea_refcount_store(ctx->refcount, blk, count);
4043 mark_block_used(ctx, blk);
4044 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4049 inode->i_file_acl = 0;
4050 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4054 /* Returns 1 if bad htree, 0 if OK */
4055 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4056 ext2_ino_t ino FSCK_ATTR((unused)),
4057 struct ext2_inode *inode,
4060 struct ext2_dx_root_info *root;
4061 ext2_filsys fs = ctx->fs;
4065 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4066 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4067 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4068 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4071 blk = inode->i_block[0];
4073 (blk < fs->super->s_first_data_block) ||
4074 (blk >= fs->super->s_blocks_count)) &&
4075 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4078 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4079 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4082 /* XXX should check that beginning matches a directory */
4083 root = (struct ext2_dx_root_info *) (block_buf + 24);
4085 if ((root->reserved_zero || root->info_length < 8) &&
4086 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4089 pctx->num = root->hash_version;
4090 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4091 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4092 (root->hash_version != EXT2_HASH_TEA) &&
4093 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4096 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4097 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4100 pctx->num = root->indirect_levels;
4101 if ((root->indirect_levels > 1) &&
4102 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4109 * This subroutine is called on each inode to account for all of the
4110 * blocks used by that inode.
4112 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4115 ext2_filsys fs = ctx->fs;
4116 struct process_block_struct_1 pb;
4117 ext2_ino_t ino = pctx->ino;
4118 struct ext2_inode *inode = pctx->inode;
4120 int dirty_inode = 0;
4126 pb.num_illegal_blocks = 0;
4127 pb.suppress = 0; pb.clear = 0;
4130 pb.previous_block = 0;
4131 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4132 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4133 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4140 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4141 if (fs->super->s_feature_incompat &
4142 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4145 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4146 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4152 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4155 if (ext2fs_inode_has_valid_blocks(inode))
4156 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4157 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4158 block_buf, process_block, &pb);
4159 end_problem_latch(ctx, PR_LATCH_BLOCK);
4160 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4161 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4164 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4166 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4167 ctx->fs_fragmented++;
4170 inode->i_links_count = 0;
4171 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4172 inode->i_dtime = time(NULL);
4174 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4175 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4176 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4178 * The inode was probably partially accounted for
4179 * before processing was aborted, so we need to
4180 * restart the pass 1 scan.
4182 ctx->flags |= E2F_FLAG_RESTART;
4186 if (inode->i_flags & EXT2_INDEX_FL) {
4187 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4188 inode->i_flags &= ~EXT2_INDEX_FL;
4192 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4196 if (ctx->dirs_to_hash && pb.is_dir &&
4197 !(inode->i_flags & EXT2_INDEX_FL) &&
4198 ((inode->i_size / fs->blocksize) >= 3))
4199 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4201 if (!pb.num_blocks && pb.is_dir) {
4202 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4203 inode->i_links_count = 0;
4204 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4205 inode->i_dtime = time(NULL);
4207 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4208 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4209 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4210 ctx->fs_directory_count--;
4215 pb.num_blocks *= (fs->blocksize / 512);
4218 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4219 if (nblock > (pb.last_block + 1))
4221 else if (nblock < (pb.last_block + 1)) {
4222 if (((pb.last_block + 1) - nblock) >
4223 fs->super->s_prealloc_dir_blocks)
4227 size = EXT2_I_SIZE(inode);
4228 if ((pb.last_block >= 0) &&
4229 (size < (__u64) pb.last_block * fs->blocksize))
4231 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4234 /* i_size for symlinks is checked elsewhere */
4235 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4236 pctx->num = (pb.last_block+1) * fs->blocksize;
4237 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4238 inode->i_size = pctx->num;
4239 if (!LINUX_S_ISDIR(inode->i_mode))
4240 inode->i_size_high = pctx->num >> 32;
4245 if (LINUX_S_ISREG(inode->i_mode) &&
4246 (inode->i_size_high || inode->i_size & 0x80000000UL))
4248 if (pb.num_blocks != inode->i_blocks) {
4249 pctx->num = pb.num_blocks;
4250 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4251 inode->i_blocks = pb.num_blocks;
4258 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4263 * This is a helper function for check_blocks().
4265 static int process_block(ext2_filsys fs,
4267 e2_blkcnt_t blockcnt,
4268 blk_t ref_block FSCK_ATTR((unused)),
4269 int ref_offset FSCK_ATTR((unused)),
4272 struct process_block_struct_1 *p;
4273 struct problem_context *pctx;
4274 blk_t blk = *block_nr;
4279 p = (struct process_block_struct_1 *) priv_data;
4283 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4284 /* todo: Check that the comprblk_fl is high, that the
4285 blkaddr pattern looks right (all non-holes up to
4286 first EXT2FS_COMPRESSED_BLKADDR, then all
4287 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4288 that the feature_incompat bit is high, and that the
4289 inode is a regular file. If we're doing a "full
4290 check" (a concept introduced to e2fsck by e2compr,
4291 meaning that we look at data blocks as well as
4292 metadata) then call some library routine that
4293 checks the compressed data. I'll have to think
4294 about this, because one particularly important
4295 problem to be able to fix is to recalculate the
4296 cluster size if necessary. I think that perhaps
4297 we'd better do most/all e2compr-specific checks
4298 separately, after the non-e2compr checks. If not
4299 doing a full check, it may be useful to test that
4300 the personality is linux; e.g. if it isn't then
4301 perhaps this really is just an illegal block. */
4306 if (p->is_dir == 0) {
4308 * Should never happen, since only directories
4309 * get called with BLOCK_FLAG_HOLE
4312 printf("process_block() called with blk == 0, "
4313 "blockcnt=%d, inode %lu???\n",
4320 if (blockcnt * fs->blocksize < p->inode->i_size) {
4327 * Simplistic fragmentation check. We merely require that the
4328 * file be contiguous. (Which can never be true for really
4329 * big files that are greater than a block group.)
4331 if (!HOLE_BLKADDR(p->previous_block)) {
4332 if (p->previous_block+1 != blk)
4335 p->previous_block = blk;
4337 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4338 problem = PR_1_TOOBIG_DIR;
4339 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4340 problem = PR_1_TOOBIG_REG;
4341 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4342 problem = PR_1_TOOBIG_SYMLINK;
4344 if (blk < fs->super->s_first_data_block ||
4345 blk >= fs->super->s_blocks_count)
4346 problem = PR_1_ILLEGAL_BLOCK_NUM;
4349 p->num_illegal_blocks++;
4350 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4351 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4355 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4357 set_latch_flags(PR_LATCH_BLOCK,
4362 pctx->blkcount = blockcnt;
4363 if (fix_problem(ctx, problem, pctx)) {
4364 blk = *block_nr = 0;
4365 ret_code = BLOCK_CHANGED;
4371 if (p->ino == EXT2_RESIZE_INO) {
4373 * The resize inode has already be sanity checked
4374 * during pass #0 (the superblock checks). All we
4375 * have to do is mark the double indirect block as
4376 * being in use; all of the other blocks are handled
4377 * by mark_table_blocks()).
4379 if (blockcnt == BLOCK_COUNT_DIND)
4380 mark_block_used(ctx, blk);
4382 mark_block_used(ctx, blk);
4385 p->last_block = blockcnt;
4387 if (p->is_dir && (blockcnt >= 0)) {
4388 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4390 if (pctx->errcode) {
4392 pctx->num = blockcnt;
4393 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4394 /* Should never get here */
4395 ctx->flags |= E2F_FLAG_ABORT;
4402 static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4404 e2_blkcnt_t blockcnt,
4405 blk_t ref_block FSCK_ATTR((unused)),
4406 int ref_offset FSCK_ATTR((unused)),
4407 void *priv_data EXT2FS_ATTR((unused)))
4410 * Note: This function processes blocks for the bad blocks
4411 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4414 printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4419 * This routine gets called at the end of pass 1 if bad blocks are
4420 * detected in the superblock, group descriptors, inode_bitmaps, or
4421 * block bitmaps. At this point, all of the blocks have been mapped
4422 * out, so we can try to allocate new block(s) to replace the bad
4425 static void handle_fs_bad_blocks(e2fsck_t ctx)
4427 printf("Bad blocks detected on your filesystem\n"
4428 "You should get your data off as the device will soon die\n");
4432 * This routine marks all blocks which are used by the superblock,
4433 * group descriptors, inode bitmaps, and block bitmaps.
4435 static void mark_table_blocks(e2fsck_t ctx)
4437 ext2_filsys fs = ctx->fs;
4441 struct problem_context pctx;
4443 clear_problem_context(&pctx);
4445 block = fs->super->s_first_data_block;
4446 for (i = 0; i < fs->group_desc_count; i++) {
4449 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4452 * Mark the blocks used for the inode table
4454 if (fs->group_desc[i].bg_inode_table) {
4455 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4456 j < fs->inode_blocks_per_group;
4458 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4461 if (fix_problem(ctx,
4462 PR_1_ITABLE_CONFLICT, &pctx)) {
4463 ctx->invalid_inode_table_flag[i]++;
4464 ctx->invalid_bitmaps++;
4467 ext2fs_mark_block_bitmap(ctx->block_found_map,
4474 * Mark block used for the block bitmap
4476 if (fs->group_desc[i].bg_block_bitmap) {
4477 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4478 fs->group_desc[i].bg_block_bitmap)) {
4479 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4480 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4481 ctx->invalid_block_bitmap_flag[i]++;
4482 ctx->invalid_bitmaps++;
4485 ext2fs_mark_block_bitmap(ctx->block_found_map,
4486 fs->group_desc[i].bg_block_bitmap);
4491 * Mark block used for the inode bitmap
4493 if (fs->group_desc[i].bg_inode_bitmap) {
4494 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4495 fs->group_desc[i].bg_inode_bitmap)) {
4496 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4497 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4498 ctx->invalid_inode_bitmap_flag[i]++;
4499 ctx->invalid_bitmaps++;
4502 ext2fs_mark_block_bitmap(ctx->block_found_map,
4503 fs->group_desc[i].bg_inode_bitmap);
4506 block += fs->super->s_blocks_per_group;
4511 * Thes subroutines short circuits ext2fs_get_blocks and
4512 * ext2fs_check_directory; we use them since we already have the inode
4513 * structure, so there's no point in letting the ext2fs library read
4516 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4519 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4522 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4523 return EXT2_ET_CALLBACK_NOTHANDLED;
4525 for (i=0; i < EXT2_N_BLOCKS; i++)
4526 blocks[i] = ctx->stashed_inode->i_block[i];
4530 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4531 struct ext2_inode *inode)
4533 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4535 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4536 return EXT2_ET_CALLBACK_NOTHANDLED;
4537 *inode = *ctx->stashed_inode;
4541 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4542 struct ext2_inode *inode)
4544 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4546 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4547 *ctx->stashed_inode = *inode;
4548 return EXT2_ET_CALLBACK_NOTHANDLED;
4551 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4553 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4555 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4556 return EXT2_ET_CALLBACK_NOTHANDLED;
4558 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4559 return EXT2_ET_NO_DIRECTORY;
4563 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4565 ext2_filsys fs = ctx->fs;
4568 fs->get_blocks = pass1_get_blocks;
4569 fs->check_directory = pass1_check_directory;
4570 fs->read_inode = pass1_read_inode;
4571 fs->write_inode = pass1_write_inode;
4572 ctx->stashed_ino = 0;
4575 fs->check_directory = 0;
4577 fs->write_inode = 0;
4582 * pass1b.c --- Pass #1b of e2fsck
4584 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4585 * only invoked if pass 1 discovered blocks which are in use by more
4588 * Pass1B scans the data blocks of all the inodes again, generating a
4589 * complete list of duplicate blocks and which inodes have claimed
4592 * Pass1C does a tree-traversal of the filesystem, to determine the
4593 * parent directories of these inodes. This step is necessary so that
4594 * e2fsck can print out the pathnames of affected inodes.
4596 * Pass1D is a reconciliation pass. For each inode with duplicate
4597 * blocks, the user is prompted if s/he would like to clone the file
4598 * (so that the file gets a fresh copy of the duplicated blocks) or
4599 * simply to delete the file.
4604 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4605 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4606 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4608 /* Define an extension to the ext2 library's block count information */
4609 #define BLOCK_COUNT_EXTATTR (-5)
4613 struct block_el *next;
4618 struct inode_el *next;
4623 struct inode_el *inode_list;
4627 * This structure stores information about a particular inode which
4628 * is sharing blocks with other inodes. This information is collected
4629 * to display to the user, so that the user knows what files he or she
4630 * is dealing with, when trying to decide how to resolve the conflict
4631 * of multiply-claimed blocks.
4636 struct ext2_inode inode;
4637 struct block_el *block_list;
4640 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
4641 e2_blkcnt_t blockcnt, blk_t ref_blk,
4642 int ref_offset, void *priv_data);
4643 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4644 struct dup_inode *dp, char *block_buf);
4645 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4646 struct dup_inode *dp, char* block_buf);
4647 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4649 static void pass1b(e2fsck_t ctx, char *block_buf);
4650 static void pass1c(e2fsck_t ctx, char *block_buf);
4651 static void pass1d(e2fsck_t ctx, char *block_buf);
4653 static int dup_inode_count = 0;
4655 static dict_t blk_dict, ino_dict;
4657 static ext2fs_inode_bitmap inode_dup_map;
4659 static int dict_int_cmp(const void *a, const void *b)
4670 * Add a duplicate block record
4672 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4673 struct ext2_inode *inode)
4676 struct dup_block *db;
4677 struct dup_inode *di;
4678 struct block_el *blk_el;
4679 struct inode_el *ino_el;
4681 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4683 db = (struct dup_block *) dnode_get(n);
4685 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4686 sizeof(struct dup_block), "duplicate block header");
4689 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4691 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4692 sizeof(struct inode_el), "inode element");
4693 ino_el->inode = ino;
4694 ino_el->next = db->inode_list;
4695 db->inode_list = ino_el;
4698 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4700 di = (struct dup_inode *) dnode_get(n);
4702 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4703 sizeof(struct dup_inode), "duplicate inode header");
4704 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0;
4705 di->num_dupblocks = 0;
4708 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4710 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4711 sizeof(struct block_el), "block element");
4712 blk_el->block = blk;
4713 blk_el->next = di->block_list;
4714 di->block_list = blk_el;
4715 di->num_dupblocks++;
4719 * Free a duplicate inode record
4721 static void inode_dnode_free(dnode_t *node)
4723 struct dup_inode *di;
4724 struct block_el *p, *next;
4726 di = (struct dup_inode *) dnode_get(node);
4727 for (p = di->block_list; p; p = next) {
4735 * Free a duplicate block record
4737 static void block_dnode_free(dnode_t *node)
4739 struct dup_block *db;
4740 struct inode_el *p, *next;
4742 db = (struct dup_block *) dnode_get(node);
4743 for (p = db->inode_list; p; p = next) {
4752 * Main procedure for handling duplicate blocks
4754 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4756 ext2_filsys fs = ctx->fs;
4757 struct problem_context pctx;
4759 clear_problem_context(&pctx);
4761 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4762 _("multiply claimed inode map"), &inode_dup_map);
4764 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4765 ctx->flags |= E2F_FLAG_ABORT;
4769 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4770 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4771 dict_set_allocator(&ino_dict, inode_dnode_free);
4772 dict_set_allocator(&blk_dict, block_dnode_free);
4774 pass1b(ctx, block_buf);
4775 pass1c(ctx, block_buf);
4776 pass1d(ctx, block_buf);
4779 * Time to free all of the accumulated data structures that we
4780 * don't need anymore.
4782 dict_free_nodes(&ino_dict);
4783 dict_free_nodes(&blk_dict);
4787 * Scan the inodes looking for inodes that contain duplicate blocks.
4789 struct process_block_struct_1b {
4793 struct ext2_inode *inode;
4794 struct problem_context *pctx;
4797 static void pass1b(e2fsck_t ctx, char *block_buf)
4799 ext2_filsys fs = ctx->fs;
4801 struct ext2_inode inode;
4802 ext2_inode_scan scan;
4803 struct process_block_struct_1b pb;
4804 struct problem_context pctx;
4806 clear_problem_context(&pctx);
4808 if (!(ctx->options & E2F_OPT_PREEN))
4809 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4810 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4813 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4814 ctx->flags |= E2F_FLAG_ABORT;
4817 ctx->stashed_inode = &inode;
4820 pctx.str = "pass1b";
4822 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4823 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4826 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4827 ctx->flags |= E2F_FLAG_ABORT;
4832 pctx.ino = ctx->stashed_ino = ino;
4833 if ((ino != EXT2_BAD_INO) &&
4834 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4841 if (ext2fs_inode_has_valid_blocks(&inode) ||
4842 (ino == EXT2_BAD_INO))
4843 pctx.errcode = ext2fs_block_iterate2(fs, ino,
4844 0, block_buf, process_pass1b_block, &pb);
4845 if (inode.i_file_acl)
4846 process_pass1b_block(fs, &inode.i_file_acl,
4847 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4848 if (pb.dup_blocks) {
4849 end_problem_latch(ctx, PR_LATCH_DBLOCK);
4850 if (ino >= EXT2_FIRST_INODE(fs->super) ||
4851 ino == EXT2_ROOT_INO)
4855 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4857 ext2fs_close_inode_scan(scan);
4858 e2fsck_use_inode_shortcuts(ctx, 0);
4861 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4863 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4864 blk_t ref_blk FSCK_ATTR((unused)),
4865 int ref_offset FSCK_ATTR((unused)),
4868 struct process_block_struct_1b *p;
4871 if (HOLE_BLKADDR(*block_nr))
4873 p = (struct process_block_struct_1b *) priv_data;
4876 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4879 /* OK, this is a duplicate block */
4880 if (p->ino != EXT2_BAD_INO) {
4881 p->pctx->blk = *block_nr;
4882 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4885 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4887 add_dupe(ctx, p->ino, *block_nr, p->inode);
4893 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4894 * is used so that we can print pathnames when prompting the user for
4897 struct search_dir_struct {
4899 ext2_ino_t first_inode;
4900 ext2_ino_t max_inode;
4903 static int search_dirent_proc(ext2_ino_t dir, int entry,
4904 struct ext2_dir_entry *dirent,
4905 int offset FSCK_ATTR((unused)),
4906 int blocksize FSCK_ATTR((unused)),
4907 char *buf FSCK_ATTR((unused)),
4910 struct search_dir_struct *sd;
4911 struct dup_inode *p;
4914 sd = (struct search_dir_struct *) priv_data;
4916 if (dirent->inode > sd->max_inode)
4917 /* Should abort this inode, but not everything */
4920 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4921 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4924 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4927 p = (struct dup_inode *) dnode_get(n);
4931 return sd->count ? 0 : DIRENT_ABORT;
4935 static void pass1c(e2fsck_t ctx, char *block_buf)
4937 ext2_filsys fs = ctx->fs;
4938 struct search_dir_struct sd;
4939 struct problem_context pctx;
4941 clear_problem_context(&pctx);
4943 if (!(ctx->options & E2F_OPT_PREEN))
4944 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4947 * Search through all directories to translate inodes to names
4948 * (by searching for the containing directory for that inode.)
4950 sd.count = dup_inode_count;
4951 sd.first_inode = EXT2_FIRST_INODE(fs->super);
4952 sd.max_inode = fs->super->s_inodes_count;
4953 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4954 search_dirent_proc, &sd);
4957 static void pass1d(e2fsck_t ctx, char *block_buf)
4959 ext2_filsys fs = ctx->fs;
4960 struct dup_inode *p, *t;
4961 struct dup_block *q;
4962 ext2_ino_t *shared, ino;
4967 struct problem_context pctx;
4972 clear_problem_context(&pctx);
4974 if (!(ctx->options & E2F_OPT_PREEN))
4975 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
4976 e2fsck_read_bitmaps(ctx);
4978 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
4979 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
4980 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
4981 sizeof(ext2_ino_t) * dict_count(&ino_dict),
4982 "Shared inode list");
4983 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
4984 p = (struct dup_inode *) dnode_get(n);
4987 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
4988 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
4992 * Find all of the inodes which share blocks with this
4993 * one. First we find all of the duplicate blocks
4994 * belonging to this inode, and then search each block
4995 * get the list of inodes, and merge them together.
4997 for (s = p->block_list; s; s = s->next) {
4998 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5000 continue; /* Should never happen... */
5001 q = (struct dup_block *) dnode_get(m);
5004 if (check_if_fs_block(ctx, s->block)) {
5010 * Add all inodes used by this block to the
5011 * shared[] --- which is a unique list, so
5012 * if an inode is already in shared[], don't
5015 for (r = q->inode_list; r; r = r->next) {
5016 if (r->inode == ino)
5018 for (i = 0; i < shared_len; i++)
5019 if (shared[i] == r->inode)
5021 if (i == shared_len) {
5022 shared[shared_len++] = r->inode;
5028 * Report the inode that we are working on
5030 pctx.inode = &p->inode;
5033 pctx.blkcount = p->num_dupblocks;
5034 pctx.num = meta_data ? shared_len+1 : shared_len;
5035 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5040 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5042 for (i = 0; i < shared_len; i++) {
5043 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5045 continue; /* should never happen */
5046 t = (struct dup_inode *) dnode_get(m);
5048 * Report the inode that we are sharing with
5050 pctx.inode = &t->inode;
5051 pctx.ino = shared[i];
5053 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5056 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5059 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5060 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5062 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5066 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5067 delete_file(ctx, ino, p, block_buf);
5069 ext2fs_unmark_valid(fs);
5071 ext2fs_free_mem(&shared);
5075 * Drop the refcount on the dup_block structure, and clear the entry
5076 * in the block_dup_map if appropriate.
5078 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5081 if (p->num_bad <= 0 ||
5082 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5083 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5086 static int delete_file_block(ext2_filsys fs,
5088 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5089 blk_t ref_block FSCK_ATTR((unused)),
5090 int ref_offset FSCK_ATTR((unused)),
5093 struct process_block_struct_1b *pb;
5094 struct dup_block *p;
5098 pb = (struct process_block_struct_1b *) priv_data;
5101 if (HOLE_BLKADDR(*block_nr))
5104 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5105 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5107 p = (struct dup_block *) dnode_get(n);
5108 decrement_badcount(ctx, *block_nr, p);
5110 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5113 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5114 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5120 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5121 struct dup_inode *dp, char* block_buf)
5123 ext2_filsys fs = ctx->fs;
5124 struct process_block_struct_1b pb;
5125 struct ext2_inode inode;
5126 struct problem_context pctx;
5129 clear_problem_context(&pctx);
5130 pctx.ino = pb.ino = ino;
5131 pb.dup_blocks = dp->num_dupblocks;
5133 pctx.str = "delete_file";
5135 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5136 if (ext2fs_inode_has_valid_blocks(&inode))
5137 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5138 delete_file_block, &pb);
5140 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5141 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5142 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5143 if (ctx->inode_bad_map)
5144 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5145 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5147 /* Inode may have changed by block_iterate, so reread it */
5148 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5149 inode.i_links_count = 0;
5150 inode.i_dtime = time(NULL);
5151 if (inode.i_file_acl &&
5152 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5154 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5155 block_buf, -1, &count);
5156 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5161 pctx.blk = inode.i_file_acl;
5162 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5165 * If the count is zero, then arrange to have the
5166 * block deleted. If the block is in the block_dup_map,
5167 * also call delete_file_block since it will take care
5168 * of keeping the accounting straight.
5171 ext2fs_test_block_bitmap(ctx->block_dup_map,
5173 delete_file_block(fs, &inode.i_file_acl,
5174 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5176 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5179 struct clone_struct {
5186 static int clone_file_block(ext2_filsys fs,
5188 e2_blkcnt_t blockcnt,
5189 blk_t ref_block FSCK_ATTR((unused)),
5190 int ref_offset FSCK_ATTR((unused)),
5193 struct dup_block *p;
5196 struct clone_struct *cs = (struct clone_struct *) priv_data;
5202 if (HOLE_BLKADDR(*block_nr))
5205 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5206 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5208 p = (struct dup_block *) dnode_get(n);
5209 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5212 cs->errcode = retval;
5215 if (cs->dir && (blockcnt >= 0)) {
5216 retval = ext2fs_set_dir_block(fs->dblist,
5217 cs->dir, new_block, blockcnt);
5219 cs->errcode = retval;
5224 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5227 cs->errcode = retval;
5230 retval = io_channel_write_blk(fs->io, new_block, 1,
5233 cs->errcode = retval;
5236 decrement_badcount(ctx, *block_nr, p);
5237 *block_nr = new_block;
5238 ext2fs_mark_block_bitmap(ctx->block_found_map,
5240 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5241 return BLOCK_CHANGED;
5243 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5249 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5250 struct dup_inode *dp, char* block_buf)
5252 ext2_filsys fs = ctx->fs;
5254 struct clone_struct cs;
5255 struct problem_context pctx;
5258 struct inode_el *ino_el;
5259 struct dup_block *db;
5260 struct dup_inode *di;
5262 clear_problem_context(&pctx);
5266 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5270 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5274 pctx.str = "clone_file";
5275 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5276 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5277 clone_file_block, &cs);
5278 ext2fs_mark_bb_dirty(fs);
5280 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5281 retval = pctx.errcode;
5285 bb_error_msg(_("returned from clone_file_block"));
5286 retval = cs.errcode;
5289 /* The inode may have changed on disk, so we have to re-read it */
5290 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5291 blk = dp->inode.i_file_acl;
5292 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5293 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5295 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5297 * If we cloned the EA block, find all other inodes
5298 * which refered to that EA block, and modify
5299 * them to point to the new EA block.
5301 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5302 db = (struct dup_block *) dnode_get(n);
5303 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5304 if (ino_el->inode == ino)
5306 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5307 di = (struct dup_inode *) dnode_get(n);
5308 if (di->inode.i_file_acl == blk) {
5309 di->inode.i_file_acl = dp->inode.i_file_acl;
5310 e2fsck_write_inode(ctx, ino_el->inode,
5311 &di->inode, "clone file EA");
5312 decrement_badcount(ctx, blk, db);
5318 ext2fs_free_mem(&cs.buf);
5323 * This routine returns 1 if a block overlaps with one of the superblocks,
5324 * group descriptors, inode bitmaps, or block bitmaps.
5326 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5328 ext2_filsys fs = ctx->fs;
5332 block = fs->super->s_first_data_block;
5333 for (i = 0; i < fs->group_desc_count; i++) {
5335 /* Check superblocks/block group descriptros */
5336 if (ext2fs_bg_has_super(fs, i)) {
5337 if (test_block >= block &&
5338 (test_block <= block + fs->desc_blocks))
5342 /* Check the inode table */
5343 if ((fs->group_desc[i].bg_inode_table) &&
5344 (test_block >= fs->group_desc[i].bg_inode_table) &&
5345 (test_block < (fs->group_desc[i].bg_inode_table +
5346 fs->inode_blocks_per_group)))
5349 /* Check the bitmap blocks */
5350 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5351 (test_block == fs->group_desc[i].bg_inode_bitmap))
5354 block += fs->super->s_blocks_per_group;
5359 * pass2.c --- check directory structure
5361 * Pass 2 of e2fsck iterates through all active directory inodes, and
5362 * applies to following tests to each directory entry in the directory
5363 * blocks in the inodes:
5365 * - The length of the directory entry (rec_len) should be at
5366 * least 8 bytes, and no more than the remaining space
5367 * left in the directory block.
5368 * - The length of the name in the directory entry (name_len)
5369 * should be less than (rec_len - 8).
5370 * - The inode number in the directory entry should be within
5372 * - The inode number should refer to a in-use inode.
5373 * - The first entry should be '.', and its inode should be
5374 * the inode of the directory.
5375 * - The second entry should be '..'.
5377 * To minimize disk seek time, the directory blocks are processed in
5378 * sorted order of block numbers.
5380 * Pass 2 also collects the following information:
5381 * - The inode numbers of the subdirectories for each directory.
5383 * Pass 2 relies on the following information from previous passes:
5384 * - The directory information collected in pass 1.
5385 * - The inode_used_map bitmap
5386 * - The inode_bad_map bitmap
5387 * - The inode_dir_map bitmap
5389 * Pass 2 frees the following data structures
5390 * - The inode_bad_map bitmap
5391 * - The inode_reg_map bitmap
5395 * Keeps track of how many times an inode is referenced.
5397 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5398 static int check_dir_block(ext2_filsys fs,
5399 struct ext2_db_entry *dir_blocks_info,
5401 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5402 struct problem_context *pctx);
5403 static int update_dir_block(ext2_filsys fs,
5405 e2_blkcnt_t blockcnt,
5409 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5410 static int htree_depth(struct dx_dir_info *dx_dir,
5411 struct dx_dirblock_info *dx_db);
5412 static int special_dir_block_cmp(const void *a, const void *b);
5414 struct check_dir_struct {
5416 struct problem_context pctx;
5421 static void e2fsck_pass2(e2fsck_t ctx)
5423 struct ext2_super_block *sb = ctx->fs->super;
5424 struct problem_context pctx;
5425 ext2_filsys fs = ctx->fs;
5427 struct dir_info *dir;
5428 struct check_dir_struct cd;
5429 struct dx_dir_info *dx_dir;
5430 struct dx_dirblock_info *dx_db, *dx_parent;
5436 clear_problem_context(&cd.pctx);
5440 if (!(ctx->options & E2F_OPT_PREEN))
5441 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5443 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5444 0, ctx->inode_link_info,
5446 if (cd.pctx.errcode) {
5447 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5448 ctx->flags |= E2F_FLAG_ABORT;
5451 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5452 "directory scan buffer");
5455 * Set up the parent pointer for the root directory, if
5456 * present. (If the root directory is not present, we will
5457 * create it in pass 3.)
5459 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5461 dir->parent = EXT2_ROOT_INO;
5466 cd.max = ext2fs_dblist_count(fs->dblist);
5469 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5471 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5472 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5474 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5476 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5478 if (cd.pctx.errcode) {
5479 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5480 ctx->flags |= E2F_FLAG_ABORT;
5485 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5486 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5488 if (dx_dir->numblocks == 0)
5490 clear_problem_context(&pctx);
5492 pctx.dir = dx_dir->ino;
5493 dx_db = dx_dir->dx_block;
5494 if (dx_db->flags & DX_FLAG_REFERENCED)
5495 dx_db->flags |= DX_FLAG_DUP_REF;
5497 dx_db->flags |= DX_FLAG_REFERENCED;
5499 * Find all of the first and last leaf blocks, and
5500 * update their parent's min and max hash values
5502 for (b=0, dx_db = dx_dir->dx_block;
5503 b < dx_dir->numblocks;
5505 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5506 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5508 dx_parent = &dx_dir->dx_block[dx_db->parent];
5510 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5512 if (dx_db->flags & DX_FLAG_FIRST)
5513 dx_parent->min_hash = dx_db->min_hash;
5515 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5517 if (dx_db->flags & DX_FLAG_LAST)
5518 dx_parent->max_hash = dx_db->max_hash;
5521 for (b=0, dx_db = dx_dir->dx_block;
5522 b < dx_dir->numblocks;
5525 pctx.group = dx_db->parent;
5527 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5528 (dx_db->min_hash < dx_db->node_min_hash)) {
5529 pctx.blk = dx_db->min_hash;
5530 pctx.blk2 = dx_db->node_min_hash;
5531 code = PR_2_HTREE_MIN_HASH;
5532 fix_problem(ctx, code, &pctx);
5535 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5536 depth = htree_depth(dx_dir, dx_db);
5537 if (depth != dx_dir->depth) {
5538 code = PR_2_HTREE_BAD_DEPTH;
5539 fix_problem(ctx, code, &pctx);
5544 * This test doesn't apply for the root block
5548 (dx_db->max_hash > dx_db->node_max_hash)) {
5549 pctx.blk = dx_db->max_hash;
5550 pctx.blk2 = dx_db->node_max_hash;
5551 code = PR_2_HTREE_MAX_HASH;
5552 fix_problem(ctx, code, &pctx);
5555 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5556 code = PR_2_HTREE_NOTREF;
5557 fix_problem(ctx, code, &pctx);
5559 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5560 code = PR_2_HTREE_DUPREF;
5561 fix_problem(ctx, code, &pctx);
5567 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5568 clear_htree(ctx, dx_dir->ino);
5569 dx_dir->numblocks = 0;
5573 ext2fs_free_mem(&buf);
5574 ext2fs_free_dblist(fs->dblist);
5576 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5577 ctx->inode_bad_map = 0;
5578 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5579 ctx->inode_reg_map = 0;
5581 clear_problem_context(&pctx);
5582 if (ctx->large_files) {
5583 if (!(sb->s_feature_ro_compat &
5584 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5585 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5586 sb->s_feature_ro_compat |=
5587 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5588 ext2fs_mark_super_dirty(fs);
5590 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5591 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5592 ext2fs_update_dynamic_rev(fs);
5593 ext2fs_mark_super_dirty(fs);
5595 } else if (!ctx->large_files &&
5596 (sb->s_feature_ro_compat &
5597 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5598 if (fs->flags & EXT2_FLAG_RW) {
5599 sb->s_feature_ro_compat &=
5600 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5601 ext2fs_mark_super_dirty(fs);
5607 #define MAX_DEPTH 32000
5608 static int htree_depth(struct dx_dir_info *dx_dir,
5609 struct dx_dirblock_info *dx_db)
5613 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5614 dx_db = &dx_dir->dx_block[dx_db->parent];
5620 static int dict_de_cmp(const void *a, const void *b)
5622 const struct ext2_dir_entry *de_a, *de_b;
5625 de_a = (const struct ext2_dir_entry *) a;
5626 a_len = de_a->name_len & 0xFF;
5627 de_b = (const struct ext2_dir_entry *) b;
5628 b_len = de_b->name_len & 0xFF;
5631 return (a_len - b_len);
5633 return strncmp(de_a->name, de_b->name, a_len);
5637 * This is special sort function that makes sure that directory blocks
5638 * with a dirblock of zero are sorted to the beginning of the list.
5639 * This guarantees that the root node of the htree directories are
5640 * processed first, so we know what hash version to use.
5642 static int special_dir_block_cmp(const void *a, const void *b)
5644 const struct ext2_db_entry *db_a =
5645 (const struct ext2_db_entry *) a;
5646 const struct ext2_db_entry *db_b =
5647 (const struct ext2_db_entry *) b;
5649 if (db_a->blockcnt && !db_b->blockcnt)
5652 if (!db_a->blockcnt && db_b->blockcnt)
5655 if (db_a->blk != db_b->blk)
5656 return (int) (db_a->blk - db_b->blk);
5658 if (db_a->ino != db_b->ino)
5659 return (int) (db_a->ino - db_b->ino);
5661 return (int) (db_a->blockcnt - db_b->blockcnt);
5666 * Make sure the first entry in the directory is '.', and that the
5667 * directory entry is sane.
5669 static int check_dot(e2fsck_t ctx,
5670 struct ext2_dir_entry *dirent,
5671 ext2_ino_t ino, struct problem_context *pctx)
5673 struct ext2_dir_entry *nextdir;
5680 problem = PR_2_MISSING_DOT;
5681 else if (((dirent->name_len & 0xFF) != 1) ||
5682 (dirent->name[0] != '.'))
5683 problem = PR_2_1ST_NOT_DOT;
5684 else if (dirent->name[1] != '\0')
5685 problem = PR_2_DOT_NULL_TERM;
5688 if (fix_problem(ctx, problem, pctx)) {
5689 if (dirent->rec_len < 12)
5690 dirent->rec_len = 12;
5691 dirent->inode = ino;
5692 dirent->name_len = 1;
5693 dirent->name[0] = '.';
5694 dirent->name[1] = '\0';
5699 if (dirent->inode != ino) {
5700 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5701 dirent->inode = ino;
5705 if (dirent->rec_len > 12) {
5706 new_len = dirent->rec_len - 12;
5709 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5710 nextdir = (struct ext2_dir_entry *)
5711 ((char *) dirent + 12);
5712 dirent->rec_len = 12;
5713 nextdir->rec_len = new_len;
5715 nextdir->name_len = 0;
5724 * Make sure the second entry in the directory is '..', and that the
5725 * directory entry is sane. We do not check the inode number of '..'
5726 * here; this gets done in pass 3.
5728 static int check_dotdot(e2fsck_t ctx,
5729 struct ext2_dir_entry *dirent,
5730 struct dir_info *dir, struct problem_context *pctx)
5735 problem = PR_2_MISSING_DOT_DOT;
5736 else if (((dirent->name_len & 0xFF) != 2) ||
5737 (dirent->name[0] != '.') ||
5738 (dirent->name[1] != '.'))
5739 problem = PR_2_2ND_NOT_DOT_DOT;
5740 else if (dirent->name[2] != '\0')
5741 problem = PR_2_DOT_DOT_NULL_TERM;
5744 if (fix_problem(ctx, problem, pctx)) {
5745 if (dirent->rec_len < 12)
5746 dirent->rec_len = 12;
5748 * Note: we don't have the parent inode just
5749 * yet, so we will fill it in with the root
5750 * inode. This will get fixed in pass 3.
5752 dirent->inode = EXT2_ROOT_INO;
5753 dirent->name_len = 2;
5754 dirent->name[0] = '.';
5755 dirent->name[1] = '.';
5756 dirent->name[2] = '\0';
5761 dir->dotdot = dirent->inode;
5766 * Check to make sure a directory entry doesn't contain any illegal
5769 static int check_name(e2fsck_t ctx,
5770 struct ext2_dir_entry *dirent,
5771 struct problem_context *pctx)
5777 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5778 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5780 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5783 dirent->name[i] = '.';
5792 * Check the directory filetype (if present)
5796 * Given a mode, return the ext2 file type
5798 static int ext2_file_type(unsigned int mode)
5800 if (LINUX_S_ISREG(mode))
5801 return EXT2_FT_REG_FILE;
5803 if (LINUX_S_ISDIR(mode))
5806 if (LINUX_S_ISCHR(mode))
5807 return EXT2_FT_CHRDEV;
5809 if (LINUX_S_ISBLK(mode))
5810 return EXT2_FT_BLKDEV;
5812 if (LINUX_S_ISLNK(mode))
5813 return EXT2_FT_SYMLINK;
5815 if (LINUX_S_ISFIFO(mode))
5816 return EXT2_FT_FIFO;
5818 if (LINUX_S_ISSOCK(mode))
5819 return EXT2_FT_SOCK;
5824 static int check_filetype(e2fsck_t ctx,
5825 struct ext2_dir_entry *dirent,
5826 struct problem_context *pctx)
5828 int filetype = dirent->name_len >> 8;
5829 int should_be = EXT2_FT_UNKNOWN;
5830 struct ext2_inode inode;
5832 if (!(ctx->fs->super->s_feature_incompat &
5833 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5834 if (filetype == 0 ||
5835 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5837 dirent->name_len = dirent->name_len & 0xFF;
5841 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5842 should_be = EXT2_FT_DIR;
5843 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5845 should_be = EXT2_FT_REG_FILE;
5846 } else if (ctx->inode_bad_map &&
5847 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5851 e2fsck_read_inode(ctx, dirent->inode, &inode,
5853 should_be = ext2_file_type(inode.i_mode);
5855 if (filetype == should_be)
5857 pctx->num = should_be;
5859 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5863 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5868 static void parse_int_node(ext2_filsys fs,
5869 struct ext2_db_entry *db,
5870 struct check_dir_struct *cd,
5871 struct dx_dir_info *dx_dir,
5874 struct ext2_dx_root_info *root;
5875 struct ext2_dx_entry *ent;
5876 struct ext2_dx_countlimit *limit;
5877 struct dx_dirblock_info *dx_db;
5878 int i, expect_limit, count;
5880 ext2_dirhash_t min_hash = 0xffffffff;
5881 ext2_dirhash_t max_hash = 0;
5882 ext2_dirhash_t hash = 0, prev_hash;
5884 if (db->blockcnt == 0) {
5885 root = (struct ext2_dx_root_info *) (block_buf + 24);
5886 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5888 ent = (struct ext2_dx_entry *) (block_buf+8);
5890 limit = (struct ext2_dx_countlimit *) ent;
5892 count = ext2fs_le16_to_cpu(limit->count);
5893 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5894 sizeof(struct ext2_dx_entry);
5895 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5896 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5897 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5898 goto clear_and_exit;
5900 if (count > expect_limit) {
5901 cd->pctx.num = count;
5902 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5903 goto clear_and_exit;
5904 count = expect_limit;
5907 for (i=0; i < count; i++) {
5909 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5910 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5911 /* Check to make sure the block is valid */
5912 if (blk > (blk_t) dx_dir->numblocks) {
5914 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5916 goto clear_and_exit;
5918 if (hash < prev_hash &&
5919 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5920 goto clear_and_exit;
5921 dx_db = &dx_dir->dx_block[blk];
5922 if (dx_db->flags & DX_FLAG_REFERENCED) {
5923 dx_db->flags |= DX_FLAG_DUP_REF;
5925 dx_db->flags |= DX_FLAG_REFERENCED;
5926 dx_db->parent = db->blockcnt;
5928 if (hash < min_hash)
5930 if (hash > max_hash)
5932 dx_db->node_min_hash = hash;
5934 dx_db->node_max_hash =
5935 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5937 dx_db->node_max_hash = 0xfffffffe;
5938 dx_db->flags |= DX_FLAG_LAST;
5941 dx_db->flags |= DX_FLAG_FIRST;
5943 dx_db = &dx_dir->dx_block[db->blockcnt];
5944 dx_db->min_hash = min_hash;
5945 dx_db->max_hash = max_hash;
5949 clear_htree(cd->ctx, cd->pctx.ino);
5950 dx_dir->numblocks = 0;
5952 #endif /* ENABLE_HTREE */
5955 * Given a busted directory, try to salvage it somehow.
5958 static void salvage_directory(ext2_filsys fs,
5959 struct ext2_dir_entry *dirent,
5960 struct ext2_dir_entry *prev,
5961 unsigned int *offset)
5963 char *cp = (char *) dirent;
5964 int left = fs->blocksize - *offset - dirent->rec_len;
5965 int name_len = dirent->name_len & 0xFF;
5968 * Special case of directory entry of size 8: copy what's left
5969 * of the directory block up to cover up the invalid hole.
5971 if ((left >= 12) && (dirent->rec_len == 8)) {
5972 memmove(cp, cp+8, left);
5973 memset(cp + left, 0, 8);
5977 * If the directory entry overruns the end of the directory
5978 * block, and the name is small enough to fit, then adjust the
5982 (name_len + 8 <= dirent->rec_len + left) &&
5983 dirent->inode <= fs->super->s_inodes_count &&
5984 strnlen(dirent->name, name_len) == name_len) {
5985 dirent->rec_len += left;
5989 * If the directory entry is a multiple of four, so it is
5990 * valid, let the previous directory entry absorb the invalid
5993 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
5994 prev->rec_len += dirent->rec_len;
5995 *offset += dirent->rec_len;
5999 * Default salvage method --- kill all of the directory
6000 * entries for the rest of the block. We will either try to
6001 * absorb it into the previous directory entry, or create a
6002 * new empty directory entry the rest of the directory block.
6005 prev->rec_len += fs->blocksize - *offset;
6006 *offset = fs->blocksize;
6008 dirent->rec_len = fs->blocksize - *offset;
6009 dirent->name_len = 0;
6014 static int check_dir_block(ext2_filsys fs,
6015 struct ext2_db_entry *db,
6018 struct dir_info *subdir, *dir;
6019 struct dx_dir_info *dx_dir;
6021 struct dx_dirblock_info *dx_db = 0;
6022 #endif /* ENABLE_HTREE */
6023 struct ext2_dir_entry *dirent, *prev;
6024 ext2_dirhash_t hash;
6025 unsigned int offset = 0;
6026 int dir_modified = 0;
6028 blk_t block_nr = db->blk;
6029 ext2_ino_t ino = db->ino;
6031 struct check_dir_struct *cd;
6035 struct ext2_dx_root_info *root;
6036 struct ext2_dx_countlimit *limit;
6037 static dict_t de_dict;
6038 struct problem_context pctx;
6041 cd = (struct check_dir_struct *) priv_data;
6045 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6046 return DIRENT_ABORT;
6048 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6049 return DIRENT_ABORT;
6052 * Make sure the inode is still in use (could have been
6053 * deleted in the duplicate/bad blocks pass.
6055 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6059 cd->pctx.blk = block_nr;
6060 cd->pctx.blkcount = db->blockcnt;
6062 cd->pctx.dirent = 0;
6066 if (allocate_dir_block(ctx, db, &cd->pctx))
6076 if (ctx->dirs_to_hash &&
6077 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6080 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6081 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6082 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6083 if (cd->pctx.errcode) {
6084 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6085 ctx->flags |= E2F_FLAG_ABORT;
6086 return DIRENT_ABORT;
6088 memset(buf, 0, fs->blocksize);
6091 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6092 if (dx_dir && dx_dir->numblocks) {
6093 if (db->blockcnt >= dx_dir->numblocks) {
6094 printf("XXX should never happen!!!\n");
6097 dx_db = &dx_dir->dx_block[db->blockcnt];
6098 dx_db->type = DX_DIRBLOCK_LEAF;
6099 dx_db->phys = block_nr;
6100 dx_db->min_hash = ~0;
6101 dx_db->max_hash = 0;
6103 dirent = (struct ext2_dir_entry *) buf;
6104 limit = (struct ext2_dx_countlimit *) (buf+8);
6105 if (db->blockcnt == 0) {
6106 root = (struct ext2_dx_root_info *) (buf + 24);
6107 dx_db->type = DX_DIRBLOCK_ROOT;
6108 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6109 if ((root->reserved_zero ||
6110 root->info_length < 8 ||
6111 root->indirect_levels > 1) &&
6112 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6113 clear_htree(ctx, ino);
6114 dx_dir->numblocks = 0;
6117 dx_dir->hashversion = root->hash_version;
6118 dx_dir->depth = root->indirect_levels + 1;
6119 } else if ((dirent->inode == 0) &&
6120 (dirent->rec_len == fs->blocksize) &&
6121 (dirent->name_len == 0) &&
6122 (ext2fs_le16_to_cpu(limit->limit) ==
6123 ((fs->blocksize-8) /
6124 sizeof(struct ext2_dx_entry))))
6125 dx_db->type = DX_DIRBLOCK_NODE;
6127 #endif /* ENABLE_HTREE */
6129 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6133 dirent = (struct ext2_dir_entry *) (buf + offset);
6134 cd->pctx.dirent = dirent;
6135 cd->pctx.num = offset;
6136 if (((offset + dirent->rec_len) > fs->blocksize) ||
6137 (dirent->rec_len < 12) ||
6138 ((dirent->rec_len % 4) != 0) ||
6139 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6140 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6141 salvage_directory(fs, dirent, prev, &offset);
6145 goto abort_free_dict;
6147 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6148 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6149 dirent->name_len = EXT2_NAME_LEN;
6154 if (dot_state == 0) {
6155 if (check_dot(ctx, dirent, ino, &cd->pctx))
6157 } else if (dot_state == 1) {
6158 dir = e2fsck_get_dir_info(ctx, ino);
6160 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6161 goto abort_free_dict;
6163 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6165 } else if (dirent->inode == ino) {
6166 problem = PR_2_LINK_DOT;
6167 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6177 * Make sure the inode listed is a legal one.
6179 if (((dirent->inode != EXT2_ROOT_INO) &&
6180 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6181 (dirent->inode > fs->super->s_inodes_count)) {
6182 problem = PR_2_BAD_INO;
6183 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6186 * If the inode is unused, offer to clear it.
6188 problem = PR_2_UNUSED_INODE;
6189 } else if ((dot_state > 1) &&
6190 ((dirent->name_len & 0xFF) == 1) &&
6191 (dirent->name[0] == '.')) {
6193 * If there's a '.' entry in anything other
6194 * than the first directory entry, it's a
6195 * duplicate entry that should be removed.
6197 problem = PR_2_DUP_DOT;
6198 } else if ((dot_state > 1) &&
6199 ((dirent->name_len & 0xFF) == 2) &&
6200 (dirent->name[0] == '.') &&
6201 (dirent->name[1] == '.')) {
6203 * If there's a '..' entry in anything other
6204 * than the second directory entry, it's a
6205 * duplicate entry that should be removed.
6207 problem = PR_2_DUP_DOT_DOT;
6208 } else if ((dot_state > 1) &&
6209 (dirent->inode == EXT2_ROOT_INO)) {
6211 * Don't allow links to the root directory.
6212 * We check this specially to make sure we
6213 * catch this error case even if the root
6214 * directory hasn't been created yet.
6216 problem = PR_2_LINK_ROOT;
6217 } else if ((dot_state > 1) &&
6218 (dirent->name_len & 0xFF) == 0) {
6220 * Don't allow zero-length directory names.
6222 problem = PR_2_NULL_NAME;
6226 if (fix_problem(ctx, problem, &cd->pctx)) {
6231 ext2fs_unmark_valid(fs);
6232 if (problem == PR_2_BAD_INO)
6238 * If the inode was marked as having bad fields in
6239 * pass1, process it and offer to fix/clear it.
6240 * (We wait until now so that we can display the
6241 * pathname to the user.)
6243 if (ctx->inode_bad_map &&
6244 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6246 if (e2fsck_process_bad_inode(ctx, ino,
6248 buf + fs->blocksize)) {
6253 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6254 return DIRENT_ABORT;
6257 if (check_name(ctx, dirent, &cd->pctx))
6260 if (check_filetype(ctx, dirent, &cd->pctx))
6265 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6266 (dirent->name_len & 0xFF),
6267 fs->super->s_hash_seed, &hash, 0);
6268 if (hash < dx_db->min_hash)
6269 dx_db->min_hash = hash;
6270 if (hash > dx_db->max_hash)
6271 dx_db->max_hash = hash;
6276 * If this is a directory, then mark its parent in its
6277 * dir_info structure. If the parent field is already
6278 * filled in, then this directory has more than one
6279 * hard link. We assume the first link is correct,
6280 * and ask the user if he/she wants to clear this one.
6282 if ((dot_state > 1) &&
6283 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6285 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6287 cd->pctx.ino = dirent->inode;
6288 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6289 goto abort_free_dict;
6291 if (subdir->parent) {
6292 cd->pctx.ino2 = subdir->parent;
6293 if (fix_problem(ctx, PR_2_LINK_DIR,
6301 subdir->parent = ino;
6306 } else if (dict_lookup(&de_dict, dirent)) {
6307 clear_problem_context(&pctx);
6309 pctx.dirent = dirent;
6310 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6311 if (!ctx->dirs_to_hash)
6312 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6313 if (ctx->dirs_to_hash)
6314 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6317 dict_alloc_insert(&de_dict, dirent, dirent);
6319 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6322 ctx->fs_links_count++;
6323 ctx->fs_total_count++;
6326 offset += dirent->rec_len;
6328 } while (offset < fs->blocksize);
6331 cd->pctx.dir = cd->pctx.ino;
6332 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6333 (dx_db->type == DX_DIRBLOCK_NODE))
6334 parse_int_node(fs, db, cd, dx_dir, buf);
6336 #endif /* ENABLE_HTREE */
6337 if (offset != fs->blocksize) {
6338 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6339 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6340 dirent->rec_len = cd->pctx.num;
6345 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6346 if (cd->pctx.errcode) {
6347 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6349 goto abort_free_dict;
6351 ext2fs_mark_changed(fs);
6353 dict_free_nodes(&de_dict);
6356 dict_free_nodes(&de_dict);
6357 ctx->flags |= E2F_FLAG_ABORT;
6358 return DIRENT_ABORT;
6362 * This function is called to deallocate a block, and is an interator
6363 * functioned called by deallocate inode via ext2fs_iterate_block().
6365 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6366 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6367 blk_t ref_block FSCK_ATTR((unused)),
6368 int ref_offset FSCK_ATTR((unused)),
6371 e2fsck_t ctx = (e2fsck_t) priv_data;
6373 if (HOLE_BLKADDR(*block_nr))
6375 if ((*block_nr < fs->super->s_first_data_block) ||
6376 (*block_nr >= fs->super->s_blocks_count))
6378 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6379 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6384 * This fuction deallocates an inode
6386 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6388 ext2_filsys fs = ctx->fs;
6389 struct ext2_inode inode;
6390 struct problem_context pctx;
6393 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6394 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6395 inode.i_links_count = 0;
6396 inode.i_dtime = time(NULL);
6397 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6398 clear_problem_context(&pctx);
6402 * Fix up the bitmaps...
6404 e2fsck_read_bitmaps(ctx);
6405 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6406 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6407 if (ctx->inode_bad_map)
6408 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6409 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6411 if (inode.i_file_acl &&
6412 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6413 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6414 block_buf, -1, &count);
6415 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6420 pctx.blk = inode.i_file_acl;
6421 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6422 ctx->flags |= E2F_FLAG_ABORT;
6426 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6428 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6430 inode.i_file_acl = 0;
6433 if (!ext2fs_inode_has_valid_blocks(&inode))
6436 if (LINUX_S_ISREG(inode.i_mode) &&
6437 (inode.i_size_high || inode.i_size & 0x80000000UL))
6440 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6441 deallocate_inode_block, ctx);
6443 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6444 ctx->flags |= E2F_FLAG_ABORT;
6450 * This fuction clears the htree flag on an inode
6452 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6454 struct ext2_inode inode;
6456 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6457 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6458 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6459 if (ctx->dirs_to_hash)
6460 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6464 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6465 ext2_ino_t ino, char *buf)
6467 ext2_filsys fs = ctx->fs;
6468 struct ext2_inode inode;
6469 int inode_modified = 0;
6471 unsigned char *frag, *fsize;
6472 struct problem_context pctx;
6475 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6477 clear_problem_context(&pctx);
6480 pctx.inode = &inode;
6482 if (inode.i_file_acl &&
6483 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6484 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6485 inode.i_file_acl = 0;
6488 * This is a special kludge to deal with long symlinks
6489 * on big endian systems. i_blocks had already been
6490 * decremented earlier in pass 1, but since i_file_acl
6491 * hadn't yet been cleared, ext2fs_read_inode()
6492 * assumed that the file was short symlink and would
6493 * not have byte swapped i_block[0]. Hence, we have
6494 * to byte-swap it here.
6496 if (LINUX_S_ISLNK(inode.i_mode) &&
6497 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6498 (inode.i_blocks == fs->blocksize >> 9))
6499 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6505 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6506 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6507 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6508 !(LINUX_S_ISSOCK(inode.i_mode)))
6509 problem = PR_2_BAD_MODE;
6510 else if (LINUX_S_ISCHR(inode.i_mode)
6511 && !e2fsck_pass1_check_device_inode(fs, &inode))
6512 problem = PR_2_BAD_CHAR_DEV;
6513 else if (LINUX_S_ISBLK(inode.i_mode)
6514 && !e2fsck_pass1_check_device_inode(fs, &inode))
6515 problem = PR_2_BAD_BLOCK_DEV;
6516 else if (LINUX_S_ISFIFO(inode.i_mode)
6517 && !e2fsck_pass1_check_device_inode(fs, &inode))
6518 problem = PR_2_BAD_FIFO;
6519 else if (LINUX_S_ISSOCK(inode.i_mode)
6520 && !e2fsck_pass1_check_device_inode(fs, &inode))
6521 problem = PR_2_BAD_SOCKET;
6522 else if (LINUX_S_ISLNK(inode.i_mode)
6523 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6524 problem = PR_2_INVALID_SYMLINK;
6528 if (fix_problem(ctx, problem, &pctx)) {
6529 deallocate_inode(ctx, ino, 0);
6530 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6538 if (inode.i_faddr) {
6539 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6546 switch (fs->super->s_creator_os) {
6548 frag = &inode.osd2.linux2.l_i_frag;
6549 fsize = &inode.osd2.linux2.l_i_fsize;
6552 frag = &inode.osd2.hurd2.h_i_frag;
6553 fsize = &inode.osd2.hurd2.h_i_fsize;
6556 frag = &inode.osd2.masix2.m_i_frag;
6557 fsize = &inode.osd2.masix2.m_i_fsize;
6562 if (frag && *frag) {
6564 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6571 if (fsize && *fsize) {
6573 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6581 if (inode.i_file_acl &&
6582 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6583 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6584 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6585 inode.i_file_acl = 0;
6590 if (inode.i_dir_acl &&
6591 LINUX_S_ISDIR(inode.i_mode)) {
6592 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6593 inode.i_dir_acl = 0;
6600 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6602 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6608 * allocate_dir_block --- this function allocates a new directory
6609 * block for a particular inode; this is done if a directory has
6610 * a "hole" in it, or if a directory has a illegal block number
6611 * that was zeroed out and now needs to be replaced.
6613 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6614 struct problem_context *pctx)
6616 ext2_filsys fs = ctx->fs;
6619 struct ext2_inode inode;
6621 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6625 * Read the inode and block bitmaps in; we'll be messing with
6628 e2fsck_read_bitmaps(ctx);
6631 * First, find a free block
6633 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6634 if (pctx->errcode) {
6635 pctx->str = "ext2fs_new_block";
6636 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6639 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6640 ext2fs_mark_block_bitmap(fs->block_map, blk);
6641 ext2fs_mark_bb_dirty(fs);
6644 * Now let's create the actual data block for the inode
6647 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6649 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6650 EXT2_ROOT_INO, &block);
6652 if (pctx->errcode) {
6653 pctx->str = "ext2fs_new_dir_block";
6654 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6658 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6659 ext2fs_free_mem(&block);
6660 if (pctx->errcode) {
6661 pctx->str = "ext2fs_write_dir_block";
6662 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6667 * Update the inode block count
6669 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6670 inode.i_blocks += fs->blocksize / 512;
6671 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6672 inode.i_size = (db->blockcnt+1) * fs->blocksize;
6673 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6676 * Finally, update the block pointers for the inode
6679 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6680 0, update_dir_block, db);
6681 if (pctx->errcode) {
6682 pctx->str = "ext2fs_block_iterate";
6683 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6691 * This is a helper function for allocate_dir_block().
6693 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6695 e2_blkcnt_t blockcnt,
6696 blk_t ref_block FSCK_ATTR((unused)),
6697 int ref_offset FSCK_ATTR((unused)),
6700 struct ext2_db_entry *db;
6702 db = (struct ext2_db_entry *) priv_data;
6703 if (db->blockcnt == (int) blockcnt) {
6704 *block_nr = db->blk;
6705 return BLOCK_CHANGED;
6711 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6713 * Pass #3 assures that all directories are connected to the
6714 * filesystem tree, using the following algorithm:
6716 * First, the root directory is checked to make sure it exists; if
6717 * not, e2fsck will offer to create a new one. It is then marked as
6720 * Then, pass3 interates over all directory inodes; for each directory
6721 * it attempts to trace up the filesystem tree, using dirinfo.parent
6722 * until it reaches a directory which has been marked "done". If it
6723 * cannot do so, then the directory must be disconnected, and e2fsck
6724 * will offer to reconnect it to /lost+found. While it is chasing
6725 * parent pointers up the filesystem tree, if pass3 sees a directory
6726 * twice, then it has detected a filesystem loop, and it will again
6727 * offer to reconnect the directory to /lost+found in to break the
6730 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6731 * reconnect inodes to /lost+found; this subroutine is also used by
6732 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6733 * is responsible for creating /lost+found if it does not exist.
6735 * Pass 3 frees the following data structures:
6736 * - The dirinfo directory information cache.
6739 static void check_root(e2fsck_t ctx);
6740 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6741 struct problem_context *pctx);
6742 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6744 static ext2fs_inode_bitmap inode_loop_detect;
6745 static ext2fs_inode_bitmap inode_done_map;
6747 static void e2fsck_pass3(e2fsck_t ctx)
6749 ext2_filsys fs = ctx->fs;
6751 struct problem_context pctx;
6752 struct dir_info *dir;
6753 unsigned long maxdirs, count;
6755 clear_problem_context(&pctx);
6759 if (!(ctx->options & E2F_OPT_PREEN))
6760 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6763 * Allocate some bitmaps to do loop detection.
6765 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6769 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6770 ctx->flags |= E2F_FLAG_ABORT;
6774 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6777 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6779 maxdirs = e2fsck_get_num_dirinfo(ctx);
6783 if ((ctx->progress)(ctx, 3, 0, maxdirs))
6786 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6787 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6789 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6791 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6792 if (check_directory(ctx, dir, &pctx))
6797 * Force the creation of /lost+found if not present
6799 if ((ctx->flags & E2F_OPT_READONLY) == 0)
6800 e2fsck_get_lost_and_found(ctx, 1);
6803 * If there are any directories that need to be indexed or
6804 * optimized, do it here.
6806 e2fsck_rehash_directories(ctx);
6809 e2fsck_free_dir_info(ctx);
6810 ext2fs_free_inode_bitmap(inode_loop_detect);
6811 inode_loop_detect = 0;
6812 ext2fs_free_inode_bitmap(inode_done_map);
6817 * This makes sure the root inode is present; if not, we ask if the
6818 * user wants us to create it. Not creating it is a fatal error.
6820 static void check_root(e2fsck_t ctx)
6822 ext2_filsys fs = ctx->fs;
6824 struct ext2_inode inode;
6826 struct problem_context pctx;
6828 clear_problem_context(&pctx);
6830 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6832 * If the root inode is not a directory, die here. The
6833 * user must have answered 'no' in pass1 when we
6834 * offered to clear it.
6836 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6838 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6839 ctx->flags |= E2F_FLAG_ABORT;
6844 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6845 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6846 ctx->flags |= E2F_FLAG_ABORT;
6850 e2fsck_read_bitmaps(ctx);
6853 * First, find a free block
6855 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6857 pctx.str = "ext2fs_new_block";
6858 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6859 ctx->flags |= E2F_FLAG_ABORT;
6862 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6863 ext2fs_mark_block_bitmap(fs->block_map, blk);
6864 ext2fs_mark_bb_dirty(fs);
6867 * Now let's create the actual data block for the inode
6869 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6872 pctx.str = "ext2fs_new_dir_block";
6873 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6874 ctx->flags |= E2F_FLAG_ABORT;
6878 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6880 pctx.str = "ext2fs_write_dir_block";
6881 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6882 ctx->flags |= E2F_FLAG_ABORT;
6885 ext2fs_free_mem(&block);
6888 * Set up the inode structure
6890 memset(&inode, 0, sizeof(inode));
6891 inode.i_mode = 040755;
6892 inode.i_size = fs->blocksize;
6893 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
6894 inode.i_links_count = 2;
6895 inode.i_blocks = fs->blocksize / 512;
6896 inode.i_block[0] = blk;
6899 * Write out the inode.
6901 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6903 pctx.str = "ext2fs_write_inode";
6904 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6905 ctx->flags |= E2F_FLAG_ABORT;
6910 * Miscellaneous bookkeeping...
6912 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6913 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6914 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6916 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6917 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6918 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6919 ext2fs_mark_ib_dirty(fs);
6923 * This subroutine is responsible for making sure that a particular
6924 * directory is connected to the root; if it isn't we trace it up as
6925 * far as we can go, and then offer to connect the resulting parent to
6926 * the lost+found. We have to do loop detection; if we ever discover
6927 * a loop, we treat that as a disconnected directory and offer to
6928 * reparent it to lost+found.
6930 * However, loop detection is expensive, because for very large
6931 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6932 * is non-trivial. Loops in filesystems are also a rare error case,
6933 * and we shouldn't optimize for error cases. So we try two passes of
6934 * the algorithm. The first time, we ignore loop detection and merely
6935 * increment a counter; if the counter exceeds some extreme threshold,
6936 * then we try again with the loop detection bitmap enabled.
6938 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6939 struct problem_context *pctx)
6941 ext2_filsys fs = ctx->fs;
6942 struct dir_info *p = dir;
6943 int loop_pass = 0, parent_count = 0;
6950 * Mark this inode as being "done"; by the time we
6951 * return from this function, the inode we either be
6952 * verified as being connected to the directory tree,
6953 * or we will have offered to reconnect this to
6956 * If it was marked done already, then we've reached a
6957 * parent we've already checked.
6959 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6963 * If this directory doesn't have a parent, or we've
6964 * seen the parent once already, then offer to
6965 * reparent it to lost+found
6969 (ext2fs_test_inode_bitmap(inode_loop_detect,
6972 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6973 if (e2fsck_reconnect_file(ctx, pctx->ino))
6974 ext2fs_unmark_valid(fs);
6976 p = e2fsck_get_dir_info(ctx, pctx->ino);
6977 p->parent = ctx->lost_and_found;
6978 fix_dotdot(ctx, p, ctx->lost_and_found);
6983 p = e2fsck_get_dir_info(ctx, p->parent);
6985 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
6989 ext2fs_mark_inode_bitmap(inode_loop_detect,
6991 } else if (parent_count++ > 2048) {
6993 * If we've run into a path depth that's
6994 * greater than 2048, try again with the inode
6995 * loop bitmap turned on and start from the
6999 if (inode_loop_detect)
7000 ext2fs_clear_inode_bitmap(inode_loop_detect);
7002 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7003 if (pctx->errcode) {
7006 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7007 ctx->flags |= E2F_FLAG_ABORT;
7016 * Make sure that .. and the parent directory are the same;
7017 * offer to fix it if not.
7019 if (dir->parent != dir->dotdot) {
7020 pctx->ino = dir->ino;
7021 pctx->ino2 = dir->dotdot;
7022 pctx->dir = dir->parent;
7023 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7024 fix_dotdot(ctx, dir, dir->parent);
7030 * This routine gets the lost_and_found inode, making it a directory
7033 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7035 ext2_filsys fs = ctx->fs;
7039 struct ext2_inode inode;
7041 static const char name[] = "lost+found";
7042 struct problem_context pctx;
7043 struct dir_info *dirinfo;
7045 if (ctx->lost_and_found)
7046 return ctx->lost_and_found;
7048 clear_problem_context(&pctx);
7050 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7051 sizeof(name)-1, 0, &ino);
7055 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7056 ctx->lost_and_found = ino;
7060 /* Lost+found isn't a directory! */
7064 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7067 /* OK, unlink the old /lost+found file. */
7068 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7070 pctx.str = "ext2fs_unlink";
7071 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7074 dirinfo = e2fsck_get_dir_info(ctx, ino);
7076 dirinfo->parent = 0;
7077 e2fsck_adjust_inode_count(ctx, ino, -1);
7078 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7079 pctx.errcode = retval;
7080 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7082 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7086 * Read the inode and block bitmaps in; we'll be messing with
7089 e2fsck_read_bitmaps(ctx);
7092 * First, find a free block
7094 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7096 pctx.errcode = retval;
7097 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7100 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7101 ext2fs_block_alloc_stats(fs, blk, +1);
7104 * Next find a free inode.
7106 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7107 ctx->inode_used_map, &ino);
7109 pctx.errcode = retval;
7110 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7113 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7114 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7115 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7118 * Now let's create the actual data block for the inode
7120 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7122 pctx.errcode = retval;
7123 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7127 retval = ext2fs_write_dir_block(fs, blk, block);
7128 ext2fs_free_mem(&block);
7130 pctx.errcode = retval;
7131 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7136 * Set up the inode structure
7138 memset(&inode, 0, sizeof(inode));
7139 inode.i_mode = 040700;
7140 inode.i_size = fs->blocksize;
7141 inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL);
7142 inode.i_links_count = 2;
7143 inode.i_blocks = fs->blocksize / 512;
7144 inode.i_block[0] = blk;
7147 * Next, write out the inode.
7149 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7151 pctx.str = "ext2fs_write_inode";
7152 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7156 * Finally, create the directory link
7158 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7160 pctx.str = "ext2fs_link";
7161 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7166 * Miscellaneous bookkeeping that needs to be kept straight.
7168 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7169 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7170 ext2fs_icount_store(ctx->inode_count, ino, 2);
7171 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7172 ctx->lost_and_found = ino;
7177 * This routine will connect a file to lost+found
7179 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7181 ext2_filsys fs = ctx->fs;
7184 struct problem_context pctx;
7185 struct ext2_inode inode;
7188 clear_problem_context(&pctx);
7191 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7192 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7193 ctx->bad_lost_and_found++;
7195 if (ctx->bad_lost_and_found) {
7196 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7200 sprintf(name, "#%u", ino);
7201 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7202 file_type = ext2_file_type(inode.i_mode);
7203 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7204 if (retval == EXT2_ET_DIR_NO_SPACE) {
7205 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7207 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7210 pctx.errcode = retval;
7211 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7214 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7218 pctx.errcode = retval;
7219 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7222 e2fsck_adjust_inode_count(ctx, ino, 1);
7228 * Utility routine to adjust the inode counts on an inode.
7230 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7232 ext2_filsys fs = ctx->fs;
7234 struct ext2_inode inode;
7239 retval = ext2fs_read_inode(fs, ino, &inode);
7244 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7245 if (inode.i_links_count == (__u16) ~0)
7247 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7248 inode.i_links_count++;
7249 } else if (adj == -1) {
7250 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7251 if (inode.i_links_count == 0)
7253 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7254 inode.i_links_count--;
7257 retval = ext2fs_write_inode(fs, ino, &inode);
7265 * Fix parent --- this routine fixes up the parent of a directory.
7267 struct fix_dotdot_struct {
7274 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7275 int offset FSCK_ATTR((unused)),
7276 int blocksize FSCK_ATTR((unused)),
7277 char *buf FSCK_ATTR((unused)),
7280 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7282 struct problem_context pctx;
7284 if ((dirent->name_len & 0xFF) != 2)
7286 if (strncmp(dirent->name, "..", 2))
7289 clear_problem_context(&pctx);
7291 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7293 pctx.errcode = retval;
7294 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7296 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7298 pctx.errcode = retval;
7299 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7301 dirent->inode = fp->parent;
7304 return DIRENT_ABORT | DIRENT_CHANGED;
7307 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7309 ext2_filsys fs = ctx->fs;
7311 struct fix_dotdot_struct fp;
7312 struct problem_context pctx;
7319 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7320 0, fix_dotdot_proc, &fp);
7321 if (retval || !fp.done) {
7322 clear_problem_context(&pctx);
7323 pctx.ino = dir->ino;
7324 pctx.errcode = retval;
7325 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7326 PR_3_FIX_PARENT_NOFIND, &pctx);
7327 ext2fs_unmark_valid(fs);
7329 dir->dotdot = parent;
7333 * These routines are responsible for expanding a /lost+found if it is
7337 struct expand_dir_struct {
7339 int guaranteed_size;
7346 static int expand_dir_proc(ext2_filsys fs,
7348 e2_blkcnt_t blockcnt,
7349 blk_t ref_block FSCK_ATTR((unused)),
7350 int ref_offset FSCK_ATTR((unused)),
7353 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7355 static blk_t last_blk = 0;
7362 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7366 es->last_block = blockcnt;
7368 last_blk = *blocknr;
7371 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7378 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7384 retval = ext2fs_write_dir_block(fs, new_blk, block);
7386 retval = ext2fs_get_mem(fs->blocksize, &block);
7391 memset(block, 0, fs->blocksize);
7392 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7398 ext2fs_free_mem(&block);
7400 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7401 ext2fs_block_alloc_stats(fs, new_blk, +1);
7405 return (BLOCK_CHANGED | BLOCK_ABORT);
7407 return BLOCK_CHANGED;
7410 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7411 int num, int guaranteed_size)
7413 ext2_filsys fs = ctx->fs;
7415 struct expand_dir_struct es;
7416 struct ext2_inode inode;
7418 if (!(fs->flags & EXT2_FLAG_RW))
7419 return EXT2_ET_RO_FILSYS;
7422 * Read the inode and block bitmaps in; we'll be messing with
7425 e2fsck_read_bitmaps(ctx);
7427 retval = ext2fs_check_directory(fs, dir);
7432 es.guaranteed_size = guaranteed_size;
7438 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7439 0, expand_dir_proc, &es);
7445 * Update the size and block count fields in the inode.
7447 retval = ext2fs_read_inode(fs, dir, &inode);
7451 inode.i_size = (es.last_block + 1) * fs->blocksize;
7452 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7454 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7460 * pass4.c -- pass #4 of e2fsck: Check reference counts
7462 * Pass 4 frees the following data structures:
7463 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7467 * This routine is called when an inode is not connected to the
7470 * This subroutine returns 1 then the caller shouldn't bother with the
7471 * rest of the pass 4 tests.
7473 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7475 ext2_filsys fs = ctx->fs;
7476 struct ext2_inode inode;
7477 struct problem_context pctx;
7479 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7480 clear_problem_context(&pctx);
7482 pctx.inode = &inode;
7485 * Offer to delete any zero-length files that does not have
7486 * blocks. If there is an EA block, it might have useful
7487 * information, so we won't prompt to delete it, but let it be
7488 * reconnected to lost+found.
7490 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7491 LINUX_S_ISDIR(inode.i_mode))) {
7492 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7493 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7494 inode.i_links_count = 0;
7495 inode.i_dtime = time(NULL);
7496 e2fsck_write_inode(ctx, i, &inode,
7497 "disconnect_inode");
7499 * Fix up the bitmaps...
7501 e2fsck_read_bitmaps(ctx);
7502 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7503 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7504 ext2fs_inode_alloc_stats2(fs, i, -1,
7505 LINUX_S_ISDIR(inode.i_mode));
7511 * Prompt to reconnect.
7513 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7514 if (e2fsck_reconnect_file(ctx, i))
7515 ext2fs_unmark_valid(fs);
7518 * If we don't attach the inode, then skip the
7519 * i_links_test since there's no point in trying to
7520 * force i_links_count to zero.
7522 ext2fs_unmark_valid(fs);
7529 static void e2fsck_pass4(e2fsck_t ctx)
7531 ext2_filsys fs = ctx->fs;
7533 struct ext2_inode inode;
7534 struct problem_context pctx;
7535 __u16 link_count, link_counted;
7537 int group, maxgroup;
7541 clear_problem_context(&pctx);
7543 if (!(ctx->options & E2F_OPT_PREEN))
7544 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7547 maxgroup = fs->group_desc_count;
7549 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7552 for (i=1; i <= fs->super->s_inodes_count; i++) {
7553 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7555 if ((i % fs->super->s_inodes_per_group) == 0) {
7558 if ((ctx->progress)(ctx, 4, group, maxgroup))
7561 if (i == EXT2_BAD_INO ||
7562 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7564 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7565 (ctx->inode_imagic_map &&
7566 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7568 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7569 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7570 if (link_counted == 0) {
7572 buf = e2fsck_allocate_memory(ctx,
7573 fs->blocksize, "bad_inode buffer");
7574 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7576 if (disconnect_inode(ctx, i))
7578 ext2fs_icount_fetch(ctx->inode_link_info, i,
7580 ext2fs_icount_fetch(ctx->inode_count, i,
7583 if (link_counted != link_count) {
7584 e2fsck_read_inode(ctx, i, &inode, "pass4");
7586 pctx.inode = &inode;
7587 if (link_count != inode.i_links_count) {
7588 pctx.num = link_count;
7590 PR_4_INCONSISTENT_COUNT, &pctx);
7592 pctx.num = link_counted;
7593 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7594 inode.i_links_count = link_counted;
7595 e2fsck_write_inode(ctx, i, &inode, "pass4");
7599 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7600 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7601 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7602 ctx->inode_imagic_map = 0;
7603 ext2fs_free_mem(&buf);
7607 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7610 #define NO_BLK ((blk_t) -1)
7612 static void print_bitmap_problem(e2fsck_t ctx, int problem,
7613 struct problem_context *pctx)
7616 case PR_5_BLOCK_UNUSED:
7617 if (pctx->blk == pctx->blk2)
7620 problem = PR_5_BLOCK_RANGE_UNUSED;
7622 case PR_5_BLOCK_USED:
7623 if (pctx->blk == pctx->blk2)
7626 problem = PR_5_BLOCK_RANGE_USED;
7628 case PR_5_INODE_UNUSED:
7629 if (pctx->ino == pctx->ino2)
7632 problem = PR_5_INODE_RANGE_UNUSED;
7634 case PR_5_INODE_USED:
7635 if (pctx->ino == pctx->ino2)
7638 problem = PR_5_INODE_RANGE_USED;
7641 fix_problem(ctx, problem, pctx);
7642 pctx->blk = pctx->blk2 = NO_BLK;
7643 pctx->ino = pctx->ino2 = 0;
7646 static void check_block_bitmaps(e2fsck_t ctx)
7648 ext2_filsys fs = ctx->fs;
7652 unsigned int blocks = 0;
7653 unsigned int free_blocks = 0;
7656 struct problem_context pctx;
7657 int problem, save_problem, fixit, had_problem;
7660 clear_problem_context(&pctx);
7661 free_array = (int *) e2fsck_allocate_memory(ctx,
7662 fs->group_desc_count * sizeof(int), "free block count array");
7664 if ((fs->super->s_first_data_block <
7665 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7666 (fs->super->s_blocks_count-1 >
7667 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7669 pctx.blk = fs->super->s_first_data_block;
7670 pctx.blk2 = fs->super->s_blocks_count -1;
7671 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7672 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7673 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7675 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7679 if ((fs->super->s_first_data_block <
7680 ext2fs_get_block_bitmap_start(fs->block_map)) ||
7681 (fs->super->s_blocks_count-1 >
7682 ext2fs_get_block_bitmap_end(fs->block_map))) {
7684 pctx.blk = fs->super->s_first_data_block;
7685 pctx.blk2 = fs->super->s_blocks_count -1;
7686 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7687 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7688 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7690 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7697 pctx.blk = pctx.blk2 = NO_BLK;
7698 for (i = fs->super->s_first_data_block;
7699 i < fs->super->s_blocks_count;
7701 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7702 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7704 if (actual == bitmap)
7707 if (!actual && bitmap) {
7709 * Block not used, but marked in use in the bitmap.
7711 problem = PR_5_BLOCK_UNUSED;
7714 * Block used, but not marked in use in the bitmap.
7716 problem = PR_5_BLOCK_USED;
7718 if (pctx.blk == NO_BLK) {
7719 pctx.blk = pctx.blk2 = i;
7720 save_problem = problem;
7722 if ((problem == save_problem) &&
7726 print_bitmap_problem(ctx, save_problem, &pctx);
7727 pctx.blk = pctx.blk2 = i;
7728 save_problem = problem;
7731 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7740 if ((blocks == fs->super->s_blocks_per_group) ||
7741 (i == fs->super->s_blocks_count-1)) {
7742 free_array[group] = group_free;
7747 if ((ctx->progress)(ctx, 5, group,
7748 fs->group_desc_count*2))
7752 if (pctx.blk != NO_BLK)
7753 print_bitmap_problem(ctx, save_problem, &pctx);
7755 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7758 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7761 ext2fs_free_block_bitmap(fs->block_map);
7762 retval = ext2fs_copy_bitmap(ctx->block_found_map,
7765 clear_problem_context(&pctx);
7766 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7767 ctx->flags |= E2F_FLAG_ABORT;
7770 ext2fs_set_bitmap_padding(fs->block_map);
7771 ext2fs_mark_bb_dirty(fs);
7773 /* Redo the counts */
7774 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7775 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7777 } else if (fixit == 0)
7778 ext2fs_unmark_valid(fs);
7780 for (i = 0; i < fs->group_desc_count; i++) {
7781 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7783 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7784 pctx.blk2 = free_array[i];
7786 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7788 fs->group_desc[i].bg_free_blocks_count =
7790 ext2fs_mark_super_dirty(fs);
7792 ext2fs_unmark_valid(fs);
7795 if (free_blocks != fs->super->s_free_blocks_count) {
7797 pctx.blk = fs->super->s_free_blocks_count;
7798 pctx.blk2 = free_blocks;
7800 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7801 fs->super->s_free_blocks_count = free_blocks;
7802 ext2fs_mark_super_dirty(fs);
7804 ext2fs_unmark_valid(fs);
7806 ext2fs_free_mem(&free_array);
7809 static void check_inode_bitmaps(e2fsck_t ctx)
7811 ext2_filsys fs = ctx->fs;
7813 unsigned int free_inodes = 0;
7817 unsigned int inodes = 0;
7822 struct problem_context pctx;
7823 int problem, save_problem, fixit, had_problem;
7825 clear_problem_context(&pctx);
7826 free_array = (int *) e2fsck_allocate_memory(ctx,
7827 fs->group_desc_count * sizeof(int), "free inode count array");
7829 dir_array = (int *) e2fsck_allocate_memory(ctx,
7830 fs->group_desc_count * sizeof(int), "directory count array");
7832 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7833 (fs->super->s_inodes_count >
7834 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7837 pctx.blk2 = fs->super->s_inodes_count;
7838 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7839 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7840 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7842 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7845 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7846 (fs->super->s_inodes_count >
7847 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7850 pctx.blk2 = fs->super->s_inodes_count;
7851 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7852 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7853 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7855 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7862 pctx.ino = pctx.ino2 = 0;
7863 for (i = 1; i <= fs->super->s_inodes_count; i++) {
7864 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7865 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7867 if (actual == bitmap)
7870 if (!actual && bitmap) {
7872 * Inode wasn't used, but marked in bitmap
7874 problem = PR_5_INODE_UNUSED;
7875 } else /* if (actual && !bitmap) */ {
7877 * Inode used, but not in bitmap
7879 problem = PR_5_INODE_USED;
7881 if (pctx.ino == 0) {
7882 pctx.ino = pctx.ino2 = i;
7883 save_problem = problem;
7885 if ((problem == save_problem) &&
7889 print_bitmap_problem(ctx, save_problem, &pctx);
7890 pctx.ino = pctx.ino2 = i;
7891 save_problem = problem;
7894 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7902 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7906 if ((inodes == fs->super->s_inodes_per_group) ||
7907 (i == fs->super->s_inodes_count)) {
7908 free_array[group] = group_free;
7909 dir_array[group] = dirs_count;
7915 if ((ctx->progress)(ctx, 5,
7916 group + fs->group_desc_count,
7917 fs->group_desc_count*2))
7922 print_bitmap_problem(ctx, save_problem, &pctx);
7925 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7928 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7931 ext2fs_free_inode_bitmap(fs->inode_map);
7932 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7935 clear_problem_context(&pctx);
7936 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7937 ctx->flags |= E2F_FLAG_ABORT;
7940 ext2fs_set_bitmap_padding(fs->inode_map);
7941 ext2fs_mark_ib_dirty(fs);
7944 inodes = 0; free_inodes = 0; group_free = 0;
7945 dirs_count = 0; group = 0;
7946 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7947 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7949 } else if (fixit == 0)
7950 ext2fs_unmark_valid(fs);
7952 for (i = 0; i < fs->group_desc_count; i++) {
7953 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7955 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7956 pctx.ino2 = free_array[i];
7957 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7959 fs->group_desc[i].bg_free_inodes_count =
7961 ext2fs_mark_super_dirty(fs);
7963 ext2fs_unmark_valid(fs);
7965 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7967 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7968 pctx.ino2 = dir_array[i];
7970 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7972 fs->group_desc[i].bg_used_dirs_count =
7974 ext2fs_mark_super_dirty(fs);
7976 ext2fs_unmark_valid(fs);
7979 if (free_inodes != fs->super->s_free_inodes_count) {
7981 pctx.ino = fs->super->s_free_inodes_count;
7982 pctx.ino2 = free_inodes;
7984 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
7985 fs->super->s_free_inodes_count = free_inodes;
7986 ext2fs_mark_super_dirty(fs);
7988 ext2fs_unmark_valid(fs);
7990 ext2fs_free_mem(&free_array);
7991 ext2fs_free_mem(&dir_array);
7994 static void check_inode_end(e2fsck_t ctx)
7996 ext2_filsys fs = ctx->fs;
7997 ext2_ino_t end, save_inodes_count, i;
7998 struct problem_context pctx;
8000 clear_problem_context(&pctx);
8002 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8003 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8004 &save_inodes_count);
8007 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8008 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8011 if (save_inodes_count == end)
8014 for (i = save_inodes_count + 1; i <= end; i++) {
8015 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8016 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8017 for (i = save_inodes_count + 1; i <= end; i++)
8018 ext2fs_mark_inode_bitmap(fs->inode_map,
8020 ext2fs_mark_ib_dirty(fs);
8022 ext2fs_unmark_valid(fs);
8027 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8028 save_inodes_count, 0);
8031 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8032 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8037 static void check_block_end(e2fsck_t ctx)
8039 ext2_filsys fs = ctx->fs;
8040 blk_t end, save_blocks_count, i;
8041 struct problem_context pctx;
8043 clear_problem_context(&pctx);
8045 end = fs->block_map->start +
8046 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8047 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8048 &save_blocks_count);
8051 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8052 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8055 if (save_blocks_count == end)
8058 for (i = save_blocks_count + 1; i <= end; i++) {
8059 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8060 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8061 for (i = save_blocks_count + 1; i <= end; i++)
8062 ext2fs_mark_block_bitmap(fs->block_map,
8064 ext2fs_mark_bb_dirty(fs);
8066 ext2fs_unmark_valid(fs);
8071 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8072 save_blocks_count, 0);
8075 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8076 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8081 static void e2fsck_pass5(e2fsck_t ctx)
8083 struct problem_context pctx;
8087 clear_problem_context(&pctx);
8089 if (!(ctx->options & E2F_OPT_PREEN))
8090 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8093 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8096 e2fsck_read_bitmaps(ctx);
8098 check_block_bitmaps(ctx);
8099 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8101 check_inode_bitmaps(ctx);
8102 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8104 check_inode_end(ctx);
8105 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8107 check_block_end(ctx);
8108 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8111 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8112 ctx->inode_used_map = 0;
8113 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8114 ctx->inode_dir_map = 0;
8115 ext2fs_free_block_bitmap(ctx->block_found_map);
8116 ctx->block_found_map = 0;
8120 * problem.c --- report filesystem problems to the user
8123 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8124 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8125 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8126 #define PR_MSG_ONLY 0x000008 /* Print message only */
8128 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8130 #define PR_FATAL 0x001000 /* Fatal error */
8131 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8133 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8134 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8135 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8136 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8137 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8140 #define PROMPT_NONE 0
8141 #define PROMPT_FIX 1
8142 #define PROMPT_CLEAR 2
8143 #define PROMPT_RELOCATE 3
8144 #define PROMPT_ALLOCATE 4
8145 #define PROMPT_EXPAND 5
8146 #define PROMPT_CONNECT 6
8147 #define PROMPT_CREATE 7
8148 #define PROMPT_SALVAGE 8
8149 #define PROMPT_TRUNCATE 9
8150 #define PROMPT_CLEAR_INODE 10
8151 #define PROMPT_ABORT 11
8152 #define PROMPT_SPLIT 12
8153 #define PROMPT_CONTINUE 13
8154 #define PROMPT_CLONE 14
8155 #define PROMPT_DELETE 15
8156 #define PROMPT_SUPPRESS 16
8157 #define PROMPT_UNLINK 17
8158 #define PROMPT_CLEAR_HTREE 18
8159 #define PROMPT_RECREATE 19
8160 #define PROMPT_NULL 20
8162 struct e2fsck_problem {
8164 const char * e2p_description;
8167 problem_t second_code;
8170 struct latch_descr {
8173 problem_t end_message;
8178 * These are the prompts which are used to ask the user if they want
8181 static const char *const prompt[] = {
8182 N_("(no prompt)"), /* 0 */
8184 N_("Clear"), /* 2 */
8185 N_("Relocate"), /* 3 */
8186 N_("Allocate"), /* 4 */
8187 N_("Expand"), /* 5 */
8188 N_("Connect to /lost+found"), /* 6 */
8189 N_("Create"), /* 7 */
8190 N_("Salvage"), /* 8 */
8191 N_("Truncate"), /* 9 */
8192 N_("Clear inode"), /* 10 */
8193 N_("Abort"), /* 11 */
8194 N_("Split"), /* 12 */
8195 N_("Continue"), /* 13 */
8196 N_("Clone multiply-claimed blocks"), /* 14 */
8197 N_("Delete file"), /* 15 */
8198 N_("Suppress messages"),/* 16 */
8199 N_("Unlink"), /* 17 */
8200 N_("Clear HTree index"),/* 18 */
8201 N_("Recreate"), /* 19 */
8206 * These messages are printed when we are preen mode and we will be
8207 * automatically fixing the problem.
8209 static const char *const preen_msg[] = {
8210 N_("(NONE)"), /* 0 */
8211 N_("FIXED"), /* 1 */
8212 N_("CLEARED"), /* 2 */
8213 N_("RELOCATED"), /* 3 */
8214 N_("ALLOCATED"), /* 4 */
8215 N_("EXPANDED"), /* 5 */
8216 N_("RECONNECTED"), /* 6 */
8217 N_("CREATED"), /* 7 */
8218 N_("SALVAGED"), /* 8 */
8219 N_("TRUNCATED"), /* 9 */
8220 N_("INODE CLEARED"), /* 10 */
8221 N_("ABORTED"), /* 11 */
8222 N_("SPLIT"), /* 12 */
8223 N_("CONTINUING"), /* 13 */
8224 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8225 N_("FILE DELETED"), /* 15 */
8226 N_("SUPPRESSED"), /* 16 */
8227 N_("UNLINKED"), /* 17 */
8228 N_("HTREE INDEX CLEARED"),/* 18 */
8229 N_("WILL RECREATE"), /* 19 */
8233 static const struct e2fsck_problem problem_table[] = {
8235 /* Pre-Pass 1 errors */
8237 /* Block bitmap not in group */
8238 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8239 PROMPT_RELOCATE, PR_LATCH_RELOC },
8241 /* Inode bitmap not in group */
8242 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8243 PROMPT_RELOCATE, PR_LATCH_RELOC },
8245 /* Inode table not in group */
8246 { PR_0_ITABLE_NOT_GROUP,
8247 N_("@i table for @g %g is not in @g. (@b %b)\n"
8248 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8249 PROMPT_RELOCATE, PR_LATCH_RELOC },
8251 /* Superblock corrupt */
8253 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8254 "@f. If the @v is valid and it really contains an ext2\n"
8255 "@f (and not swap or ufs or something else), then the @S\n"
8256 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8257 " e2fsck -b %S <@v>\n\n"),
8258 PROMPT_NONE, PR_FATAL },
8260 /* Filesystem size is wrong */
8261 { PR_0_FS_SIZE_WRONG,
8262 N_("The @f size (according to the @S) is %b @bs\n"
8263 "The physical size of the @v is %c @bs\n"
8264 "Either the @S or the partition table is likely to be corrupt!\n"),
8267 /* Fragments not supported */
8268 { PR_0_NO_FRAGMENTS,
8269 N_("@S @b_size = %b, fragsize = %c.\n"
8270 "This version of e2fsck does not support fragment sizes different\n"
8271 "from the @b size.\n"),
8272 PROMPT_NONE, PR_FATAL },
8274 /* Bad blocks_per_group */
8275 { PR_0_BLOCKS_PER_GROUP,
8276 N_("@S @bs_per_group = %b, should have been %c\n"),
8277 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8279 /* Bad first_data_block */
8280 { PR_0_FIRST_DATA_BLOCK,
8281 N_("@S first_data_@b = %b, should have been %c\n"),
8282 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8284 /* Adding UUID to filesystem */
8286 N_("@f did not have a UUID; generating one.\n\n"),
8290 { PR_0_RELOCATE_HINT,
8291 N_("Note: if several inode or block bitmap blocks or part\n"
8292 "of the inode table require relocation, you may wish to try\n"
8293 "running e2fsck with the '-b %S' option first. The problem\n"
8294 "may lie only with the primary block group descriptors, and\n"
8295 "the backup block group descriptors may be OK.\n\n"),
8296 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8298 /* Miscellaneous superblock corruption */
8299 { PR_0_MISC_CORRUPT_SUPER,
8300 N_("Corruption found in @S. (%s = %N).\n"),
8301 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8303 /* Error determing physical device size of filesystem */
8304 { PR_0_GETSIZE_ERROR,
8305 N_("Error determining size of the physical @v: %m\n"),
8306 PROMPT_NONE, PR_FATAL },
8308 /* Inode count in superblock is incorrect */
8309 { PR_0_INODE_COUNT_WRONG,
8310 N_("@i count in @S is %i, @s %j.\n"),
8313 { PR_0_HURD_CLEAR_FILETYPE,
8314 N_("The Hurd does not support the filetype feature.\n"),
8317 /* Journal inode is invalid */
8318 { PR_0_JOURNAL_BAD_INODE,
8319 N_("@S has an @n ext3 @j (@i %i).\n"),
8320 PROMPT_CLEAR, PR_PREEN_OK },
8322 /* The external journal has (unsupported) multiple filesystems */
8323 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8324 N_("External @j has multiple @f users (unsupported).\n"),
8325 PROMPT_NONE, PR_FATAL },
8327 /* Can't find external journal */
8328 { PR_0_CANT_FIND_JOURNAL,
8329 N_("Can't find external @j\n"),
8330 PROMPT_NONE, PR_FATAL },
8332 /* External journal has bad superblock */
8333 { PR_0_EXT_JOURNAL_BAD_SUPER,
8334 N_("External @j has bad @S\n"),
8335 PROMPT_NONE, PR_FATAL },
8337 /* Superblock has a bad journal UUID */
8338 { PR_0_JOURNAL_BAD_UUID,
8339 N_("External @j does not support this @f\n"),
8340 PROMPT_NONE, PR_FATAL },
8342 /* Journal has an unknown superblock type */
8343 { PR_0_JOURNAL_UNSUPP_SUPER,
8344 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8345 "It is likely that your copy of e2fsck is old and/or doesn't "
8346 "support this @j format.\n"
8347 "It is also possible the @j @S is corrupt.\n"),
8348 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8350 /* Journal superblock is corrupt */
8351 { PR_0_JOURNAL_BAD_SUPER,
8352 N_("Ext3 @j @S is corrupt.\n"),
8353 PROMPT_FIX, PR_PREEN_OK },
8355 /* Superblock flag should be cleared */
8356 { PR_0_JOURNAL_HAS_JOURNAL,
8357 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8358 PROMPT_CLEAR, PR_PREEN_OK },
8360 /* Superblock flag is incorrect */
8361 { PR_0_JOURNAL_RECOVER_SET,
8362 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8363 PROMPT_CLEAR, PR_PREEN_OK },
8365 /* Journal has data, but recovery flag is clear */
8366 { PR_0_JOURNAL_RECOVERY_CLEAR,
8367 N_("ext3 recovery flag is clear, but @j has data.\n"),
8370 /* Ask if we should clear the journal */
8371 { PR_0_JOURNAL_RESET_JOURNAL,
8373 PROMPT_NULL, PR_PREEN_NOMSG },
8375 /* Ask if we should run the journal anyway */
8377 N_("Run @j anyway"),
8380 /* Run the journal by default */
8381 { PR_0_JOURNAL_RUN_DEFAULT,
8382 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8385 /* Clearing orphan inode */
8386 { PR_0_ORPHAN_CLEAR_INODE,
8387 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8390 /* Illegal block found in orphaned inode */
8391 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8392 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8395 /* Already cleared block found in orphaned inode */
8396 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8397 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8400 /* Illegal orphan inode in superblock */
8401 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8402 N_("@I @o @i %i in @S.\n"),
8405 /* Illegal inode in orphaned inode list */
8406 { PR_0_ORPHAN_ILLEGAL_INODE,
8407 N_("@I @i %i in @o @i list.\n"),
8410 /* Filesystem revision is 0, but feature flags are set */
8411 { PR_0_FS_REV_LEVEL,
8412 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8413 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8415 /* Journal superblock has an unknown read-only feature flag set */
8416 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8417 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8420 /* Journal superblock has an unknown incompatible feature flag set */
8421 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8422 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8425 /* Journal has unsupported version number */
8426 { PR_0_JOURNAL_UNSUPP_VERSION,
8427 N_("@j version not supported by this e2fsck.\n"),
8430 /* Moving journal to hidden file */
8431 { PR_0_MOVE_JOURNAL,
8432 N_("Moving @j from /%s to hidden @i.\n\n"),
8435 /* Error moving journal to hidden file */
8436 { PR_0_ERR_MOVE_JOURNAL,
8437 N_("Error moving @j: %m\n\n"),
8440 /* Clearing V2 journal superblock */
8441 { PR_0_CLEAR_V2_JOURNAL,
8442 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8443 "Clearing fields beyond the V1 @j @S...\n\n"),
8446 /* Backup journal inode blocks */
8448 N_("Backing up @j @i @b information.\n\n"),
8451 /* Reserved blocks w/o resize_inode */
8452 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8453 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8454 "is %N; @s zero. "),
8457 /* Resize_inode not enabled, but resize inode is non-zero */
8458 { PR_0_CLEAR_RESIZE_INODE,
8459 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8462 /* Resize inode invalid */
8463 { PR_0_RESIZE_INODE_INVALID,
8464 N_("Resize @i not valid. "),
8465 PROMPT_RECREATE, 0 },
8469 /* Pass 1: Checking inodes, blocks, and sizes */
8471 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8474 /* Root directory is not an inode */
8475 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8478 /* Root directory has dtime set */
8480 N_("@r has dtime set (probably due to old mke2fs). "),
8481 PROMPT_FIX, PR_PREEN_OK },
8483 /* Reserved inode has bad mode */
8484 { PR_1_RESERVED_BAD_MODE,
8485 N_("Reserved @i %i (%Q) has @n mode. "),
8486 PROMPT_CLEAR, PR_PREEN_OK },
8488 /* Deleted inode has zero dtime */
8490 N_("@D @i %i has zero dtime. "),
8491 PROMPT_FIX, PR_PREEN_OK },
8493 /* Inode in use, but dtime set */
8495 N_("@i %i is in use, but has dtime set. "),
8496 PROMPT_FIX, PR_PREEN_OK },
8498 /* Zero-length directory */
8499 { PR_1_ZERO_LENGTH_DIR,
8500 N_("@i %i is a @z @d. "),
8501 PROMPT_CLEAR, PR_PREEN_OK },
8503 /* Block bitmap conflicts with some other fs block */
8505 N_("@g %g's @b @B at %b @C.\n"),
8506 PROMPT_RELOCATE, 0 },
8508 /* Inode bitmap conflicts with some other fs block */
8510 N_("@g %g's @i @B at %b @C.\n"),
8511 PROMPT_RELOCATE, 0 },
8513 /* Inode table conflicts with some other fs block */
8514 { PR_1_ITABLE_CONFLICT,
8515 N_("@g %g's @i table at %b @C.\n"),
8516 PROMPT_RELOCATE, 0 },
8518 /* Block bitmap is on a bad block */
8519 { PR_1_BB_BAD_BLOCK,
8520 N_("@g %g's @b @B (%b) is bad. "),
8521 PROMPT_RELOCATE, 0 },
8523 /* Inode bitmap is on a bad block */
8524 { PR_1_IB_BAD_BLOCK,
8525 N_("@g %g's @i @B (%b) is bad. "),
8526 PROMPT_RELOCATE, 0 },
8528 /* Inode has incorrect i_size */
8530 N_("@i %i, i_size is %Is, @s %N. "),
8531 PROMPT_FIX, PR_PREEN_OK },
8533 /* Inode has incorrect i_blocks */
8534 { PR_1_BAD_I_BLOCKS,
8535 N_("@i %i, i_@bs is %Ib, @s %N. "),
8536 PROMPT_FIX, PR_PREEN_OK },
8538 /* Illegal blocknumber in inode */
8539 { PR_1_ILLEGAL_BLOCK_NUM,
8540 N_("@I @b #%B (%b) in @i %i. "),
8541 PROMPT_CLEAR, PR_LATCH_BLOCK },
8543 /* Block number overlaps fs metadata */
8544 { PR_1_BLOCK_OVERLAPS_METADATA,
8545 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8546 PROMPT_CLEAR, PR_LATCH_BLOCK },
8548 /* Inode has illegal blocks (latch question) */
8549 { PR_1_INODE_BLOCK_LATCH,
8550 N_("@i %i has illegal @b(s). "),
8553 /* Too many bad blocks in inode */
8554 { PR_1_TOO_MANY_BAD_BLOCKS,
8555 N_("Too many illegal @bs in @i %i.\n"),
8556 PROMPT_CLEAR_INODE, PR_NO_OK },
8558 /* Illegal block number in bad block inode */
8559 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8560 N_("@I @b #%B (%b) in bad @b @i. "),
8561 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8563 /* Bad block inode has illegal blocks (latch question) */
8564 { PR_1_INODE_BBLOCK_LATCH,
8565 N_("Bad @b @i has illegal @b(s). "),
8568 /* Duplicate or bad blocks in use! */
8569 { PR_1_DUP_BLOCKS_PREENSTOP,
8570 N_("Duplicate or bad @b in use!\n"),
8573 /* Bad block used as bad block indirect block */
8574 { PR_1_BBINODE_BAD_METABLOCK,
8575 N_("Bad @b %b used as bad @b @i indirect @b. "),
8576 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8578 /* Inconsistency can't be fixed prompt */
8579 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8580 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8581 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8583 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8585 /* Bad primary block */
8586 { PR_1_BAD_PRIMARY_BLOCK,
8587 N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
8588 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8590 /* Bad primary block prompt */
8591 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8592 N_("You can remove this @b from the bad @b list and hope\n"
8593 "that the @b is really OK. But there are no guarantees.\n\n"),
8594 PROMPT_CLEAR, PR_PREEN_NOMSG },
8596 /* Bad primary superblock */
8597 { PR_1_BAD_PRIMARY_SUPERBLOCK,
8598 N_("The primary @S (%b) is on the bad @b list.\n"),
8599 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8601 /* Bad primary block group descriptors */
8602 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8603 N_("Block %b in the primary @g descriptors "
8604 "is on the bad @b list\n"),
8605 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8607 /* Bad superblock in group */
8608 { PR_1_BAD_SUPERBLOCK,
8609 N_("Warning: Group %g's @S (%b) is bad.\n"),
8610 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8612 /* Bad block group descriptors in group */
8613 { PR_1_BAD_GROUP_DESCRIPTORS,
8614 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8616 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8618 /* Block claimed for no reason */
8619 { PR_1_PROGERR_CLAIMED_BLOCK,
8620 N_("Programming error? @b #%b claimed for no reason in "
8621 "process_bad_@b.\n"),
8622 PROMPT_NONE, PR_PREEN_OK },
8624 /* Error allocating blocks for relocating metadata */
8625 { PR_1_RELOC_BLOCK_ALLOCATE,
8626 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8627 PROMPT_NONE, PR_PREEN_OK },
8629 /* Error allocating block buffer during relocation process */
8630 { PR_1_RELOC_MEMORY_ALLOCATE,
8631 N_("@A @b buffer for relocating %s\n"),
8632 PROMPT_NONE, PR_PREEN_OK },
8634 /* Relocating metadata group information from X to Y */
8635 { PR_1_RELOC_FROM_TO,
8636 N_("Relocating @g %g's %s from %b to %c...\n"),
8637 PROMPT_NONE, PR_PREEN_OK },
8639 /* Relocating metatdata group information to X */
8641 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8642 PROMPT_NONE, PR_PREEN_OK },
8644 /* Block read error during relocation process */
8645 { PR_1_RELOC_READ_ERR,
8646 N_("Warning: could not read @b %b of %s: %m\n"),
8647 PROMPT_NONE, PR_PREEN_OK },
8649 /* Block write error during relocation process */
8650 { PR_1_RELOC_WRITE_ERR,
8651 N_("Warning: could not write @b %b for %s: %m\n"),
8652 PROMPT_NONE, PR_PREEN_OK },
8654 /* Error allocating inode bitmap */
8655 { PR_1_ALLOCATE_IBITMAP_ERROR,
8656 N_("@A @i @B (%N): %m\n"),
8657 PROMPT_NONE, PR_FATAL },
8659 /* Error allocating block bitmap */
8660 { PR_1_ALLOCATE_BBITMAP_ERROR,
8661 N_("@A @b @B (%N): %m\n"),
8662 PROMPT_NONE, PR_FATAL },
8664 /* Error allocating icount structure */
8665 { PR_1_ALLOCATE_ICOUNT,
8666 N_("@A icount link information: %m\n"),
8667 PROMPT_NONE, PR_FATAL },
8669 /* Error allocating dbcount */
8670 { PR_1_ALLOCATE_DBCOUNT,
8671 N_("@A @d @b array: %m\n"),
8672 PROMPT_NONE, PR_FATAL },
8674 /* Error while scanning inodes */
8676 N_("Error while scanning @is (%i): %m\n"),
8677 PROMPT_NONE, PR_FATAL },
8679 /* Error while iterating over blocks */
8680 { PR_1_BLOCK_ITERATE,
8681 N_("Error while iterating over @bs in @i %i: %m\n"),
8682 PROMPT_NONE, PR_FATAL },
8684 /* Error while storing inode count information */
8685 { PR_1_ICOUNT_STORE,
8686 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8687 PROMPT_NONE, PR_FATAL },
8689 /* Error while storing directory block information */
8691 N_("Error storing @d @b information "
8692 "(@i=%i, @b=%b, num=%N): %m\n"),
8693 PROMPT_NONE, PR_FATAL },
8695 /* Error while reading inode (for clearing) */
8697 N_("Error reading @i %i: %m\n"),
8698 PROMPT_NONE, PR_FATAL },
8700 /* Suppress messages prompt */
8701 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8703 /* Imagic flag set on an inode when filesystem doesn't support it */
8705 N_("@i %i has imagic flag set. "),
8708 /* Immutable flag set on a device or socket inode */
8709 { PR_1_SET_IMMUTABLE,
8710 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8711 "or append-only flag set. "),
8712 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8714 /* Compression flag set on an inode when filesystem doesn't support it */
8716 N_("@i %i has @cion flag set on @f without @cion support. "),
8719 /* Non-zero size for device, fifo or socket inode */
8720 { PR_1_SET_NONZSIZE,
8721 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8722 PROMPT_FIX, PR_PREEN_OK },
8724 /* Filesystem revision is 0, but feature flags are set */
8725 { PR_1_FS_REV_LEVEL,
8726 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8727 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8729 /* Journal inode is not in use, but contains data */
8730 { PR_1_JOURNAL_INODE_NOT_CLEAR,
8731 N_("@j @i is not in use, but contains data. "),
8732 PROMPT_CLEAR, PR_PREEN_OK },
8734 /* Journal has bad mode */
8735 { PR_1_JOURNAL_BAD_MODE,
8736 N_("@j is not regular file. "),
8737 PROMPT_FIX, PR_PREEN_OK },
8739 /* Deal with inodes that were part of orphan linked list */
8741 N_("@i %i was part of the @o @i list. "),
8742 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8744 /* Deal with inodes that were part of corrupted orphan linked
8745 list (latch question) */
8746 { PR_1_ORPHAN_LIST_REFUGEES,
8747 N_("@is that were part of a corrupted orphan linked list found. "),
8750 /* Error allocating refcount structure */
8751 { PR_1_ALLOCATE_REFCOUNT,
8752 N_("@A refcount structure (%N): %m\n"),
8753 PROMPT_NONE, PR_FATAL },
8755 /* Error reading extended attribute block */
8756 { PR_1_READ_EA_BLOCK,
8757 N_("Error reading @a @b %b for @i %i. "),
8760 /* Invalid extended attribute block */
8761 { PR_1_BAD_EA_BLOCK,
8762 N_("@i %i has a bad @a @b %b. "),
8765 /* Error reading Extended Attribute block while fixing refcount */
8766 { PR_1_EXTATTR_READ_ABORT,
8767 N_("Error reading @a @b %b (%m). "),
8770 /* Extended attribute reference count incorrect */
8771 { PR_1_EXTATTR_REFCOUNT,
8772 N_("@a @b %b has reference count %B, @s %N. "),
8775 /* Error writing Extended Attribute block while fixing refcount */
8776 { PR_1_EXTATTR_WRITE,
8777 N_("Error writing @a @b %b (%m). "),
8780 /* Multiple EA blocks not supported */
8781 { PR_1_EA_MULTI_BLOCK,
8782 N_("@a @b %b has h_@bs > 1. "),
8785 /* Error allocating EA region allocation structure */
8786 { PR_1_EA_ALLOC_REGION,
8787 N_("@A @a @b %b. "),
8790 /* Error EA allocation collision */
8791 { PR_1_EA_ALLOC_COLLISION,
8792 N_("@a @b %b is corrupt (allocation collision). "),
8795 /* Bad extended attribute name */
8797 N_("@a @b %b is corrupt (@n name). "),
8800 /* Bad extended attribute value */
8801 { PR_1_EA_BAD_VALUE,
8802 N_("@a @b %b is corrupt (@n value). "),
8805 /* Inode too big (latch question) */
8806 { PR_1_INODE_TOOBIG,
8807 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
8809 /* Directory too big */
8811 N_("@b #%B (%b) causes @d to be too big. "),
8812 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8814 /* Regular file too big */
8816 N_("@b #%B (%b) causes file to be too big. "),
8817 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8819 /* Symlink too big */
8820 { PR_1_TOOBIG_SYMLINK,
8821 N_("@b #%B (%b) causes symlink to be too big. "),
8822 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8824 /* INDEX_FL flag set on a non-HTREE filesystem */
8826 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8827 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8829 /* INDEX_FL flag set on a non-directory */
8831 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8832 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8834 /* Invalid root node in HTREE directory */
8835 { PR_1_HTREE_BADROOT,
8836 N_("@h %i has an @n root node.\n"),
8837 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8839 /* Unsupported hash version in HTREE directory */
8841 N_("@h %i has an unsupported hash version (%N)\n"),
8842 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8844 /* Incompatible flag in HTREE root node */
8845 { PR_1_HTREE_INCOMPAT,
8846 N_("@h %i uses an incompatible htree root node flag.\n"),
8847 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8849 /* HTREE too deep */
8851 N_("@h %i has a tree depth (%N) which is too big\n"),
8852 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8854 /* Bad block has indirect block that conflicts with filesystem block */
8856 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8858 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8860 /* Resize inode failed */
8861 { PR_1_RESIZE_INODE_CREATE,
8862 N_("Resize @i (re)creation failed: %m."),
8865 /* invalid inode->i_extra_isize */
8867 N_("@i %i has a extra size (%IS) which is @n\n"),
8868 PROMPT_FIX, PR_PREEN_OK },
8870 /* invalid ea entry->e_name_len */
8871 { PR_1_ATTR_NAME_LEN,
8872 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8873 PROMPT_CLEAR, PR_PREEN_OK },
8875 /* invalid ea entry->e_value_size */
8876 { PR_1_ATTR_VALUE_SIZE,
8877 N_("@a in @i %i has a value size (%N) which is @n\n"),
8878 PROMPT_CLEAR, PR_PREEN_OK },
8880 /* invalid ea entry->e_value_offs */
8881 { PR_1_ATTR_VALUE_OFFSET,
8882 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8883 PROMPT_CLEAR, PR_PREEN_OK },
8885 /* invalid ea entry->e_value_block */
8886 { PR_1_ATTR_VALUE_BLOCK,
8887 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8888 PROMPT_CLEAR, PR_PREEN_OK },
8890 /* invalid ea entry->e_hash */
8892 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8893 PROMPT_CLEAR, PR_PREEN_OK },
8895 /* Pass 1b errors */
8897 /* Pass 1B: Rescan for duplicate/bad blocks */
8898 { PR_1B_PASS_HEADER,
8899 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8900 "Pass 1B: Rescanning for @m @bs\n"),
8903 /* Duplicate/bad block(s) header */
8904 { PR_1B_DUP_BLOCK_HEADER,
8905 N_("@m @b(s) in @i %i:"),
8908 /* Duplicate/bad block(s) in inode */
8911 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8913 /* Duplicate/bad block(s) end */
8914 { PR_1B_DUP_BLOCK_END,
8916 PROMPT_NONE, PR_PREEN_NOHDR },
8918 /* Error while scanning inodes */
8919 { PR_1B_ISCAN_ERROR,
8920 N_("Error while scanning inodes (%i): %m\n"),
8921 PROMPT_NONE, PR_FATAL },
8923 /* Error allocating inode bitmap */
8924 { PR_1B_ALLOCATE_IBITMAP_ERROR,
8925 N_("@A @i @B (@i_dup_map): %m\n"),
8926 PROMPT_NONE, PR_FATAL },
8928 /* Error while iterating over blocks */
8929 { PR_1B_BLOCK_ITERATE,
8930 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8933 /* Error adjusting EA refcount */
8934 { PR_1B_ADJ_EA_REFCOUNT,
8935 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8939 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8940 { PR_1C_PASS_HEADER,
8941 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8945 /* Pass 1D: Reconciling multiply-claimed blocks */
8946 { PR_1D_PASS_HEADER,
8947 N_("Pass 1D: Reconciling @m @bs\n"),
8950 /* File has duplicate blocks */
8952 N_("File %Q (@i #%i, mod time %IM)\n"
8953 " has %B @m @b(s), shared with %N file(s):\n"),
8956 /* List of files sharing duplicate blocks */
8957 { PR_1D_DUP_FILE_LIST,
8958 N_("\t%Q (@i #%i, mod time %IM)\n"),
8961 /* File sharing blocks with filesystem metadata */
8962 { PR_1D_SHARE_METADATA,
8963 N_("\t<@f metadata>\n"),
8966 /* Report of how many duplicate/bad inodes */
8967 { PR_1D_NUM_DUP_INODES,
8968 N_("(There are %N @is containing @m @bs.)\n\n"),
8971 /* Duplicated blocks already reassigned or cloned. */
8972 { PR_1D_DUP_BLOCKS_DEALT,
8973 N_("@m @bs already reassigned or cloned.\n\n"),
8976 /* Clone duplicate/bad blocks? */
8977 { PR_1D_CLONE_QUESTION,
8978 "", PROMPT_CLONE, PR_NO_OK },
8981 { PR_1D_DELETE_QUESTION,
8982 "", PROMPT_DELETE, 0 },
8984 /* Couldn't clone file (error) */
8985 { PR_1D_CLONE_ERROR,
8986 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
8990 /* Pass 2: Checking directory structure */
8992 N_("Pass 2: Checking @d structure\n"),
8995 /* Bad inode number for '.' */
8996 { PR_2_BAD_INODE_DOT,
8997 N_("@n @i number for '.' in @d @i %i.\n"),
9000 /* Directory entry has bad inode number */
9002 N_("@E has @n @i #: %Di.\n"),
9005 /* Directory entry has deleted or unused inode */
9006 { PR_2_UNUSED_INODE,
9007 N_("@E has @D/unused @i %Di. "),
9008 PROMPT_CLEAR, PR_PREEN_OK },
9010 /* Directry entry is link to '.' */
9012 N_("@E @L to '.' "),
9015 /* Directory entry points to inode now located in a bad block */
9017 N_("@E points to @i (%Di) located in a bad @b.\n"),
9020 /* Directory entry contains a link to a directory */
9022 N_("@E @L to @d %P (%Di).\n"),
9025 /* Directory entry contains a link to the root directry */
9027 N_("@E @L to the @r.\n"),
9030 /* Directory entry has illegal characters in its name */
9032 N_("@E has illegal characters in its name.\n"),
9035 /* Missing '.' in directory inode */
9037 N_("Missing '.' in @d @i %i.\n"),
9040 /* Missing '..' in directory inode */
9041 { PR_2_MISSING_DOT_DOT,
9042 N_("Missing '..' in @d @i %i.\n"),
9045 /* First entry in directory inode doesn't contain '.' */
9047 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9050 /* Second entry in directory inode doesn't contain '..' */
9051 { PR_2_2ND_NOT_DOT_DOT,
9052 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9055 /* i_faddr should be zero */
9057 N_("i_faddr @F %IF, @s zero.\n"),
9060 /* i_file_acl should be zero */
9061 { PR_2_FILE_ACL_ZERO,
9062 N_("i_file_acl @F %If, @s zero.\n"),
9065 /* i_dir_acl should be zero */
9066 { PR_2_DIR_ACL_ZERO,
9067 N_("i_dir_acl @F %Id, @s zero.\n"),
9070 /* i_frag should be zero */
9072 N_("i_frag @F %N, @s zero.\n"),
9075 /* i_fsize should be zero */
9077 N_("i_fsize @F %N, @s zero.\n"),
9080 /* inode has bad mode */
9082 N_("@i %i (%Q) has @n mode (%Im).\n"),
9085 /* directory corrupted */
9086 { PR_2_DIR_CORRUPTED,
9087 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9088 PROMPT_SALVAGE, 0 },
9090 /* filename too long */
9091 { PR_2_FILENAME_LONG,
9092 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9093 PROMPT_TRUNCATE, 0 },
9095 /* Directory inode has a missing block (hole) */
9096 { PR_2_DIRECTORY_HOLE,
9097 N_("@d @i %i has an unallocated @b #%B. "),
9098 PROMPT_ALLOCATE, 0 },
9100 /* '.' is not NULL terminated */
9101 { PR_2_DOT_NULL_TERM,
9102 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9105 /* '..' is not NULL terminated */
9106 { PR_2_DOT_DOT_NULL_TERM,
9107 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9110 /* Illegal character device inode */
9111 { PR_2_BAD_CHAR_DEV,
9112 N_("@i %i (%Q) is an @I character @v.\n"),
9115 /* Illegal block device inode */
9116 { PR_2_BAD_BLOCK_DEV,
9117 N_("@i %i (%Q) is an @I @b @v.\n"),
9120 /* Duplicate '.' entry */
9122 N_("@E is duplicate '.' @e.\n"),
9125 /* Duplicate '..' entry */
9127 N_("@E is duplicate '..' @e.\n"),
9130 /* Internal error: couldn't find dir_info */
9132 N_("Internal error: cannot find dir_info for %i.\n"),
9133 PROMPT_NONE, PR_FATAL },
9135 /* Final rec_len is wrong */
9136 { PR_2_FINAL_RECLEN,
9137 N_("@E has rec_len of %Dr, @s %N.\n"),
9140 /* Error allocating icount structure */
9141 { PR_2_ALLOCATE_ICOUNT,
9142 N_("@A icount structure: %m\n"),
9143 PROMPT_NONE, PR_FATAL },
9145 /* Error iterating over directory blocks */
9146 { PR_2_DBLIST_ITERATE,
9147 N_("Error iterating over @d @bs: %m\n"),
9148 PROMPT_NONE, PR_FATAL },
9150 /* Error reading directory block */
9151 { PR_2_READ_DIRBLOCK,
9152 N_("Error reading @d @b %b (@i %i): %m\n"),
9153 PROMPT_CONTINUE, 0 },
9155 /* Error writing directory block */
9156 { PR_2_WRITE_DIRBLOCK,
9157 N_("Error writing @d @b %b (@i %i): %m\n"),
9158 PROMPT_CONTINUE, 0 },
9160 /* Error allocating new directory block */
9161 { PR_2_ALLOC_DIRBOCK,
9162 N_("@A new @d @b for @i %i (%s): %m\n"),
9165 /* Error deallocating inode */
9166 { PR_2_DEALLOC_INODE,
9167 N_("Error deallocating @i %i: %m\n"),
9168 PROMPT_NONE, PR_FATAL },
9170 /* Directory entry for '.' is big. Split? */
9172 N_("@d @e for '.' is big. "),
9173 PROMPT_SPLIT, PR_NO_OK },
9175 /* Illegal FIFO inode */
9177 N_("@i %i (%Q) is an @I FIFO.\n"),
9180 /* Illegal socket inode */
9182 N_("@i %i (%Q) is an @I socket.\n"),
9185 /* Directory filetype not set */
9186 { PR_2_SET_FILETYPE,
9187 N_("Setting filetype for @E to %N.\n"),
9188 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9190 /* Directory filetype incorrect */
9191 { PR_2_BAD_FILETYPE,
9192 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9195 /* Directory filetype set on filesystem */
9196 { PR_2_CLEAR_FILETYPE,
9197 N_("@E has filetype set.\n"),
9198 PROMPT_CLEAR, PR_PREEN_OK },
9200 /* Directory filename is null */
9202 N_("@E has a @z name.\n"),
9205 /* Invalid symlink */
9206 { PR_2_INVALID_SYMLINK,
9207 N_("Symlink %Q (@i #%i) is @n.\n"),
9210 /* i_file_acl (extended attribute block) is bad */
9211 { PR_2_FILE_ACL_BAD,
9212 N_("@a @b @F @n (%If).\n"),
9215 /* Filesystem contains large files, but has no such flag in sb */
9216 { PR_2_FEATURE_LARGE_FILES,
9217 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9220 /* Node in HTREE directory not referenced */
9221 { PR_2_HTREE_NOTREF,
9222 N_("@p @h %d: node (%B) not referenced\n"),
9225 /* Node in HTREE directory referenced twice */
9226 { PR_2_HTREE_DUPREF,
9227 N_("@p @h %d: node (%B) referenced twice\n"),
9230 /* Node in HTREE directory has bad min hash */
9231 { PR_2_HTREE_MIN_HASH,
9232 N_("@p @h %d: node (%B) has bad min hash\n"),
9235 /* Node in HTREE directory has bad max hash */
9236 { PR_2_HTREE_MAX_HASH,
9237 N_("@p @h %d: node (%B) has bad max hash\n"),
9240 /* Clear invalid HTREE directory */
9242 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9244 /* Bad block in htree interior node */
9245 { PR_2_HTREE_BADBLK,
9246 N_("@p @h %d (%q): bad @b number %b.\n"),
9247 PROMPT_CLEAR_HTREE, 0 },
9249 /* Error adjusting EA refcount */
9250 { PR_2_ADJ_EA_REFCOUNT,
9251 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9252 PROMPT_NONE, PR_FATAL },
9254 /* Invalid HTREE root node */
9255 { PR_2_HTREE_BAD_ROOT,
9256 N_("@p @h %d: root node is @n\n"),
9257 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9259 /* Invalid HTREE limit */
9260 { PR_2_HTREE_BAD_LIMIT,
9261 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9262 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9264 /* Invalid HTREE count */
9265 { PR_2_HTREE_BAD_COUNT,
9266 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9267 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9269 /* HTREE interior node has out-of-order hashes in table */
9270 { PR_2_HTREE_HASH_ORDER,
9271 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9272 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9274 /* Node in HTREE directory has invalid depth */
9275 { PR_2_HTREE_BAD_DEPTH,
9276 N_("@p @h %d: node (%B) has @n depth\n"),
9279 /* Duplicate directory entry found */
9280 { PR_2_DUPLICATE_DIRENT,
9281 N_("Duplicate @E found. "),
9284 /* Non-unique filename found */
9285 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9286 N_("@E has a non-unique filename.\nRename to %s"),
9289 /* Duplicate directory entry found */
9290 { PR_2_REPORT_DUP_DIRENT,
9291 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9296 /* Pass 3: Checking directory connectivity */
9298 N_("Pass 3: Checking @d connectivity\n"),
9301 /* Root inode not allocated */
9302 { PR_3_NO_ROOT_INODE,
9303 N_("@r not allocated. "),
9304 PROMPT_ALLOCATE, 0 },
9306 /* No room in lost+found */
9307 { PR_3_EXPAND_LF_DIR,
9308 N_("No room in @l @d. "),
9311 /* Unconnected directory inode */
9312 { PR_3_UNCONNECTED_DIR,
9313 N_("Unconnected @d @i %i (%p)\n"),
9314 PROMPT_CONNECT, 0 },
9316 /* /lost+found not found */
9318 N_("/@l not found. "),
9319 PROMPT_CREATE, PR_PREEN_OK },
9321 /* .. entry is incorrect */
9323 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9326 /* Bad or non-existent /lost+found. Cannot reconnect */
9328 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9331 /* Could not expand /lost+found */
9332 { PR_3_CANT_EXPAND_LPF,
9333 N_("Could not expand /@l: %m\n"),
9336 /* Could not reconnect inode */
9337 { PR_3_CANT_RECONNECT,
9338 N_("Could not reconnect %i: %m\n"),
9341 /* Error while trying to find /lost+found */
9342 { PR_3_ERR_FIND_LPF,
9343 N_("Error while trying to find /@l: %m\n"),
9346 /* Error in ext2fs_new_block while creating /lost+found */
9347 { PR_3_ERR_LPF_NEW_BLOCK,
9348 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9351 /* Error in ext2fs_new_inode while creating /lost+found */
9352 { PR_3_ERR_LPF_NEW_INODE,
9353 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9356 /* Error in ext2fs_new_dir_block while creating /lost+found */
9357 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9358 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9361 /* Error while writing directory block for /lost+found */
9362 { PR_3_ERR_LPF_WRITE_BLOCK,
9363 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9366 /* Error while adjusting inode count */
9367 { PR_3_ADJUST_INODE,
9368 N_("Error while adjusting @i count on @i %i\n"),
9371 /* Couldn't fix parent directory -- error */
9372 { PR_3_FIX_PARENT_ERR,
9373 N_("Couldn't fix parent of @i %i: %m\n\n"),
9376 /* Couldn't fix parent directory -- couldn't find it */
9377 { PR_3_FIX_PARENT_NOFIND,
9378 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9381 /* Error allocating inode bitmap */
9382 { PR_3_ALLOCATE_IBITMAP_ERROR,
9383 N_("@A @i @B (%N): %m\n"),
9384 PROMPT_NONE, PR_FATAL },
9386 /* Error creating root directory */
9387 { PR_3_CREATE_ROOT_ERROR,
9388 N_("Error creating root @d (%s): %m\n"),
9389 PROMPT_NONE, PR_FATAL },
9391 /* Error creating lost and found directory */
9392 { PR_3_CREATE_LPF_ERROR,
9393 N_("Error creating /@l @d (%s): %m\n"),
9394 PROMPT_NONE, PR_FATAL },
9396 /* Root inode is not directory; aborting */
9397 { PR_3_ROOT_NOT_DIR_ABORT,
9398 N_("@r is not a @d; aborting.\n"),
9399 PROMPT_NONE, PR_FATAL },
9401 /* Cannot proceed without a root inode. */
9402 { PR_3_NO_ROOT_INODE_ABORT,
9403 N_("Cannot proceed without a @r.\n"),
9404 PROMPT_NONE, PR_FATAL },
9406 /* Internal error: couldn't find dir_info */
9408 N_("Internal error: cannot find dir_info for %i.\n"),
9409 PROMPT_NONE, PR_FATAL },
9411 /* Lost+found not a directory */
9413 N_("/@l is not a @d (ino=%i)\n"),
9416 /* Pass 3A Directory Optimization */
9418 /* Pass 3A: Optimizing directories */
9419 { PR_3A_PASS_HEADER,
9420 N_("Pass 3A: Optimizing directories\n"),
9421 PROMPT_NONE, PR_PREEN_NOMSG },
9423 /* Error iterating over directories */
9424 { PR_3A_OPTIMIZE_ITER,
9425 N_("Failed to create dirs_to_hash iterator: %m"),
9428 /* Error rehash directory */
9429 { PR_3A_OPTIMIZE_DIR_ERR,
9430 N_("Failed to optimize directory %q (%d): %m"),
9433 /* Rehashing dir header */
9434 { PR_3A_OPTIMIZE_DIR_HEADER,
9435 N_("Optimizing directories: "),
9436 PROMPT_NONE, PR_MSG_ONLY },
9438 /* Rehashing directory %d */
9439 { PR_3A_OPTIMIZE_DIR,
9441 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9443 /* Rehashing dir end */
9444 { PR_3A_OPTIMIZE_DIR_END,
9446 PROMPT_NONE, PR_PREEN_NOHDR },
9450 /* Pass 4: Checking reference counts */
9452 N_("Pass 4: Checking reference counts\n"),
9455 /* Unattached zero-length inode */
9456 { PR_4_ZERO_LEN_INODE,
9457 N_("@u @z @i %i. "),
9458 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9460 /* Unattached inode */
9461 { PR_4_UNATTACHED_INODE,
9463 PROMPT_CONNECT, 0 },
9465 /* Inode ref count wrong */
9466 { PR_4_BAD_REF_COUNT,
9467 N_("@i %i ref count is %Il, @s %N. "),
9468 PROMPT_FIX, PR_PREEN_OK },
9470 { PR_4_INCONSISTENT_COUNT,
9471 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9472 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9473 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9474 "They @s the same!\n"),
9479 /* Pass 5: Checking group summary information */
9481 N_("Pass 5: Checking @g summary information\n"),
9484 /* Padding at end of inode bitmap is not set. */
9485 { PR_5_INODE_BMAP_PADDING,
9486 N_("Padding at end of @i @B is not set. "),
9487 PROMPT_FIX, PR_PREEN_OK },
9489 /* Padding at end of block bitmap is not set. */
9490 { PR_5_BLOCK_BMAP_PADDING,
9491 N_("Padding at end of @b @B is not set. "),
9492 PROMPT_FIX, PR_PREEN_OK },
9494 /* Block bitmap differences header */
9495 { PR_5_BLOCK_BITMAP_HEADER,
9496 N_("@b @B differences: "),
9497 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9499 /* Block not used, but marked in bitmap */
9500 { PR_5_BLOCK_UNUSED,
9502 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9504 /* Block used, but not marked used in bitmap */
9507 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9509 /* Block bitmap differences end */
9510 { PR_5_BLOCK_BITMAP_END,
9512 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9514 /* Inode bitmap differences header */
9515 { PR_5_INODE_BITMAP_HEADER,
9516 N_("@i @B differences: "),
9517 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9519 /* Inode not used, but marked in bitmap */
9520 { PR_5_INODE_UNUSED,
9522 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9524 /* Inode used, but not marked used in bitmap */
9527 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9529 /* Inode bitmap differences end */
9530 { PR_5_INODE_BITMAP_END,
9532 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9534 /* Free inodes count for group wrong */
9535 { PR_5_FREE_INODE_COUNT_GROUP,
9536 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9537 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9539 /* Directories count for group wrong */
9540 { PR_5_FREE_DIR_COUNT_GROUP,
9541 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9542 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9544 /* Free inodes count wrong */
9545 { PR_5_FREE_INODE_COUNT,
9546 N_("Free @is count wrong (%i, counted=%j).\n"),
9547 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9549 /* Free blocks count for group wrong */
9550 { PR_5_FREE_BLOCK_COUNT_GROUP,
9551 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9552 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9554 /* Free blocks count wrong */
9555 { PR_5_FREE_BLOCK_COUNT,
9556 N_("Free @bs count wrong (%b, counted=%c).\n"),
9557 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9559 /* Programming error: bitmap endpoints don't match */
9560 { PR_5_BMAP_ENDPOINTS,
9561 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9562 "match calculated @B endpoints (%i, %j)\n"),
9563 PROMPT_NONE, PR_FATAL },
9565 /* Internal error: fudging end of bitmap */
9566 { PR_5_FUDGE_BITMAP_ERROR,
9567 N_("Internal error: fudging end of bitmap (%N)\n"),
9568 PROMPT_NONE, PR_FATAL },
9570 /* Error copying in replacement inode bitmap */
9571 { PR_5_COPY_IBITMAP_ERROR,
9572 N_("Error copying in replacement @i @B: %m\n"),
9573 PROMPT_NONE, PR_FATAL },
9575 /* Error copying in replacement block bitmap */
9576 { PR_5_COPY_BBITMAP_ERROR,
9577 N_("Error copying in replacement @b @B: %m\n"),
9578 PROMPT_NONE, PR_FATAL },
9580 /* Block range not used, but marked in bitmap */
9581 { PR_5_BLOCK_RANGE_UNUSED,
9583 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9585 /* Block range used, but not marked used in bitmap */
9586 { PR_5_BLOCK_RANGE_USED,
9588 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9590 /* Inode range not used, but marked in bitmap */
9591 { PR_5_INODE_RANGE_UNUSED,
9593 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9595 /* Inode range used, but not marked used in bitmap */
9596 { PR_5_INODE_RANGE_USED,
9598 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9604 * This is the latch flags register. It allows several problems to be
9605 * "latched" together. This means that the user has to answer but one
9606 * question for the set of problems, and all of the associated
9607 * problems will be either fixed or not fixed.
9609 static struct latch_descr pr_latch_info[] = {
9610 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9611 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9612 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9613 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9614 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9615 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9616 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9617 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9618 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9622 static const struct e2fsck_problem *find_problem(problem_t code)
9626 for (i=0; problem_table[i].e2p_code; i++) {
9627 if (problem_table[i].e2p_code == code)
9628 return &problem_table[i];
9633 static struct latch_descr *find_latch(int code)
9637 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9638 if (pr_latch_info[i].latch_code == code)
9639 return &pr_latch_info[i];
9644 int end_problem_latch(e2fsck_t ctx, int mask)
9646 struct latch_descr *ldesc;
9647 struct problem_context pctx;
9650 ldesc = find_latch(mask);
9651 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9652 clear_problem_context(&pctx);
9653 answer = fix_problem(ctx, ldesc->end_message, &pctx);
9655 ldesc->flags &= ~(PRL_VARIABLE);
9659 int set_latch_flags(int mask, int setflags, int clearflags)
9661 struct latch_descr *ldesc;
9663 ldesc = find_latch(mask);
9666 ldesc->flags |= setflags;
9667 ldesc->flags &= ~clearflags;
9671 void clear_problem_context(struct problem_context *ctx)
9673 memset(ctx, 0, sizeof(struct problem_context));
9678 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9680 ext2_filsys fs = ctx->fs;
9681 const struct e2fsck_problem *ptr;
9682 struct latch_descr *ldesc = 0;
9683 const char *message;
9684 int def_yn, answer, ans;
9685 int print_answer = 0;
9688 ptr = find_problem(code);
9690 printf(_("Unhandled error code (0x%x)!\n"), code);
9694 if ((ptr->flags & PR_NO_DEFAULT) ||
9695 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9696 (ctx->options & E2F_OPT_NO))
9700 * Do special latch processing. This is where we ask the
9701 * latch question, if it exists
9703 if (ptr->flags & PR_LATCH_MASK) {
9704 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9705 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9706 ans = fix_problem(ctx, ldesc->question, pctx);
9708 ldesc->flags |= PRL_YES;
9710 ldesc->flags |= PRL_NO;
9711 ldesc->flags |= PRL_LATCHED;
9713 if (ldesc->flags & PRL_SUPPRESS)
9716 if ((ptr->flags & PR_PREEN_NOMSG) &&
9717 (ctx->options & E2F_OPT_PREEN))
9719 if ((ptr->flags & PR_NO_NOMSG) &&
9720 (ctx->options & E2F_OPT_NO))
9723 message = ptr->e2p_description;
9724 if ((ctx->options & E2F_OPT_PREEN) &&
9725 !(ptr->flags & PR_PREEN_NOHDR)) {
9726 printf("%s: ", ctx->device_name ?
9727 ctx->device_name : ctx->filesystem_name);
9730 print_e2fsck_message(ctx, _(message), pctx, 1);
9732 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9735 if (ptr->flags & PR_FATAL)
9736 bb_error_msg_and_die(0);
9738 if (ptr->prompt == PROMPT_NONE) {
9739 if (ptr->flags & PR_NOCOLLATE)
9744 if (ctx->options & E2F_OPT_PREEN) {
9746 if (!(ptr->flags & PR_PREEN_NOMSG))
9748 } else if ((ptr->flags & PR_LATCH_MASK) &&
9749 (ldesc->flags & (PRL_YES | PRL_NO))) {
9752 if (ldesc->flags & PRL_YES)
9757 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9758 if (!answer && !(ptr->flags & PR_NO_OK))
9759 ext2fs_unmark_valid(fs);
9762 printf("%s.\n", answer ?
9763 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9767 if ((ptr->prompt == PROMPT_ABORT) && answer)
9768 bb_error_msg_and_die(0);
9770 if (ptr->flags & PR_AFTER_CODE)
9771 answer = fix_problem(ctx, ptr->second_code, pctx);
9777 * linux/fs/recovery.c
9779 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9783 * Maintain information about the progress of the recovery job, so that
9784 * the different passes can carry information between them.
9786 struct recovery_info
9788 tid_t start_transaction;
9789 tid_t end_transaction;
9796 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9797 static int do_one_pass(journal_t *journal,
9798 struct recovery_info *info, enum passtype pass);
9799 static int scan_revoke_records(journal_t *, struct buffer_head *,
9800 tid_t, struct recovery_info *);
9803 * Read a block from the journal
9806 static int jread(struct buffer_head **bhp, journal_t *journal,
9807 unsigned int offset)
9810 unsigned long blocknr;
9811 struct buffer_head *bh;
9815 err = journal_bmap(journal, offset, &blocknr);
9818 printf("JBD: bad block at offset %u\n", offset);
9822 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9826 if (!buffer_uptodate(bh)) {
9827 /* If this is a brand new buffer, start readahead.
9828 Otherwise, we assume we are already reading it. */
9829 if (!buffer_req(bh))
9830 do_readahead(journal, offset);
9834 if (!buffer_uptodate(bh)) {
9835 printf("JBD: Failed to read block at offset %u\n", offset);
9846 * Count the number of in-use tags in a journal descriptor block.
9849 static int count_tags(struct buffer_head *bh, int size)
9852 journal_block_tag_t * tag;
9855 tagp = &bh->b_data[sizeof(journal_header_t)];
9857 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9858 tag = (journal_block_tag_t *) tagp;
9861 tagp += sizeof(journal_block_tag_t);
9862 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9865 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9873 /* Make sure we wrap around the log correctly! */
9874 #define wrap(journal, var) \
9876 if (var >= (journal)->j_last) \
9877 var -= ((journal)->j_last - (journal)->j_first); \
9881 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9882 * @journal: the journal to recover
9884 * The primary function for recovering the log contents when mounting a
9887 * Recovery is done in three passes. In the first pass, we look for the
9888 * end of the log. In the second, we assemble the list of revoke
9889 * blocks. In the third and final pass, we replay any un-revoked blocks
9892 int journal_recover(journal_t *journal)
9895 journal_superblock_t * sb;
9897 struct recovery_info info;
9899 memset(&info, 0, sizeof(info));
9900 sb = journal->j_superblock;
9903 * The journal superblock's s_start field (the current log head)
9904 * is always zero if, and only if, the journal was cleanly
9909 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9913 err = do_one_pass(journal, &info, PASS_SCAN);
9915 err = do_one_pass(journal, &info, PASS_REVOKE);
9917 err = do_one_pass(journal, &info, PASS_REPLAY);
9919 /* Restart the log at the next transaction ID, thus invalidating
9920 * any existing commit records in the log. */
9921 journal->j_transaction_sequence = ++info.end_transaction;
9923 journal_clear_revoke(journal);
9924 sync_blockdev(journal->j_fs_dev);
9928 static int do_one_pass(journal_t *journal,
9929 struct recovery_info *info, enum passtype pass)
9931 unsigned int first_commit_ID, next_commit_ID;
9932 unsigned long next_log_block;
9933 int err, success = 0;
9934 journal_superblock_t * sb;
9935 journal_header_t * tmp;
9936 struct buffer_head * bh;
9937 unsigned int sequence;
9940 /* Precompute the maximum metadata descriptors in a descriptor block */
9941 int MAX_BLOCKS_PER_DESC;
9942 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9943 / sizeof(journal_block_tag_t));
9946 * First thing is to establish what we expect to find in the log
9947 * (in terms of transaction IDs), and where (in terms of log
9948 * block offsets): query the superblock.
9951 sb = journal->j_superblock;
9952 next_commit_ID = ntohl(sb->s_sequence);
9953 next_log_block = ntohl(sb->s_start);
9955 first_commit_ID = next_commit_ID;
9956 if (pass == PASS_SCAN)
9957 info->start_transaction = first_commit_ID;
9960 * Now we walk through the log, transaction by transaction,
9961 * making sure that each transaction has a commit block in the
9962 * expected place. Each complete transaction gets replayed back
9963 * into the main filesystem.
9969 journal_block_tag_t * tag;
9970 struct buffer_head * obh;
9971 struct buffer_head * nbh;
9973 /* If we already know where to stop the log traversal,
9974 * check right now that we haven't gone past the end of
9977 if (pass != PASS_SCAN)
9978 if (tid_geq(next_commit_ID, info->end_transaction))
9981 /* Skip over each chunk of the transaction looking
9982 * either the next descriptor block or the final commit
9985 err = jread(&bh, journal, next_log_block);
9990 wrap(journal, next_log_block);
9992 /* What kind of buffer is it?
9994 * If it is a descriptor block, check that it has the
9995 * expected sequence number. Otherwise, we're all done
9998 tmp = (journal_header_t *)bh->b_data;
10000 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10005 blocktype = ntohl(tmp->h_blocktype);
10006 sequence = ntohl(tmp->h_sequence);
10008 if (sequence != next_commit_ID) {
10013 /* OK, we have a valid descriptor block which matches
10014 * all of the sequence number checks. What are we going
10015 * to do with it? That depends on the pass... */
10017 switch (blocktype) {
10018 case JFS_DESCRIPTOR_BLOCK:
10019 /* If it is a valid descriptor block, replay it
10020 * in pass REPLAY; otherwise, just skip over the
10021 * blocks it describes. */
10022 if (pass != PASS_REPLAY) {
10024 count_tags(bh, journal->j_blocksize);
10025 wrap(journal, next_log_block);
10030 /* A descriptor block: we can now write all of
10031 * the data blocks. Yay, useful work is finally
10032 * getting done here! */
10034 tagp = &bh->b_data[sizeof(journal_header_t)];
10035 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10036 <= journal->j_blocksize) {
10037 unsigned long io_block;
10039 tag = (journal_block_tag_t *) tagp;
10040 flags = ntohl(tag->t_flags);
10042 io_block = next_log_block++;
10043 wrap(journal, next_log_block);
10044 err = jread(&obh, journal, io_block);
10046 /* Recover what we can, but
10047 * report failure at the end. */
10049 printf("JBD: IO error %d recovering "
10050 "block %ld in log\n",
10053 unsigned long blocknr;
10055 blocknr = ntohl(tag->t_blocknr);
10057 /* If the block has been
10058 * revoked, then we're all done
10060 if (journal_test_revoke
10064 ++info->nr_revoke_hits;
10068 /* Find a buffer for the new
10069 * data being restored */
10070 nbh = getblk(journal->j_fs_dev,
10072 journal->j_blocksize);
10074 printf("JBD: Out of memory "
10075 "during recovery.\n");
10083 memcpy(nbh->b_data, obh->b_data,
10084 journal->j_blocksize);
10085 if (flags & JFS_FLAG_ESCAPE) {
10086 *((unsigned int *)bh->b_data) =
10087 htonl(JFS_MAGIC_NUMBER);
10090 mark_buffer_uptodate(nbh, 1);
10091 mark_buffer_dirty(nbh);
10092 ++info->nr_replays;
10093 /* ll_rw_block(WRITE, 1, &nbh); */
10094 unlock_buffer(nbh);
10100 tagp += sizeof(journal_block_tag_t);
10101 if (!(flags & JFS_FLAG_SAME_UUID))
10104 if (flags & JFS_FLAG_LAST_TAG)
10111 case JFS_COMMIT_BLOCK:
10112 /* Found an expected commit block: not much to
10113 * do other than move on to the next sequence
10119 case JFS_REVOKE_BLOCK:
10120 /* If we aren't in the REVOKE pass, then we can
10121 * just skip over this block. */
10122 if (pass != PASS_REVOKE) {
10127 err = scan_revoke_records(journal, bh,
10128 next_commit_ID, info);
10141 * We broke out of the log scan loop: either we came to the
10142 * known end of the log or we found an unexpected block in the
10143 * log. If the latter happened, then we know that the "current"
10144 * transaction marks the end of the valid log.
10147 if (pass == PASS_SCAN)
10148 info->end_transaction = next_commit_ID;
10150 /* It's really bad news if different passes end up at
10151 * different places (but possible due to IO errors). */
10152 if (info->end_transaction != next_commit_ID) {
10153 printf("JBD: recovery pass %d ended at "
10154 "transaction %u, expected %u\n",
10155 pass, next_commit_ID, info->end_transaction);
10168 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10170 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10171 tid_t sequence, struct recovery_info *info)
10173 journal_revoke_header_t *header;
10176 header = (journal_revoke_header_t *) bh->b_data;
10177 offset = sizeof(journal_revoke_header_t);
10178 max = ntohl(header->r_count);
10180 while (offset < max) {
10181 unsigned long blocknr;
10184 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10186 err = journal_set_revoke(journal, blocknr, sequence);
10189 ++info->nr_revokes;
10196 * rehash.c --- rebuild hash tree directories
10198 * This algorithm is designed for simplicity of implementation and to
10199 * pack the directory as much as possible. It however requires twice
10200 * as much memory as the size of the directory. The maximum size
10201 * directory supported using a 4k blocksize is roughly a gigabyte, and
10202 * so there may very well be problems with machines that don't have
10203 * virtual memory, and obscenely large directories.
10205 * An alternate algorithm which is much more disk intensive could be
10206 * written, and probably will need to be written in the future. The
10207 * design goals of such an algorithm are: (a) use (roughly) constant
10208 * amounts of memory, no matter how large the directory, (b) the
10209 * directory must be safe at all times, even if e2fsck is interrupted
10210 * in the middle, (c) we must use minimal amounts of extra disk
10211 * blocks. This pretty much requires an incremental approach, where
10212 * we are reading from one part of the directory, and inserting into
10213 * the front half. So the algorithm will have to keep track of a
10214 * moving block boundary between the new tree and the old tree, and
10215 * files will need to be moved from the old directory and inserted
10216 * into the new tree. If the new directory requires space which isn't
10217 * yet available, blocks from the beginning part of the old directory
10218 * may need to be moved to the end of the directory to make room for
10221 * --------------------------------------------------------
10222 * | new tree | | old tree |
10223 * --------------------------------------------------------
10225 * tail new head old
10227 * This is going to be a pain in the tuckus to implement, and will
10228 * require a lot more disk accesses. So I'm going to skip it for now;
10229 * it's only really going to be an issue for really, really big
10230 * filesystems (when we reach the level of tens of millions of files
10231 * in a single directory). It will probably be easier to simply
10232 * require that e2fsck use VM first.
10235 struct fill_dir_struct {
10237 struct ext2_inode *inode;
10240 struct hash_entry *harray;
10241 int max_array, num_array;
10247 struct hash_entry {
10248 ext2_dirhash_t hash;
10249 ext2_dirhash_t minor_hash;
10250 struct ext2_dir_entry *dir;
10257 ext2_dirhash_t *hashes;
10260 static int fill_dir_block(ext2_filsys fs,
10262 e2_blkcnt_t blockcnt,
10263 blk_t ref_block FSCK_ATTR((unused)),
10264 int ref_offset FSCK_ATTR((unused)),
10267 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10268 struct hash_entry *new_array, *ent;
10269 struct ext2_dir_entry *dirent;
10271 unsigned int offset, dir_offset;
10276 offset = blockcnt * fs->blocksize;
10277 if (offset + fs->blocksize > fd->inode->i_size) {
10278 fd->err = EXT2_ET_DIR_CORRUPTED;
10279 return BLOCK_ABORT;
10281 dir = (fd->buf+offset);
10282 if (HOLE_BLKADDR(*block_nr)) {
10283 memset(dir, 0, fs->blocksize);
10284 dirent = (struct ext2_dir_entry *) dir;
10285 dirent->rec_len = fs->blocksize;
10287 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10289 return BLOCK_ABORT;
10291 /* While the directory block is "hot", index it. */
10293 while (dir_offset < fs->blocksize) {
10294 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10295 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10296 (dirent->rec_len < 8) ||
10297 ((dirent->rec_len % 4) != 0) ||
10298 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10299 fd->err = EXT2_ET_DIR_CORRUPTED;
10300 return BLOCK_ABORT;
10302 dir_offset += dirent->rec_len;
10303 if (dirent->inode == 0)
10305 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10306 (dirent->name[0] == '.'))
10308 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10309 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10310 fd->parent = dirent->inode;
10313 if (fd->num_array >= fd->max_array) {
10314 new_array = realloc(fd->harray,
10315 sizeof(struct hash_entry) * (fd->max_array+500));
10318 return BLOCK_ABORT;
10320 fd->harray = new_array;
10321 fd->max_array += 500;
10323 ent = fd->harray + fd->num_array++;
10325 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10327 ent->hash = ent->minor_hash = 0;
10329 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10331 dirent->name_len & 0xFF,
10332 fs->super->s_hash_seed,
10333 &ent->hash, &ent->minor_hash);
10335 return BLOCK_ABORT;
10342 /* Used for sorting the hash entry */
10343 static int name_cmp(const void *a, const void *b)
10345 const struct hash_entry *he_a = (const struct hash_entry *) a;
10346 const struct hash_entry *he_b = (const struct hash_entry *) b;
10350 min_len = he_a->dir->name_len;
10351 if (min_len > he_b->dir->name_len)
10352 min_len = he_b->dir->name_len;
10354 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10356 if (he_a->dir->name_len > he_b->dir->name_len)
10358 else if (he_a->dir->name_len < he_b->dir->name_len)
10361 ret = he_b->dir->inode - he_a->dir->inode;
10366 /* Used for sorting the hash entry */
10367 static int hash_cmp(const void *a, const void *b)
10369 const struct hash_entry *he_a = (const struct hash_entry *) a;
10370 const struct hash_entry *he_b = (const struct hash_entry *) b;
10373 if (he_a->hash > he_b->hash)
10375 else if (he_a->hash < he_b->hash)
10378 if (he_a->minor_hash > he_b->minor_hash)
10380 else if (he_a->minor_hash < he_b->minor_hash)
10383 ret = name_cmp(a, b);
10388 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10394 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10397 outdir->buf = new_mem;
10398 new_mem = realloc(outdir->hashes,
10399 blocks * sizeof(ext2_dirhash_t));
10402 outdir->hashes = new_mem;
10404 outdir->buf = malloc(blocks * fs->blocksize);
10405 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10408 outdir->max = blocks;
10412 static void free_out_dir(struct out_dir *outdir)
10415 free(outdir->hashes);
10420 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10425 if (outdir->num >= outdir->max) {
10426 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10430 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10431 memset(*ret, 0, fs->blocksize);
10436 * This function is used to make a unique filename. We do this by
10437 * appending ~0, and then incrementing the number. However, we cannot
10438 * expand the length of the filename beyond the padding available in
10439 * the directory entry.
10441 static void mutate_name(char *str, __u16 *len)
10444 __u16 l = *len & 0xFF, h = *len & 0xff00;
10447 * First check to see if it looks the name has been mutated
10450 for (i = l-1; i > 0; i--) {
10451 if (!isdigit(str[i]))
10454 if ((i == l-1) || (str[i] != '~')) {
10455 if (((l-1) & 3) < 2)
10464 for (i = l-1; i >= 0; i--) {
10465 if (isdigit(str[i])) {
10477 else if (str[0] == 'Z') {
10482 } else if (i > 0) {
10495 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10497 struct fill_dir_struct *fd)
10499 struct problem_context pctx;
10500 struct hash_entry *ent, *prev;
10503 char new_name[256];
10506 clear_problem_context(&pctx);
10509 for (i=1; i < fd->num_array; i++) {
10510 ent = fd->harray + i;
10512 if (!ent->dir->inode ||
10513 ((ent->dir->name_len & 0xFF) !=
10514 (prev->dir->name_len & 0xFF)) ||
10515 (strncmp(ent->dir->name, prev->dir->name,
10516 ent->dir->name_len & 0xFF)))
10518 pctx.dirent = ent->dir;
10519 if ((ent->dir->inode == prev->dir->inode) &&
10520 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10521 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10522 ent->dir->inode = 0;
10526 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10527 new_len = ent->dir->name_len;
10528 mutate_name(new_name, &new_len);
10529 for (j=0; j < fd->num_array; j++) {
10531 ((ent->dir->name_len & 0xFF) !=
10532 (fd->harray[j].dir->name_len & 0xFF)) ||
10533 (strncmp(new_name, fd->harray[j].dir->name,
10536 mutate_name(new_name, &new_len);
10540 new_name[new_len & 0xFF] = 0;
10541 pctx.str = new_name;
10542 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10543 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10544 ent->dir->name_len = new_len;
10545 ext2fs_dirhash(fs->super->s_def_hash_version,
10547 ent->dir->name_len & 0xFF,
10548 fs->super->s_hash_seed,
10549 &ent->hash, &ent->minor_hash);
10557 static errcode_t copy_dir_entries(ext2_filsys fs,
10558 struct fill_dir_struct *fd,
10559 struct out_dir *outdir)
10563 struct hash_entry *ent;
10564 struct ext2_dir_entry *dirent;
10565 int i, rec_len, left;
10566 ext2_dirhash_t prev_hash;
10570 retval = alloc_size_dir(fs, outdir,
10571 (fd->dir_size / fs->blocksize) + 2);
10574 outdir->num = fd->compress ? 0 : 1;
10576 outdir->hashes[0] = 0;
10578 if ((retval = get_next_block(fs, outdir, &block_start)))
10580 dirent = (struct ext2_dir_entry *) block_start;
10581 left = fs->blocksize;
10582 for (i=0; i < fd->num_array; i++) {
10583 ent = fd->harray + i;
10584 if (ent->dir->inode == 0)
10586 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10587 if (rec_len > left) {
10589 dirent->rec_len += left;
10590 if ((retval = get_next_block(fs, outdir,
10595 left = fs->blocksize - offset;
10596 dirent = (struct ext2_dir_entry *) (block_start + offset);
10598 if (ent->hash == prev_hash)
10599 outdir->hashes[outdir->num-1] = ent->hash | 1;
10601 outdir->hashes[outdir->num-1] = ent->hash;
10603 dirent->inode = ent->dir->inode;
10604 dirent->name_len = ent->dir->name_len;
10605 dirent->rec_len = rec_len;
10606 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10610 dirent->rec_len += left;
10614 prev_hash = ent->hash;
10617 dirent->rec_len += left;
10623 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10624 ext2_ino_t ino, ext2_ino_t parent)
10626 struct ext2_dir_entry *dir;
10627 struct ext2_dx_root_info *root;
10628 struct ext2_dx_countlimit *limits;
10631 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10632 filetype = EXT2_FT_DIR << 8;
10634 memset(buf, 0, fs->blocksize);
10635 dir = (struct ext2_dir_entry *) buf;
10637 dir->name[0] = '.';
10638 dir->name_len = 1 | filetype;
10640 dir = (struct ext2_dir_entry *) (buf + 12);
10641 dir->inode = parent;
10642 dir->name[0] = '.';
10643 dir->name[1] = '.';
10644 dir->name_len = 2 | filetype;
10645 dir->rec_len = fs->blocksize - 12;
10647 root = (struct ext2_dx_root_info *) (buf+24);
10648 root->reserved_zero = 0;
10649 root->hash_version = fs->super->s_def_hash_version;
10650 root->info_length = 8;
10651 root->indirect_levels = 0;
10652 root->unused_flags = 0;
10654 limits = (struct ext2_dx_countlimit *) (buf+32);
10655 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10662 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10664 struct ext2_dir_entry *dir;
10665 struct ext2_dx_countlimit *limits;
10667 memset(buf, 0, fs->blocksize);
10668 dir = (struct ext2_dir_entry *) buf;
10670 dir->rec_len = fs->blocksize;
10672 limits = (struct ext2_dx_countlimit *) (buf+8);
10673 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10676 return (struct ext2_dx_entry *) limits;
10680 * This function takes the leaf nodes which have been written in
10681 * outdir, and populates the root node and any necessary interior nodes.
10683 static errcode_t calculate_tree(ext2_filsys fs,
10684 struct out_dir *outdir,
10688 struct ext2_dx_root_info *root_info;
10689 struct ext2_dx_entry *root, *dx_ent = 0;
10690 struct ext2_dx_countlimit *root_limit, *limit;
10692 char * block_start;
10693 int i, c1, c2, nblks;
10694 int limit_offset, root_offset;
10696 root_info = set_root_node(fs, outdir->buf, ino, parent);
10697 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10698 root_info->info_length;
10699 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10700 c1 = root_limit->limit;
10701 nblks = outdir->num;
10703 /* Write out the pointer blocks */
10704 if (nblks-1 <= c1) {
10705 /* Just write out the root block, and we're done */
10706 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10707 for (i=1; i < nblks; i++) {
10708 root->block = ext2fs_cpu_to_le32(i);
10711 ext2fs_cpu_to_le32(outdir->hashes[i]);
10718 root_info->indirect_levels = 1;
10719 for (i=1; i < nblks; i++) {
10724 limit->limit = limit->count =
10725 ext2fs_cpu_to_le16(limit->limit);
10726 root = (struct ext2_dx_entry *)
10727 (outdir->buf + root_offset);
10728 root->block = ext2fs_cpu_to_le32(outdir->num);
10731 ext2fs_cpu_to_le32(outdir->hashes[i]);
10732 if ((retval = get_next_block(fs, outdir,
10735 dx_ent = set_int_node(fs, block_start);
10736 limit = (struct ext2_dx_countlimit *) dx_ent;
10738 root_offset += sizeof(struct ext2_dx_entry);
10741 dx_ent->block = ext2fs_cpu_to_le32(i);
10742 if (c2 != limit->limit)
10744 ext2fs_cpu_to_le32(outdir->hashes[i]);
10748 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10749 limit->limit = ext2fs_cpu_to_le16(limit->limit);
10751 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10752 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10753 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10758 struct write_dir_struct {
10759 struct out_dir *outdir;
10766 * Helper function which writes out a directory block.
10768 static int write_dir_block(ext2_filsys fs,
10770 e2_blkcnt_t blockcnt,
10771 blk_t ref_block FSCK_ATTR((unused)),
10772 int ref_offset FSCK_ATTR((unused)),
10775 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10779 if (*block_nr == 0)
10781 if (blockcnt >= wd->outdir->num) {
10782 e2fsck_read_bitmaps(wd->ctx);
10784 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10785 ext2fs_block_alloc_stats(fs, blk, -1);
10788 return BLOCK_CHANGED;
10793 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10794 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10796 return BLOCK_ABORT;
10800 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10801 struct out_dir *outdir,
10802 ext2_ino_t ino, int compress)
10804 struct write_dir_struct wd;
10806 struct ext2_inode inode;
10808 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10812 wd.outdir = outdir;
10817 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10818 write_dir_block, &wd);
10824 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10826 inode.i_flags &= ~EXT2_INDEX_FL;
10828 inode.i_flags |= EXT2_INDEX_FL;
10829 inode.i_size = outdir->num * fs->blocksize;
10830 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10831 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10836 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10838 ext2_filsys fs = ctx->fs;
10840 struct ext2_inode inode;
10842 struct fill_dir_struct fd;
10843 struct out_dir outdir;
10845 outdir.max = outdir.num = 0;
10848 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10852 dir_buf = malloc(inode.i_size);
10856 fd.max_array = inode.i_size / 32;
10858 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
10868 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10869 (inode.i_size / fs->blocksize) < 2)
10873 /* Read in the entire directory into memory */
10874 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10875 fill_dir_block, &fd);
10881 /* Sort the list */
10884 qsort(fd.harray+2, fd.num_array-2,
10885 sizeof(struct hash_entry), name_cmp);
10887 qsort(fd.harray, fd.num_array,
10888 sizeof(struct hash_entry), hash_cmp);
10891 * Look for duplicates
10893 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10896 if (ctx->options & E2F_OPT_NO) {
10902 * Copy the directory entries. In a htree directory these
10903 * will become the leaf nodes.
10905 retval = copy_dir_entries(fs, &fd, &outdir);
10909 free(dir_buf); dir_buf = 0;
10911 if (!fd.compress) {
10912 /* Calculate the interior nodes */
10913 retval = calculate_tree(fs, &outdir, ino, fd.parent);
10918 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10924 free_out_dir(&outdir);
10928 void e2fsck_rehash_directories(e2fsck_t ctx)
10930 struct problem_context pctx;
10931 struct dir_info *dir;
10932 ext2_u32_iterate iter;
10935 int i, cur, max, all_dirs, dir_index, first = 1;
10937 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10939 if (!ctx->dirs_to_hash && !all_dirs)
10942 e2fsck_get_lost_and_found(ctx, 0);
10944 clear_problem_context(&pctx);
10946 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10950 max = e2fsck_get_num_dirinfo(ctx);
10952 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10955 pctx.errcode = retval;
10956 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10959 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10963 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10967 if (!ext2fs_u32_list_iterate(iter, &ino))
10970 if (ino == ctx->lost_and_found)
10974 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
10977 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
10978 if (pctx.errcode) {
10979 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10980 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
10982 if (ctx->progress && !ctx->progress_fd)
10983 e2fsck_simple_progress(ctx, "Rebuilding directory",
10984 100.0 * (float) (++cur) / (float) max, ino);
10986 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10988 ext2fs_u32_list_iterate_end(iter);
10990 ext2fs_u32_list_free(ctx->dirs_to_hash);
10991 ctx->dirs_to_hash = 0;
10995 * linux/fs/revoke.c
10997 * Journal revoke routines for the generic filesystem journaling code;
10998 * part of the ext2fs journaling system.
11000 * Revoke is the mechanism used to prevent old log records for deleted
11001 * metadata from being replayed on top of newer data using the same
11002 * blocks. The revoke mechanism is used in two separate places:
11004 * + Commit: during commit we write the entire list of the current
11005 * transaction's revoked blocks to the journal
11007 * + Recovery: during recovery we record the transaction ID of all
11008 * revoked blocks. If there are multiple revoke records in the log
11009 * for a single block, only the last one counts, and if there is a log
11010 * entry for a block beyond the last revoke, then that log entry still
11013 * We can get interactions between revokes and new log data within a
11014 * single transaction:
11016 * Block is revoked and then journaled:
11017 * The desired end result is the journaling of the new block, so we
11018 * cancel the revoke before the transaction commits.
11020 * Block is journaled and then revoked:
11021 * The revoke must take precedence over the write of the block, so we
11022 * need either to cancel the journal entry or to write the revoke
11023 * later in the log than the log block. In this case, we choose the
11024 * latter: journaling a block cancels any revoke record for that block
11025 * in the current transaction, so any revoke for that block in the
11026 * transaction must have happened after the block was journaled and so
11027 * the revoke must take precedence.
11029 * Block is revoked and then written as data:
11030 * The data write is allowed to succeed, but the revoke is _not_
11031 * cancelled. We still need to prevent old log records from
11032 * overwriting the new data. We don't even need to clear the revoke
11035 * Revoke information on buffers is a tri-state value:
11037 * RevokeValid clear: no cached revoke status, need to look it up
11038 * RevokeValid set, Revoked clear:
11039 * buffer has not been revoked, and cancel_revoke
11041 * RevokeValid set, Revoked set:
11042 * buffer has been revoked.
11045 static kmem_cache_t *revoke_record_cache;
11046 static kmem_cache_t *revoke_table_cache;
11048 /* Each revoke record represents one single revoked block. During
11049 journal replay, this involves recording the transaction ID of the
11050 last transaction to revoke this block. */
11052 struct jbd_revoke_record_s
11054 struct list_head hash;
11055 tid_t sequence; /* Used for recovery only */
11056 unsigned long blocknr;
11060 /* The revoke table is just a simple hash table of revoke records. */
11061 struct jbd_revoke_table_s
11063 /* It is conceivable that we might want a larger hash table
11064 * for recovery. Must be a power of two. */
11067 struct list_head *hash_table;
11071 /* Utility functions to maintain the revoke table */
11073 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11074 static int hash(journal_t *journal, unsigned long block)
11076 struct jbd_revoke_table_s *table = journal->j_revoke;
11077 int hash_shift = table->hash_shift;
11079 return ((block << (hash_shift - 6)) ^
11081 (block << (hash_shift - 12))) & (table->hash_size - 1);
11084 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11087 struct list_head *hash_list;
11088 struct jbd_revoke_record_s *record;
11090 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11094 record->sequence = seq;
11095 record->blocknr = blocknr;
11096 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11097 list_add(&record->hash, hash_list);
11104 /* Find a revoke record in the journal's hash table. */
11106 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11107 unsigned long blocknr)
11109 struct list_head *hash_list;
11110 struct jbd_revoke_record_s *record;
11112 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11114 record = (struct jbd_revoke_record_s *) hash_list->next;
11115 while (&(record->hash) != hash_list) {
11116 if (record->blocknr == blocknr)
11118 record = (struct jbd_revoke_record_s *) record->hash.next;
11123 int journal_init_revoke_caches(void)
11125 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11126 if (revoke_record_cache == 0)
11129 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11130 if (revoke_table_cache == 0) {
11131 do_cache_destroy(revoke_record_cache);
11132 revoke_record_cache = NULL;
11138 void journal_destroy_revoke_caches(void)
11140 do_cache_destroy(revoke_record_cache);
11141 revoke_record_cache = 0;
11142 do_cache_destroy(revoke_table_cache);
11143 revoke_table_cache = 0;
11146 /* Initialise the revoke table for a given journal to a given size. */
11148 int journal_init_revoke(journal_t *journal, int hash_size)
11152 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11153 if (!journal->j_revoke)
11156 /* Check that the hash_size is a power of two */
11157 journal->j_revoke->hash_size = hash_size;
11161 while ((tmp >>= 1UL) != 0UL)
11163 journal->j_revoke->hash_shift = shift;
11165 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11166 if (!journal->j_revoke->hash_table) {
11167 free(journal->j_revoke);
11168 journal->j_revoke = NULL;
11172 for (tmp = 0; tmp < hash_size; tmp++)
11173 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11178 /* Destoy a journal's revoke table. The table must already be empty! */
11180 void journal_destroy_revoke(journal_t *journal)
11182 struct jbd_revoke_table_s *table;
11183 struct list_head *hash_list;
11186 table = journal->j_revoke;
11190 for (i=0; i<table->hash_size; i++) {
11191 hash_list = &table->hash_table[i];
11194 free(table->hash_table);
11196 journal->j_revoke = NULL;
11200 * Revoke support for recovery.
11202 * Recovery needs to be able to:
11204 * record all revoke records, including the tid of the latest instance
11205 * of each revoke in the journal
11207 * check whether a given block in a given transaction should be replayed
11208 * (ie. has not been revoked by a revoke record in that or a subsequent
11211 * empty the revoke table after recovery.
11215 * First, setting revoke records. We create a new revoke record for
11216 * every block ever revoked in the log as we scan it for recovery, and
11217 * we update the existing records if we find multiple revokes for a
11221 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11224 struct jbd_revoke_record_s *record;
11226 record = find_revoke_record(journal, blocknr);
11228 /* If we have multiple occurences, only record the
11229 * latest sequence number in the hashed record */
11230 if (tid_gt(sequence, record->sequence))
11231 record->sequence = sequence;
11234 return insert_revoke_hash(journal, blocknr, sequence);
11238 * Test revoke records. For a given block referenced in the log, has
11239 * that block been revoked? A revoke record with a given transaction
11240 * sequence number revokes all blocks in that transaction and earlier
11241 * ones, but later transactions still need replayed.
11244 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11247 struct jbd_revoke_record_s *record;
11249 record = find_revoke_record(journal, blocknr);
11252 if (tid_gt(sequence, record->sequence))
11258 * Finally, once recovery is over, we need to clear the revoke table so
11259 * that it can be reused by the running filesystem.
11262 void journal_clear_revoke(journal_t *journal)
11265 struct list_head *hash_list;
11266 struct jbd_revoke_record_s *record;
11267 struct jbd_revoke_table_s *revoke_var;
11269 revoke_var = journal->j_revoke;
11271 for (i = 0; i < revoke_var->hash_size; i++) {
11272 hash_list = &revoke_var->hash_table[i];
11273 while (!list_empty(hash_list)) {
11274 record = (struct jbd_revoke_record_s*) hash_list->next;
11275 list_del(&record->hash);
11282 * e2fsck.c - superblock checks
11285 #define MIN_CHECK 1
11286 #define MAX_CHECK 2
11288 static void check_super_value(e2fsck_t ctx, const char *descr,
11289 unsigned long value, int flags,
11290 unsigned long min_val, unsigned long max_val)
11292 struct problem_context pctx;
11294 if (((flags & MIN_CHECK) && (value < min_val)) ||
11295 ((flags & MAX_CHECK) && (value > max_val))) {
11296 clear_problem_context(&pctx);
11299 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11300 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11305 * This routine may get stubbed out in special compilations of the
11308 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11309 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11311 return (ext2fs_get_device_size(ctx->filesystem_name,
11312 EXT2_BLOCK_SIZE(ctx->fs->super),
11313 &ctx->num_blocks));
11318 * helper function to release an inode
11320 struct process_block_struct {
11323 struct problem_context *pctx;
11325 int truncate_offset;
11326 e2_blkcnt_t truncate_block;
11327 int truncated_blocks;
11332 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11333 e2_blkcnt_t blockcnt,
11334 blk_t ref_blk FSCK_ATTR((unused)),
11335 int ref_offset FSCK_ATTR((unused)),
11338 struct process_block_struct *pb;
11340 struct problem_context *pctx;
11341 blk_t blk = *block_nr;
11344 pb = (struct process_block_struct *) priv_data;
11349 pctx->blkcount = blockcnt;
11351 if (HOLE_BLKADDR(blk))
11354 if ((blk < fs->super->s_first_data_block) ||
11355 (blk >= fs->super->s_blocks_count)) {
11356 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11359 return BLOCK_ABORT;
11362 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11363 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11368 * If we are deleting an orphan, then we leave the fields alone.
11369 * If we are truncating an orphan, then update the inode fields
11370 * and clean up any partial block data.
11372 if (pb->truncating) {
11374 * We only remove indirect blocks if they are
11375 * completely empty.
11377 if (blockcnt < 0) {
11381 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11386 limit = fs->blocksize >> 2;
11387 for (i = 0, bp = (blk_t *) pb->buf;
11388 i < limit; i++, bp++)
11393 * We don't remove direct blocks until we've reached
11394 * the truncation block.
11396 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11399 * If part of the last block needs truncating, we do
11402 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11403 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11407 memset(pb->buf + pb->truncate_offset, 0,
11408 fs->blocksize - pb->truncate_offset);
11409 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11414 pb->truncated_blocks++;
11416 retval |= BLOCK_CHANGED;
11419 ext2fs_block_alloc_stats(fs, blk, -1);
11424 * This function releases an inode. Returns 1 if an inconsistency was
11425 * found. If the inode has a link count, then it is being truncated and
11428 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11429 struct ext2_inode *inode, char *block_buf,
11430 struct problem_context *pctx)
11432 struct process_block_struct pb;
11433 ext2_filsys fs = ctx->fs;
11437 if (!ext2fs_inode_has_valid_blocks(inode))
11440 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11445 if (inode->i_links_count) {
11447 pb.truncate_block = (e2_blkcnt_t)
11448 ((((long long)inode->i_size_high << 32) +
11449 inode->i_size + fs->blocksize - 1) /
11451 pb.truncate_offset = inode->i_size % fs->blocksize;
11454 pb.truncate_block = 0;
11455 pb.truncate_offset = 0;
11457 pb.truncated_blocks = 0;
11458 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11459 block_buf, release_inode_block, &pb);
11461 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11468 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11469 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11471 if (pb.truncated_blocks)
11472 inode->i_blocks -= pb.truncated_blocks *
11473 (fs->blocksize / 512);
11475 if (inode->i_file_acl) {
11476 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11477 block_buf, -1, &count);
11478 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11483 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11488 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11489 inode->i_file_acl = 0;
11495 * This function releases all of the orphan inodes. It returns 1 if
11496 * it hit some error, and 0 on success.
11498 static int release_orphan_inodes(e2fsck_t ctx)
11500 ext2_filsys fs = ctx->fs;
11501 ext2_ino_t ino, next_ino;
11502 struct ext2_inode inode;
11503 struct problem_context pctx;
11506 if ((ino = fs->super->s_last_orphan) == 0)
11510 * Win or lose, we won't be using the head of the orphan inode
11513 fs->super->s_last_orphan = 0;
11514 ext2fs_mark_super_dirty(fs);
11517 * If the filesystem contains errors, don't run the orphan
11518 * list, since the orphan list can't be trusted; and we're
11519 * going to be running a full e2fsck run anyway...
11521 if (fs->super->s_state & EXT2_ERROR_FS)
11524 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11525 (ino > fs->super->s_inodes_count)) {
11526 clear_problem_context(&pctx);
11528 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11532 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11533 "block iterate buffer");
11534 e2fsck_read_bitmaps(ctx);
11537 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11538 clear_problem_context(&pctx);
11540 pctx.inode = &inode;
11541 pctx.str = inode.i_links_count ? _("Truncating") :
11544 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11546 next_ino = inode.i_dtime;
11548 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11549 (next_ino > fs->super->s_inodes_count))) {
11550 pctx.ino = next_ino;
11551 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11555 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11558 if (!inode.i_links_count) {
11559 ext2fs_inode_alloc_stats2(fs, ino, -1,
11560 LINUX_S_ISDIR(inode.i_mode));
11561 inode.i_dtime = time(NULL);
11565 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11568 ext2fs_free_mem(&block_buf);
11571 ext2fs_free_mem(&block_buf);
11576 * Check the resize inode to make sure it is sane. We check both for
11577 * the case where on-line resizing is not enabled (in which case the
11578 * resize inode should be cleared) as well as the case where on-line
11579 * resizing is enabled.
11581 static void check_resize_inode(e2fsck_t ctx)
11583 ext2_filsys fs = ctx->fs;
11584 struct ext2_inode inode;
11585 struct problem_context pctx;
11586 int i, j, gdt_off, ind_off;
11587 blk_t blk, pblk, expect;
11588 __u32 *dind_buf = 0, *ind_buf;
11591 clear_problem_context(&pctx);
11594 * If the resize inode feature isn't set, then
11595 * s_reserved_gdt_blocks must be zero.
11597 if (!(fs->super->s_feature_compat &
11598 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11599 if (fs->super->s_reserved_gdt_blocks) {
11600 pctx.num = fs->super->s_reserved_gdt_blocks;
11601 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11603 fs->super->s_reserved_gdt_blocks = 0;
11604 ext2fs_mark_super_dirty(fs);
11609 /* Read the resize inode */
11610 pctx.ino = EXT2_RESIZE_INO;
11611 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11613 if (fs->super->s_feature_compat &
11614 EXT2_FEATURE_COMPAT_RESIZE_INODE)
11615 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11620 * If the resize inode feature isn't set, check to make sure
11621 * the resize inode is cleared; then we're done.
11623 if (!(fs->super->s_feature_compat &
11624 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11625 for (i=0; i < EXT2_N_BLOCKS; i++) {
11626 if (inode.i_block[i])
11629 if ((i < EXT2_N_BLOCKS) &&
11630 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11631 memset(&inode, 0, sizeof(inode));
11632 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11639 * The resize inode feature is enabled; check to make sure the
11640 * only block in use is the double indirect block
11642 blk = inode.i_block[EXT2_DIND_BLOCK];
11643 for (i=0; i < EXT2_N_BLOCKS; i++) {
11644 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11647 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11648 !(inode.i_mode & LINUX_S_IFREG) ||
11649 (blk < fs->super->s_first_data_block ||
11650 blk >= fs->super->s_blocks_count)) {
11651 resize_inode_invalid:
11652 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11653 memset(&inode, 0, sizeof(inode));
11654 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11656 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11658 if (!(ctx->options & E2F_OPT_READONLY)) {
11659 fs->super->s_state &= ~EXT2_VALID_FS;
11660 ext2fs_mark_super_dirty(fs);
11664 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11665 "resize dind buffer");
11666 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11668 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11670 goto resize_inode_invalid;
11672 gdt_off = fs->desc_blocks;
11673 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11674 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11675 i++, gdt_off++, pblk++) {
11676 gdt_off %= fs->blocksize/4;
11677 if (dind_buf[gdt_off] != pblk)
11678 goto resize_inode_invalid;
11679 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11681 goto resize_inode_invalid;
11683 for (j = 1; j < fs->group_desc_count; j++) {
11684 if (!ext2fs_bg_has_super(fs, j))
11686 expect = pblk + (j * fs->super->s_blocks_per_group);
11687 if (ind_buf[ind_off] != expect)
11688 goto resize_inode_invalid;
11694 ext2fs_free_mem(&dind_buf);
11698 static void check_super_block(e2fsck_t ctx)
11700 ext2_filsys fs = ctx->fs;
11701 blk_t first_block, last_block;
11702 struct ext2_super_block *sb = fs->super;
11703 struct ext2_group_desc *gd;
11704 blk_t blocks_per_group = fs->super->s_blocks_per_group;
11706 int inodes_per_block;
11711 struct problem_context pctx;
11712 __u32 free_blocks = 0, free_inodes = 0;
11714 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11715 ipg_max = inodes_per_block * (blocks_per_group - 4);
11716 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11717 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11718 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11719 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11720 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11722 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11723 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11724 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11725 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11726 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11727 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11729 clear_problem_context(&pctx);
11732 * Verify the super block constants...
11734 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11736 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11738 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11739 MAX_CHECK, 0, sb->s_blocks_count);
11740 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11741 MIN_CHECK | MAX_CHECK, 0,
11742 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11743 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11744 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11745 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11746 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11748 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11749 MIN_CHECK | MAX_CHECK, 8, bpg_max);
11750 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11751 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11752 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11753 MAX_CHECK, 0, sb->s_blocks_count / 2);
11754 check_super_value(ctx, "reserved_gdt_blocks",
11755 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11757 inode_size = EXT2_INODE_SIZE(sb);
11758 check_super_value(ctx, "inode_size",
11759 inode_size, MIN_CHECK | MAX_CHECK,
11760 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11761 if (inode_size & (inode_size - 1)) {
11762 pctx.num = inode_size;
11763 pctx.str = "inode_size";
11764 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11765 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11769 if (!ctx->num_blocks) {
11770 pctx.errcode = e2fsck_get_device_size(ctx);
11771 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11772 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11773 ctx->flags |= E2F_FLAG_ABORT;
11776 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11777 (ctx->num_blocks < sb->s_blocks_count)) {
11778 pctx.blk = sb->s_blocks_count;
11779 pctx.blk2 = ctx->num_blocks;
11780 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11781 ctx->flags |= E2F_FLAG_ABORT;
11787 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11788 pctx.blk = EXT2_BLOCK_SIZE(sb);
11789 pctx.blk2 = EXT2_FRAG_SIZE(sb);
11790 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11791 ctx->flags |= E2F_FLAG_ABORT;
11795 should_be = sb->s_frags_per_group >>
11796 (sb->s_log_block_size - sb->s_log_frag_size);
11797 if (sb->s_blocks_per_group != should_be) {
11798 pctx.blk = sb->s_blocks_per_group;
11799 pctx.blk2 = should_be;
11800 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11801 ctx->flags |= E2F_FLAG_ABORT;
11805 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11806 if (sb->s_first_data_block != should_be) {
11807 pctx.blk = sb->s_first_data_block;
11808 pctx.blk2 = should_be;
11809 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11810 ctx->flags |= E2F_FLAG_ABORT;
11814 should_be = sb->s_inodes_per_group * fs->group_desc_count;
11815 if (sb->s_inodes_count != should_be) {
11816 pctx.ino = sb->s_inodes_count;
11817 pctx.ino2 = should_be;
11818 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11819 sb->s_inodes_count = should_be;
11820 ext2fs_mark_super_dirty(fs);
11825 * Verify the group descriptors....
11827 first_block = sb->s_first_data_block;
11828 last_block = first_block + blocks_per_group;
11830 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11833 if (i == fs->group_desc_count - 1)
11834 last_block = sb->s_blocks_count;
11835 if ((gd->bg_block_bitmap < first_block) ||
11836 (gd->bg_block_bitmap >= last_block)) {
11837 pctx.blk = gd->bg_block_bitmap;
11838 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11839 gd->bg_block_bitmap = 0;
11841 if (gd->bg_block_bitmap == 0) {
11842 ctx->invalid_block_bitmap_flag[i]++;
11843 ctx->invalid_bitmaps++;
11845 if ((gd->bg_inode_bitmap < first_block) ||
11846 (gd->bg_inode_bitmap >= last_block)) {
11847 pctx.blk = gd->bg_inode_bitmap;
11848 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11849 gd->bg_inode_bitmap = 0;
11851 if (gd->bg_inode_bitmap == 0) {
11852 ctx->invalid_inode_bitmap_flag[i]++;
11853 ctx->invalid_bitmaps++;
11855 if ((gd->bg_inode_table < first_block) ||
11856 ((gd->bg_inode_table +
11857 fs->inode_blocks_per_group - 1) >= last_block)) {
11858 pctx.blk = gd->bg_inode_table;
11859 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11860 gd->bg_inode_table = 0;
11862 if (gd->bg_inode_table == 0) {
11863 ctx->invalid_inode_table_flag[i]++;
11864 ctx->invalid_bitmaps++;
11866 free_blocks += gd->bg_free_blocks_count;
11867 free_inodes += gd->bg_free_inodes_count;
11868 first_block += sb->s_blocks_per_group;
11869 last_block += sb->s_blocks_per_group;
11871 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11872 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11873 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11874 ext2fs_unmark_valid(fs);
11879 * Update the global counts from the block group counts. This
11880 * is needed for an experimental patch which eliminates
11881 * locking the entire filesystem when allocating blocks or
11882 * inodes; if the filesystem is not unmounted cleanly, the
11883 * global counts may not be accurate.
11885 if ((free_blocks != sb->s_free_blocks_count) ||
11886 (free_inodes != sb->s_free_inodes_count)) {
11887 if (ctx->options & E2F_OPT_READONLY)
11888 ext2fs_unmark_valid(fs);
11890 sb->s_free_blocks_count = free_blocks;
11891 sb->s_free_inodes_count = free_inodes;
11892 ext2fs_mark_super_dirty(fs);
11896 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11897 (sb->s_free_inodes_count > sb->s_inodes_count))
11898 ext2fs_unmark_valid(fs);
11902 * If we have invalid bitmaps, set the error state of the
11905 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11906 sb->s_state &= ~EXT2_VALID_FS;
11907 ext2fs_mark_super_dirty(fs);
11910 clear_problem_context(&pctx);
11913 * If the UUID field isn't assigned, assign it.
11915 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11916 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11917 uuid_generate(sb->s_uuid);
11918 ext2fs_mark_super_dirty(fs);
11919 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11923 /* FIXME - HURD support?
11924 * For the Hurd, check to see if the filetype option is set,
11925 * since it doesn't support it.
11927 if (!(ctx->options & E2F_OPT_READONLY) &&
11928 fs->super->s_creator_os == EXT2_OS_HURD &&
11929 (fs->super->s_feature_incompat &
11930 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11931 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11932 fs->super->s_feature_incompat &=
11933 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11934 ext2fs_mark_super_dirty(fs);
11940 * If we have any of the compatibility flags set, we need to have a
11941 * revision 1 filesystem. Most kernels will not check the flags on
11942 * a rev 0 filesystem and we may have corruption issues because of
11943 * the incompatible changes to the filesystem.
11945 if (!(ctx->options & E2F_OPT_READONLY) &&
11946 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11947 (fs->super->s_feature_compat ||
11948 fs->super->s_feature_ro_compat ||
11949 fs->super->s_feature_incompat) &&
11950 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11951 ext2fs_update_dynamic_rev(fs);
11952 ext2fs_mark_super_dirty(fs);
11955 check_resize_inode(ctx);
11958 * Clean up any orphan inodes, if present.
11960 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11961 fs->super->s_state &= ~EXT2_VALID_FS;
11962 ext2fs_mark_super_dirty(fs);
11966 * Move the ext3 journal file, if necessary.
11968 e2fsck_move_ext3_journal(ctx);
11972 * swapfs.c --- byte-swap an ext2 filesystem
11975 #ifdef ENABLE_SWAPFS
11977 struct swap_block_struct {
11982 struct ext2_inode *inode;
11986 * This is a helper function for block_iterate. We mark all of the
11987 * indirect and direct blocks as changed, so that block_iterate will
11990 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
11995 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
11997 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
11998 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
12000 sb->errcode = retval;
12001 return BLOCK_ABORT;
12003 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
12005 sb->errcode = retval;
12006 return BLOCK_ABORT;
12009 if (blockcnt >= 0) {
12010 if (blockcnt < EXT2_NDIR_BLOCKS)
12012 return BLOCK_CHANGED;
12014 if (blockcnt == BLOCK_COUNT_IND) {
12015 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
12017 return BLOCK_CHANGED;
12019 if (blockcnt == BLOCK_COUNT_DIND) {
12020 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12022 return BLOCK_CHANGED;
12024 if (blockcnt == BLOCK_COUNT_TIND) {
12025 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12027 return BLOCK_CHANGED;
12029 return BLOCK_CHANGED;
12033 * This function is responsible for byte-swapping all of the indirect,
12034 * block pointers. It is also responsible for byte-swapping directories.
12036 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12037 struct ext2_inode *inode)
12040 struct swap_block_struct sb;
12044 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12047 if (LINUX_S_ISDIR(inode->i_mode))
12050 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12053 bb_error_msg(_("while calling ext2fs_block_iterate"));
12054 ctx->flags |= E2F_FLAG_ABORT;
12058 bb_error_msg(_("while calling iterator function"));
12059 ctx->flags |= E2F_FLAG_ABORT;
12064 static void swap_inodes(e2fsck_t ctx)
12066 ext2_filsys fs = ctx->fs;
12069 ext2_ino_t ino = 1;
12070 char *buf, *block_buf;
12072 struct ext2_inode * inode;
12074 e2fsck_use_inode_shortcuts(ctx, 1);
12076 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12079 bb_error_msg(_("while allocating inode buffer"));
12080 ctx->flags |= E2F_FLAG_ABORT;
12083 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12084 "block interate buffer");
12085 for (group = 0; group < fs->group_desc_count; group++) {
12086 retval = io_channel_read_blk(fs->io,
12087 fs->group_desc[group].bg_inode_table,
12088 fs->inode_blocks_per_group, buf);
12090 bb_error_msg(_("while reading inode table (group %d)"),
12092 ctx->flags |= E2F_FLAG_ABORT;
12095 inode = (struct ext2_inode *) buf;
12096 for (i=0; i < fs->super->s_inodes_per_group;
12097 i++, ino++, inode++) {
12098 ctx->stashed_ino = ino;
12099 ctx->stashed_inode = inode;
12101 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12102 ext2fs_swap_inode(fs, inode, inode, 0);
12105 * Skip deleted files.
12107 if (inode->i_links_count == 0)
12110 if (LINUX_S_ISDIR(inode->i_mode) ||
12111 ((inode->i_block[EXT2_IND_BLOCK] ||
12112 inode->i_block[EXT2_DIND_BLOCK] ||
12113 inode->i_block[EXT2_TIND_BLOCK]) &&
12114 ext2fs_inode_has_valid_blocks(inode)))
12115 swap_inode_blocks(ctx, ino, block_buf, inode);
12117 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12120 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12121 ext2fs_swap_inode(fs, inode, inode, 1);
12123 retval = io_channel_write_blk(fs->io,
12124 fs->group_desc[group].bg_inode_table,
12125 fs->inode_blocks_per_group, buf);
12127 bb_error_msg(_("while writing inode table (group %d)"),
12129 ctx->flags |= E2F_FLAG_ABORT;
12133 ext2fs_free_mem(&buf);
12134 ext2fs_free_mem(&block_buf);
12135 e2fsck_use_inode_shortcuts(ctx, 0);
12136 ext2fs_flush_icache(fs);
12139 #if defined(__powerpc__) && BB_BIG_ENDIAN
12141 * On the PowerPC, the big-endian variant of the ext2 filesystem
12142 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12143 * of each word. Thus a bitmap with only bit 0 set would be, as
12144 * a string of bytes, 00 00 00 01 00 ...
12145 * To cope with this, we byte-reverse each word of a bitmap if
12146 * we have a big-endian filesystem, that is, if we are *not*
12147 * byte-swapping other word-sized numbers.
12149 #define EXT2_BIG_ENDIAN_BITMAPS
12152 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12153 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12155 __u32 *p = (__u32 *) bmap->bitmap;
12156 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12158 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12159 *p = ext2fs_swab32(*p);
12164 #ifdef ENABLE_SWAPFS
12165 static void swap_filesys(e2fsck_t ctx)
12167 ext2_filsys fs = ctx->fs;
12168 if (!(ctx->options & E2F_OPT_PREEN))
12169 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12173 if (fs->super->s_mnt_count) {
12174 fprintf(stderr, _("%s: the filesystem must be freshly "
12175 "checked using fsck\n"
12176 "and not mounted before trying to "
12177 "byte-swap it.\n"), ctx->device_name);
12178 ctx->flags |= E2F_FLAG_ABORT;
12181 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12182 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12183 EXT2_FLAG_SWAP_BYTES_WRITE);
12184 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12186 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12187 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12190 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12192 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12193 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12194 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12195 EXT2_FLAG_SWAP_BYTES_WRITE);
12197 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12198 e2fsck_read_bitmaps(ctx);
12199 ext2fs_swap_bitmap(fs->inode_map);
12200 ext2fs_swap_bitmap(fs->block_map);
12201 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12203 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12205 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12207 #endif /* ENABLE_SWAPFS */
12212 * util.c --- miscellaneous utilities
12216 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12217 const char *description)
12222 ret = malloc(size);
12224 sprintf(buf, "Can't allocate %s\n", description);
12225 bb_error_msg_and_die(buf);
12227 memset(ret, 0, size);
12231 static char *string_copy(const char *str, int len)
12239 ret = malloc(len+1);
12241 strncpy(ret, str, len);
12247 #ifndef HAVE_CONIO_H
12248 static int read_a_char(void)
12255 if (e2fsck_global_ctx &&
12256 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12259 r = read(0, &c, 1);
12269 static int ask_yn(const char * string, int def)
12272 const char *defstr;
12273 static const char short_yes[] = "yY";
12274 static const char short_no[] = "nN";
12276 #ifdef HAVE_TERMIOS_H
12277 struct termios termios, tmp;
12279 tcgetattr (0, &termios);
12281 tmp.c_lflag &= ~(ICANON | ECHO);
12282 tmp.c_cc[VMIN] = 1;
12283 tmp.c_cc[VTIME] = 0;
12284 tcsetattr_stdin_TCSANOW(&tmp);
12293 printf("%s%s? ", string, defstr);
12296 if ((c = read_a_char()) == EOF)
12299 #ifdef HAVE_TERMIOS_H
12300 tcsetattr_stdin_TCSANOW(&termios);
12302 if (e2fsck_global_ctx &&
12303 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12305 longjmp(e2fsck_global_ctx->abort_loc, 1);
12307 puts(_("cancelled!\n"));
12310 if (strchr(short_yes, (char) c)) {
12314 else if (strchr(short_no, (char) c)) {
12318 else if ((c == ' ' || c == '\n') && (def != -1))
12325 #ifdef HAVE_TERMIOS_H
12326 tcsetattr_stdin_TCSANOW(&termios);
12331 int ask (e2fsck_t ctx, const char * string, int def)
12333 if (ctx->options & E2F_OPT_NO) {
12334 printf(_("%s? no\n\n"), string);
12337 if (ctx->options & E2F_OPT_YES) {
12338 printf(_("%s? yes\n\n"), string);
12341 if (ctx->options & E2F_OPT_PREEN) {
12342 printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
12345 return ask_yn(string, def);
12348 void e2fsck_read_bitmaps(e2fsck_t ctx)
12350 ext2_filsys fs = ctx->fs;
12353 if (ctx->invalid_bitmaps) {
12354 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12356 bb_error_msg_and_die(0);
12359 ehandler_operation(_("reading inode and block bitmaps"));
12360 retval = ext2fs_read_bitmaps(fs);
12361 ehandler_operation(0);
12363 bb_error_msg(_("while retrying to read bitmaps for %s"),
12365 bb_error_msg_and_die(0);
12369 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12371 ext2_filsys fs = ctx->fs;
12374 if (ext2fs_test_bb_dirty(fs)) {
12375 ehandler_operation(_("writing block bitmaps"));
12376 retval = ext2fs_write_block_bitmap(fs);
12377 ehandler_operation(0);
12379 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12381 bb_error_msg_and_die(0);
12385 if (ext2fs_test_ib_dirty(fs)) {
12386 ehandler_operation(_("writing inode bitmaps"));
12387 retval = ext2fs_write_inode_bitmap(fs);
12388 ehandler_operation(0);
12390 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12392 bb_error_msg_and_die(0);
12397 void preenhalt(e2fsck_t ctx)
12399 ext2_filsys fs = ctx->fs;
12401 if (!(ctx->options & E2F_OPT_PREEN))
12403 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12404 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12407 fs->super->s_state |= EXT2_ERROR_FS;
12408 ext2fs_mark_super_dirty(fs);
12411 exit(EXIT_UNCORRECTED);
12414 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12415 struct ext2_inode * inode, const char *proc)
12419 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12421 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12422 bb_error_msg_and_die(0);
12426 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12427 struct ext2_inode * inode, int bufsize,
12432 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12434 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12435 bb_error_msg_and_die(0);
12439 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12440 struct ext2_inode * inode, const char *proc)
12444 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12446 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12447 bb_error_msg_and_die(0);
12451 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12452 io_manager manager)
12454 struct ext2_super_block *sb;
12455 io_channel io = NULL;
12458 blk_t superblock, ret_sb = 8193;
12460 if (fs && fs->super) {
12461 ret_sb = (fs->super->s_blocks_per_group +
12462 fs->super->s_first_data_block);
12464 ctx->superblock = ret_sb;
12465 ctx->blocksize = fs->blocksize;
12471 if (ctx->blocksize) {
12472 ret_sb = ctx->blocksize * 8;
12473 if (ctx->blocksize == 1024)
12475 ctx->superblock = ret_sb;
12478 ctx->superblock = ret_sb;
12479 ctx->blocksize = 1024;
12482 if (!name || !manager)
12485 if (manager->open(name, 0, &io) != 0)
12488 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12490 sb = (struct ext2_super_block *) buf;
12492 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12493 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
12494 superblock = blocksize*8;
12495 if (blocksize == 1024)
12497 io_channel_set_blksize(io, blocksize);
12498 if (io_channel_read_blk(io, superblock,
12499 -SUPERBLOCK_SIZE, buf))
12502 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12503 ext2fs_swap_super(sb);
12505 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12506 ret_sb = superblock;
12508 ctx->superblock = superblock;
12509 ctx->blocksize = blocksize;
12517 io_channel_close(io);
12518 ext2fs_free_mem(&buf);
12524 * This function runs through the e2fsck passes and calls them all,
12525 * returning restart, abort, or cancel as necessary...
12527 typedef void (*pass_t)(e2fsck_t ctx);
12529 static const pass_t e2fsck_passes[] = {
12530 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12533 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12535 static int e2fsck_run(e2fsck_t ctx)
12538 pass_t e2fsck_pass;
12540 if (setjmp(ctx->abort_loc)) {
12541 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12542 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12544 ctx->flags |= E2F_FLAG_SETJMP_OK;
12546 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12547 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12551 (void) (ctx->progress)(ctx, 0, 0, 0);
12553 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12555 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12556 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12562 * unix.c - The unix-specific code for e2fsck
12566 /* Command line options */
12568 #ifdef ENABLE_SWAPFS
12569 static int normalize_swapfs;
12571 static int cflag; /* check disk */
12572 static int show_version_only;
12573 static int verbose;
12575 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12577 static void show_stats(e2fsck_t ctx)
12579 ext2_filsys fs = ctx->fs;
12580 int inodes, inodes_used, blocks, blocks_used;
12582 int num_files, num_links;
12585 dir_links = 2 * ctx->fs_directory_count - 1;
12586 num_files = ctx->fs_total_count - dir_links;
12587 num_links = ctx->fs_links_count - dir_links;
12588 inodes = fs->super->s_inodes_count;
12589 inodes_used = (fs->super->s_inodes_count -
12590 fs->super->s_free_inodes_count);
12591 blocks = fs->super->s_blocks_count;
12592 blocks_used = (fs->super->s_blocks_count -
12593 fs->super->s_free_blocks_count);
12595 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12596 frag_percent = (frag_percent + 5) / 10;
12599 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12600 ctx->device_name, inodes_used, inodes,
12601 frag_percent / 10, frag_percent % 10,
12602 blocks_used, blocks);
12605 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12606 100 * inodes_used / inodes);
12607 printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12608 P_E2("", "s", ctx->fs_fragmented),
12609 frag_percent / 10, frag_percent % 10);
12610 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12611 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12612 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12613 (int) ((long long) 100 * blocks_used / blocks));
12614 printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12615 printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12616 printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12617 printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12618 printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12619 printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12620 printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12621 printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12622 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12623 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12624 printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12627 static void check_mount(e2fsck_t ctx)
12632 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12633 &ctx->mount_flags);
12635 bb_error_msg(_("while determining whether %s is mounted"),
12636 ctx->filesystem_name);
12641 * If the filesystem isn't mounted, or it's the root filesystem
12642 * and it's mounted read-only, then everything's fine.
12644 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12645 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12646 (ctx->mount_flags & EXT2_MF_READONLY)))
12649 if (ctx->options & E2F_OPT_READONLY) {
12650 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
12654 printf(_("%s is mounted. "), ctx->filesystem_name);
12655 if (!ctx->interactive)
12656 bb_error_msg_and_die(_("cannot continue, aborting"));
12657 printf(_("\n\n\007\007\007\007WARNING!!! "
12658 "Running e2fsck on a mounted filesystem may cause\n"
12659 "SEVERE filesystem damage.\007\007\007\n\n"));
12660 cont = ask_yn(_("Do you really want to continue"), -1);
12662 printf(_("check aborted.\n"));
12667 static int is_on_batt(void)
12671 char tmp[80], tmp2[80], fname[80];
12672 unsigned int acflag;
12675 f = fopen_for_read("/proc/apm");
12677 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12680 return (acflag != 1);
12682 d = opendir("/proc/acpi/ac_adapter");
12684 while ((de=readdir(d)) != NULL) {
12685 if (!strncmp(".", de->d_name, 1))
12687 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12689 f = fopen_for_read(fname);
12692 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12695 if (strncmp(tmp, "off-line", 8) == 0) {
12706 * This routine checks to see if a filesystem can be skipped; if so,
12707 * it will exit with EXIT_OK. Under some conditions it will print a
12708 * message explaining why a check is being forced.
12710 static void check_if_skip(e2fsck_t ctx)
12712 ext2_filsys fs = ctx->fs;
12713 const char *reason = NULL;
12714 unsigned int reason_arg = 0;
12716 int batt = is_on_batt();
12717 time_t now = time(NULL);
12719 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12722 if ((fs->super->s_state & EXT2_ERROR_FS) ||
12723 !ext2fs_test_valid(fs))
12724 reason = _(" contains a file system with errors");
12725 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12726 reason = _(" was not cleanly unmounted");
12727 else if ((fs->super->s_max_mnt_count > 0) &&
12728 (fs->super->s_mnt_count >=
12729 (unsigned) fs->super->s_max_mnt_count)) {
12730 reason = _(" has been mounted %u times without being checked");
12731 reason_arg = fs->super->s_mnt_count;
12732 if (batt && (fs->super->s_mnt_count <
12733 (unsigned) fs->super->s_max_mnt_count*2))
12735 } else if (fs->super->s_checkinterval &&
12736 ((now - fs->super->s_lastcheck) >=
12737 fs->super->s_checkinterval)) {
12738 reason = _(" has gone %u days without being checked");
12739 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12740 if (batt && ((now - fs->super->s_lastcheck) <
12741 fs->super->s_checkinterval*2))
12745 fputs(ctx->device_name, stdout);
12746 printf(reason, reason_arg);
12747 fputs(_(", check forced.\n"), stdout);
12750 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12751 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12752 fs->super->s_inodes_count,
12753 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12754 fs->super->s_blocks_count);
12755 next_check = 100000;
12756 if (fs->super->s_max_mnt_count > 0) {
12757 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12758 if (next_check <= 0)
12761 if (fs->super->s_checkinterval &&
12762 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12764 if (next_check <= 5) {
12765 if (next_check == 1)
12766 fputs(_(" (check after next mount)"), stdout);
12768 printf(_(" (check in %ld mounts)"), next_check);
12773 e2fsck_free_context(ctx);
12778 * For completion notice
12780 struct percent_tbl {
12784 static const struct percent_tbl e2fsck_tbl = {
12785 5, { 0, 70, 90, 92, 95, 100 }
12788 static char bar[128], spaces[128];
12790 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12797 if (pass > tbl->max_pass || max == 0)
12799 percent = ((float) curr) / ((float) max);
12800 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12801 + tbl->table[pass-1]);
12804 void e2fsck_clear_progbar(e2fsck_t ctx)
12806 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12809 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12812 ctx->flags &= ~E2F_FLAG_PROG_BAR;
12815 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12816 unsigned int dpynum)
12818 static const char spinner[] = "\\|/-";
12825 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12829 * Calculate the new progress position. If the
12830 * percentage hasn't changed, then we skip out right
12833 fixed_percent = (int) ((10 * percent) + 0.5);
12834 if (ctx->progress_last_percent == fixed_percent)
12836 ctx->progress_last_percent = fixed_percent;
12839 * If we've already updated the spinner once within
12840 * the last 1/8th of a second, no point doing it
12843 gettimeofday(&tv, NULL);
12844 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12845 if ((tick == ctx->progress_last_time) &&
12846 (fixed_percent != 0) && (fixed_percent != 1000))
12848 ctx->progress_last_time = tick;
12851 * Advance the spinner, and note that the progress bar
12852 * will be on the screen
12854 ctx->progress_pos = (ctx->progress_pos+1) & 3;
12855 ctx->flags |= E2F_FLAG_PROG_BAR;
12857 dpywidth = 66 - strlen(label);
12858 dpywidth = 8 * (dpywidth / 8);
12862 i = ((percent * dpywidth) + 50) / 100;
12863 printf("%s%s: |%s%s", ctx->start_meta, label,
12864 bar + (sizeof(bar) - (i+1)),
12865 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12866 if (fixed_percent == 1000)
12869 bb_putchar(spinner[ctx->progress_pos & 3]);
12870 printf(" %4.1f%% ", percent);
12872 printf("%u\r", dpynum);
12874 fputs(" \r", stdout);
12875 fputs(ctx->stop_meta, stdout);
12877 if (fixed_percent == 1000)
12878 e2fsck_clear_progbar(ctx);
12884 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12885 unsigned long cur, unsigned long max)
12893 if (ctx->progress_fd) {
12894 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12895 xwrite_str(ctx->progress_fd, buf);
12897 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12898 e2fsck_simple_progress(ctx, ctx->device_name,
12904 static void reserve_stdio_fds(void)
12909 fd = open(bb_dev_null, O_RDWR);
12913 fprintf(stderr, _("ERROR: Cannot open "
12914 "/dev/null (%s)\n"),
12922 static void signal_progress_on(int sig FSCK_ATTR((unused)))
12924 e2fsck_t ctx = e2fsck_global_ctx;
12929 ctx->progress = e2fsck_update_progress;
12930 ctx->progress_fd = 0;
12933 static void signal_progress_off(int sig FSCK_ATTR((unused)))
12935 e2fsck_t ctx = e2fsck_global_ctx;
12940 e2fsck_clear_progbar(ctx);
12944 static void signal_cancel(int sig FSCK_ATTR((unused)))
12946 e2fsck_t ctx = e2fsck_global_ctx;
12949 exit(FSCK_CANCELED);
12951 ctx->flags |= E2F_FLAG_CANCEL;
12954 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12956 char *buf, *token, *next, *p, *arg;
12958 int extended_usage = 0;
12960 buf = string_copy(opts, 0);
12961 for (token = buf; token && *token; token = next) {
12962 p = strchr(token, ',');
12968 arg = strchr(token, '=');
12973 if (strcmp(token, "ea_ver") == 0) {
12978 ea_ver = strtoul(arg, &p, 0);
12980 ((ea_ver != 1) && (ea_ver != 2))) {
12982 _("Invalid EA version.\n"));
12986 ctx->ext_attr_ver = ea_ver;
12988 fprintf(stderr, _("Unknown extended option: %s\n"),
12993 if (extended_usage) {
12994 bb_error_msg_and_die(
12995 "Extended options are separated by commas, "
12996 "and may take an argument which\n"
12997 "is set off by an equals ('=') sign. "
12998 "Valid extended options are:\n"
12999 "\tea_ver=<ea_version (1 or 2)>\n\n");
13004 static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx)
13010 struct sigaction sa;
13011 char *extended_opts = 0;
13013 retval = e2fsck_allocate_context(&ctx);
13019 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
13020 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
13021 if (isatty(0) && isatty(1)) {
13022 ctx->interactive = 1;
13024 ctx->start_meta[0] = '\001';
13025 ctx->stop_meta[0] = '\002';
13027 memset(bar, '=', sizeof(bar)-1);
13028 memset(spaces, ' ', sizeof(spaces)-1);
13029 blkid_get_cache(&ctx->blkid, NULL);
13032 ctx->program_name = *argv;
13034 ctx->program_name = "e2fsck";
13035 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13038 ctx->progress = e2fsck_update_progress;
13039 ctx->progress_fd = atoi(optarg);
13040 if (!ctx->progress_fd)
13042 /* Validate the file descriptor to avoid disasters */
13043 fd = dup(ctx->progress_fd);
13046 _("Error validating file descriptor %d: %s\n"),
13048 error_message(errno));
13049 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13054 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13057 extended_opts = optarg;
13061 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13063 bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified"));
13065 ctx->options |= E2F_OPT_PREEN;
13068 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13070 ctx->options |= E2F_OPT_NO;
13073 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13075 ctx->options |= E2F_OPT_YES;
13078 /* FIXME - This needs to go away in a future path - will change binary */
13079 fprintf(stderr, _("The -t option is not "
13080 "supported on this version of e2fsck.\n"));
13084 ctx->options |= E2F_OPT_WRITECHECK;
13085 ctx->options |= E2F_OPT_CHECKBLOCKS;
13088 /* What we do by default, anyway! */
13091 ctx->use_superblock = atoi(optarg);
13092 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13095 ctx->blocksize = atoi(optarg);
13098 ctx->inode_buffer_blocks = atoi(optarg);
13101 ctx->journal_name = string_copy(optarg, 0);
13104 ctx->process_inode_size = atoi(optarg);
13107 ctx->options |= E2F_OPT_DEBUG;
13110 ctx->options |= E2F_OPT_FORCE;
13119 show_version_only = 1;
13122 ctx->device_name = optarg;
13124 #ifdef ENABLE_SWAPFS
13126 normalize_swapfs = 1;
13133 fprintf(stderr, _("Byte-swapping filesystems "
13134 "not compiled in this version "
13141 if (show_version_only)
13143 if (optind != argc - 1)
13145 if ((ctx->options & E2F_OPT_NO) &&
13146 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13147 ctx->options |= E2F_OPT_READONLY;
13148 ctx->io_options = strchr(argv[optind], '?');
13149 if (ctx->io_options)
13150 *ctx->io_options++ = 0;
13151 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13152 if (!ctx->filesystem_name) {
13153 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13154 bb_error_msg_and_die(0);
13157 parse_extended_opts(ctx, extended_opts);
13160 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13162 bb_error_msg(_("while opening %s for flushing"),
13163 ctx->filesystem_name);
13164 bb_error_msg_and_die(0);
13166 if ((retval = ext2fs_sync_device(fd, 1))) {
13167 bb_error_msg(_("while trying to flush %s"),
13168 ctx->filesystem_name);
13169 bb_error_msg_and_die(0);
13173 #ifdef ENABLE_SWAPFS
13174 if (swapfs && cflag) {
13175 fprintf(stderr, _("Incompatible options not "
13176 "allowed when byte-swapping.\n"));
13181 * Set up signal action
13183 memset(&sa, 0, sizeof(struct sigaction));
13184 sa.sa_handler = signal_cancel;
13185 sigaction(SIGINT, &sa, 0);
13186 sigaction(SIGTERM, &sa, 0);
13188 sa.sa_flags = SA_RESTART;
13190 e2fsck_global_ctx = ctx;
13191 sa.sa_handler = signal_progress_on;
13192 sigaction(SIGUSR1, &sa, 0);
13193 sa.sa_handler = signal_progress_off;
13194 sigaction(SIGUSR2, &sa, 0);
13196 /* Update our PATH to include /sbin if we need to run badblocks */
13198 e2fs_set_sbin_path();
13202 static const char my_ver_string[] = E2FSPROGS_VERSION;
13203 static const char my_ver_date[] = E2FSPROGS_DATE;
13205 int e2fsck_main (int argc, char **argv);
13206 int e2fsck_main (int argc, char **argv)
13209 int exit_value = EXIT_OK;
13210 ext2_filsys fs = 0;
13212 struct ext2_super_block *sb;
13213 const char *lib_ver_date;
13214 int my_ver, lib_ver;
13216 struct problem_context pctx;
13217 int flags, run_result;
13219 clear_problem_context(&pctx);
13221 my_ver = ext2fs_parse_version_string(my_ver_string);
13222 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13223 if (my_ver > lib_ver) {
13224 fprintf( stderr, _("Error: ext2fs library version "
13225 "out of date!\n"));
13226 show_version_only++;
13229 retval = PRS(argc, argv, &ctx);
13231 bb_error_msg(_("while trying to initialize program"));
13234 reserve_stdio_fds();
13236 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13237 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13240 if (show_version_only) {
13241 fprintf(stderr, _("\tUsing %s, %s\n"),
13242 error_message(EXT2_ET_BASE), lib_ver_date);
13248 if (!(ctx->options & E2F_OPT_PREEN) &&
13249 !(ctx->options & E2F_OPT_NO) &&
13250 !(ctx->options & E2F_OPT_YES)) {
13251 if (!ctx->interactive)
13252 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13254 ctx->superblock = ctx->use_superblock;
13256 #ifdef CONFIG_TESTIO_DEBUG
13257 io_ptr = test_io_manager;
13258 test_io_backing_manager = unix_io_manager;
13260 io_ptr = unix_io_manager;
13263 if ((ctx->options & E2F_OPT_READONLY) == 0)
13264 flags |= EXT2_FLAG_RW;
13266 if (ctx->superblock && ctx->blocksize) {
13267 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13268 flags, ctx->superblock, ctx->blocksize,
13270 } else if (ctx->superblock) {
13272 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13273 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13274 retval = ext2fs_open2(ctx->filesystem_name,
13275 ctx->io_options, flags,
13276 ctx->superblock, blocksize,
13282 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13283 flags, 0, 0, io_ptr, &fs);
13284 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13285 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13286 ((retval == EXT2_ET_BAD_MAGIC) ||
13287 ((retval == 0) && ext2fs_check_desc(fs)))) {
13288 if (!fs || (fs->group_desc_count > 1)) {
13289 printf(_("%s trying backup blocks...\n"),
13290 retval ? _("Couldn't find ext2 superblock,") :
13291 _("Group descriptors look bad..."));
13292 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13299 bb_error_msg(_("while trying to open %s"),
13300 ctx->filesystem_name);
13301 if (retval == EXT2_ET_REV_TOO_HIGH) {
13302 printf(_("The filesystem revision is apparently "
13303 "too high for this version of e2fsck.\n"
13304 "(Or the filesystem superblock "
13305 "is corrupt)\n\n"));
13306 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13307 } else if (retval == EXT2_ET_SHORT_READ)
13308 printf(_("Could this be a zero-length partition?\n"));
13309 else if ((retval == EPERM) || (retval == EACCES))
13310 printf(_("You must have %s access to the "
13311 "filesystem or be root\n"),
13312 (ctx->options & E2F_OPT_READONLY) ?
13314 else if (retval == ENXIO)
13315 printf(_("Possibly non-existent or swap device?\n"));
13317 else if (retval == EROFS)
13318 printf(_("Disk write-protected; use the -n option "
13319 "to do a read-only\n"
13320 "check of the device.\n"));
13323 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13324 bb_error_msg_and_die(0);
13327 fs->priv_data = ctx;
13329 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13330 bb_error_msg(_("while trying to open %s"),
13331 ctx->filesystem_name);
13333 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13337 * Set the device name, which is used whenever we print error
13338 * or informational messages to the user.
13340 if (ctx->device_name == 0 &&
13341 (sb->s_volume_name[0] != 0)) {
13342 ctx->device_name = string_copy(sb->s_volume_name,
13343 sizeof(sb->s_volume_name));
13345 if (ctx->device_name == 0)
13346 ctx->device_name = ctx->filesystem_name;
13349 * Make sure the ext3 superblock fields are consistent.
13351 retval = e2fsck_check_ext3_journal(ctx);
13353 bb_error_msg(_("while checking ext3 journal for %s"),
13355 bb_error_msg_and_die(0);
13359 * Check to see if we need to do ext3-style recovery. If so,
13360 * do it, and then restart the fsck.
13362 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13363 if (ctx->options & E2F_OPT_READONLY) {
13364 printf(_("Warning: skipping journal recovery "
13365 "because doing a read-only filesystem "
13367 io_channel_flush(ctx->fs->io);
13369 if (ctx->flags & E2F_FLAG_RESTARTED) {
13371 * Whoops, we attempted to run the
13372 * journal twice. This should never
13373 * happen, unless the hardware or
13374 * device driver is being bogus.
13376 bb_error_msg(_("cannot set superblock flags on %s"), ctx->device_name);
13377 bb_error_msg_and_die(0);
13379 retval = e2fsck_run_ext3_journal(ctx);
13381 bb_error_msg(_("while recovering ext3 journal of %s"),
13383 bb_error_msg_and_die(0);
13385 ext2fs_close(ctx->fs);
13387 ctx->flags |= E2F_FLAG_RESTARTED;
13393 * Check for compatibility with the feature sets. We need to
13394 * be more stringent than ext2fs_open().
13396 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13397 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13398 bb_error_msg("(%s)", ctx->device_name);
13401 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13402 bb_error_msg("(%s)", ctx->device_name);
13405 #ifdef ENABLE_COMPRESSION
13406 /* FIXME - do we support this at all? */
13407 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13408 bb_error_msg(_("warning: compression support is experimental"));
13410 #ifndef ENABLE_HTREE
13411 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13412 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13413 "but filesystem %s has HTREE directories."),
13420 * If the user specified a specific superblock, presumably the
13421 * master superblock has been trashed. So we mark the
13422 * superblock as dirty, so it can be written out.
13424 if (ctx->superblock &&
13425 !(ctx->options & E2F_OPT_READONLY))
13426 ext2fs_mark_super_dirty(fs);
13429 * We only update the master superblock because (a) paranoia;
13430 * we don't want to corrupt the backup superblocks, and (b) we
13431 * don't need to update the mount count and last checked
13432 * fields in the backup superblock (the kernel doesn't
13433 * update the backup superblocks anyway).
13435 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13437 ehandler_init(fs->io);
13439 if (ctx->superblock)
13440 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13441 ext2fs_mark_valid(fs);
13442 check_super_block(ctx);
13443 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13444 bb_error_msg_and_die(0);
13445 check_if_skip(ctx);
13446 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13447 bb_error_msg_and_die(0);
13448 #ifdef ENABLE_SWAPFS
13450 #ifdef WORDS_BIGENDIAN
13451 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13453 #define NATIVE_FLAG 0
13457 if (normalize_swapfs) {
13458 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13459 fprintf(stderr, _("%s: Filesystem byte order "
13460 "already normalized.\n"), ctx->device_name);
13461 bb_error_msg_and_die(0);
13466 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13467 bb_error_msg_and_die(0);
13472 * Mark the system as valid, 'til proven otherwise
13474 ext2fs_mark_valid(fs);
13476 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13478 bb_error_msg(_("while reading bad blocks inode"));
13480 printf(_("This doesn't bode well,"
13481 " but we'll try to go on...\n"));
13484 run_result = e2fsck_run(ctx);
13485 e2fsck_clear_progbar(ctx);
13486 if (run_result == E2F_FLAG_RESTART) {
13487 printf(_("Restarting e2fsck from the beginning...\n"));
13488 retval = e2fsck_reset_context(ctx);
13490 bb_error_msg(_("while resetting context"));
13491 bb_error_msg_and_die(0);
13496 if (run_result & E2F_FLAG_CANCEL) {
13497 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13498 ctx->device_name : ctx->filesystem_name);
13499 exit_value |= FSCK_CANCELED;
13501 if (run_result & E2F_FLAG_ABORT)
13502 bb_error_msg_and_die(_("aborted"));
13505 if (ext2fs_test_changed(fs)) {
13506 exit_value |= EXIT_NONDESTRUCT;
13507 if (!(ctx->options & E2F_OPT_PREEN))
13508 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13510 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13511 printf(_("%s: ***** REBOOT LINUX *****\n"),
13513 exit_value |= EXIT_DESTRUCT;
13516 if (!ext2fs_test_valid(fs)) {
13517 printf(_("\n%s: ********** WARNING: Filesystem still has "
13518 "errors **********\n\n"), ctx->device_name);
13519 exit_value |= EXIT_UNCORRECTED;
13520 exit_value &= ~EXIT_NONDESTRUCT;
13522 if (exit_value & FSCK_CANCELED)
13523 exit_value &= ~EXIT_NONDESTRUCT;
13526 if (!(ctx->options & E2F_OPT_READONLY)) {
13527 if (ext2fs_test_valid(fs)) {
13528 if (!(sb->s_state & EXT2_VALID_FS))
13529 exit_value |= EXIT_NONDESTRUCT;
13530 sb->s_state = EXT2_VALID_FS;
13532 sb->s_state &= ~EXT2_VALID_FS;
13533 sb->s_mnt_count = 0;
13534 sb->s_lastcheck = time(NULL);
13535 ext2fs_mark_super_dirty(fs);
13539 e2fsck_write_bitmaps(ctx);
13543 free(ctx->filesystem_name);
13544 free(ctx->journal_name);
13545 e2fsck_free_context(ctx);