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 unrecognisable 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(0);
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);
2293 * message.c --- print e2fsck messages (with compression)
2295 * print_e2fsck_message() prints a message to the user, using
2296 * compression techniques and expansions of abbreviations.
2298 * The following % expansions are supported:
2300 * %b <blk> block number
2301 * %B <blkcount> integer
2302 * %c <blk2> block number
2303 * %Di <dirent>->ino inode number
2304 * %Dn <dirent>->name string
2305 * %Dr <dirent>->rec_len
2306 * %Dl <dirent>->name_len
2307 * %Dt <dirent>->filetype
2308 * %d <dir> inode number
2309 * %g <group> integer
2310 * %i <ino> inode number
2311 * %Is <inode> -> i_size
2312 * %IS <inode> -> i_extra_isize
2313 * %Ib <inode> -> i_blocks
2314 * %Il <inode> -> i_links_count
2315 * %Im <inode> -> i_mode
2316 * %IM <inode> -> i_mtime
2317 * %IF <inode> -> i_faddr
2318 * %If <inode> -> i_file_acl
2319 * %Id <inode> -> i_dir_acl
2320 * %Iu <inode> -> i_uid
2321 * %Ig <inode> -> i_gid
2322 * %j <ino2> inode number
2323 * %m <com_err error message>
2325 * %p ext2fs_get_pathname of directory <ino>
2326 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2327 * the containing directory. (If dirent is NULL
2328 * then return the pathname of directory <ino2>)
2329 * %q ext2fs_get_pathname of directory <dir>
2330 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2331 * the containing directory.
2332 * %s <str> miscellaneous string
2333 * %S backup superblock
2334 * %X <num> hexadecimal format
2336 * The following '@' expansions are supported:
2338 * @a extended attribute
2339 * @A error allocating
2343 * @C conflicts with some other fs block
2347 * @E Entry '%Dn' in %p (%i)
2349 * @F for @i %i (%Q) is
2351 * @h HTREE directory inode
2357 * @m multiply-claimed
2371 * This structure defines the abbreviations used by the text strings
2372 * below. The first character in the string is the index letter. An
2373 * abbreviation of the form '@<i>' is expanded by looking up the index
2374 * letter <i> in the table below.
2376 static const char * const abbrevs[] = {
2377 N_("aextended attribute"),
2378 N_("Aerror allocating"),
2382 N_("Cconflicts with some other fs @b"),
2389 N_("E@e '%Dn' in %p (%i)"),
2391 N_("Ffor @i %i (%Q) is"),
2396 N_("mmultiply-claimed"),
2411 * Give more user friendly names to the "special" inodes.
2413 #define num_special_inodes 11
2414 static const char * const special_inode_name[] =
2416 N_("<The NULL inode>"), /* 0 */
2417 N_("<The bad blocks inode>"), /* 1 */
2419 N_("<The ACL index inode>"), /* 3 */
2420 N_("<The ACL data inode>"), /* 4 */
2421 N_("<The boot loader inode>"), /* 5 */
2422 N_("<The undelete directory inode>"), /* 6 */
2423 N_("<The group descriptor inode>"), /* 7 */
2424 N_("<The journal inode>"), /* 8 */
2425 N_("<Reserved inode 9>"), /* 9 */
2426 N_("<Reserved inode 10>"), /* 10 */
2430 * This function does "safe" printing. It will convert non-printable
2431 * ASCII characters using '^' and M- notation.
2433 static void safe_print(const char *cp, int len)
2443 fputs("M-", stdout);
2446 if ((ch < 32) || (ch == 0x7f)) {
2448 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2456 * This function prints a pathname, using the ext2fs_get_pathname
2459 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2464 if (!dir && (ino < num_special_inodes)) {
2465 fputs(_(special_inode_name[ino]), stdout);
2469 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2471 fputs("???", stdout);
2473 safe_print(path, -1);
2474 ext2fs_free_mem(&path);
2478 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2479 struct problem_context *pctx, int first);
2481 * This function handles the '@' expansion. We allow recursive
2482 * expansion; an @ expression can contain further '@' and '%'
2485 static void expand_at_expression(e2fsck_t ctx, char ch,
2486 struct problem_context *pctx,
2489 const char * const *cpp;
2492 /* Search for the abbreviation */
2493 for (cpp = abbrevs; *cpp; cpp++) {
2499 if (*first && islower(*str)) {
2501 fputc(toupper(*str++), stdout);
2503 print_e2fsck_message(ctx, str, pctx, *first);
2509 * This function expands '%IX' expressions
2511 static void expand_inode_expression(char ch,
2512 struct problem_context *ctx)
2514 struct ext2_inode *inode;
2515 struct ext2_inode_large *large_inode;
2520 if (!ctx || !ctx->inode)
2524 large_inode = (struct ext2_inode_large *) inode;
2528 if (LINUX_S_ISDIR(inode->i_mode))
2529 printf("%u", inode->i_size);
2531 printf("%"PRIu64, (inode->i_size |
2532 ((uint64_t) inode->i_size_high << 32)));
2536 printf("%u", large_inode->i_extra_isize);
2539 printf("%u", inode->i_blocks);
2542 printf("%d", inode->i_links_count);
2545 printf("0%o", inode->i_mode);
2548 /* The diet libc doesn't respect the TZ environemnt variable */
2550 time_str = getenv("TZ");
2553 do_gmt = !strcmp(time_str, "GMT");
2556 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2557 printf("%.24s", time_str);
2560 printf("%u", inode->i_faddr);
2563 printf("%u", inode->i_file_acl);
2566 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2567 inode->i_dir_acl : 0));
2570 printf("%d", (inode->i_uid |
2571 (inode->osd2.linux2.l_i_uid_high << 16)));
2574 printf("%d", (inode->i_gid |
2575 (inode->osd2.linux2.l_i_gid_high << 16)));
2579 printf("%%I%c", ch);
2585 * This function expands '%dX' expressions
2587 static void expand_dirent_expression(char ch,
2588 struct problem_context *ctx)
2590 struct ext2_dir_entry *dirent;
2593 if (!ctx || !ctx->dirent)
2596 dirent = ctx->dirent;
2600 printf("%u", dirent->inode);
2603 len = dirent->name_len & 0xFF;
2604 if (len > EXT2_NAME_LEN)
2605 len = EXT2_NAME_LEN;
2606 if (len > dirent->rec_len)
2607 len = dirent->rec_len;
2608 safe_print(dirent->name, len);
2611 printf("%u", dirent->rec_len);
2614 printf("%u", dirent->name_len & 0xFF);
2617 printf("%u", dirent->name_len >> 8);
2621 printf("%%D%c", ch);
2626 static void expand_percent_expression(ext2_filsys fs, char ch,
2627 struct problem_context *ctx)
2637 printf("%u", ctx->blk);
2640 printf("%"PRIi64, ctx->blkcount);
2643 printf("%u", ctx->blk2);
2646 printf("%u", ctx->dir);
2649 printf("%d", ctx->group);
2652 printf("%u", ctx->ino);
2655 printf("%u", ctx->ino2);
2658 printf("%s", error_message(ctx->errcode));
2661 printf("%"PRIi64, ctx->num);
2664 print_pathname(fs, ctx->ino, 0);
2667 print_pathname(fs, ctx->ino2,
2668 ctx->dirent ? ctx->dirent->inode : 0);
2671 print_pathname(fs, ctx->dir, 0);
2674 print_pathname(fs, ctx->dir, ctx->ino);
2677 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2680 printf("%s", ctx->str ? ctx->str : "NULL");
2683 printf("0x%"PRIi64, ctx->num);
2693 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2694 struct problem_context *pctx, int first)
2696 ext2_filsys fs = ctx->fs;
2700 e2fsck_clear_progbar(ctx);
2701 for (cp = msg; *cp; cp++) {
2704 expand_at_expression(ctx, *cp, pctx, &first);
2705 } else if (cp[0] == '%' && cp[1] == 'I') {
2707 expand_inode_expression(*cp, pctx);
2708 } else if (cp[0] == '%' && cp[1] == 'D') {
2710 expand_dirent_expression(*cp, pctx);
2711 } else if ((cp[0] == '%')) {
2713 expand_percent_expression(fs, *cp, pctx);
2715 for (i=0; cp[i]; i++)
2716 if ((cp[i] == '@') || cp[i] == '%')
2718 printf("%.*s", i, cp);
2727 * region.c --- code which manages allocations within a region.
2731 region_addr_t start;
2733 struct region_el *next;
2736 struct region_struct {
2739 struct region_el *allocated;
2742 static region_t region_create(region_addr_t min, region_addr_t max)
2746 region = malloc(sizeof(struct region_struct));
2749 memset(region, 0, sizeof(struct region_struct));
2755 static void region_free(region_t region)
2757 struct region_el *r, *next;
2759 for (r = region->allocated; r; r = next) {
2763 memset(region, 0, sizeof(struct region_struct));
2767 static int region_allocate(region_t region, region_addr_t start, int n)
2769 struct region_el *r, *new_region, *prev, *next;
2773 if ((start < region->min) || (end > region->max))
2779 * Search through the linked list. If we find that it
2780 * conflicts witih something that's already allocated, return
2781 * 1; if we can find an existing region which we can grow, do
2782 * so. Otherwise, stop when we find the appropriate place
2783 * insert a new region element into the linked list.
2785 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2786 if (((start >= r->start) && (start < r->end)) ||
2787 ((end > r->start) && (end <= r->end)) ||
2788 ((start <= r->start) && (end >= r->end)))
2790 if (end == r->start) {
2794 if (start == r->end) {
2795 if ((next = r->next)) {
2796 if (end > next->start)
2798 if (end == next->start) {
2800 r->next = next->next;
2808 if (start < r->start)
2812 * Insert a new region element structure into the linked list
2814 new_region = malloc(sizeof(struct region_el));
2817 new_region->start = start;
2818 new_region->end = start + n;
2819 new_region->next = r;
2821 prev->next = new_region;
2823 region->allocated = new_region;
2828 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2830 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2831 * and applies the following tests to each inode:
2833 * - The mode field of the inode must be legal.
2834 * - The size and block count fields of the inode are correct.
2835 * - A data block must not be used by another inode
2837 * Pass 1 also gathers the collects the following information:
2839 * - A bitmap of which inodes are in use. (inode_used_map)
2840 * - A bitmap of which inodes are directories. (inode_dir_map)
2841 * - A bitmap of which inodes are regular files. (inode_reg_map)
2842 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2843 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2844 * - A bitmap of which blocks are in use. (block_found_map)
2845 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2846 * - The data blocks of the directory inodes. (dir_map)
2848 * Pass 1 is designed to stash away enough information so that the
2849 * other passes should not need to read in the inode information
2850 * during the normal course of a filesystem check. (Althogh if an
2851 * inconsistency is detected, other passes may need to read in an
2854 * Note that pass 1B will be invoked if there are any duplicate blocks
2859 static int process_block(ext2_filsys fs, blk_t *blocknr,
2860 e2_blkcnt_t blockcnt, blk_t ref_blk,
2861 int ref_offset, void *priv_data);
2862 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2863 e2_blkcnt_t blockcnt, blk_t ref_blk,
2864 int ref_offset, void *priv_data);
2865 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2867 static void mark_table_blocks(e2fsck_t ctx);
2868 static void alloc_imagic_map(e2fsck_t ctx);
2869 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2870 static void handle_fs_bad_blocks(e2fsck_t ctx);
2871 static void process_inodes(e2fsck_t ctx, char *block_buf);
2872 static int process_inode_cmp(const void *a, const void *b);
2873 static errcode_t scan_callback(ext2_filsys fs,
2874 dgrp_t group, void * priv_data);
2875 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2876 char *block_buf, int adjust_sign);
2877 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2879 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2880 struct ext2_inode * inode, int bufsize,
2883 struct process_block_struct_1 {
2885 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
2886 fragmented:1, compressed:1, bbcheck:1;
2889 e2_blkcnt_t last_block;
2890 int num_illegal_blocks;
2891 blk_t previous_block;
2892 struct ext2_inode *inode;
2893 struct problem_context *pctx;
2894 ext2fs_block_bitmap fs_meta_blocks;
2898 struct process_inode_block {
2900 struct ext2_inode inode;
2903 struct scan_callback_struct {
2909 * For the inodes to process list.
2911 static struct process_inode_block *inodes_to_process;
2912 static int process_inode_count;
2914 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2915 EXT2_MIN_BLOCK_LOG_SIZE + 1];
2918 * Free all memory allocated by pass1 in preparation for restarting
2921 static void unwind_pass1(void)
2923 ext2fs_free_mem(&inodes_to_process);
2927 * Check to make sure a device inode is real. Returns 1 if the device
2928 * checks out, 0 if not.
2930 * Note: this routine is now also used to check FIFO's and Sockets,
2931 * since they have the same requirement; the i_block fields should be
2935 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2940 * If i_blocks is non-zero, or the index flag is set, then
2941 * this is a bogus device/fifo/socket
2943 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2944 (inode->i_flags & EXT2_INDEX_FL))
2948 * We should be able to do the test below all the time, but
2949 * because the kernel doesn't forcibly clear the device
2950 * inode's additional i_block fields, there are some rare
2951 * occasions when a legitimate device inode will have non-zero
2952 * additional i_block fields. So for now, we only complain
2953 * when the immutable flag is set, which should never happen
2954 * for devices. (And that's when the problem is caused, since
2955 * you can't set or clear immutable flags for devices.) Once
2956 * the kernel has been fixed we can change this...
2958 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2959 for (i=4; i < EXT2_N_BLOCKS; i++)
2960 if (inode->i_block[i])
2967 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2968 * checks out, 0 if not.
2971 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
2977 if ((inode->i_size_high || inode->i_size == 0) ||
2978 (inode->i_flags & EXT2_INDEX_FL))
2981 blocks = ext2fs_inode_data_blocks(fs, inode);
2983 if ((inode->i_size >= fs->blocksize) ||
2984 (blocks != fs->blocksize >> 9) ||
2985 (inode->i_block[0] < fs->super->s_first_data_block) ||
2986 (inode->i_block[0] >= fs->super->s_blocks_count))
2989 for (i = 1; i < EXT2_N_BLOCKS; i++)
2990 if (inode->i_block[i])
2993 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
2996 len = strnlen(buf, fs->blocksize);
2997 if (len == fs->blocksize)
3000 if (inode->i_size >= sizeof(inode->i_block))
3003 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3004 if (len == sizeof(inode->i_block))
3007 if (len != inode->i_size)
3013 * If the immutable (or append-only) flag is set on the inode, offer
3016 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3017 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3019 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3022 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3025 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3026 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3030 * If device, fifo or socket, check size is zero -- if not offer to
3033 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3035 struct ext2_inode *inode = pctx->inode;
3037 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3040 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3044 inode->i_size_high = 0;
3045 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3048 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3050 struct ext2_super_block *sb = ctx->fs->super;
3051 struct ext2_inode_large *inode;
3052 struct ext2_ext_attr_entry *entry;
3054 int storage_size, remain, offs;
3057 inode = (struct ext2_inode_large *) pctx->inode;
3058 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3059 inode->i_extra_isize;
3060 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3061 inode->i_extra_isize + sizeof(__u32);
3062 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3063 entry = (struct ext2_ext_attr_entry *) start;
3065 /* scan all entry's headers first */
3067 /* take finish entry 0UL into account */
3068 remain = storage_size - sizeof(__u32);
3071 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3073 /* header eats this space */
3074 remain -= sizeof(struct ext2_ext_attr_entry);
3076 /* is attribute name valid? */
3077 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3078 pctx->num = entry->e_name_len;
3079 problem = PR_1_ATTR_NAME_LEN;
3083 /* attribute len eats this space */
3084 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3086 /* check value size */
3087 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3088 pctx->num = entry->e_value_size;
3089 problem = PR_1_ATTR_VALUE_SIZE;
3093 /* check value placement */
3094 if (entry->e_value_offs +
3095 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3096 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3097 pctx->num = entry->e_value_offs;
3098 problem = PR_1_ATTR_VALUE_OFFSET;
3102 /* e_value_block must be 0 in inode's ea */
3103 if (entry->e_value_block != 0) {
3104 pctx->num = entry->e_value_block;
3105 problem = PR_1_ATTR_VALUE_BLOCK;
3109 /* e_hash must be 0 in inode's ea */
3110 if (entry->e_hash != 0) {
3111 pctx->num = entry->e_hash;
3112 problem = PR_1_ATTR_HASH;
3116 remain -= entry->e_value_size;
3117 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3119 entry = EXT2_EXT_ATTR_NEXT(entry);
3123 * it seems like a corruption. it's very unlikely we could repair
3124 * EA(s) in automatic fashion -bzzz
3126 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3129 /* simple remove all possible EA(s) */
3130 *((__u32 *)start) = 0UL;
3131 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3132 EXT2_INODE_SIZE(sb), "pass1");
3135 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3137 struct ext2_super_block *sb = ctx->fs->super;
3138 struct ext2_inode_large *inode;
3142 inode = (struct ext2_inode_large *) pctx->inode;
3143 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3144 /* this isn't large inode. so, nothing to check */
3148 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3149 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3150 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3152 * For now we will allow i_extra_isize to be 0, but really
3153 * implementations should never allow i_extra_isize to be 0
3155 if (inode->i_extra_isize &&
3156 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3157 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3159 inode->i_extra_isize = min;
3160 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3161 EXT2_INODE_SIZE(sb), "pass1");
3165 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3166 inode->i_extra_isize);
3167 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3168 /* it seems inode has an extended attribute(s) in body */
3169 check_ea_in_inode(ctx, pctx);
3173 static void e2fsck_pass1(e2fsck_t ctx)
3177 ext2_filsys fs = ctx->fs;
3179 struct ext2_inode *inode;
3180 ext2_inode_scan scan;
3182 unsigned char frag, fsize;
3183 struct problem_context pctx;
3184 struct scan_callback_struct scan_struct;
3185 struct ext2_super_block *sb = ctx->fs->super;
3187 int busted_fs_time = 0;
3190 clear_problem_context(&pctx);
3192 if (!(ctx->options & E2F_OPT_PREEN))
3193 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3195 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3196 !(ctx->options & E2F_OPT_NO)) {
3197 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3198 ctx->dirs_to_hash = 0;
3203 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3205 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3206 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3207 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3208 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3209 max_sizes = (max_sizes * (1UL << i)) - 1;
3210 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3214 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3217 * Allocate bitmaps structures
3219 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3220 &ctx->inode_used_map);
3223 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3224 ctx->flags |= E2F_FLAG_ABORT;
3227 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3228 _("directory inode map"), &ctx->inode_dir_map);
3231 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3232 ctx->flags |= E2F_FLAG_ABORT;
3235 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3236 _("regular file inode map"), &ctx->inode_reg_map);
3239 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3240 ctx->flags |= E2F_FLAG_ABORT;
3243 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3244 &ctx->block_found_map);
3247 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3248 ctx->flags |= E2F_FLAG_ABORT;
3251 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3252 &ctx->inode_link_info);
3254 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3255 ctx->flags |= E2F_FLAG_ABORT;
3258 inode_size = EXT2_INODE_SIZE(fs->super);
3259 inode = (struct ext2_inode *)
3260 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3262 inodes_to_process = (struct process_inode_block *)
3263 e2fsck_allocate_memory(ctx,
3264 (ctx->process_inode_size *
3265 sizeof(struct process_inode_block)),
3266 "array of inodes to process");
3267 process_inode_count = 0;
3269 pctx.errcode = ext2fs_init_dblist(fs, 0);
3271 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3272 ctx->flags |= E2F_FLAG_ABORT;
3277 * If the last orphan field is set, clear it, since the pass1
3278 * processing will automatically find and clear the orphans.
3279 * In the future, we may want to try using the last_orphan
3280 * linked list ourselves, but for now, we clear it so that the
3281 * ext3 mount code won't get confused.
3283 if (!(ctx->options & E2F_OPT_READONLY)) {
3284 if (fs->super->s_last_orphan) {
3285 fs->super->s_last_orphan = 0;
3286 ext2fs_mark_super_dirty(fs);
3290 mark_table_blocks(ctx);
3291 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3292 "block interate buffer");
3293 e2fsck_use_inode_shortcuts(ctx, 1);
3294 ehandler_operation(_("doing inode scan"));
3295 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3298 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3299 ctx->flags |= E2F_FLAG_ABORT;
3302 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3303 ctx->stashed_inode = inode;
3304 scan_struct.ctx = ctx;
3305 scan_struct.block_buf = block_buf;
3306 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3308 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3310 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3311 (fs->super->s_mtime < fs->super->s_inodes_count))
3315 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3317 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3319 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3323 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3324 ctx->flags |= E2F_FLAG_ABORT;
3331 ctx->stashed_ino = ino;
3332 if (inode->i_links_count) {
3333 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3334 ino, inode->i_links_count);
3336 pctx.num = inode->i_links_count;
3337 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3338 ctx->flags |= E2F_FLAG_ABORT;
3342 if (ino == EXT2_BAD_INO) {
3343 struct process_block_struct_1 pb;
3345 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3346 &pb.fs_meta_blocks);
3349 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3350 ctx->flags |= E2F_FLAG_ABORT;
3353 pb.ino = EXT2_BAD_INO;
3354 pb.num_blocks = pb.last_block = 0;
3355 pb.num_illegal_blocks = 0;
3356 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3357 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3361 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3362 block_buf, process_bad_block, &pb);
3363 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3365 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3366 ctx->flags |= E2F_FLAG_ABORT;
3370 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3371 ctx->flags |= E2F_FLAG_ABORT;
3374 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3375 clear_problem_context(&pctx);
3377 } else if (ino == EXT2_ROOT_INO) {
3379 * Make sure the root inode is a directory; if
3380 * not, offer to clear it. It will be
3381 * regnerated in pass #3.
3383 if (!LINUX_S_ISDIR(inode->i_mode)) {
3384 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3385 inode->i_dtime = time(0);
3386 inode->i_links_count = 0;
3387 ext2fs_icount_store(ctx->inode_link_info,
3389 e2fsck_write_inode(ctx, ino, inode,
3395 * If dtime is set, offer to clear it. mke2fs
3396 * version 0.2b created filesystems with the
3397 * dtime field set for the root and lost+found
3398 * directories. We won't worry about
3399 * /lost+found, since that can be regenerated
3400 * easily. But we will fix the root directory
3401 * as a special case.
3403 if (inode->i_dtime && inode->i_links_count) {
3404 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3406 e2fsck_write_inode(ctx, ino, inode,
3410 } else if (ino == EXT2_JOURNAL_INO) {
3411 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3412 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3413 if (!LINUX_S_ISREG(inode->i_mode) &&
3414 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3416 inode->i_mode = LINUX_S_IFREG;
3417 e2fsck_write_inode(ctx, ino, inode,
3420 check_blocks(ctx, &pctx, block_buf);
3423 if ((inode->i_links_count || inode->i_blocks ||
3424 inode->i_blocks || inode->i_block[0]) &&
3425 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3427 memset(inode, 0, inode_size);
3428 ext2fs_icount_store(ctx->inode_link_info,
3430 e2fsck_write_inode_full(ctx, ino, inode,
3431 inode_size, "pass1");
3433 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3436 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3437 if (ino == EXT2_BOOT_LOADER_INO) {
3438 if (LINUX_S_ISDIR(inode->i_mode))
3439 problem = PR_1_RESERVED_BAD_MODE;
3440 } else if (ino == EXT2_RESIZE_INO) {
3441 if (inode->i_mode &&
3442 !LINUX_S_ISREG(inode->i_mode))
3443 problem = PR_1_RESERVED_BAD_MODE;
3445 if (inode->i_mode != 0)
3446 problem = PR_1_RESERVED_BAD_MODE;
3449 if (fix_problem(ctx, problem, &pctx)) {
3451 e2fsck_write_inode(ctx, ino, inode,
3455 check_blocks(ctx, &pctx, block_buf);
3459 * Check for inodes who might have been part of the
3460 * orphaned list linked list. They should have gotten
3461 * dealt with by now, unless the list had somehow been
3464 * FIXME: In the future, inodes which are still in use
3465 * (and which are therefore) pending truncation should
3466 * be handled specially. Right now we just clear the
3467 * dtime field, and the normal e2fsck handling of
3468 * inodes where i_size and the inode blocks are
3469 * inconsistent is to fix i_size, instead of releasing
3470 * the extra blocks. This won't catch the inodes that
3471 * was at the end of the orphan list, but it's better
3472 * than nothing. The right answer is that there
3473 * shouldn't be any bugs in the orphan list handling. :-)
3475 if (inode->i_dtime && !busted_fs_time &&
3476 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3477 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3478 inode->i_dtime = inode->i_links_count ?
3480 e2fsck_write_inode(ctx, ino, inode,
3486 * This code assumes that deleted inodes have
3487 * i_links_count set to 0.
3489 if (!inode->i_links_count) {
3490 if (!inode->i_dtime && inode->i_mode) {
3491 if (fix_problem(ctx,
3492 PR_1_ZERO_DTIME, &pctx)) {
3493 inode->i_dtime = time(0);
3494 e2fsck_write_inode(ctx, ino, inode,
3501 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3502 * deleted files. Oops.
3504 * Since all new ext2 implementations get this right,
3505 * we now assume that the case of non-zero
3506 * i_links_count and non-zero dtime means that we
3507 * should keep the file, not delete it.
3510 if (inode->i_dtime) {
3511 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3513 e2fsck_write_inode(ctx, ino, inode, "pass1");
3517 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3518 switch (fs->super->s_creator_os) {
3520 frag = inode->osd2.linux2.l_i_frag;
3521 fsize = inode->osd2.linux2.l_i_fsize;
3524 frag = inode->osd2.hurd2.h_i_frag;
3525 fsize = inode->osd2.hurd2.h_i_fsize;
3528 frag = inode->osd2.masix2.m_i_frag;
3529 fsize = inode->osd2.masix2.m_i_fsize;
3535 if (inode->i_faddr || frag || fsize ||
3536 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3537 mark_inode_bad(ctx, ino);
3538 if (inode->i_flags & EXT2_IMAGIC_FL) {
3540 if (!ctx->inode_imagic_map)
3541 alloc_imagic_map(ctx);
3542 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3545 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3546 inode->i_flags &= ~EXT2_IMAGIC_FL;
3547 e2fsck_write_inode(ctx, ino,
3553 check_inode_extra_space(ctx, &pctx);
3555 if (LINUX_S_ISDIR(inode->i_mode)) {
3556 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3557 e2fsck_add_dir_info(ctx, ino, 0);
3558 ctx->fs_directory_count++;
3559 } else if (LINUX_S_ISREG (inode->i_mode)) {
3560 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3561 ctx->fs_regular_count++;
3562 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3563 e2fsck_pass1_check_device_inode(fs, inode)) {
3564 check_immutable(ctx, &pctx);
3565 check_size(ctx, &pctx);
3566 ctx->fs_chardev_count++;
3567 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3568 e2fsck_pass1_check_device_inode(fs, inode)) {
3569 check_immutable(ctx, &pctx);
3570 check_size(ctx, &pctx);
3571 ctx->fs_blockdev_count++;
3572 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3573 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3574 check_immutable(ctx, &pctx);
3575 ctx->fs_symlinks_count++;
3576 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3577 ctx->fs_fast_symlinks_count++;
3578 check_blocks(ctx, &pctx, block_buf);
3582 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3583 e2fsck_pass1_check_device_inode(fs, inode)) {
3584 check_immutable(ctx, &pctx);
3585 check_size(ctx, &pctx);
3586 ctx->fs_fifo_count++;
3587 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3588 e2fsck_pass1_check_device_inode(fs, inode)) {
3589 check_immutable(ctx, &pctx);
3590 check_size(ctx, &pctx);
3591 ctx->fs_sockets_count++;
3593 mark_inode_bad(ctx, ino);
3594 if (inode->i_block[EXT2_IND_BLOCK])
3595 ctx->fs_ind_count++;
3596 if (inode->i_block[EXT2_DIND_BLOCK])
3597 ctx->fs_dind_count++;
3598 if (inode->i_block[EXT2_TIND_BLOCK])
3599 ctx->fs_tind_count++;
3600 if (inode->i_block[EXT2_IND_BLOCK] ||
3601 inode->i_block[EXT2_DIND_BLOCK] ||
3602 inode->i_block[EXT2_TIND_BLOCK] ||
3603 inode->i_file_acl) {
3604 inodes_to_process[process_inode_count].ino = ino;
3605 inodes_to_process[process_inode_count].inode = *inode;
3606 process_inode_count++;
3608 check_blocks(ctx, &pctx, block_buf);
3610 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3613 if (process_inode_count >= ctx->process_inode_size) {
3614 process_inodes(ctx, block_buf);
3616 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3620 process_inodes(ctx, block_buf);
3621 ext2fs_close_inode_scan(scan);
3622 ehandler_operation(0);
3625 * If any extended attribute blocks' reference counts need to
3626 * be adjusted, either up (ctx->refcount_extra), or down
3627 * (ctx->refcount), then fix them.
3629 if (ctx->refcount) {
3630 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3631 ea_refcount_free(ctx->refcount);
3634 if (ctx->refcount_extra) {
3635 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3637 ea_refcount_free(ctx->refcount_extra);
3638 ctx->refcount_extra = 0;
3641 if (ctx->invalid_bitmaps)
3642 handle_fs_bad_blocks(ctx);
3644 /* We don't need the block_ea_map any more */
3645 ext2fs_free_block_bitmap(ctx->block_ea_map);
3646 ctx->block_ea_map = 0;
3648 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3649 ext2fs_block_bitmap save_bmap;
3651 save_bmap = fs->block_map;
3652 fs->block_map = ctx->block_found_map;
3653 clear_problem_context(&pctx);
3654 pctx.errcode = ext2fs_create_resize_inode(fs);
3656 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3657 /* Should never get here */
3658 ctx->flags |= E2F_FLAG_ABORT;
3661 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3663 inode->i_mtime = time(0);
3664 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3666 fs->block_map = save_bmap;
3667 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3670 if (ctx->flags & E2F_FLAG_RESTART) {
3672 * Only the master copy of the superblock and block
3673 * group descriptors are going to be written during a
3674 * restart, so set the superblock to be used to be the
3675 * master superblock.
3677 ctx->use_superblock = 0;
3682 if (ctx->block_dup_map) {
3683 if (ctx->options & E2F_OPT_PREEN) {
3684 clear_problem_context(&pctx);
3685 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3687 e2fsck_pass1_dupblocks(ctx, block_buf);
3689 ext2fs_free_mem(&inodes_to_process);
3691 e2fsck_use_inode_shortcuts(ctx, 0);
3693 ext2fs_free_mem(&block_buf);
3694 ext2fs_free_mem(&inode);
3699 * When the inode_scan routines call this callback at the end of the
3700 * glock group, call process_inodes.
3702 static errcode_t scan_callback(ext2_filsys fs,
3703 dgrp_t group, void * priv_data)
3705 struct scan_callback_struct *scan_struct;
3708 scan_struct = (struct scan_callback_struct *) priv_data;
3709 ctx = scan_struct->ctx;
3711 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3714 if ((ctx->progress)(ctx, 1, group+1,
3715 ctx->fs->group_desc_count))
3716 return EXT2_ET_CANCEL_REQUESTED;
3722 * Process the inodes in the "inodes to process" list.
3724 static void process_inodes(e2fsck_t ctx, char *block_buf)
3727 struct ext2_inode *old_stashed_inode;
3728 ext2_ino_t old_stashed_ino;
3729 const char *old_operation;
3731 struct problem_context pctx;
3733 /* begin process_inodes */
3734 if (process_inode_count == 0)
3736 old_operation = ehandler_operation(0);
3737 old_stashed_inode = ctx->stashed_inode;
3738 old_stashed_ino = ctx->stashed_ino;
3739 qsort(inodes_to_process, process_inode_count,
3740 sizeof(struct process_inode_block), process_inode_cmp);
3741 clear_problem_context(&pctx);
3742 for (i=0; i < process_inode_count; i++) {
3743 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3744 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3745 sprintf(buf, _("reading indirect blocks of inode %u"),
3747 ehandler_operation(buf);
3748 check_blocks(ctx, &pctx, block_buf);
3749 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3752 ctx->stashed_inode = old_stashed_inode;
3753 ctx->stashed_ino = old_stashed_ino;
3754 process_inode_count = 0;
3755 /* end process inodes */
3757 ehandler_operation(old_operation);
3760 static int process_inode_cmp(const void *a, const void *b)
3762 const struct process_inode_block *ib_a =
3763 (const struct process_inode_block *) a;
3764 const struct process_inode_block *ib_b =
3765 (const struct process_inode_block *) b;
3768 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3769 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3771 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3776 * Mark an inode as being bad in some what
3778 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3780 struct problem_context pctx;
3782 if (!ctx->inode_bad_map) {
3783 clear_problem_context(&pctx);
3785 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3786 _("bad inode map"), &ctx->inode_bad_map);
3789 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3790 /* Should never get here */
3791 ctx->flags |= E2F_FLAG_ABORT;
3795 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3800 * This procedure will allocate the inode imagic table
3802 static void alloc_imagic_map(e2fsck_t ctx)
3804 struct problem_context pctx;
3806 clear_problem_context(&pctx);
3807 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3808 _("imagic inode map"),
3809 &ctx->inode_imagic_map);
3812 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3813 /* Should never get here */
3814 ctx->flags |= E2F_FLAG_ABORT;
3820 * Marks a block as in use, setting the dup_map if it's been set
3821 * already. Called by process_block and process_bad_block.
3823 * WARNING: Assumes checks have already been done to make sure block
3824 * is valid. This is true in both process_block and process_bad_block.
3826 static void mark_block_used(e2fsck_t ctx, blk_t block)
3828 struct problem_context pctx;
3830 clear_problem_context(&pctx);
3832 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3833 if (!ctx->block_dup_map) {
3834 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3835 _("multiply claimed block map"),
3836 &ctx->block_dup_map);
3839 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3841 /* Should never get here */
3842 ctx->flags |= E2F_FLAG_ABORT;
3846 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3848 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3853 * Adjust the extended attribute block's reference counts at the end
3854 * of pass 1, either by subtracting out references for EA blocks that
3855 * are still referenced in ctx->refcount, or by adding references for
3856 * EA blocks that had extra references as accounted for in
3857 * ctx->refcount_extra.
3859 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3860 char *block_buf, int adjust_sign)
3862 struct ext2_ext_attr_header *header;
3863 struct problem_context pctx;
3864 ext2_filsys fs = ctx->fs;
3869 clear_problem_context(&pctx);
3871 ea_refcount_intr_begin(refcount);
3873 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3876 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3878 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3881 header = (struct ext2_ext_attr_header *) block_buf;
3882 pctx.blkcount = header->h_refcount;
3883 should_be = header->h_refcount + adjust_sign * count;
3884 pctx.num = should_be;
3885 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3886 header->h_refcount = should_be;
3887 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3890 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3898 * Handle processing the extended attribute blocks
3900 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3903 ext2_filsys fs = ctx->fs;
3904 ext2_ino_t ino = pctx->ino;
3905 struct ext2_inode *inode = pctx->inode;
3908 struct ext2_ext_attr_header *header;
3909 struct ext2_ext_attr_entry *entry;
3913 blk = inode->i_file_acl;
3918 * If the Extended attribute flag isn't set, then a non-zero
3919 * file acl means that the inode is corrupted.
3921 * Or if the extended attribute block is an invalid block,
3922 * then the inode is also corrupted.
3924 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3925 (blk < fs->super->s_first_data_block) ||
3926 (blk >= fs->super->s_blocks_count)) {
3927 mark_inode_bad(ctx, ino);
3931 /* If ea bitmap hasn't been allocated, create it */
3932 if (!ctx->block_ea_map) {
3933 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3934 _("ext attr block map"),
3935 &ctx->block_ea_map);
3936 if (pctx->errcode) {
3938 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3939 ctx->flags |= E2F_FLAG_ABORT;
3944 /* Create the EA refcount structure if necessary */
3945 if (!ctx->refcount) {
3946 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3947 if (pctx->errcode) {
3949 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3950 ctx->flags |= E2F_FLAG_ABORT;
3955 /* Have we seen this EA block before? */
3956 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3957 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3959 /* Ooops, this EA was referenced more than it stated */
3960 if (!ctx->refcount_extra) {
3961 pctx->errcode = ea_refcount_create(0,
3962 &ctx->refcount_extra);
3963 if (pctx->errcode) {
3965 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3966 ctx->flags |= E2F_FLAG_ABORT;
3970 ea_refcount_increment(ctx->refcount_extra, blk, 0);
3975 * OK, we haven't seen this EA block yet. So we need to
3979 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3980 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
3982 header = (struct ext2_ext_attr_header *) block_buf;
3983 pctx->blk = inode->i_file_acl;
3984 if (((ctx->ext_attr_ver == 1) &&
3985 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
3986 ((ctx->ext_attr_ver == 2) &&
3987 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
3988 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
3992 if (header->h_blocks != 1) {
3993 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
3997 region = region_create(0, fs->blocksize);
3999 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
4000 ctx->flags |= E2F_FLAG_ABORT;
4003 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4004 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4008 entry = (struct ext2_ext_attr_entry *)(header+1);
4009 end = block_buf + fs->blocksize;
4010 while ((char *)entry < end && *(__u32 *)entry) {
4011 if (region_allocate(region, (char *)entry - (char *)header,
4012 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4013 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4016 if ((ctx->ext_attr_ver == 1 &&
4017 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4018 (ctx->ext_attr_ver == 2 &&
4019 entry->e_name_index == 0)) {
4020 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4023 if (entry->e_value_block != 0) {
4024 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4027 if (entry->e_value_size &&
4028 region_allocate(region, entry->e_value_offs,
4029 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4030 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4033 entry = EXT2_EXT_ATTR_NEXT(entry);
4035 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4036 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4039 region_free(region);
4041 count = header->h_refcount - 1;
4043 ea_refcount_store(ctx->refcount, blk, count);
4044 mark_block_used(ctx, blk);
4045 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4050 inode->i_file_acl = 0;
4051 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4055 /* Returns 1 if bad htree, 0 if OK */
4056 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4057 ext2_ino_t ino FSCK_ATTR((unused)),
4058 struct ext2_inode *inode,
4061 struct ext2_dx_root_info *root;
4062 ext2_filsys fs = ctx->fs;
4066 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4067 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4068 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4069 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4072 blk = inode->i_block[0];
4074 (blk < fs->super->s_first_data_block) ||
4075 (blk >= fs->super->s_blocks_count)) &&
4076 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4079 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4080 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4083 /* XXX should check that beginning matches a directory */
4084 root = (struct ext2_dx_root_info *) (block_buf + 24);
4086 if ((root->reserved_zero || root->info_length < 8) &&
4087 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4090 pctx->num = root->hash_version;
4091 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4092 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4093 (root->hash_version != EXT2_HASH_TEA) &&
4094 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4097 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4098 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4101 pctx->num = root->indirect_levels;
4102 if ((root->indirect_levels > 1) &&
4103 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4110 * This subroutine is called on each inode to account for all of the
4111 * blocks used by that inode.
4113 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4116 ext2_filsys fs = ctx->fs;
4117 struct process_block_struct_1 pb;
4118 ext2_ino_t ino = pctx->ino;
4119 struct ext2_inode *inode = pctx->inode;
4121 int dirty_inode = 0;
4127 pb.num_illegal_blocks = 0;
4128 pb.suppress = 0; pb.clear = 0;
4131 pb.previous_block = 0;
4132 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4133 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4134 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4141 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4142 if (fs->super->s_feature_incompat &
4143 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4146 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4147 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4153 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4156 if (ext2fs_inode_has_valid_blocks(inode))
4157 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4158 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4159 block_buf, process_block, &pb);
4160 end_problem_latch(ctx, PR_LATCH_BLOCK);
4161 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4162 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4165 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4167 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4168 ctx->fs_fragmented++;
4171 inode->i_links_count = 0;
4172 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4173 inode->i_dtime = time(0);
4175 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4176 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4177 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4179 * The inode was probably partially accounted for
4180 * before processing was aborted, so we need to
4181 * restart the pass 1 scan.
4183 ctx->flags |= E2F_FLAG_RESTART;
4187 if (inode->i_flags & EXT2_INDEX_FL) {
4188 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4189 inode->i_flags &= ~EXT2_INDEX_FL;
4193 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4197 if (ctx->dirs_to_hash && pb.is_dir &&
4198 !(inode->i_flags & EXT2_INDEX_FL) &&
4199 ((inode->i_size / fs->blocksize) >= 3))
4200 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4202 if (!pb.num_blocks && pb.is_dir) {
4203 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4204 inode->i_links_count = 0;
4205 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4206 inode->i_dtime = time(0);
4208 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4209 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4210 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4211 ctx->fs_directory_count--;
4216 pb.num_blocks *= (fs->blocksize / 512);
4219 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4220 if (nblock > (pb.last_block + 1))
4222 else if (nblock < (pb.last_block + 1)) {
4223 if (((pb.last_block + 1) - nblock) >
4224 fs->super->s_prealloc_dir_blocks)
4228 size = EXT2_I_SIZE(inode);
4229 if ((pb.last_block >= 0) &&
4230 (size < (__u64) pb.last_block * fs->blocksize))
4232 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4235 /* i_size for symlinks is checked elsewhere */
4236 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4237 pctx->num = (pb.last_block+1) * fs->blocksize;
4238 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4239 inode->i_size = pctx->num;
4240 if (!LINUX_S_ISDIR(inode->i_mode))
4241 inode->i_size_high = pctx->num >> 32;
4246 if (LINUX_S_ISREG(inode->i_mode) &&
4247 (inode->i_size_high || inode->i_size & 0x80000000UL))
4249 if (pb.num_blocks != inode->i_blocks) {
4250 pctx->num = pb.num_blocks;
4251 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4252 inode->i_blocks = pb.num_blocks;
4259 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4264 * This is a helper function for check_blocks().
4266 static int process_block(ext2_filsys fs,
4268 e2_blkcnt_t blockcnt,
4269 blk_t ref_block FSCK_ATTR((unused)),
4270 int ref_offset FSCK_ATTR((unused)),
4273 struct process_block_struct_1 *p;
4274 struct problem_context *pctx;
4275 blk_t blk = *block_nr;
4280 p = (struct process_block_struct_1 *) priv_data;
4284 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4285 /* todo: Check that the comprblk_fl is high, that the
4286 blkaddr pattern looks right (all non-holes up to
4287 first EXT2FS_COMPRESSED_BLKADDR, then all
4288 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4289 that the feature_incompat bit is high, and that the
4290 inode is a regular file. If we're doing a "full
4291 check" (a concept introduced to e2fsck by e2compr,
4292 meaning that we look at data blocks as well as
4293 metadata) then call some library routine that
4294 checks the compressed data. I'll have to think
4295 about this, because one particularly important
4296 problem to be able to fix is to recalculate the
4297 cluster size if necessary. I think that perhaps
4298 we'd better do most/all e2compr-specific checks
4299 separately, after the non-e2compr checks. If not
4300 doing a full check, it may be useful to test that
4301 the personality is linux; e.g. if it isn't then
4302 perhaps this really is just an illegal block. */
4307 if (p->is_dir == 0) {
4309 * Should never happen, since only directories
4310 * get called with BLOCK_FLAG_HOLE
4313 printf("process_block() called with blk == 0, "
4314 "blockcnt=%d, inode %lu???\n",
4321 if (blockcnt * fs->blocksize < p->inode->i_size) {
4328 * Simplistic fragmentation check. We merely require that the
4329 * file be contiguous. (Which can never be true for really
4330 * big files that are greater than a block group.)
4332 if (!HOLE_BLKADDR(p->previous_block)) {
4333 if (p->previous_block+1 != blk)
4336 p->previous_block = blk;
4338 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4339 problem = PR_1_TOOBIG_DIR;
4340 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4341 problem = PR_1_TOOBIG_REG;
4342 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4343 problem = PR_1_TOOBIG_SYMLINK;
4345 if (blk < fs->super->s_first_data_block ||
4346 blk >= fs->super->s_blocks_count)
4347 problem = PR_1_ILLEGAL_BLOCK_NUM;
4350 p->num_illegal_blocks++;
4351 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4352 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4356 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4358 set_latch_flags(PR_LATCH_BLOCK,
4363 pctx->blkcount = blockcnt;
4364 if (fix_problem(ctx, problem, pctx)) {
4365 blk = *block_nr = 0;
4366 ret_code = BLOCK_CHANGED;
4372 if (p->ino == EXT2_RESIZE_INO) {
4374 * The resize inode has already be sanity checked
4375 * during pass #0 (the superblock checks). All we
4376 * have to do is mark the double indirect block as
4377 * being in use; all of the other blocks are handled
4378 * by mark_table_blocks()).
4380 if (blockcnt == BLOCK_COUNT_DIND)
4381 mark_block_used(ctx, blk);
4383 mark_block_used(ctx, blk);
4386 p->last_block = blockcnt;
4388 if (p->is_dir && (blockcnt >= 0)) {
4389 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4391 if (pctx->errcode) {
4393 pctx->num = blockcnt;
4394 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4395 /* Should never get here */
4396 ctx->flags |= E2F_FLAG_ABORT;
4403 static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4405 e2_blkcnt_t blockcnt,
4406 blk_t ref_block FSCK_ATTR((unused)),
4407 int ref_offset FSCK_ATTR((unused)),
4408 void *priv_data EXT2FS_ATTR((unused)))
4411 * Note: This function processes blocks for the bad blocks
4412 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4415 printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4420 * This routine gets called at the end of pass 1 if bad blocks are
4421 * detected in the superblock, group descriptors, inode_bitmaps, or
4422 * block bitmaps. At this point, all of the blocks have been mapped
4423 * out, so we can try to allocate new block(s) to replace the bad
4426 static void handle_fs_bad_blocks(e2fsck_t ctx)
4428 printf("Bad blocks detected on your filesystem\n"
4429 "You should get your data off as the device will soon die\n");
4433 * This routine marks all blocks which are used by the superblock,
4434 * group descriptors, inode bitmaps, and block bitmaps.
4436 static void mark_table_blocks(e2fsck_t ctx)
4438 ext2_filsys fs = ctx->fs;
4442 struct problem_context pctx;
4444 clear_problem_context(&pctx);
4446 block = fs->super->s_first_data_block;
4447 for (i = 0; i < fs->group_desc_count; i++) {
4450 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4453 * Mark the blocks used for the inode table
4455 if (fs->group_desc[i].bg_inode_table) {
4456 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4457 j < fs->inode_blocks_per_group;
4459 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4462 if (fix_problem(ctx,
4463 PR_1_ITABLE_CONFLICT, &pctx)) {
4464 ctx->invalid_inode_table_flag[i]++;
4465 ctx->invalid_bitmaps++;
4468 ext2fs_mark_block_bitmap(ctx->block_found_map,
4475 * Mark block used for the block bitmap
4477 if (fs->group_desc[i].bg_block_bitmap) {
4478 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4479 fs->group_desc[i].bg_block_bitmap)) {
4480 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4481 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4482 ctx->invalid_block_bitmap_flag[i]++;
4483 ctx->invalid_bitmaps++;
4486 ext2fs_mark_block_bitmap(ctx->block_found_map,
4487 fs->group_desc[i].bg_block_bitmap);
4492 * Mark block used for the inode bitmap
4494 if (fs->group_desc[i].bg_inode_bitmap) {
4495 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4496 fs->group_desc[i].bg_inode_bitmap)) {
4497 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4498 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4499 ctx->invalid_inode_bitmap_flag[i]++;
4500 ctx->invalid_bitmaps++;
4503 ext2fs_mark_block_bitmap(ctx->block_found_map,
4504 fs->group_desc[i].bg_inode_bitmap);
4507 block += fs->super->s_blocks_per_group;
4512 * Thes subroutines short circuits ext2fs_get_blocks and
4513 * ext2fs_check_directory; we use them since we already have the inode
4514 * structure, so there's no point in letting the ext2fs library read
4517 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4520 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4523 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4524 return EXT2_ET_CALLBACK_NOTHANDLED;
4526 for (i=0; i < EXT2_N_BLOCKS; i++)
4527 blocks[i] = ctx->stashed_inode->i_block[i];
4531 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4532 struct ext2_inode *inode)
4534 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4536 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4537 return EXT2_ET_CALLBACK_NOTHANDLED;
4538 *inode = *ctx->stashed_inode;
4542 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4543 struct ext2_inode *inode)
4545 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4547 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4548 *ctx->stashed_inode = *inode;
4549 return EXT2_ET_CALLBACK_NOTHANDLED;
4552 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4554 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4556 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4557 return EXT2_ET_CALLBACK_NOTHANDLED;
4559 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4560 return EXT2_ET_NO_DIRECTORY;
4564 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4566 ext2_filsys fs = ctx->fs;
4569 fs->get_blocks = pass1_get_blocks;
4570 fs->check_directory = pass1_check_directory;
4571 fs->read_inode = pass1_read_inode;
4572 fs->write_inode = pass1_write_inode;
4573 ctx->stashed_ino = 0;
4576 fs->check_directory = 0;
4578 fs->write_inode = 0;
4583 * pass1b.c --- Pass #1b of e2fsck
4585 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4586 * only invoked if pass 1 discovered blocks which are in use by more
4589 * Pass1B scans the data blocks of all the inodes again, generating a
4590 * complete list of duplicate blocks and which inodes have claimed
4593 * Pass1C does a tree-traversal of the filesystem, to determine the
4594 * parent directories of these inodes. This step is necessary so that
4595 * e2fsck can print out the pathnames of affected inodes.
4597 * Pass1D is a reconciliation pass. For each inode with duplicate
4598 * blocks, the user is prompted if s/he would like to clone the file
4599 * (so that the file gets a fresh copy of the duplicated blocks) or
4600 * simply to delete the file.
4605 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4606 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4607 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4609 /* Define an extension to the ext2 library's block count information */
4610 #define BLOCK_COUNT_EXTATTR (-5)
4614 struct block_el *next;
4619 struct inode_el *next;
4624 struct inode_el *inode_list;
4628 * This structure stores information about a particular inode which
4629 * is sharing blocks with other inodes. This information is collected
4630 * to display to the user, so that the user knows what files he or she
4631 * is dealing with, when trying to decide how to resolve the conflict
4632 * of multiply-claimed blocks.
4637 struct ext2_inode inode;
4638 struct block_el *block_list;
4641 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
4642 e2_blkcnt_t blockcnt, blk_t ref_blk,
4643 int ref_offset, void *priv_data);
4644 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4645 struct dup_inode *dp, char *block_buf);
4646 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4647 struct dup_inode *dp, char* block_buf);
4648 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4650 static void pass1b(e2fsck_t ctx, char *block_buf);
4651 static void pass1c(e2fsck_t ctx, char *block_buf);
4652 static void pass1d(e2fsck_t ctx, char *block_buf);
4654 static int dup_inode_count = 0;
4656 static dict_t blk_dict, ino_dict;
4658 static ext2fs_inode_bitmap inode_dup_map;
4660 static int dict_int_cmp(const void *a, const void *b)
4671 * Add a duplicate block record
4673 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4674 struct ext2_inode *inode)
4677 struct dup_block *db;
4678 struct dup_inode *di;
4679 struct block_el *blk_el;
4680 struct inode_el *ino_el;
4682 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4684 db = (struct dup_block *) dnode_get(n);
4686 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4687 sizeof(struct dup_block), "duplicate block header");
4690 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4692 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4693 sizeof(struct inode_el), "inode element");
4694 ino_el->inode = ino;
4695 ino_el->next = db->inode_list;
4696 db->inode_list = ino_el;
4699 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4701 di = (struct dup_inode *) dnode_get(n);
4703 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4704 sizeof(struct dup_inode), "duplicate inode header");
4705 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
4706 di->num_dupblocks = 0;
4709 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4711 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4712 sizeof(struct block_el), "block element");
4713 blk_el->block = blk;
4714 blk_el->next = di->block_list;
4715 di->block_list = blk_el;
4716 di->num_dupblocks++;
4720 * Free a duplicate inode record
4722 static void inode_dnode_free(dnode_t *node)
4724 struct dup_inode *di;
4725 struct block_el *p, *next;
4727 di = (struct dup_inode *) dnode_get(node);
4728 for (p = di->block_list; p; p = next) {
4736 * Free a duplicate block record
4738 static void block_dnode_free(dnode_t *node)
4740 struct dup_block *db;
4741 struct inode_el *p, *next;
4743 db = (struct dup_block *) dnode_get(node);
4744 for (p = db->inode_list; p; p = next) {
4753 * Main procedure for handling duplicate blocks
4755 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4757 ext2_filsys fs = ctx->fs;
4758 struct problem_context pctx;
4760 clear_problem_context(&pctx);
4762 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4763 _("multiply claimed inode map"), &inode_dup_map);
4765 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4766 ctx->flags |= E2F_FLAG_ABORT;
4770 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4771 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4772 dict_set_allocator(&ino_dict, inode_dnode_free);
4773 dict_set_allocator(&blk_dict, block_dnode_free);
4775 pass1b(ctx, block_buf);
4776 pass1c(ctx, block_buf);
4777 pass1d(ctx, block_buf);
4780 * Time to free all of the accumulated data structures that we
4781 * don't need anymore.
4783 dict_free_nodes(&ino_dict);
4784 dict_free_nodes(&blk_dict);
4788 * Scan the inodes looking for inodes that contain duplicate blocks.
4790 struct process_block_struct_1b {
4794 struct ext2_inode *inode;
4795 struct problem_context *pctx;
4798 static void pass1b(e2fsck_t ctx, char *block_buf)
4800 ext2_filsys fs = ctx->fs;
4802 struct ext2_inode inode;
4803 ext2_inode_scan scan;
4804 struct process_block_struct_1b pb;
4805 struct problem_context pctx;
4807 clear_problem_context(&pctx);
4809 if (!(ctx->options & E2F_OPT_PREEN))
4810 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4811 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4814 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4815 ctx->flags |= E2F_FLAG_ABORT;
4818 ctx->stashed_inode = &inode;
4821 pctx.str = "pass1b";
4823 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4824 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4827 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4828 ctx->flags |= E2F_FLAG_ABORT;
4833 pctx.ino = ctx->stashed_ino = ino;
4834 if ((ino != EXT2_BAD_INO) &&
4835 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4842 if (ext2fs_inode_has_valid_blocks(&inode) ||
4843 (ino == EXT2_BAD_INO))
4844 pctx.errcode = ext2fs_block_iterate2(fs, ino,
4845 0, block_buf, process_pass1b_block, &pb);
4846 if (inode.i_file_acl)
4847 process_pass1b_block(fs, &inode.i_file_acl,
4848 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4849 if (pb.dup_blocks) {
4850 end_problem_latch(ctx, PR_LATCH_DBLOCK);
4851 if (ino >= EXT2_FIRST_INODE(fs->super) ||
4852 ino == EXT2_ROOT_INO)
4856 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4858 ext2fs_close_inode_scan(scan);
4859 e2fsck_use_inode_shortcuts(ctx, 0);
4862 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4864 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4865 blk_t ref_blk FSCK_ATTR((unused)),
4866 int ref_offset FSCK_ATTR((unused)),
4869 struct process_block_struct_1b *p;
4872 if (HOLE_BLKADDR(*block_nr))
4874 p = (struct process_block_struct_1b *) priv_data;
4877 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4880 /* OK, this is a duplicate block */
4881 if (p->ino != EXT2_BAD_INO) {
4882 p->pctx->blk = *block_nr;
4883 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4886 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4888 add_dupe(ctx, p->ino, *block_nr, p->inode);
4894 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4895 * is used so that we can print pathnames when prompting the user for
4898 struct search_dir_struct {
4900 ext2_ino_t first_inode;
4901 ext2_ino_t max_inode;
4904 static int search_dirent_proc(ext2_ino_t dir, int entry,
4905 struct ext2_dir_entry *dirent,
4906 int offset FSCK_ATTR((unused)),
4907 int blocksize FSCK_ATTR((unused)),
4908 char *buf FSCK_ATTR((unused)),
4911 struct search_dir_struct *sd;
4912 struct dup_inode *p;
4915 sd = (struct search_dir_struct *) priv_data;
4917 if (dirent->inode > sd->max_inode)
4918 /* Should abort this inode, but not everything */
4921 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4922 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4925 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4928 p = (struct dup_inode *) dnode_get(n);
4932 return(sd->count ? 0 : DIRENT_ABORT);
4936 static void pass1c(e2fsck_t ctx, char *block_buf)
4938 ext2_filsys fs = ctx->fs;
4939 struct search_dir_struct sd;
4940 struct problem_context pctx;
4942 clear_problem_context(&pctx);
4944 if (!(ctx->options & E2F_OPT_PREEN))
4945 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4948 * Search through all directories to translate inodes to names
4949 * (by searching for the containing directory for that inode.)
4951 sd.count = dup_inode_count;
4952 sd.first_inode = EXT2_FIRST_INODE(fs->super);
4953 sd.max_inode = fs->super->s_inodes_count;
4954 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4955 search_dirent_proc, &sd);
4958 static void pass1d(e2fsck_t ctx, char *block_buf)
4960 ext2_filsys fs = ctx->fs;
4961 struct dup_inode *p, *t;
4962 struct dup_block *q;
4963 ext2_ino_t *shared, ino;
4968 struct problem_context pctx;
4973 clear_problem_context(&pctx);
4975 if (!(ctx->options & E2F_OPT_PREEN))
4976 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
4977 e2fsck_read_bitmaps(ctx);
4979 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
4980 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
4981 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
4982 sizeof(ext2_ino_t) * dict_count(&ino_dict),
4983 "Shared inode list");
4984 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
4985 p = (struct dup_inode *) dnode_get(n);
4988 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
4989 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
4993 * Find all of the inodes which share blocks with this
4994 * one. First we find all of the duplicate blocks
4995 * belonging to this inode, and then search each block
4996 * get the list of inodes, and merge them together.
4998 for (s = p->block_list; s; s = s->next) {
4999 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5001 continue; /* Should never happen... */
5002 q = (struct dup_block *) dnode_get(m);
5005 if (check_if_fs_block(ctx, s->block)) {
5011 * Add all inodes used by this block to the
5012 * shared[] --- which is a unique list, so
5013 * if an inode is already in shared[], don't
5016 for (r = q->inode_list; r; r = r->next) {
5017 if (r->inode == ino)
5019 for (i = 0; i < shared_len; i++)
5020 if (shared[i] == r->inode)
5022 if (i == shared_len) {
5023 shared[shared_len++] = r->inode;
5029 * Report the inode that we are working on
5031 pctx.inode = &p->inode;
5034 pctx.blkcount = p->num_dupblocks;
5035 pctx.num = meta_data ? shared_len+1 : shared_len;
5036 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5041 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5043 for (i = 0; i < shared_len; i++) {
5044 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5046 continue; /* should never happen */
5047 t = (struct dup_inode *) dnode_get(m);
5049 * Report the inode that we are sharing with
5051 pctx.inode = &t->inode;
5052 pctx.ino = shared[i];
5054 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5057 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5060 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5061 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5063 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5067 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5068 delete_file(ctx, ino, p, block_buf);
5070 ext2fs_unmark_valid(fs);
5072 ext2fs_free_mem(&shared);
5076 * Drop the refcount on the dup_block structure, and clear the entry
5077 * in the block_dup_map if appropriate.
5079 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5082 if (p->num_bad <= 0 ||
5083 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5084 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5087 static int delete_file_block(ext2_filsys fs,
5089 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5090 blk_t ref_block FSCK_ATTR((unused)),
5091 int ref_offset FSCK_ATTR((unused)),
5094 struct process_block_struct_1b *pb;
5095 struct dup_block *p;
5099 pb = (struct process_block_struct_1b *) priv_data;
5102 if (HOLE_BLKADDR(*block_nr))
5105 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5106 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5108 p = (struct dup_block *) dnode_get(n);
5109 decrement_badcount(ctx, *block_nr, p);
5111 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5114 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5115 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5121 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5122 struct dup_inode *dp, char* block_buf)
5124 ext2_filsys fs = ctx->fs;
5125 struct process_block_struct_1b pb;
5126 struct ext2_inode inode;
5127 struct problem_context pctx;
5130 clear_problem_context(&pctx);
5131 pctx.ino = pb.ino = ino;
5132 pb.dup_blocks = dp->num_dupblocks;
5134 pctx.str = "delete_file";
5136 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5137 if (ext2fs_inode_has_valid_blocks(&inode))
5138 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5139 delete_file_block, &pb);
5141 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5142 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5143 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5144 if (ctx->inode_bad_map)
5145 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5146 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5148 /* Inode may have changed by block_iterate, so reread it */
5149 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5150 inode.i_links_count = 0;
5151 inode.i_dtime = time(0);
5152 if (inode.i_file_acl &&
5153 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5155 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5156 block_buf, -1, &count);
5157 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5162 pctx.blk = inode.i_file_acl;
5163 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5166 * If the count is zero, then arrange to have the
5167 * block deleted. If the block is in the block_dup_map,
5168 * also call delete_file_block since it will take care
5169 * of keeping the accounting straight.
5172 ext2fs_test_block_bitmap(ctx->block_dup_map,
5174 delete_file_block(fs, &inode.i_file_acl,
5175 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5177 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5180 struct clone_struct {
5187 static int clone_file_block(ext2_filsys fs,
5189 e2_blkcnt_t blockcnt,
5190 blk_t ref_block FSCK_ATTR((unused)),
5191 int ref_offset FSCK_ATTR((unused)),
5194 struct dup_block *p;
5197 struct clone_struct *cs = (struct clone_struct *) priv_data;
5203 if (HOLE_BLKADDR(*block_nr))
5206 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5207 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5209 p = (struct dup_block *) dnode_get(n);
5210 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5213 cs->errcode = retval;
5216 if (cs->dir && (blockcnt >= 0)) {
5217 retval = ext2fs_set_dir_block(fs->dblist,
5218 cs->dir, new_block, blockcnt);
5220 cs->errcode = retval;
5225 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5228 cs->errcode = retval;
5231 retval = io_channel_write_blk(fs->io, new_block, 1,
5234 cs->errcode = retval;
5237 decrement_badcount(ctx, *block_nr, p);
5238 *block_nr = new_block;
5239 ext2fs_mark_block_bitmap(ctx->block_found_map,
5241 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5242 return BLOCK_CHANGED;
5244 bb_error_msg(_("internal error; can't find dup_blk for %d"),
5250 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5251 struct dup_inode *dp, char* block_buf)
5253 ext2_filsys fs = ctx->fs;
5255 struct clone_struct cs;
5256 struct problem_context pctx;
5259 struct inode_el *ino_el;
5260 struct dup_block *db;
5261 struct dup_inode *di;
5263 clear_problem_context(&pctx);
5267 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5271 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5275 pctx.str = "clone_file";
5276 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5277 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5278 clone_file_block, &cs);
5279 ext2fs_mark_bb_dirty(fs);
5281 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5282 retval = pctx.errcode;
5286 bb_error_msg(_("returned from clone_file_block"));
5287 retval = cs.errcode;
5290 /* The inode may have changed on disk, so we have to re-read it */
5291 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5292 blk = dp->inode.i_file_acl;
5293 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5294 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5296 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5298 * If we cloned the EA block, find all other inodes
5299 * which refered to that EA block, and modify
5300 * them to point to the new EA block.
5302 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5303 db = (struct dup_block *) dnode_get(n);
5304 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5305 if (ino_el->inode == ino)
5307 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5308 di = (struct dup_inode *) dnode_get(n);
5309 if (di->inode.i_file_acl == blk) {
5310 di->inode.i_file_acl = dp->inode.i_file_acl;
5311 e2fsck_write_inode(ctx, ino_el->inode,
5312 &di->inode, "clone file EA");
5313 decrement_badcount(ctx, blk, db);
5319 ext2fs_free_mem(&cs.buf);
5324 * This routine returns 1 if a block overlaps with one of the superblocks,
5325 * group descriptors, inode bitmaps, or block bitmaps.
5327 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5329 ext2_filsys fs = ctx->fs;
5333 block = fs->super->s_first_data_block;
5334 for (i = 0; i < fs->group_desc_count; i++) {
5336 /* Check superblocks/block group descriptros */
5337 if (ext2fs_bg_has_super(fs, i)) {
5338 if (test_block >= block &&
5339 (test_block <= block + fs->desc_blocks))
5343 /* Check the inode table */
5344 if ((fs->group_desc[i].bg_inode_table) &&
5345 (test_block >= fs->group_desc[i].bg_inode_table) &&
5346 (test_block < (fs->group_desc[i].bg_inode_table +
5347 fs->inode_blocks_per_group)))
5350 /* Check the bitmap blocks */
5351 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5352 (test_block == fs->group_desc[i].bg_inode_bitmap))
5355 block += fs->super->s_blocks_per_group;
5360 * pass2.c --- check directory structure
5362 * Pass 2 of e2fsck iterates through all active directory inodes, and
5363 * applies to following tests to each directory entry in the directory
5364 * blocks in the inodes:
5366 * - The length of the directory entry (rec_len) should be at
5367 * least 8 bytes, and no more than the remaining space
5368 * left in the directory block.
5369 * - The length of the name in the directory entry (name_len)
5370 * should be less than (rec_len - 8).
5371 * - The inode number in the directory entry should be within
5373 * - The inode number should refer to a in-use inode.
5374 * - The first entry should be '.', and its inode should be
5375 * the inode of the directory.
5376 * - The second entry should be '..'.
5378 * To minimize disk seek time, the directory blocks are processed in
5379 * sorted order of block numbers.
5381 * Pass 2 also collects the following information:
5382 * - The inode numbers of the subdirectories for each directory.
5384 * Pass 2 relies on the following information from previous passes:
5385 * - The directory information collected in pass 1.
5386 * - The inode_used_map bitmap
5387 * - The inode_bad_map bitmap
5388 * - The inode_dir_map bitmap
5390 * Pass 2 frees the following data structures
5391 * - The inode_bad_map bitmap
5392 * - The inode_reg_map bitmap
5396 * Keeps track of how many times an inode is referenced.
5398 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5399 static int check_dir_block(ext2_filsys fs,
5400 struct ext2_db_entry *dir_blocks_info,
5402 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5403 struct problem_context *pctx);
5404 static int update_dir_block(ext2_filsys fs,
5406 e2_blkcnt_t blockcnt,
5410 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5411 static int htree_depth(struct dx_dir_info *dx_dir,
5412 struct dx_dirblock_info *dx_db);
5413 static int special_dir_block_cmp(const void *a, const void *b);
5415 struct check_dir_struct {
5417 struct problem_context pctx;
5422 static void e2fsck_pass2(e2fsck_t ctx)
5424 struct ext2_super_block *sb = ctx->fs->super;
5425 struct problem_context pctx;
5426 ext2_filsys fs = ctx->fs;
5428 struct dir_info *dir;
5429 struct check_dir_struct cd;
5430 struct dx_dir_info *dx_dir;
5431 struct dx_dirblock_info *dx_db, *dx_parent;
5437 clear_problem_context(&cd.pctx);
5441 if (!(ctx->options & E2F_OPT_PREEN))
5442 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5444 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5445 0, ctx->inode_link_info,
5447 if (cd.pctx.errcode) {
5448 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5449 ctx->flags |= E2F_FLAG_ABORT;
5452 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5453 "directory scan buffer");
5456 * Set up the parent pointer for the root directory, if
5457 * present. (If the root directory is not present, we will
5458 * create it in pass 3.)
5460 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5462 dir->parent = EXT2_ROOT_INO;
5467 cd.max = ext2fs_dblist_count(fs->dblist);
5470 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5472 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5473 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5475 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5477 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5479 if (cd.pctx.errcode) {
5480 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5481 ctx->flags |= E2F_FLAG_ABORT;
5486 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5487 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5489 if (dx_dir->numblocks == 0)
5491 clear_problem_context(&pctx);
5493 pctx.dir = dx_dir->ino;
5494 dx_db = dx_dir->dx_block;
5495 if (dx_db->flags & DX_FLAG_REFERENCED)
5496 dx_db->flags |= DX_FLAG_DUP_REF;
5498 dx_db->flags |= DX_FLAG_REFERENCED;
5500 * Find all of the first and last leaf blocks, and
5501 * update their parent's min and max hash values
5503 for (b=0, dx_db = dx_dir->dx_block;
5504 b < dx_dir->numblocks;
5506 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5507 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5509 dx_parent = &dx_dir->dx_block[dx_db->parent];
5511 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5513 if (dx_db->flags & DX_FLAG_FIRST)
5514 dx_parent->min_hash = dx_db->min_hash;
5516 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5518 if (dx_db->flags & DX_FLAG_LAST)
5519 dx_parent->max_hash = dx_db->max_hash;
5522 for (b=0, dx_db = dx_dir->dx_block;
5523 b < dx_dir->numblocks;
5526 pctx.group = dx_db->parent;
5528 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5529 (dx_db->min_hash < dx_db->node_min_hash)) {
5530 pctx.blk = dx_db->min_hash;
5531 pctx.blk2 = dx_db->node_min_hash;
5532 code = PR_2_HTREE_MIN_HASH;
5533 fix_problem(ctx, code, &pctx);
5536 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5537 depth = htree_depth(dx_dir, dx_db);
5538 if (depth != dx_dir->depth) {
5539 code = PR_2_HTREE_BAD_DEPTH;
5540 fix_problem(ctx, code, &pctx);
5545 * This test doesn't apply for the root block
5549 (dx_db->max_hash > dx_db->node_max_hash)) {
5550 pctx.blk = dx_db->max_hash;
5551 pctx.blk2 = dx_db->node_max_hash;
5552 code = PR_2_HTREE_MAX_HASH;
5553 fix_problem(ctx, code, &pctx);
5556 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5557 code = PR_2_HTREE_NOTREF;
5558 fix_problem(ctx, code, &pctx);
5560 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5561 code = PR_2_HTREE_DUPREF;
5562 fix_problem(ctx, code, &pctx);
5568 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5569 clear_htree(ctx, dx_dir->ino);
5570 dx_dir->numblocks = 0;
5574 ext2fs_free_mem(&buf);
5575 ext2fs_free_dblist(fs->dblist);
5577 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5578 ctx->inode_bad_map = 0;
5579 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5580 ctx->inode_reg_map = 0;
5582 clear_problem_context(&pctx);
5583 if (ctx->large_files) {
5584 if (!(sb->s_feature_ro_compat &
5585 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5586 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5587 sb->s_feature_ro_compat |=
5588 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5589 ext2fs_mark_super_dirty(fs);
5591 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5592 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5593 ext2fs_update_dynamic_rev(fs);
5594 ext2fs_mark_super_dirty(fs);
5596 } else if (!ctx->large_files &&
5597 (sb->s_feature_ro_compat &
5598 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5599 if (fs->flags & EXT2_FLAG_RW) {
5600 sb->s_feature_ro_compat &=
5601 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5602 ext2fs_mark_super_dirty(fs);
5608 #define MAX_DEPTH 32000
5609 static int htree_depth(struct dx_dir_info *dx_dir,
5610 struct dx_dirblock_info *dx_db)
5614 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5615 dx_db = &dx_dir->dx_block[dx_db->parent];
5621 static int dict_de_cmp(const void *a, const void *b)
5623 const struct ext2_dir_entry *de_a, *de_b;
5626 de_a = (const struct ext2_dir_entry *) a;
5627 a_len = de_a->name_len & 0xFF;
5628 de_b = (const struct ext2_dir_entry *) b;
5629 b_len = de_b->name_len & 0xFF;
5632 return (a_len - b_len);
5634 return strncmp(de_a->name, de_b->name, a_len);
5638 * This is special sort function that makes sure that directory blocks
5639 * with a dirblock of zero are sorted to the beginning of the list.
5640 * This guarantees that the root node of the htree directories are
5641 * processed first, so we know what hash version to use.
5643 static int special_dir_block_cmp(const void *a, const void *b)
5645 const struct ext2_db_entry *db_a =
5646 (const struct ext2_db_entry *) a;
5647 const struct ext2_db_entry *db_b =
5648 (const struct ext2_db_entry *) b;
5650 if (db_a->blockcnt && !db_b->blockcnt)
5653 if (!db_a->blockcnt && db_b->blockcnt)
5656 if (db_a->blk != db_b->blk)
5657 return (int) (db_a->blk - db_b->blk);
5659 if (db_a->ino != db_b->ino)
5660 return (int) (db_a->ino - db_b->ino);
5662 return (int) (db_a->blockcnt - db_b->blockcnt);
5667 * Make sure the first entry in the directory is '.', and that the
5668 * directory entry is sane.
5670 static int check_dot(e2fsck_t ctx,
5671 struct ext2_dir_entry *dirent,
5672 ext2_ino_t ino, struct problem_context *pctx)
5674 struct ext2_dir_entry *nextdir;
5681 problem = PR_2_MISSING_DOT;
5682 else if (((dirent->name_len & 0xFF) != 1) ||
5683 (dirent->name[0] != '.'))
5684 problem = PR_2_1ST_NOT_DOT;
5685 else if (dirent->name[1] != '\0')
5686 problem = PR_2_DOT_NULL_TERM;
5689 if (fix_problem(ctx, problem, pctx)) {
5690 if (dirent->rec_len < 12)
5691 dirent->rec_len = 12;
5692 dirent->inode = ino;
5693 dirent->name_len = 1;
5694 dirent->name[0] = '.';
5695 dirent->name[1] = '\0';
5700 if (dirent->inode != ino) {
5701 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5702 dirent->inode = ino;
5706 if (dirent->rec_len > 12) {
5707 new_len = dirent->rec_len - 12;
5710 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5711 nextdir = (struct ext2_dir_entry *)
5712 ((char *) dirent + 12);
5713 dirent->rec_len = 12;
5714 nextdir->rec_len = new_len;
5716 nextdir->name_len = 0;
5725 * Make sure the second entry in the directory is '..', and that the
5726 * directory entry is sane. We do not check the inode number of '..'
5727 * here; this gets done in pass 3.
5729 static int check_dotdot(e2fsck_t ctx,
5730 struct ext2_dir_entry *dirent,
5731 struct dir_info *dir, struct problem_context *pctx)
5736 problem = PR_2_MISSING_DOT_DOT;
5737 else if (((dirent->name_len & 0xFF) != 2) ||
5738 (dirent->name[0] != '.') ||
5739 (dirent->name[1] != '.'))
5740 problem = PR_2_2ND_NOT_DOT_DOT;
5741 else if (dirent->name[2] != '\0')
5742 problem = PR_2_DOT_DOT_NULL_TERM;
5745 if (fix_problem(ctx, problem, pctx)) {
5746 if (dirent->rec_len < 12)
5747 dirent->rec_len = 12;
5749 * Note: we don't have the parent inode just
5750 * yet, so we will fill it in with the root
5751 * inode. This will get fixed in pass 3.
5753 dirent->inode = EXT2_ROOT_INO;
5754 dirent->name_len = 2;
5755 dirent->name[0] = '.';
5756 dirent->name[1] = '.';
5757 dirent->name[2] = '\0';
5762 dir->dotdot = dirent->inode;
5767 * Check to make sure a directory entry doesn't contain any illegal
5770 static int check_name(e2fsck_t ctx,
5771 struct ext2_dir_entry *dirent,
5772 struct problem_context *pctx)
5778 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5779 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5781 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5784 dirent->name[i] = '.';
5793 * Check the directory filetype (if present)
5797 * Given a mode, return the ext2 file type
5799 static int ext2_file_type(unsigned int mode)
5801 if (LINUX_S_ISREG(mode))
5802 return EXT2_FT_REG_FILE;
5804 if (LINUX_S_ISDIR(mode))
5807 if (LINUX_S_ISCHR(mode))
5808 return EXT2_FT_CHRDEV;
5810 if (LINUX_S_ISBLK(mode))
5811 return EXT2_FT_BLKDEV;
5813 if (LINUX_S_ISLNK(mode))
5814 return EXT2_FT_SYMLINK;
5816 if (LINUX_S_ISFIFO(mode))
5817 return EXT2_FT_FIFO;
5819 if (LINUX_S_ISSOCK(mode))
5820 return EXT2_FT_SOCK;
5825 static int check_filetype(e2fsck_t ctx,
5826 struct ext2_dir_entry *dirent,
5827 struct problem_context *pctx)
5829 int filetype = dirent->name_len >> 8;
5830 int should_be = EXT2_FT_UNKNOWN;
5831 struct ext2_inode inode;
5833 if (!(ctx->fs->super->s_feature_incompat &
5834 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5835 if (filetype == 0 ||
5836 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5838 dirent->name_len = dirent->name_len & 0xFF;
5842 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5843 should_be = EXT2_FT_DIR;
5844 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5846 should_be = EXT2_FT_REG_FILE;
5847 } else if (ctx->inode_bad_map &&
5848 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5852 e2fsck_read_inode(ctx, dirent->inode, &inode,
5854 should_be = ext2_file_type(inode.i_mode);
5856 if (filetype == should_be)
5858 pctx->num = should_be;
5860 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5864 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5869 static void parse_int_node(ext2_filsys fs,
5870 struct ext2_db_entry *db,
5871 struct check_dir_struct *cd,
5872 struct dx_dir_info *dx_dir,
5875 struct ext2_dx_root_info *root;
5876 struct ext2_dx_entry *ent;
5877 struct ext2_dx_countlimit *limit;
5878 struct dx_dirblock_info *dx_db;
5879 int i, expect_limit, count;
5881 ext2_dirhash_t min_hash = 0xffffffff;
5882 ext2_dirhash_t max_hash = 0;
5883 ext2_dirhash_t hash = 0, prev_hash;
5885 if (db->blockcnt == 0) {
5886 root = (struct ext2_dx_root_info *) (block_buf + 24);
5887 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5889 ent = (struct ext2_dx_entry *) (block_buf+8);
5891 limit = (struct ext2_dx_countlimit *) ent;
5893 count = ext2fs_le16_to_cpu(limit->count);
5894 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5895 sizeof(struct ext2_dx_entry);
5896 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5897 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5898 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5899 goto clear_and_exit;
5901 if (count > expect_limit) {
5902 cd->pctx.num = count;
5903 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5904 goto clear_and_exit;
5905 count = expect_limit;
5908 for (i=0; i < count; i++) {
5910 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5911 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5912 /* Check to make sure the block is valid */
5913 if (blk > (blk_t) dx_dir->numblocks) {
5915 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5917 goto clear_and_exit;
5919 if (hash < prev_hash &&
5920 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5921 goto clear_and_exit;
5922 dx_db = &dx_dir->dx_block[blk];
5923 if (dx_db->flags & DX_FLAG_REFERENCED) {
5924 dx_db->flags |= DX_FLAG_DUP_REF;
5926 dx_db->flags |= DX_FLAG_REFERENCED;
5927 dx_db->parent = db->blockcnt;
5929 if (hash < min_hash)
5931 if (hash > max_hash)
5933 dx_db->node_min_hash = hash;
5935 dx_db->node_max_hash =
5936 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5938 dx_db->node_max_hash = 0xfffffffe;
5939 dx_db->flags |= DX_FLAG_LAST;
5942 dx_db->flags |= DX_FLAG_FIRST;
5944 dx_db = &dx_dir->dx_block[db->blockcnt];
5945 dx_db->min_hash = min_hash;
5946 dx_db->max_hash = max_hash;
5950 clear_htree(cd->ctx, cd->pctx.ino);
5951 dx_dir->numblocks = 0;
5953 #endif /* ENABLE_HTREE */
5956 * Given a busted directory, try to salvage it somehow.
5959 static void salvage_directory(ext2_filsys fs,
5960 struct ext2_dir_entry *dirent,
5961 struct ext2_dir_entry *prev,
5962 unsigned int *offset)
5964 char *cp = (char *) dirent;
5965 int left = fs->blocksize - *offset - dirent->rec_len;
5966 int name_len = dirent->name_len & 0xFF;
5969 * Special case of directory entry of size 8: copy what's left
5970 * of the directory block up to cover up the invalid hole.
5972 if ((left >= 12) && (dirent->rec_len == 8)) {
5973 memmove(cp, cp+8, left);
5974 memset(cp + left, 0, 8);
5978 * If the directory entry overruns the end of the directory
5979 * block, and the name is small enough to fit, then adjust the
5983 (name_len + 8 <= dirent->rec_len + left) &&
5984 dirent->inode <= fs->super->s_inodes_count &&
5985 strnlen(dirent->name, name_len) == name_len) {
5986 dirent->rec_len += left;
5990 * If the directory entry is a multiple of four, so it is
5991 * valid, let the previous directory entry absorb the invalid
5994 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
5995 prev->rec_len += dirent->rec_len;
5996 *offset += dirent->rec_len;
6000 * Default salvage method --- kill all of the directory
6001 * entries for the rest of the block. We will either try to
6002 * absorb it into the previous directory entry, or create a
6003 * new empty directory entry the rest of the directory block.
6006 prev->rec_len += fs->blocksize - *offset;
6007 *offset = fs->blocksize;
6009 dirent->rec_len = fs->blocksize - *offset;
6010 dirent->name_len = 0;
6015 static int check_dir_block(ext2_filsys fs,
6016 struct ext2_db_entry *db,
6019 struct dir_info *subdir, *dir;
6020 struct dx_dir_info *dx_dir;
6022 struct dx_dirblock_info *dx_db = 0;
6023 #endif /* ENABLE_HTREE */
6024 struct ext2_dir_entry *dirent, *prev;
6025 ext2_dirhash_t hash;
6026 unsigned int offset = 0;
6027 int dir_modified = 0;
6029 blk_t block_nr = db->blk;
6030 ext2_ino_t ino = db->ino;
6032 struct check_dir_struct *cd;
6036 struct ext2_dx_root_info *root;
6037 struct ext2_dx_countlimit *limit;
6038 static dict_t de_dict;
6039 struct problem_context pctx;
6042 cd = (struct check_dir_struct *) priv_data;
6046 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6047 return DIRENT_ABORT;
6049 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6050 return DIRENT_ABORT;
6053 * Make sure the inode is still in use (could have been
6054 * deleted in the duplicate/bad blocks pass.
6056 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6060 cd->pctx.blk = block_nr;
6061 cd->pctx.blkcount = db->blockcnt;
6063 cd->pctx.dirent = 0;
6067 if (allocate_dir_block(ctx, db, &cd->pctx))
6077 if (ctx->dirs_to_hash &&
6078 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6081 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6082 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6083 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6084 if (cd->pctx.errcode) {
6085 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6086 ctx->flags |= E2F_FLAG_ABORT;
6087 return DIRENT_ABORT;
6089 memset(buf, 0, fs->blocksize);
6092 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6093 if (dx_dir && dx_dir->numblocks) {
6094 if (db->blockcnt >= dx_dir->numblocks) {
6095 printf("XXX should never happen!!!\n");
6098 dx_db = &dx_dir->dx_block[db->blockcnt];
6099 dx_db->type = DX_DIRBLOCK_LEAF;
6100 dx_db->phys = block_nr;
6101 dx_db->min_hash = ~0;
6102 dx_db->max_hash = 0;
6104 dirent = (struct ext2_dir_entry *) buf;
6105 limit = (struct ext2_dx_countlimit *) (buf+8);
6106 if (db->blockcnt == 0) {
6107 root = (struct ext2_dx_root_info *) (buf + 24);
6108 dx_db->type = DX_DIRBLOCK_ROOT;
6109 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6110 if ((root->reserved_zero ||
6111 root->info_length < 8 ||
6112 root->indirect_levels > 1) &&
6113 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6114 clear_htree(ctx, ino);
6115 dx_dir->numblocks = 0;
6118 dx_dir->hashversion = root->hash_version;
6119 dx_dir->depth = root->indirect_levels + 1;
6120 } else if ((dirent->inode == 0) &&
6121 (dirent->rec_len == fs->blocksize) &&
6122 (dirent->name_len == 0) &&
6123 (ext2fs_le16_to_cpu(limit->limit) ==
6124 ((fs->blocksize-8) /
6125 sizeof(struct ext2_dx_entry))))
6126 dx_db->type = DX_DIRBLOCK_NODE;
6128 #endif /* ENABLE_HTREE */
6130 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6134 dirent = (struct ext2_dir_entry *) (buf + offset);
6135 cd->pctx.dirent = dirent;
6136 cd->pctx.num = offset;
6137 if (((offset + dirent->rec_len) > fs->blocksize) ||
6138 (dirent->rec_len < 12) ||
6139 ((dirent->rec_len % 4) != 0) ||
6140 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6141 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6142 salvage_directory(fs, dirent, prev, &offset);
6146 goto abort_free_dict;
6148 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6149 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6150 dirent->name_len = EXT2_NAME_LEN;
6155 if (dot_state == 0) {
6156 if (check_dot(ctx, dirent, ino, &cd->pctx))
6158 } else if (dot_state == 1) {
6159 dir = e2fsck_get_dir_info(ctx, ino);
6161 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6162 goto abort_free_dict;
6164 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6166 } else if (dirent->inode == ino) {
6167 problem = PR_2_LINK_DOT;
6168 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6178 * Make sure the inode listed is a legal one.
6180 if (((dirent->inode != EXT2_ROOT_INO) &&
6181 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6182 (dirent->inode > fs->super->s_inodes_count)) {
6183 problem = PR_2_BAD_INO;
6184 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6187 * If the inode is unused, offer to clear it.
6189 problem = PR_2_UNUSED_INODE;
6190 } else if ((dot_state > 1) &&
6191 ((dirent->name_len & 0xFF) == 1) &&
6192 (dirent->name[0] == '.')) {
6194 * If there's a '.' entry in anything other
6195 * than the first directory entry, it's a
6196 * duplicate entry that should be removed.
6198 problem = PR_2_DUP_DOT;
6199 } else if ((dot_state > 1) &&
6200 ((dirent->name_len & 0xFF) == 2) &&
6201 (dirent->name[0] == '.') &&
6202 (dirent->name[1] == '.')) {
6204 * If there's a '..' entry in anything other
6205 * than the second directory entry, it's a
6206 * duplicate entry that should be removed.
6208 problem = PR_2_DUP_DOT_DOT;
6209 } else if ((dot_state > 1) &&
6210 (dirent->inode == EXT2_ROOT_INO)) {
6212 * Don't allow links to the root directory.
6213 * We check this specially to make sure we
6214 * catch this error case even if the root
6215 * directory hasn't been created yet.
6217 problem = PR_2_LINK_ROOT;
6218 } else if ((dot_state > 1) &&
6219 (dirent->name_len & 0xFF) == 0) {
6221 * Don't allow zero-length directory names.
6223 problem = PR_2_NULL_NAME;
6227 if (fix_problem(ctx, problem, &cd->pctx)) {
6232 ext2fs_unmark_valid(fs);
6233 if (problem == PR_2_BAD_INO)
6239 * If the inode was marked as having bad fields in
6240 * pass1, process it and offer to fix/clear it.
6241 * (We wait until now so that we can display the
6242 * pathname to the user.)
6244 if (ctx->inode_bad_map &&
6245 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6247 if (e2fsck_process_bad_inode(ctx, ino,
6249 buf + fs->blocksize)) {
6254 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6255 return DIRENT_ABORT;
6258 if (check_name(ctx, dirent, &cd->pctx))
6261 if (check_filetype(ctx, dirent, &cd->pctx))
6266 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6267 (dirent->name_len & 0xFF),
6268 fs->super->s_hash_seed, &hash, 0);
6269 if (hash < dx_db->min_hash)
6270 dx_db->min_hash = hash;
6271 if (hash > dx_db->max_hash)
6272 dx_db->max_hash = hash;
6277 * If this is a directory, then mark its parent in its
6278 * dir_info structure. If the parent field is already
6279 * filled in, then this directory has more than one
6280 * hard link. We assume the first link is correct,
6281 * and ask the user if he/she wants to clear this one.
6283 if ((dot_state > 1) &&
6284 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6286 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6288 cd->pctx.ino = dirent->inode;
6289 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6290 goto abort_free_dict;
6292 if (subdir->parent) {
6293 cd->pctx.ino2 = subdir->parent;
6294 if (fix_problem(ctx, PR_2_LINK_DIR,
6302 subdir->parent = ino;
6307 } else if (dict_lookup(&de_dict, dirent)) {
6308 clear_problem_context(&pctx);
6310 pctx.dirent = dirent;
6311 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6312 if (!ctx->dirs_to_hash)
6313 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6314 if (ctx->dirs_to_hash)
6315 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6318 dict_alloc_insert(&de_dict, dirent, dirent);
6320 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6323 ctx->fs_links_count++;
6324 ctx->fs_total_count++;
6327 offset += dirent->rec_len;
6329 } while (offset < fs->blocksize);
6332 cd->pctx.dir = cd->pctx.ino;
6333 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6334 (dx_db->type == DX_DIRBLOCK_NODE))
6335 parse_int_node(fs, db, cd, dx_dir, buf);
6337 #endif /* ENABLE_HTREE */
6338 if (offset != fs->blocksize) {
6339 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6340 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6341 dirent->rec_len = cd->pctx.num;
6346 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6347 if (cd->pctx.errcode) {
6348 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6350 goto abort_free_dict;
6352 ext2fs_mark_changed(fs);
6354 dict_free_nodes(&de_dict);
6357 dict_free_nodes(&de_dict);
6358 ctx->flags |= E2F_FLAG_ABORT;
6359 return DIRENT_ABORT;
6363 * This function is called to deallocate a block, and is an interator
6364 * functioned called by deallocate inode via ext2fs_iterate_block().
6366 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6367 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6368 blk_t ref_block FSCK_ATTR((unused)),
6369 int ref_offset FSCK_ATTR((unused)),
6372 e2fsck_t ctx = (e2fsck_t) priv_data;
6374 if (HOLE_BLKADDR(*block_nr))
6376 if ((*block_nr < fs->super->s_first_data_block) ||
6377 (*block_nr >= fs->super->s_blocks_count))
6379 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6380 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6385 * This fuction deallocates an inode
6387 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6389 ext2_filsys fs = ctx->fs;
6390 struct ext2_inode inode;
6391 struct problem_context pctx;
6394 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6395 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6396 inode.i_links_count = 0;
6397 inode.i_dtime = time(0);
6398 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6399 clear_problem_context(&pctx);
6403 * Fix up the bitmaps...
6405 e2fsck_read_bitmaps(ctx);
6406 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6407 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6408 if (ctx->inode_bad_map)
6409 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6410 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6412 if (inode.i_file_acl &&
6413 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6414 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6415 block_buf, -1, &count);
6416 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6421 pctx.blk = inode.i_file_acl;
6422 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6423 ctx->flags |= E2F_FLAG_ABORT;
6427 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6429 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6431 inode.i_file_acl = 0;
6434 if (!ext2fs_inode_has_valid_blocks(&inode))
6437 if (LINUX_S_ISREG(inode.i_mode) &&
6438 (inode.i_size_high || inode.i_size & 0x80000000UL))
6441 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6442 deallocate_inode_block, ctx);
6444 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6445 ctx->flags |= E2F_FLAG_ABORT;
6451 * This fuction clears the htree flag on an inode
6453 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6455 struct ext2_inode inode;
6457 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6458 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6459 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6460 if (ctx->dirs_to_hash)
6461 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6465 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6466 ext2_ino_t ino, char *buf)
6468 ext2_filsys fs = ctx->fs;
6469 struct ext2_inode inode;
6470 int inode_modified = 0;
6472 unsigned char *frag, *fsize;
6473 struct problem_context pctx;
6476 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6478 clear_problem_context(&pctx);
6481 pctx.inode = &inode;
6483 if (inode.i_file_acl &&
6484 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6485 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6486 inode.i_file_acl = 0;
6489 * This is a special kludge to deal with long symlinks
6490 * on big endian systems. i_blocks had already been
6491 * decremented earlier in pass 1, but since i_file_acl
6492 * hadn't yet been cleared, ext2fs_read_inode()
6493 * assumed that the file was short symlink and would
6494 * not have byte swapped i_block[0]. Hence, we have
6495 * to byte-swap it here.
6497 if (LINUX_S_ISLNK(inode.i_mode) &&
6498 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6499 (inode.i_blocks == fs->blocksize >> 9))
6500 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6506 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6507 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6508 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6509 !(LINUX_S_ISSOCK(inode.i_mode)))
6510 problem = PR_2_BAD_MODE;
6511 else if (LINUX_S_ISCHR(inode.i_mode)
6512 && !e2fsck_pass1_check_device_inode(fs, &inode))
6513 problem = PR_2_BAD_CHAR_DEV;
6514 else if (LINUX_S_ISBLK(inode.i_mode)
6515 && !e2fsck_pass1_check_device_inode(fs, &inode))
6516 problem = PR_2_BAD_BLOCK_DEV;
6517 else if (LINUX_S_ISFIFO(inode.i_mode)
6518 && !e2fsck_pass1_check_device_inode(fs, &inode))
6519 problem = PR_2_BAD_FIFO;
6520 else if (LINUX_S_ISSOCK(inode.i_mode)
6521 && !e2fsck_pass1_check_device_inode(fs, &inode))
6522 problem = PR_2_BAD_SOCKET;
6523 else if (LINUX_S_ISLNK(inode.i_mode)
6524 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6525 problem = PR_2_INVALID_SYMLINK;
6529 if (fix_problem(ctx, problem, &pctx)) {
6530 deallocate_inode(ctx, ino, 0);
6531 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6539 if (inode.i_faddr) {
6540 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6547 switch (fs->super->s_creator_os) {
6549 frag = &inode.osd2.linux2.l_i_frag;
6550 fsize = &inode.osd2.linux2.l_i_fsize;
6553 frag = &inode.osd2.hurd2.h_i_frag;
6554 fsize = &inode.osd2.hurd2.h_i_fsize;
6557 frag = &inode.osd2.masix2.m_i_frag;
6558 fsize = &inode.osd2.masix2.m_i_fsize;
6563 if (frag && *frag) {
6565 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6572 if (fsize && *fsize) {
6574 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6582 if (inode.i_file_acl &&
6583 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6584 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6585 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6586 inode.i_file_acl = 0;
6591 if (inode.i_dir_acl &&
6592 LINUX_S_ISDIR(inode.i_mode)) {
6593 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6594 inode.i_dir_acl = 0;
6601 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6603 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6609 * allocate_dir_block --- this function allocates a new directory
6610 * block for a particular inode; this is done if a directory has
6611 * a "hole" in it, or if a directory has a illegal block number
6612 * that was zeroed out and now needs to be replaced.
6614 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6615 struct problem_context *pctx)
6617 ext2_filsys fs = ctx->fs;
6620 struct ext2_inode inode;
6622 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6626 * Read the inode and block bitmaps in; we'll be messing with
6629 e2fsck_read_bitmaps(ctx);
6632 * First, find a free block
6634 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6635 if (pctx->errcode) {
6636 pctx->str = "ext2fs_new_block";
6637 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6640 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6641 ext2fs_mark_block_bitmap(fs->block_map, blk);
6642 ext2fs_mark_bb_dirty(fs);
6645 * Now let's create the actual data block for the inode
6648 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6650 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6651 EXT2_ROOT_INO, &block);
6653 if (pctx->errcode) {
6654 pctx->str = "ext2fs_new_dir_block";
6655 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6659 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6660 ext2fs_free_mem(&block);
6661 if (pctx->errcode) {
6662 pctx->str = "ext2fs_write_dir_block";
6663 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6668 * Update the inode block count
6670 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6671 inode.i_blocks += fs->blocksize / 512;
6672 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6673 inode.i_size = (db->blockcnt+1) * fs->blocksize;
6674 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6677 * Finally, update the block pointers for the inode
6680 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6681 0, update_dir_block, db);
6682 if (pctx->errcode) {
6683 pctx->str = "ext2fs_block_iterate";
6684 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6692 * This is a helper function for allocate_dir_block().
6694 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6696 e2_blkcnt_t blockcnt,
6697 blk_t ref_block FSCK_ATTR((unused)),
6698 int ref_offset FSCK_ATTR((unused)),
6701 struct ext2_db_entry *db;
6703 db = (struct ext2_db_entry *) priv_data;
6704 if (db->blockcnt == (int) blockcnt) {
6705 *block_nr = db->blk;
6706 return BLOCK_CHANGED;
6712 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6714 * Pass #3 assures that all directories are connected to the
6715 * filesystem tree, using the following algorithm:
6717 * First, the root directory is checked to make sure it exists; if
6718 * not, e2fsck will offer to create a new one. It is then marked as
6721 * Then, pass3 interates over all directory inodes; for each directory
6722 * it attempts to trace up the filesystem tree, using dirinfo.parent
6723 * until it reaches a directory which has been marked "done". If it
6724 * cannot do so, then the directory must be disconnected, and e2fsck
6725 * will offer to reconnect it to /lost+found. While it is chasing
6726 * parent pointers up the filesystem tree, if pass3 sees a directory
6727 * twice, then it has detected a filesystem loop, and it will again
6728 * offer to reconnect the directory to /lost+found in to break the
6731 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6732 * reconnect inodes to /lost+found; this subroutine is also used by
6733 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6734 * is responsible for creating /lost+found if it does not exist.
6736 * Pass 3 frees the following data structures:
6737 * - The dirinfo directory information cache.
6740 static void check_root(e2fsck_t ctx);
6741 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6742 struct problem_context *pctx);
6743 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6745 static ext2fs_inode_bitmap inode_loop_detect;
6746 static ext2fs_inode_bitmap inode_done_map;
6748 static void e2fsck_pass3(e2fsck_t ctx)
6750 ext2_filsys fs = ctx->fs;
6752 struct problem_context pctx;
6753 struct dir_info *dir;
6754 unsigned long maxdirs, count;
6756 clear_problem_context(&pctx);
6760 if (!(ctx->options & E2F_OPT_PREEN))
6761 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6764 * Allocate some bitmaps to do loop detection.
6766 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6770 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6771 ctx->flags |= E2F_FLAG_ABORT;
6775 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6778 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6780 maxdirs = e2fsck_get_num_dirinfo(ctx);
6784 if ((ctx->progress)(ctx, 3, 0, maxdirs))
6787 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6788 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6790 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6792 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6793 if (check_directory(ctx, dir, &pctx))
6798 * Force the creation of /lost+found if not present
6800 if ((ctx->flags & E2F_OPT_READONLY) == 0)
6801 e2fsck_get_lost_and_found(ctx, 1);
6804 * If there are any directories that need to be indexed or
6805 * optimized, do it here.
6807 e2fsck_rehash_directories(ctx);
6810 e2fsck_free_dir_info(ctx);
6811 ext2fs_free_inode_bitmap(inode_loop_detect);
6812 inode_loop_detect = 0;
6813 ext2fs_free_inode_bitmap(inode_done_map);
6818 * This makes sure the root inode is present; if not, we ask if the
6819 * user wants us to create it. Not creating it is a fatal error.
6821 static void check_root(e2fsck_t ctx)
6823 ext2_filsys fs = ctx->fs;
6825 struct ext2_inode inode;
6827 struct problem_context pctx;
6829 clear_problem_context(&pctx);
6831 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6833 * If the root inode is not a directory, die here. The
6834 * user must have answered 'no' in pass1 when we
6835 * offered to clear it.
6837 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6839 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6840 ctx->flags |= E2F_FLAG_ABORT;
6845 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6846 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6847 ctx->flags |= E2F_FLAG_ABORT;
6851 e2fsck_read_bitmaps(ctx);
6854 * First, find a free block
6856 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6858 pctx.str = "ext2fs_new_block";
6859 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6860 ctx->flags |= E2F_FLAG_ABORT;
6863 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6864 ext2fs_mark_block_bitmap(fs->block_map, blk);
6865 ext2fs_mark_bb_dirty(fs);
6868 * Now let's create the actual data block for the inode
6870 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6873 pctx.str = "ext2fs_new_dir_block";
6874 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6875 ctx->flags |= E2F_FLAG_ABORT;
6879 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6881 pctx.str = "ext2fs_write_dir_block";
6882 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6883 ctx->flags |= E2F_FLAG_ABORT;
6886 ext2fs_free_mem(&block);
6889 * Set up the inode structure
6891 memset(&inode, 0, sizeof(inode));
6892 inode.i_mode = 040755;
6893 inode.i_size = fs->blocksize;
6894 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
6895 inode.i_links_count = 2;
6896 inode.i_blocks = fs->blocksize / 512;
6897 inode.i_block[0] = blk;
6900 * Write out the inode.
6902 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6904 pctx.str = "ext2fs_write_inode";
6905 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6906 ctx->flags |= E2F_FLAG_ABORT;
6911 * Miscellaneous bookkeeping...
6913 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6914 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6915 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6917 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6918 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6919 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6920 ext2fs_mark_ib_dirty(fs);
6924 * This subroutine is responsible for making sure that a particular
6925 * directory is connected to the root; if it isn't we trace it up as
6926 * far as we can go, and then offer to connect the resulting parent to
6927 * the lost+found. We have to do loop detection; if we ever discover
6928 * a loop, we treat that as a disconnected directory and offer to
6929 * reparent it to lost+found.
6931 * However, loop detection is expensive, because for very large
6932 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6933 * is non-trivial. Loops in filesystems are also a rare error case,
6934 * and we shouldn't optimize for error cases. So we try two passes of
6935 * the algorithm. The first time, we ignore loop detection and merely
6936 * increment a counter; if the counter exceeds some extreme threshold,
6937 * then we try again with the loop detection bitmap enabled.
6939 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6940 struct problem_context *pctx)
6942 ext2_filsys fs = ctx->fs;
6943 struct dir_info *p = dir;
6944 int loop_pass = 0, parent_count = 0;
6951 * Mark this inode as being "done"; by the time we
6952 * return from this function, the inode we either be
6953 * verified as being connected to the directory tree,
6954 * or we will have offered to reconnect this to
6957 * If it was marked done already, then we've reached a
6958 * parent we've already checked.
6960 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6964 * If this directory doesn't have a parent, or we've
6965 * seen the parent once already, then offer to
6966 * reparent it to lost+found
6970 (ext2fs_test_inode_bitmap(inode_loop_detect,
6973 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6974 if (e2fsck_reconnect_file(ctx, pctx->ino))
6975 ext2fs_unmark_valid(fs);
6977 p = e2fsck_get_dir_info(ctx, pctx->ino);
6978 p->parent = ctx->lost_and_found;
6979 fix_dotdot(ctx, p, ctx->lost_and_found);
6984 p = e2fsck_get_dir_info(ctx, p->parent);
6986 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
6990 ext2fs_mark_inode_bitmap(inode_loop_detect,
6992 } else if (parent_count++ > 2048) {
6994 * If we've run into a path depth that's
6995 * greater than 2048, try again with the inode
6996 * loop bitmap turned on and start from the
7000 if (inode_loop_detect)
7001 ext2fs_clear_inode_bitmap(inode_loop_detect);
7003 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7004 if (pctx->errcode) {
7007 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7008 ctx->flags |= E2F_FLAG_ABORT;
7017 * Make sure that .. and the parent directory are the same;
7018 * offer to fix it if not.
7020 if (dir->parent != dir->dotdot) {
7021 pctx->ino = dir->ino;
7022 pctx->ino2 = dir->dotdot;
7023 pctx->dir = dir->parent;
7024 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7025 fix_dotdot(ctx, dir, dir->parent);
7031 * This routine gets the lost_and_found inode, making it a directory
7034 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7036 ext2_filsys fs = ctx->fs;
7040 struct ext2_inode inode;
7042 static const char name[] = "lost+found";
7043 struct problem_context pctx;
7044 struct dir_info *dirinfo;
7046 if (ctx->lost_and_found)
7047 return ctx->lost_and_found;
7049 clear_problem_context(&pctx);
7051 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7052 sizeof(name)-1, 0, &ino);
7056 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7057 ctx->lost_and_found = ino;
7061 /* Lost+found isn't a directory! */
7065 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7068 /* OK, unlink the old /lost+found file. */
7069 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7071 pctx.str = "ext2fs_unlink";
7072 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7075 dirinfo = e2fsck_get_dir_info(ctx, ino);
7077 dirinfo->parent = 0;
7078 e2fsck_adjust_inode_count(ctx, ino, -1);
7079 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7080 pctx.errcode = retval;
7081 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7083 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7087 * Read the inode and block bitmaps in; we'll be messing with
7090 e2fsck_read_bitmaps(ctx);
7093 * First, find a free block
7095 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7097 pctx.errcode = retval;
7098 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7101 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7102 ext2fs_block_alloc_stats(fs, blk, +1);
7105 * Next find a free inode.
7107 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7108 ctx->inode_used_map, &ino);
7110 pctx.errcode = retval;
7111 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7114 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7115 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7116 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7119 * Now let's create the actual data block for the inode
7121 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7123 pctx.errcode = retval;
7124 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7128 retval = ext2fs_write_dir_block(fs, blk, block);
7129 ext2fs_free_mem(&block);
7131 pctx.errcode = retval;
7132 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7137 * Set up the inode structure
7139 memset(&inode, 0, sizeof(inode));
7140 inode.i_mode = 040700;
7141 inode.i_size = fs->blocksize;
7142 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7143 inode.i_links_count = 2;
7144 inode.i_blocks = fs->blocksize / 512;
7145 inode.i_block[0] = blk;
7148 * Next, write out the inode.
7150 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7152 pctx.str = "ext2fs_write_inode";
7153 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7157 * Finally, create the directory link
7159 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7161 pctx.str = "ext2fs_link";
7162 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7167 * Miscellaneous bookkeeping that needs to be kept straight.
7169 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7170 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7171 ext2fs_icount_store(ctx->inode_count, ino, 2);
7172 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7173 ctx->lost_and_found = ino;
7178 * This routine will connect a file to lost+found
7180 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7182 ext2_filsys fs = ctx->fs;
7185 struct problem_context pctx;
7186 struct ext2_inode inode;
7189 clear_problem_context(&pctx);
7192 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7193 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7194 ctx->bad_lost_and_found++;
7196 if (ctx->bad_lost_and_found) {
7197 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7201 sprintf(name, "#%u", ino);
7202 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7203 file_type = ext2_file_type(inode.i_mode);
7204 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7205 if (retval == EXT2_ET_DIR_NO_SPACE) {
7206 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7208 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7211 pctx.errcode = retval;
7212 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7215 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7219 pctx.errcode = retval;
7220 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7223 e2fsck_adjust_inode_count(ctx, ino, 1);
7229 * Utility routine to adjust the inode counts on an inode.
7231 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7233 ext2_filsys fs = ctx->fs;
7235 struct ext2_inode inode;
7240 retval = ext2fs_read_inode(fs, ino, &inode);
7245 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7246 if (inode.i_links_count == (__u16) ~0)
7248 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7249 inode.i_links_count++;
7250 } else if (adj == -1) {
7251 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7252 if (inode.i_links_count == 0)
7254 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7255 inode.i_links_count--;
7258 retval = ext2fs_write_inode(fs, ino, &inode);
7266 * Fix parent --- this routine fixes up the parent of a directory.
7268 struct fix_dotdot_struct {
7275 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7276 int offset FSCK_ATTR((unused)),
7277 int blocksize FSCK_ATTR((unused)),
7278 char *buf FSCK_ATTR((unused)),
7281 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7283 struct problem_context pctx;
7285 if ((dirent->name_len & 0xFF) != 2)
7287 if (strncmp(dirent->name, "..", 2))
7290 clear_problem_context(&pctx);
7292 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7294 pctx.errcode = retval;
7295 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7297 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7299 pctx.errcode = retval;
7300 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7302 dirent->inode = fp->parent;
7305 return DIRENT_ABORT | DIRENT_CHANGED;
7308 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7310 ext2_filsys fs = ctx->fs;
7312 struct fix_dotdot_struct fp;
7313 struct problem_context pctx;
7320 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7321 0, fix_dotdot_proc, &fp);
7322 if (retval || !fp.done) {
7323 clear_problem_context(&pctx);
7324 pctx.ino = dir->ino;
7325 pctx.errcode = retval;
7326 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7327 PR_3_FIX_PARENT_NOFIND, &pctx);
7328 ext2fs_unmark_valid(fs);
7330 dir->dotdot = parent;
7336 * These routines are responsible for expanding a /lost+found if it is
7340 struct expand_dir_struct {
7342 int guaranteed_size;
7349 static int expand_dir_proc(ext2_filsys fs,
7351 e2_blkcnt_t blockcnt,
7352 blk_t ref_block FSCK_ATTR((unused)),
7353 int ref_offset FSCK_ATTR((unused)),
7356 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7358 static blk_t last_blk = 0;
7365 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7369 es->last_block = blockcnt;
7371 last_blk = *blocknr;
7374 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7381 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7387 retval = ext2fs_write_dir_block(fs, new_blk, block);
7389 retval = ext2fs_get_mem(fs->blocksize, &block);
7394 memset(block, 0, fs->blocksize);
7395 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7401 ext2fs_free_mem(&block);
7403 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7404 ext2fs_block_alloc_stats(fs, new_blk, +1);
7408 return (BLOCK_CHANGED | BLOCK_ABORT);
7410 return BLOCK_CHANGED;
7413 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7414 int num, int guaranteed_size)
7416 ext2_filsys fs = ctx->fs;
7418 struct expand_dir_struct es;
7419 struct ext2_inode inode;
7421 if (!(fs->flags & EXT2_FLAG_RW))
7422 return EXT2_ET_RO_FILSYS;
7425 * Read the inode and block bitmaps in; we'll be messing with
7428 e2fsck_read_bitmaps(ctx);
7430 retval = ext2fs_check_directory(fs, dir);
7435 es.guaranteed_size = guaranteed_size;
7441 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7442 0, expand_dir_proc, &es);
7448 * Update the size and block count fields in the inode.
7450 retval = ext2fs_read_inode(fs, dir, &inode);
7454 inode.i_size = (es.last_block + 1) * fs->blocksize;
7455 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7457 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7463 * pass4.c -- pass #4 of e2fsck: Check reference counts
7465 * Pass 4 frees the following data structures:
7466 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7470 * This routine is called when an inode is not connected to the
7473 * This subroutine returns 1 then the caller shouldn't bother with the
7474 * rest of the pass 4 tests.
7476 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7478 ext2_filsys fs = ctx->fs;
7479 struct ext2_inode inode;
7480 struct problem_context pctx;
7482 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7483 clear_problem_context(&pctx);
7485 pctx.inode = &inode;
7488 * Offer to delete any zero-length files that does not have
7489 * blocks. If there is an EA block, it might have useful
7490 * information, so we won't prompt to delete it, but let it be
7491 * reconnected to lost+found.
7493 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7494 LINUX_S_ISDIR(inode.i_mode))) {
7495 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7496 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7497 inode.i_links_count = 0;
7498 inode.i_dtime = time(0);
7499 e2fsck_write_inode(ctx, i, &inode,
7500 "disconnect_inode");
7502 * Fix up the bitmaps...
7504 e2fsck_read_bitmaps(ctx);
7505 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7506 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7507 ext2fs_inode_alloc_stats2(fs, i, -1,
7508 LINUX_S_ISDIR(inode.i_mode));
7514 * Prompt to reconnect.
7516 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7517 if (e2fsck_reconnect_file(ctx, i))
7518 ext2fs_unmark_valid(fs);
7521 * If we don't attach the inode, then skip the
7522 * i_links_test since there's no point in trying to
7523 * force i_links_count to zero.
7525 ext2fs_unmark_valid(fs);
7532 static void e2fsck_pass4(e2fsck_t ctx)
7534 ext2_filsys fs = ctx->fs;
7536 struct ext2_inode inode;
7537 struct problem_context pctx;
7538 __u16 link_count, link_counted;
7540 int group, maxgroup;
7544 clear_problem_context(&pctx);
7546 if (!(ctx->options & E2F_OPT_PREEN))
7547 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7550 maxgroup = fs->group_desc_count;
7552 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7555 for (i=1; i <= fs->super->s_inodes_count; i++) {
7556 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7558 if ((i % fs->super->s_inodes_per_group) == 0) {
7561 if ((ctx->progress)(ctx, 4, group, maxgroup))
7564 if (i == EXT2_BAD_INO ||
7565 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7567 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7568 (ctx->inode_imagic_map &&
7569 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7571 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7572 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7573 if (link_counted == 0) {
7575 buf = e2fsck_allocate_memory(ctx,
7576 fs->blocksize, "bad_inode buffer");
7577 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7579 if (disconnect_inode(ctx, i))
7581 ext2fs_icount_fetch(ctx->inode_link_info, i,
7583 ext2fs_icount_fetch(ctx->inode_count, i,
7586 if (link_counted != link_count) {
7587 e2fsck_read_inode(ctx, i, &inode, "pass4");
7589 pctx.inode = &inode;
7590 if (link_count != inode.i_links_count) {
7591 pctx.num = link_count;
7593 PR_4_INCONSISTENT_COUNT, &pctx);
7595 pctx.num = link_counted;
7596 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7597 inode.i_links_count = link_counted;
7598 e2fsck_write_inode(ctx, i, &inode, "pass4");
7602 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7603 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7604 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7605 ctx->inode_imagic_map = 0;
7606 ext2fs_free_mem(&buf);
7610 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7613 #define NO_BLK ((blk_t) -1)
7615 static void print_bitmap_problem(e2fsck_t ctx, int problem,
7616 struct problem_context *pctx)
7619 case PR_5_BLOCK_UNUSED:
7620 if (pctx->blk == pctx->blk2)
7623 problem = PR_5_BLOCK_RANGE_UNUSED;
7625 case PR_5_BLOCK_USED:
7626 if (pctx->blk == pctx->blk2)
7629 problem = PR_5_BLOCK_RANGE_USED;
7631 case PR_5_INODE_UNUSED:
7632 if (pctx->ino == pctx->ino2)
7635 problem = PR_5_INODE_RANGE_UNUSED;
7637 case PR_5_INODE_USED:
7638 if (pctx->ino == pctx->ino2)
7641 problem = PR_5_INODE_RANGE_USED;
7644 fix_problem(ctx, problem, pctx);
7645 pctx->blk = pctx->blk2 = NO_BLK;
7646 pctx->ino = pctx->ino2 = 0;
7649 static void check_block_bitmaps(e2fsck_t ctx)
7651 ext2_filsys fs = ctx->fs;
7655 unsigned int blocks = 0;
7656 unsigned int free_blocks = 0;
7659 struct problem_context pctx;
7660 int problem, save_problem, fixit, had_problem;
7663 clear_problem_context(&pctx);
7664 free_array = (int *) e2fsck_allocate_memory(ctx,
7665 fs->group_desc_count * sizeof(int), "free block count array");
7667 if ((fs->super->s_first_data_block <
7668 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7669 (fs->super->s_blocks_count-1 >
7670 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7672 pctx.blk = fs->super->s_first_data_block;
7673 pctx.blk2 = fs->super->s_blocks_count -1;
7674 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7675 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7676 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7678 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7682 if ((fs->super->s_first_data_block <
7683 ext2fs_get_block_bitmap_start(fs->block_map)) ||
7684 (fs->super->s_blocks_count-1 >
7685 ext2fs_get_block_bitmap_end(fs->block_map))) {
7687 pctx.blk = fs->super->s_first_data_block;
7688 pctx.blk2 = fs->super->s_blocks_count -1;
7689 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7690 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7691 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7693 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7700 pctx.blk = pctx.blk2 = NO_BLK;
7701 for (i = fs->super->s_first_data_block;
7702 i < fs->super->s_blocks_count;
7704 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7705 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7707 if (actual == bitmap)
7710 if (!actual && bitmap) {
7712 * Block not used, but marked in use in the bitmap.
7714 problem = PR_5_BLOCK_UNUSED;
7717 * Block used, but not marked in use in the bitmap.
7719 problem = PR_5_BLOCK_USED;
7721 if (pctx.blk == NO_BLK) {
7722 pctx.blk = pctx.blk2 = i;
7723 save_problem = problem;
7725 if ((problem == save_problem) &&
7729 print_bitmap_problem(ctx, save_problem, &pctx);
7730 pctx.blk = pctx.blk2 = i;
7731 save_problem = problem;
7734 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7743 if ((blocks == fs->super->s_blocks_per_group) ||
7744 (i == fs->super->s_blocks_count-1)) {
7745 free_array[group] = group_free;
7750 if ((ctx->progress)(ctx, 5, group,
7751 fs->group_desc_count*2))
7755 if (pctx.blk != NO_BLK)
7756 print_bitmap_problem(ctx, save_problem, &pctx);
7758 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7761 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7764 ext2fs_free_block_bitmap(fs->block_map);
7765 retval = ext2fs_copy_bitmap(ctx->block_found_map,
7768 clear_problem_context(&pctx);
7769 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7770 ctx->flags |= E2F_FLAG_ABORT;
7773 ext2fs_set_bitmap_padding(fs->block_map);
7774 ext2fs_mark_bb_dirty(fs);
7776 /* Redo the counts */
7777 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7778 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7780 } else if (fixit == 0)
7781 ext2fs_unmark_valid(fs);
7783 for (i = 0; i < fs->group_desc_count; i++) {
7784 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7786 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7787 pctx.blk2 = free_array[i];
7789 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7791 fs->group_desc[i].bg_free_blocks_count =
7793 ext2fs_mark_super_dirty(fs);
7795 ext2fs_unmark_valid(fs);
7798 if (free_blocks != fs->super->s_free_blocks_count) {
7800 pctx.blk = fs->super->s_free_blocks_count;
7801 pctx.blk2 = free_blocks;
7803 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7804 fs->super->s_free_blocks_count = free_blocks;
7805 ext2fs_mark_super_dirty(fs);
7807 ext2fs_unmark_valid(fs);
7809 ext2fs_free_mem(&free_array);
7812 static void check_inode_bitmaps(e2fsck_t ctx)
7814 ext2_filsys fs = ctx->fs;
7816 unsigned int free_inodes = 0;
7820 unsigned int inodes = 0;
7825 struct problem_context pctx;
7826 int problem, save_problem, fixit, had_problem;
7828 clear_problem_context(&pctx);
7829 free_array = (int *) e2fsck_allocate_memory(ctx,
7830 fs->group_desc_count * sizeof(int), "free inode count array");
7832 dir_array = (int *) e2fsck_allocate_memory(ctx,
7833 fs->group_desc_count * sizeof(int), "directory count array");
7835 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7836 (fs->super->s_inodes_count >
7837 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7840 pctx.blk2 = fs->super->s_inodes_count;
7841 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7842 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7843 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7845 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7848 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7849 (fs->super->s_inodes_count >
7850 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7853 pctx.blk2 = fs->super->s_inodes_count;
7854 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7855 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7856 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7858 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7865 pctx.ino = pctx.ino2 = 0;
7866 for (i = 1; i <= fs->super->s_inodes_count; i++) {
7867 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7868 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7870 if (actual == bitmap)
7873 if (!actual && bitmap) {
7875 * Inode wasn't used, but marked in bitmap
7877 problem = PR_5_INODE_UNUSED;
7878 } else /* if (actual && !bitmap) */ {
7880 * Inode used, but not in bitmap
7882 problem = PR_5_INODE_USED;
7884 if (pctx.ino == 0) {
7885 pctx.ino = pctx.ino2 = i;
7886 save_problem = problem;
7888 if ((problem == save_problem) &&
7892 print_bitmap_problem(ctx, save_problem, &pctx);
7893 pctx.ino = pctx.ino2 = i;
7894 save_problem = problem;
7897 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7905 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7909 if ((inodes == fs->super->s_inodes_per_group) ||
7910 (i == fs->super->s_inodes_count)) {
7911 free_array[group] = group_free;
7912 dir_array[group] = dirs_count;
7918 if ((ctx->progress)(ctx, 5,
7919 group + fs->group_desc_count,
7920 fs->group_desc_count*2))
7925 print_bitmap_problem(ctx, save_problem, &pctx);
7928 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7931 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7934 ext2fs_free_inode_bitmap(fs->inode_map);
7935 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7938 clear_problem_context(&pctx);
7939 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7940 ctx->flags |= E2F_FLAG_ABORT;
7943 ext2fs_set_bitmap_padding(fs->inode_map);
7944 ext2fs_mark_ib_dirty(fs);
7947 inodes = 0; free_inodes = 0; group_free = 0;
7948 dirs_count = 0; group = 0;
7949 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7950 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7952 } else if (fixit == 0)
7953 ext2fs_unmark_valid(fs);
7955 for (i = 0; i < fs->group_desc_count; i++) {
7956 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7958 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7959 pctx.ino2 = free_array[i];
7960 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7962 fs->group_desc[i].bg_free_inodes_count =
7964 ext2fs_mark_super_dirty(fs);
7966 ext2fs_unmark_valid(fs);
7968 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7970 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7971 pctx.ino2 = dir_array[i];
7973 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7975 fs->group_desc[i].bg_used_dirs_count =
7977 ext2fs_mark_super_dirty(fs);
7979 ext2fs_unmark_valid(fs);
7982 if (free_inodes != fs->super->s_free_inodes_count) {
7984 pctx.ino = fs->super->s_free_inodes_count;
7985 pctx.ino2 = free_inodes;
7987 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
7988 fs->super->s_free_inodes_count = free_inodes;
7989 ext2fs_mark_super_dirty(fs);
7991 ext2fs_unmark_valid(fs);
7993 ext2fs_free_mem(&free_array);
7994 ext2fs_free_mem(&dir_array);
7997 static void check_inode_end(e2fsck_t ctx)
7999 ext2_filsys fs = ctx->fs;
8000 ext2_ino_t end, save_inodes_count, i;
8001 struct problem_context pctx;
8003 clear_problem_context(&pctx);
8005 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8006 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8007 &save_inodes_count);
8010 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8011 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8014 if (save_inodes_count == end)
8017 for (i = save_inodes_count + 1; i <= end; i++) {
8018 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8019 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8020 for (i = save_inodes_count + 1; i <= end; i++)
8021 ext2fs_mark_inode_bitmap(fs->inode_map,
8023 ext2fs_mark_ib_dirty(fs);
8025 ext2fs_unmark_valid(fs);
8030 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8031 save_inodes_count, 0);
8034 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8035 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8040 static void check_block_end(e2fsck_t ctx)
8042 ext2_filsys fs = ctx->fs;
8043 blk_t end, save_blocks_count, i;
8044 struct problem_context pctx;
8046 clear_problem_context(&pctx);
8048 end = fs->block_map->start +
8049 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8050 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8051 &save_blocks_count);
8054 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8055 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8058 if (save_blocks_count == end)
8061 for (i = save_blocks_count + 1; i <= end; i++) {
8062 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8063 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8064 for (i = save_blocks_count + 1; i <= end; i++)
8065 ext2fs_mark_block_bitmap(fs->block_map,
8067 ext2fs_mark_bb_dirty(fs);
8069 ext2fs_unmark_valid(fs);
8074 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8075 save_blocks_count, 0);
8078 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8079 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8084 static void e2fsck_pass5(e2fsck_t ctx)
8086 struct problem_context pctx;
8090 clear_problem_context(&pctx);
8092 if (!(ctx->options & E2F_OPT_PREEN))
8093 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8096 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8099 e2fsck_read_bitmaps(ctx);
8101 check_block_bitmaps(ctx);
8102 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8104 check_inode_bitmaps(ctx);
8105 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8107 check_inode_end(ctx);
8108 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8110 check_block_end(ctx);
8111 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8114 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8115 ctx->inode_used_map = 0;
8116 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8117 ctx->inode_dir_map = 0;
8118 ext2fs_free_block_bitmap(ctx->block_found_map);
8119 ctx->block_found_map = 0;
8123 * problem.c --- report filesystem problems to the user
8126 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8127 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8128 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8129 #define PR_MSG_ONLY 0x000008 /* Print message only */
8131 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8133 #define PR_FATAL 0x001000 /* Fatal error */
8134 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8136 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8137 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8138 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8139 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8140 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8143 #define PROMPT_NONE 0
8144 #define PROMPT_FIX 1
8145 #define PROMPT_CLEAR 2
8146 #define PROMPT_RELOCATE 3
8147 #define PROMPT_ALLOCATE 4
8148 #define PROMPT_EXPAND 5
8149 #define PROMPT_CONNECT 6
8150 #define PROMPT_CREATE 7
8151 #define PROMPT_SALVAGE 8
8152 #define PROMPT_TRUNCATE 9
8153 #define PROMPT_CLEAR_INODE 10
8154 #define PROMPT_ABORT 11
8155 #define PROMPT_SPLIT 12
8156 #define PROMPT_CONTINUE 13
8157 #define PROMPT_CLONE 14
8158 #define PROMPT_DELETE 15
8159 #define PROMPT_SUPPRESS 16
8160 #define PROMPT_UNLINK 17
8161 #define PROMPT_CLEAR_HTREE 18
8162 #define PROMPT_RECREATE 19
8163 #define PROMPT_NULL 20
8165 struct e2fsck_problem {
8167 const char * e2p_description;
8170 problem_t second_code;
8173 struct latch_descr {
8176 problem_t end_message;
8181 * These are the prompts which are used to ask the user if they want
8184 static const char * const prompt[] = {
8185 N_("(no prompt)"), /* 0 */
8187 N_("Clear"), /* 2 */
8188 N_("Relocate"), /* 3 */
8189 N_("Allocate"), /* 4 */
8190 N_("Expand"), /* 5 */
8191 N_("Connect to /lost+found"), /* 6 */
8192 N_("Create"), /* 7 */
8193 N_("Salvage"), /* 8 */
8194 N_("Truncate"), /* 9 */
8195 N_("Clear inode"), /* 10 */
8196 N_("Abort"), /* 11 */
8197 N_("Split"), /* 12 */
8198 N_("Continue"), /* 13 */
8199 N_("Clone multiply-claimed blocks"), /* 14 */
8200 N_("Delete file"), /* 15 */
8201 N_("Suppress messages"),/* 16 */
8202 N_("Unlink"), /* 17 */
8203 N_("Clear HTree index"),/* 18 */
8204 N_("Recreate"), /* 19 */
8209 * These messages are printed when we are preen mode and we will be
8210 * automatically fixing the problem.
8212 static const char * const preen_msg[] = {
8213 N_("(NONE)"), /* 0 */
8214 N_("FIXED"), /* 1 */
8215 N_("CLEARED"), /* 2 */
8216 N_("RELOCATED"), /* 3 */
8217 N_("ALLOCATED"), /* 4 */
8218 N_("EXPANDED"), /* 5 */
8219 N_("RECONNECTED"), /* 6 */
8220 N_("CREATED"), /* 7 */
8221 N_("SALVAGED"), /* 8 */
8222 N_("TRUNCATED"), /* 9 */
8223 N_("INODE CLEARED"), /* 10 */
8224 N_("ABORTED"), /* 11 */
8225 N_("SPLIT"), /* 12 */
8226 N_("CONTINUING"), /* 13 */
8227 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8228 N_("FILE DELETED"), /* 15 */
8229 N_("SUPPRESSED"), /* 16 */
8230 N_("UNLINKED"), /* 17 */
8231 N_("HTREE INDEX CLEARED"),/* 18 */
8232 N_("WILL RECREATE"), /* 19 */
8236 static const struct e2fsck_problem problem_table[] = {
8238 /* Pre-Pass 1 errors */
8240 /* Block bitmap not in group */
8241 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8242 PROMPT_RELOCATE, PR_LATCH_RELOC },
8244 /* Inode bitmap not in group */
8245 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8246 PROMPT_RELOCATE, PR_LATCH_RELOC },
8248 /* Inode table not in group */
8249 { PR_0_ITABLE_NOT_GROUP,
8250 N_("@i table for @g %g is not in @g. (@b %b)\n"
8251 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8252 PROMPT_RELOCATE, PR_LATCH_RELOC },
8254 /* Superblock corrupt */
8256 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8257 "@f. If the @v is valid and it really contains an ext2\n"
8258 "@f (and not swap or ufs or something else), then the @S\n"
8259 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8260 " e2fsck -b %S <@v>\n\n"),
8261 PROMPT_NONE, PR_FATAL },
8263 /* Filesystem size is wrong */
8264 { PR_0_FS_SIZE_WRONG,
8265 N_("The @f size (according to the @S) is %b @bs\n"
8266 "The physical size of the @v is %c @bs\n"
8267 "Either the @S or the partition table is likely to be corrupt!\n"),
8270 /* Fragments not supported */
8271 { PR_0_NO_FRAGMENTS,
8272 N_("@S @b_size = %b, fragsize = %c.\n"
8273 "This version of e2fsck does not support fragment sizes different\n"
8274 "from the @b size.\n"),
8275 PROMPT_NONE, PR_FATAL },
8277 /* Bad blocks_per_group */
8278 { PR_0_BLOCKS_PER_GROUP,
8279 N_("@S @bs_per_group = %b, should have been %c\n"),
8280 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8282 /* Bad first_data_block */
8283 { PR_0_FIRST_DATA_BLOCK,
8284 N_("@S first_data_@b = %b, should have been %c\n"),
8285 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8287 /* Adding UUID to filesystem */
8289 N_("@f did not have a UUID; generating one.\n\n"),
8293 { PR_0_RELOCATE_HINT,
8294 N_("Note: if several inode or block bitmap blocks or part\n"
8295 "of the inode table require relocation, you may wish to try\n"
8296 "running e2fsck with the '-b %S' option first. The problem\n"
8297 "may lie only with the primary block group descriptors, and\n"
8298 "the backup block group descriptors may be OK.\n\n"),
8299 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8301 /* Miscellaneous superblock corruption */
8302 { PR_0_MISC_CORRUPT_SUPER,
8303 N_("Corruption found in @S. (%s = %N).\n"),
8304 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8306 /* Error determing physical device size of filesystem */
8307 { PR_0_GETSIZE_ERROR,
8308 N_("Error determining size of the physical @v: %m\n"),
8309 PROMPT_NONE, PR_FATAL },
8311 /* Inode count in superblock is incorrect */
8312 { PR_0_INODE_COUNT_WRONG,
8313 N_("@i count in @S is %i, @s %j.\n"),
8316 { PR_0_HURD_CLEAR_FILETYPE,
8317 N_("The Hurd does not support the filetype feature.\n"),
8320 /* Journal inode is invalid */
8321 { PR_0_JOURNAL_BAD_INODE,
8322 N_("@S has an @n ext3 @j (@i %i).\n"),
8323 PROMPT_CLEAR, PR_PREEN_OK },
8325 /* The external journal has (unsupported) multiple filesystems */
8326 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8327 N_("External @j has multiple @f users (unsupported).\n"),
8328 PROMPT_NONE, PR_FATAL },
8330 /* Can't find external journal */
8331 { PR_0_CANT_FIND_JOURNAL,
8332 N_("Can't find external @j\n"),
8333 PROMPT_NONE, PR_FATAL },
8335 /* External journal has bad superblock */
8336 { PR_0_EXT_JOURNAL_BAD_SUPER,
8337 N_("External @j has bad @S\n"),
8338 PROMPT_NONE, PR_FATAL },
8340 /* Superblock has a bad journal UUID */
8341 { PR_0_JOURNAL_BAD_UUID,
8342 N_("External @j does not support this @f\n"),
8343 PROMPT_NONE, PR_FATAL },
8345 /* Journal has an unknown superblock type */
8346 { PR_0_JOURNAL_UNSUPP_SUPER,
8347 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8348 "It is likely that your copy of e2fsck is old and/or doesn't "
8349 "support this @j format.\n"
8350 "It is also possible the @j @S is corrupt.\n"),
8351 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8353 /* Journal superblock is corrupt */
8354 { PR_0_JOURNAL_BAD_SUPER,
8355 N_("Ext3 @j @S is corrupt.\n"),
8356 PROMPT_FIX, PR_PREEN_OK },
8358 /* Superblock flag should be cleared */
8359 { PR_0_JOURNAL_HAS_JOURNAL,
8360 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8361 PROMPT_CLEAR, PR_PREEN_OK },
8363 /* Superblock flag is incorrect */
8364 { PR_0_JOURNAL_RECOVER_SET,
8365 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8366 PROMPT_CLEAR, PR_PREEN_OK },
8368 /* Journal has data, but recovery flag is clear */
8369 { PR_0_JOURNAL_RECOVERY_CLEAR,
8370 N_("ext3 recovery flag is clear, but @j has data.\n"),
8373 /* Ask if we should clear the journal */
8374 { PR_0_JOURNAL_RESET_JOURNAL,
8376 PROMPT_NULL, PR_PREEN_NOMSG },
8378 /* Ask if we should run the journal anyway */
8380 N_("Run @j anyway"),
8383 /* Run the journal by default */
8384 { PR_0_JOURNAL_RUN_DEFAULT,
8385 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8388 /* Clearing orphan inode */
8389 { PR_0_ORPHAN_CLEAR_INODE,
8390 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8393 /* Illegal block found in orphaned inode */
8394 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8395 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8398 /* Already cleared block found in orphaned inode */
8399 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8400 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8403 /* Illegal orphan inode in superblock */
8404 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8405 N_("@I @o @i %i in @S.\n"),
8408 /* Illegal inode in orphaned inode list */
8409 { PR_0_ORPHAN_ILLEGAL_INODE,
8410 N_("@I @i %i in @o @i list.\n"),
8413 /* Filesystem revision is 0, but feature flags are set */
8414 { PR_0_FS_REV_LEVEL,
8415 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8416 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8418 /* Journal superblock has an unknown read-only feature flag set */
8419 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8420 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8423 /* Journal superblock has an unknown incompatible feature flag set */
8424 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8425 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8428 /* Journal has unsupported version number */
8429 { PR_0_JOURNAL_UNSUPP_VERSION,
8430 N_("@j version not supported by this e2fsck.\n"),
8433 /* Moving journal to hidden file */
8434 { PR_0_MOVE_JOURNAL,
8435 N_("Moving @j from /%s to hidden @i.\n\n"),
8438 /* Error moving journal to hidden file */
8439 { PR_0_ERR_MOVE_JOURNAL,
8440 N_("Error moving @j: %m\n\n"),
8443 /* Clearing V2 journal superblock */
8444 { PR_0_CLEAR_V2_JOURNAL,
8445 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8446 "Clearing fields beyond the V1 @j @S...\n\n"),
8449 /* Backup journal inode blocks */
8451 N_("Backing up @j @i @b information.\n\n"),
8454 /* Reserved blocks w/o resize_inode */
8455 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8456 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8457 "is %N; @s zero. "),
8460 /* Resize_inode not enabled, but resize inode is non-zero */
8461 { PR_0_CLEAR_RESIZE_INODE,
8462 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8465 /* Resize inode invalid */
8466 { PR_0_RESIZE_INODE_INVALID,
8467 N_("Resize @i not valid. "),
8468 PROMPT_RECREATE, 0 },
8472 /* Pass 1: Checking inodes, blocks, and sizes */
8474 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8477 /* Root directory is not an inode */
8478 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8481 /* Root directory has dtime set */
8483 N_("@r has dtime set (probably due to old mke2fs). "),
8484 PROMPT_FIX, PR_PREEN_OK },
8486 /* Reserved inode has bad mode */
8487 { PR_1_RESERVED_BAD_MODE,
8488 N_("Reserved @i %i (%Q) has @n mode. "),
8489 PROMPT_CLEAR, PR_PREEN_OK },
8491 /* Deleted inode has zero dtime */
8493 N_("@D @i %i has zero dtime. "),
8494 PROMPT_FIX, PR_PREEN_OK },
8496 /* Inode in use, but dtime set */
8498 N_("@i %i is in use, but has dtime set. "),
8499 PROMPT_FIX, PR_PREEN_OK },
8501 /* Zero-length directory */
8502 { PR_1_ZERO_LENGTH_DIR,
8503 N_("@i %i is a @z @d. "),
8504 PROMPT_CLEAR, PR_PREEN_OK },
8506 /* Block bitmap conflicts with some other fs block */
8508 N_("@g %g's @b @B at %b @C.\n"),
8509 PROMPT_RELOCATE, 0 },
8511 /* Inode bitmap conflicts with some other fs block */
8513 N_("@g %g's @i @B at %b @C.\n"),
8514 PROMPT_RELOCATE, 0 },
8516 /* Inode table conflicts with some other fs block */
8517 { PR_1_ITABLE_CONFLICT,
8518 N_("@g %g's @i table at %b @C.\n"),
8519 PROMPT_RELOCATE, 0 },
8521 /* Block bitmap is on a bad block */
8522 { PR_1_BB_BAD_BLOCK,
8523 N_("@g %g's @b @B (%b) is bad. "),
8524 PROMPT_RELOCATE, 0 },
8526 /* Inode bitmap is on a bad block */
8527 { PR_1_IB_BAD_BLOCK,
8528 N_("@g %g's @i @B (%b) is bad. "),
8529 PROMPT_RELOCATE, 0 },
8531 /* Inode has incorrect i_size */
8533 N_("@i %i, i_size is %Is, @s %N. "),
8534 PROMPT_FIX, PR_PREEN_OK },
8536 /* Inode has incorrect i_blocks */
8537 { PR_1_BAD_I_BLOCKS,
8538 N_("@i %i, i_@bs is %Ib, @s %N. "),
8539 PROMPT_FIX, PR_PREEN_OK },
8541 /* Illegal blocknumber in inode */
8542 { PR_1_ILLEGAL_BLOCK_NUM,
8543 N_("@I @b #%B (%b) in @i %i. "),
8544 PROMPT_CLEAR, PR_LATCH_BLOCK },
8546 /* Block number overlaps fs metadata */
8547 { PR_1_BLOCK_OVERLAPS_METADATA,
8548 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8549 PROMPT_CLEAR, PR_LATCH_BLOCK },
8551 /* Inode has illegal blocks (latch question) */
8552 { PR_1_INODE_BLOCK_LATCH,
8553 N_("@i %i has illegal @b(s). "),
8556 /* Too many bad blocks in inode */
8557 { PR_1_TOO_MANY_BAD_BLOCKS,
8558 N_("Too many illegal @bs in @i %i.\n"),
8559 PROMPT_CLEAR_INODE, PR_NO_OK },
8561 /* Illegal block number in bad block inode */
8562 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8563 N_("@I @b #%B (%b) in bad @b @i. "),
8564 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8566 /* Bad block inode has illegal blocks (latch question) */
8567 { PR_1_INODE_BBLOCK_LATCH,
8568 N_("Bad @b @i has illegal @b(s). "),
8571 /* Duplicate or bad blocks in use! */
8572 { PR_1_DUP_BLOCKS_PREENSTOP,
8573 N_("Duplicate or bad @b in use!\n"),
8576 /* Bad block used as bad block indirect block */
8577 { PR_1_BBINODE_BAD_METABLOCK,
8578 N_("Bad @b %b used as bad @b @i indirect @b. "),
8579 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8581 /* Inconsistency can't be fixed prompt */
8582 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8583 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8584 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8586 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8588 /* Bad primary block */
8589 { PR_1_BAD_PRIMARY_BLOCK,
8590 N_("\nIf the @b is really bad, the @f cannot be fixed.\n"),
8591 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8593 /* Bad primary block prompt */
8594 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8595 N_("You can remove this @b from the bad @b list and hope\n"
8596 "that the @b is really OK. But there are no guarantees.\n\n"),
8597 PROMPT_CLEAR, PR_PREEN_NOMSG },
8599 /* Bad primary superblock */
8600 { PR_1_BAD_PRIMARY_SUPERBLOCK,
8601 N_("The primary @S (%b) is on the bad @b list.\n"),
8602 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8604 /* Bad primary block group descriptors */
8605 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8606 N_("Block %b in the primary @g descriptors "
8607 "is on the bad @b list\n"),
8608 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8610 /* Bad superblock in group */
8611 { PR_1_BAD_SUPERBLOCK,
8612 N_("Warning: Group %g's @S (%b) is bad.\n"),
8613 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8615 /* Bad block group descriptors in group */
8616 { PR_1_BAD_GROUP_DESCRIPTORS,
8617 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8619 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8621 /* Block claimed for no reason */
8622 { PR_1_PROGERR_CLAIMED_BLOCK,
8623 N_("Programming error? @b #%b claimed for no reason in "
8624 "process_bad_@b.\n"),
8625 PROMPT_NONE, PR_PREEN_OK },
8627 /* Error allocating blocks for relocating metadata */
8628 { PR_1_RELOC_BLOCK_ALLOCATE,
8629 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8630 PROMPT_NONE, PR_PREEN_OK },
8632 /* Error allocating block buffer during relocation process */
8633 { PR_1_RELOC_MEMORY_ALLOCATE,
8634 N_("@A @b buffer for relocating %s\n"),
8635 PROMPT_NONE, PR_PREEN_OK },
8637 /* Relocating metadata group information from X to Y */
8638 { PR_1_RELOC_FROM_TO,
8639 N_("Relocating @g %g's %s from %b to %c...\n"),
8640 PROMPT_NONE, PR_PREEN_OK },
8642 /* Relocating metatdata group information to X */
8644 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8645 PROMPT_NONE, PR_PREEN_OK },
8647 /* Block read error during relocation process */
8648 { PR_1_RELOC_READ_ERR,
8649 N_("Warning: could not read @b %b of %s: %m\n"),
8650 PROMPT_NONE, PR_PREEN_OK },
8652 /* Block write error during relocation process */
8653 { PR_1_RELOC_WRITE_ERR,
8654 N_("Warning: could not write @b %b for %s: %m\n"),
8655 PROMPT_NONE, PR_PREEN_OK },
8657 /* Error allocating inode bitmap */
8658 { PR_1_ALLOCATE_IBITMAP_ERROR,
8659 N_("@A @i @B (%N): %m\n"),
8660 PROMPT_NONE, PR_FATAL },
8662 /* Error allocating block bitmap */
8663 { PR_1_ALLOCATE_BBITMAP_ERROR,
8664 N_("@A @b @B (%N): %m\n"),
8665 PROMPT_NONE, PR_FATAL },
8667 /* Error allocating icount structure */
8668 { PR_1_ALLOCATE_ICOUNT,
8669 N_("@A icount link information: %m\n"),
8670 PROMPT_NONE, PR_FATAL },
8672 /* Error allocating dbcount */
8673 { PR_1_ALLOCATE_DBCOUNT,
8674 N_("@A @d @b array: %m\n"),
8675 PROMPT_NONE, PR_FATAL },
8677 /* Error while scanning inodes */
8679 N_("Error while scanning @is (%i): %m\n"),
8680 PROMPT_NONE, PR_FATAL },
8682 /* Error while iterating over blocks */
8683 { PR_1_BLOCK_ITERATE,
8684 N_("Error while iterating over @bs in @i %i: %m\n"),
8685 PROMPT_NONE, PR_FATAL },
8687 /* Error while storing inode count information */
8688 { PR_1_ICOUNT_STORE,
8689 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8690 PROMPT_NONE, PR_FATAL },
8692 /* Error while storing directory block information */
8694 N_("Error storing @d @b information "
8695 "(@i=%i, @b=%b, num=%N): %m\n"),
8696 PROMPT_NONE, PR_FATAL },
8698 /* Error while reading inode (for clearing) */
8700 N_("Error reading @i %i: %m\n"),
8701 PROMPT_NONE, PR_FATAL },
8703 /* Suppress messages prompt */
8704 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8706 /* Imagic flag set on an inode when filesystem doesn't support it */
8708 N_("@i %i has imagic flag set. "),
8711 /* Immutable flag set on a device or socket inode */
8712 { PR_1_SET_IMMUTABLE,
8713 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8714 "or append-only flag set. "),
8715 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8717 /* Compression flag set on an inode when filesystem doesn't support it */
8719 N_("@i %i has @cion flag set on @f without @cion support. "),
8722 /* Non-zero size for device, fifo or socket inode */
8723 { PR_1_SET_NONZSIZE,
8724 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8725 PROMPT_FIX, PR_PREEN_OK },
8727 /* Filesystem revision is 0, but feature flags are set */
8728 { PR_1_FS_REV_LEVEL,
8729 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8730 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8732 /* Journal inode is not in use, but contains data */
8733 { PR_1_JOURNAL_INODE_NOT_CLEAR,
8734 N_("@j @i is not in use, but contains data. "),
8735 PROMPT_CLEAR, PR_PREEN_OK },
8737 /* Journal has bad mode */
8738 { PR_1_JOURNAL_BAD_MODE,
8739 N_("@j is not regular file. "),
8740 PROMPT_FIX, PR_PREEN_OK },
8742 /* Deal with inodes that were part of orphan linked list */
8744 N_("@i %i was part of the @o @i list. "),
8745 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8747 /* Deal with inodes that were part of corrupted orphan linked
8748 list (latch question) */
8749 { PR_1_ORPHAN_LIST_REFUGEES,
8750 N_("@is that were part of a corrupted orphan linked list found. "),
8753 /* Error allocating refcount structure */
8754 { PR_1_ALLOCATE_REFCOUNT,
8755 N_("@A refcount structure (%N): %m\n"),
8756 PROMPT_NONE, PR_FATAL },
8758 /* Error reading extended attribute block */
8759 { PR_1_READ_EA_BLOCK,
8760 N_("Error reading @a @b %b for @i %i. "),
8763 /* Invalid extended attribute block */
8764 { PR_1_BAD_EA_BLOCK,
8765 N_("@i %i has a bad @a @b %b. "),
8768 /* Error reading Extended Attribute block while fixing refcount */
8769 { PR_1_EXTATTR_READ_ABORT,
8770 N_("Error reading @a @b %b (%m). "),
8773 /* Extended attribute reference count incorrect */
8774 { PR_1_EXTATTR_REFCOUNT,
8775 N_("@a @b %b has reference count %B, @s %N. "),
8778 /* Error writing Extended Attribute block while fixing refcount */
8779 { PR_1_EXTATTR_WRITE,
8780 N_("Error writing @a @b %b (%m). "),
8783 /* Multiple EA blocks not supported */
8784 { PR_1_EA_MULTI_BLOCK,
8785 N_("@a @b %b has h_@bs > 1. "),
8788 /* Error allocating EA region allocation structure */
8789 { PR_1_EA_ALLOC_REGION,
8790 N_("@A @a @b %b. "),
8793 /* Error EA allocation collision */
8794 { PR_1_EA_ALLOC_COLLISION,
8795 N_("@a @b %b is corrupt (allocation collision). "),
8798 /* Bad extended attribute name */
8800 N_("@a @b %b is corrupt (@n name). "),
8803 /* Bad extended attribute value */
8804 { PR_1_EA_BAD_VALUE,
8805 N_("@a @b %b is corrupt (@n value). "),
8808 /* Inode too big (latch question) */
8809 { PR_1_INODE_TOOBIG,
8810 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
8812 /* Directory too big */
8814 N_("@b #%B (%b) causes @d to be too big. "),
8815 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8817 /* Regular file too big */
8819 N_("@b #%B (%b) causes file to be too big. "),
8820 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8822 /* Symlink too big */
8823 { PR_1_TOOBIG_SYMLINK,
8824 N_("@b #%B (%b) causes symlink to be too big. "),
8825 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8827 /* INDEX_FL flag set on a non-HTREE filesystem */
8829 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8830 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8832 /* INDEX_FL flag set on a non-directory */
8834 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8835 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8837 /* Invalid root node in HTREE directory */
8838 { PR_1_HTREE_BADROOT,
8839 N_("@h %i has an @n root node.\n"),
8840 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8842 /* Unsupported hash version in HTREE directory */
8844 N_("@h %i has an unsupported hash version (%N)\n"),
8845 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8847 /* Incompatible flag in HTREE root node */
8848 { PR_1_HTREE_INCOMPAT,
8849 N_("@h %i uses an incompatible htree root node flag.\n"),
8850 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8852 /* HTREE too deep */
8854 N_("@h %i has a tree depth (%N) which is too big\n"),
8855 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8857 /* Bad block has indirect block that conflicts with filesystem block */
8859 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8861 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8863 /* Resize inode failed */
8864 { PR_1_RESIZE_INODE_CREATE,
8865 N_("Resize @i (re)creation failed: %m."),
8868 /* invalid inode->i_extra_isize */
8870 N_("@i %i has a extra size (%IS) which is @n\n"),
8871 PROMPT_FIX, PR_PREEN_OK },
8873 /* invalid ea entry->e_name_len */
8874 { PR_1_ATTR_NAME_LEN,
8875 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8876 PROMPT_CLEAR, PR_PREEN_OK },
8878 /* invalid ea entry->e_value_size */
8879 { PR_1_ATTR_VALUE_SIZE,
8880 N_("@a in @i %i has a value size (%N) which is @n\n"),
8881 PROMPT_CLEAR, PR_PREEN_OK },
8883 /* invalid ea entry->e_value_offs */
8884 { PR_1_ATTR_VALUE_OFFSET,
8885 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8886 PROMPT_CLEAR, PR_PREEN_OK },
8888 /* invalid ea entry->e_value_block */
8889 { PR_1_ATTR_VALUE_BLOCK,
8890 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8891 PROMPT_CLEAR, PR_PREEN_OK },
8893 /* invalid ea entry->e_hash */
8895 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8896 PROMPT_CLEAR, PR_PREEN_OK },
8898 /* Pass 1b errors */
8900 /* Pass 1B: Rescan for duplicate/bad blocks */
8901 { PR_1B_PASS_HEADER,
8902 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8903 "Pass 1B: Rescanning for @m @bs\n"),
8906 /* Duplicate/bad block(s) header */
8907 { PR_1B_DUP_BLOCK_HEADER,
8908 N_("@m @b(s) in @i %i:"),
8911 /* Duplicate/bad block(s) in inode */
8914 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8916 /* Duplicate/bad block(s) end */
8917 { PR_1B_DUP_BLOCK_END,
8919 PROMPT_NONE, PR_PREEN_NOHDR },
8921 /* Error while scanning inodes */
8922 { PR_1B_ISCAN_ERROR,
8923 N_("Error while scanning inodes (%i): %m\n"),
8924 PROMPT_NONE, PR_FATAL },
8926 /* Error allocating inode bitmap */
8927 { PR_1B_ALLOCATE_IBITMAP_ERROR,
8928 N_("@A @i @B (@i_dup_map): %m\n"),
8929 PROMPT_NONE, PR_FATAL },
8931 /* Error while iterating over blocks */
8932 { PR_1B_BLOCK_ITERATE,
8933 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8936 /* Error adjusting EA refcount */
8937 { PR_1B_ADJ_EA_REFCOUNT,
8938 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8942 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8943 { PR_1C_PASS_HEADER,
8944 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8948 /* Pass 1D: Reconciling multiply-claimed blocks */
8949 { PR_1D_PASS_HEADER,
8950 N_("Pass 1D: Reconciling @m @bs\n"),
8953 /* File has duplicate blocks */
8955 N_("File %Q (@i #%i, mod time %IM)\n"
8956 " has %B @m @b(s), shared with %N file(s):\n"),
8959 /* List of files sharing duplicate blocks */
8960 { PR_1D_DUP_FILE_LIST,
8961 N_("\t%Q (@i #%i, mod time %IM)\n"),
8964 /* File sharing blocks with filesystem metadata */
8965 { PR_1D_SHARE_METADATA,
8966 N_("\t<@f metadata>\n"),
8969 /* Report of how many duplicate/bad inodes */
8970 { PR_1D_NUM_DUP_INODES,
8971 N_("(There are %N @is containing @m @bs.)\n\n"),
8974 /* Duplicated blocks already reassigned or cloned. */
8975 { PR_1D_DUP_BLOCKS_DEALT,
8976 N_("@m @bs already reassigned or cloned.\n\n"),
8979 /* Clone duplicate/bad blocks? */
8980 { PR_1D_CLONE_QUESTION,
8981 "", PROMPT_CLONE, PR_NO_OK },
8984 { PR_1D_DELETE_QUESTION,
8985 "", PROMPT_DELETE, 0 },
8987 /* Couldn't clone file (error) */
8988 { PR_1D_CLONE_ERROR,
8989 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
8993 /* Pass 2: Checking directory structure */
8995 N_("Pass 2: Checking @d structure\n"),
8998 /* Bad inode number for '.' */
8999 { PR_2_BAD_INODE_DOT,
9000 N_("@n @i number for '.' in @d @i %i.\n"),
9003 /* Directory entry has bad inode number */
9005 N_("@E has @n @i #: %Di.\n"),
9008 /* Directory entry has deleted or unused inode */
9009 { PR_2_UNUSED_INODE,
9010 N_("@E has @D/unused @i %Di. "),
9011 PROMPT_CLEAR, PR_PREEN_OK },
9013 /* Directry entry is link to '.' */
9015 N_("@E @L to '.' "),
9018 /* Directory entry points to inode now located in a bad block */
9020 N_("@E points to @i (%Di) located in a bad @b.\n"),
9023 /* Directory entry contains a link to a directory */
9025 N_("@E @L to @d %P (%Di).\n"),
9028 /* Directory entry contains a link to the root directry */
9030 N_("@E @L to the @r.\n"),
9033 /* Directory entry has illegal characters in its name */
9035 N_("@E has illegal characters in its name.\n"),
9038 /* Missing '.' in directory inode */
9040 N_("Missing '.' in @d @i %i.\n"),
9043 /* Missing '..' in directory inode */
9044 { PR_2_MISSING_DOT_DOT,
9045 N_("Missing '..' in @d @i %i.\n"),
9048 /* First entry in directory inode doesn't contain '.' */
9050 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9053 /* Second entry in directory inode doesn't contain '..' */
9054 { PR_2_2ND_NOT_DOT_DOT,
9055 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9058 /* i_faddr should be zero */
9060 N_("i_faddr @F %IF, @s zero.\n"),
9063 /* i_file_acl should be zero */
9064 { PR_2_FILE_ACL_ZERO,
9065 N_("i_file_acl @F %If, @s zero.\n"),
9068 /* i_dir_acl should be zero */
9069 { PR_2_DIR_ACL_ZERO,
9070 N_("i_dir_acl @F %Id, @s zero.\n"),
9073 /* i_frag should be zero */
9075 N_("i_frag @F %N, @s zero.\n"),
9078 /* i_fsize should be zero */
9080 N_("i_fsize @F %N, @s zero.\n"),
9083 /* inode has bad mode */
9085 N_("@i %i (%Q) has @n mode (%Im).\n"),
9088 /* directory corrupted */
9089 { PR_2_DIR_CORRUPTED,
9090 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9091 PROMPT_SALVAGE, 0 },
9093 /* filename too long */
9094 { PR_2_FILENAME_LONG,
9095 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9096 PROMPT_TRUNCATE, 0 },
9098 /* Directory inode has a missing block (hole) */
9099 { PR_2_DIRECTORY_HOLE,
9100 N_("@d @i %i has an unallocated @b #%B. "),
9101 PROMPT_ALLOCATE, 0 },
9103 /* '.' is not NULL terminated */
9104 { PR_2_DOT_NULL_TERM,
9105 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9108 /* '..' is not NULL terminated */
9109 { PR_2_DOT_DOT_NULL_TERM,
9110 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9113 /* Illegal character device inode */
9114 { PR_2_BAD_CHAR_DEV,
9115 N_("@i %i (%Q) is an @I character @v.\n"),
9118 /* Illegal block device inode */
9119 { PR_2_BAD_BLOCK_DEV,
9120 N_("@i %i (%Q) is an @I @b @v.\n"),
9123 /* Duplicate '.' entry */
9125 N_("@E is duplicate '.' @e.\n"),
9128 /* Duplicate '..' entry */
9130 N_("@E is duplicate '..' @e.\n"),
9133 /* Internal error: couldn't find dir_info */
9135 N_("Internal error: cannot find dir_info for %i.\n"),
9136 PROMPT_NONE, PR_FATAL },
9138 /* Final rec_len is wrong */
9139 { PR_2_FINAL_RECLEN,
9140 N_("@E has rec_len of %Dr, @s %N.\n"),
9143 /* Error allocating icount structure */
9144 { PR_2_ALLOCATE_ICOUNT,
9145 N_("@A icount structure: %m\n"),
9146 PROMPT_NONE, PR_FATAL },
9148 /* Error iterating over directory blocks */
9149 { PR_2_DBLIST_ITERATE,
9150 N_("Error iterating over @d @bs: %m\n"),
9151 PROMPT_NONE, PR_FATAL },
9153 /* Error reading directory block */
9154 { PR_2_READ_DIRBLOCK,
9155 N_("Error reading @d @b %b (@i %i): %m\n"),
9156 PROMPT_CONTINUE, 0 },
9158 /* Error writing directory block */
9159 { PR_2_WRITE_DIRBLOCK,
9160 N_("Error writing @d @b %b (@i %i): %m\n"),
9161 PROMPT_CONTINUE, 0 },
9163 /* Error allocating new directory block */
9164 { PR_2_ALLOC_DIRBOCK,
9165 N_("@A new @d @b for @i %i (%s): %m\n"),
9168 /* Error deallocating inode */
9169 { PR_2_DEALLOC_INODE,
9170 N_("Error deallocating @i %i: %m\n"),
9171 PROMPT_NONE, PR_FATAL },
9173 /* Directory entry for '.' is big. Split? */
9175 N_("@d @e for '.' is big. "),
9176 PROMPT_SPLIT, PR_NO_OK },
9178 /* Illegal FIFO inode */
9180 N_("@i %i (%Q) is an @I FIFO.\n"),
9183 /* Illegal socket inode */
9185 N_("@i %i (%Q) is an @I socket.\n"),
9188 /* Directory filetype not set */
9189 { PR_2_SET_FILETYPE,
9190 N_("Setting filetype for @E to %N.\n"),
9191 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9193 /* Directory filetype incorrect */
9194 { PR_2_BAD_FILETYPE,
9195 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9198 /* Directory filetype set on filesystem */
9199 { PR_2_CLEAR_FILETYPE,
9200 N_("@E has filetype set.\n"),
9201 PROMPT_CLEAR, PR_PREEN_OK },
9203 /* Directory filename is null */
9205 N_("@E has a @z name.\n"),
9208 /* Invalid symlink */
9209 { PR_2_INVALID_SYMLINK,
9210 N_("Symlink %Q (@i #%i) is @n.\n"),
9213 /* i_file_acl (extended attribute block) is bad */
9214 { PR_2_FILE_ACL_BAD,
9215 N_("@a @b @F @n (%If).\n"),
9218 /* Filesystem contains large files, but has no such flag in sb */
9219 { PR_2_FEATURE_LARGE_FILES,
9220 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9223 /* Node in HTREE directory not referenced */
9224 { PR_2_HTREE_NOTREF,
9225 N_("@p @h %d: node (%B) not referenced\n"),
9228 /* Node in HTREE directory referenced twice */
9229 { PR_2_HTREE_DUPREF,
9230 N_("@p @h %d: node (%B) referenced twice\n"),
9233 /* Node in HTREE directory has bad min hash */
9234 { PR_2_HTREE_MIN_HASH,
9235 N_("@p @h %d: node (%B) has bad min hash\n"),
9238 /* Node in HTREE directory has bad max hash */
9239 { PR_2_HTREE_MAX_HASH,
9240 N_("@p @h %d: node (%B) has bad max hash\n"),
9243 /* Clear invalid HTREE directory */
9245 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9247 /* Bad block in htree interior node */
9248 { PR_2_HTREE_BADBLK,
9249 N_("@p @h %d (%q): bad @b number %b.\n"),
9250 PROMPT_CLEAR_HTREE, 0 },
9252 /* Error adjusting EA refcount */
9253 { PR_2_ADJ_EA_REFCOUNT,
9254 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9255 PROMPT_NONE, PR_FATAL },
9257 /* Invalid HTREE root node */
9258 { PR_2_HTREE_BAD_ROOT,
9259 N_("@p @h %d: root node is @n\n"),
9260 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9262 /* Invalid HTREE limit */
9263 { PR_2_HTREE_BAD_LIMIT,
9264 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9265 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9267 /* Invalid HTREE count */
9268 { PR_2_HTREE_BAD_COUNT,
9269 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9270 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9272 /* HTREE interior node has out-of-order hashes in table */
9273 { PR_2_HTREE_HASH_ORDER,
9274 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9275 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9277 /* Node in HTREE directory has invalid depth */
9278 { PR_2_HTREE_BAD_DEPTH,
9279 N_("@p @h %d: node (%B) has @n depth\n"),
9282 /* Duplicate directory entry found */
9283 { PR_2_DUPLICATE_DIRENT,
9284 N_("Duplicate @E found. "),
9287 /* Non-unique filename found */
9288 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9289 N_("@E has a non-unique filename.\nRename to %s"),
9292 /* Duplicate directory entry found */
9293 { PR_2_REPORT_DUP_DIRENT,
9294 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9299 /* Pass 3: Checking directory connectivity */
9301 N_("Pass 3: Checking @d connectivity\n"),
9304 /* Root inode not allocated */
9305 { PR_3_NO_ROOT_INODE,
9306 N_("@r not allocated. "),
9307 PROMPT_ALLOCATE, 0 },
9309 /* No room in lost+found */
9310 { PR_3_EXPAND_LF_DIR,
9311 N_("No room in @l @d. "),
9314 /* Unconnected directory inode */
9315 { PR_3_UNCONNECTED_DIR,
9316 N_("Unconnected @d @i %i (%p)\n"),
9317 PROMPT_CONNECT, 0 },
9319 /* /lost+found not found */
9321 N_("/@l not found. "),
9322 PROMPT_CREATE, PR_PREEN_OK },
9324 /* .. entry is incorrect */
9326 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9329 /* Bad or non-existent /lost+found. Cannot reconnect */
9331 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9334 /* Could not expand /lost+found */
9335 { PR_3_CANT_EXPAND_LPF,
9336 N_("Could not expand /@l: %m\n"),
9339 /* Could not reconnect inode */
9340 { PR_3_CANT_RECONNECT,
9341 N_("Could not reconnect %i: %m\n"),
9344 /* Error while trying to find /lost+found */
9345 { PR_3_ERR_FIND_LPF,
9346 N_("Error while trying to find /@l: %m\n"),
9349 /* Error in ext2fs_new_block while creating /lost+found */
9350 { PR_3_ERR_LPF_NEW_BLOCK,
9351 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9354 /* Error in ext2fs_new_inode while creating /lost+found */
9355 { PR_3_ERR_LPF_NEW_INODE,
9356 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9359 /* Error in ext2fs_new_dir_block while creating /lost+found */
9360 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9361 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9364 /* Error while writing directory block for /lost+found */
9365 { PR_3_ERR_LPF_WRITE_BLOCK,
9366 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9369 /* Error while adjusting inode count */
9370 { PR_3_ADJUST_INODE,
9371 N_("Error while adjusting @i count on @i %i\n"),
9374 /* Couldn't fix parent directory -- error */
9375 { PR_3_FIX_PARENT_ERR,
9376 N_("Couldn't fix parent of @i %i: %m\n\n"),
9379 /* Couldn't fix parent directory -- couldn't find it */
9380 { PR_3_FIX_PARENT_NOFIND,
9381 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9384 /* Error allocating inode bitmap */
9385 { PR_3_ALLOCATE_IBITMAP_ERROR,
9386 N_("@A @i @B (%N): %m\n"),
9387 PROMPT_NONE, PR_FATAL },
9389 /* Error creating root directory */
9390 { PR_3_CREATE_ROOT_ERROR,
9391 N_("Error creating root @d (%s): %m\n"),
9392 PROMPT_NONE, PR_FATAL },
9394 /* Error creating lost and found directory */
9395 { PR_3_CREATE_LPF_ERROR,
9396 N_("Error creating /@l @d (%s): %m\n"),
9397 PROMPT_NONE, PR_FATAL },
9399 /* Root inode is not directory; aborting */
9400 { PR_3_ROOT_NOT_DIR_ABORT,
9401 N_("@r is not a @d; aborting.\n"),
9402 PROMPT_NONE, PR_FATAL },
9404 /* Cannot proceed without a root inode. */
9405 { PR_3_NO_ROOT_INODE_ABORT,
9406 N_("Cannot proceed without a @r.\n"),
9407 PROMPT_NONE, PR_FATAL },
9409 /* Internal error: couldn't find dir_info */
9411 N_("Internal error: cannot find dir_info for %i.\n"),
9412 PROMPT_NONE, PR_FATAL },
9414 /* Lost+found not a directory */
9416 N_("/@l is not a @d (ino=%i)\n"),
9419 /* Pass 3A Directory Optimization */
9421 /* Pass 3A: Optimizing directories */
9422 { PR_3A_PASS_HEADER,
9423 N_("Pass 3A: Optimizing directories\n"),
9424 PROMPT_NONE, PR_PREEN_NOMSG },
9426 /* Error iterating over directories */
9427 { PR_3A_OPTIMIZE_ITER,
9428 N_("Failed to create dirs_to_hash iterator: %m"),
9431 /* Error rehash directory */
9432 { PR_3A_OPTIMIZE_DIR_ERR,
9433 N_("Failed to optimize directory %q (%d): %m"),
9436 /* Rehashing dir header */
9437 { PR_3A_OPTIMIZE_DIR_HEADER,
9438 N_("Optimizing directories: "),
9439 PROMPT_NONE, PR_MSG_ONLY },
9441 /* Rehashing directory %d */
9442 { PR_3A_OPTIMIZE_DIR,
9444 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9446 /* Rehashing dir end */
9447 { PR_3A_OPTIMIZE_DIR_END,
9449 PROMPT_NONE, PR_PREEN_NOHDR },
9453 /* Pass 4: Checking reference counts */
9455 N_("Pass 4: Checking reference counts\n"),
9458 /* Unattached zero-length inode */
9459 { PR_4_ZERO_LEN_INODE,
9460 N_("@u @z @i %i. "),
9461 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9463 /* Unattached inode */
9464 { PR_4_UNATTACHED_INODE,
9466 PROMPT_CONNECT, 0 },
9468 /* Inode ref count wrong */
9469 { PR_4_BAD_REF_COUNT,
9470 N_("@i %i ref count is %Il, @s %N. "),
9471 PROMPT_FIX, PR_PREEN_OK },
9473 { PR_4_INCONSISTENT_COUNT,
9474 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9475 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9476 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9477 "They @s the same!\n"),
9482 /* Pass 5: Checking group summary information */
9484 N_("Pass 5: Checking @g summary information\n"),
9487 /* Padding at end of inode bitmap is not set. */
9488 { PR_5_INODE_BMAP_PADDING,
9489 N_("Padding at end of @i @B is not set. "),
9490 PROMPT_FIX, PR_PREEN_OK },
9492 /* Padding at end of block bitmap is not set. */
9493 { PR_5_BLOCK_BMAP_PADDING,
9494 N_("Padding at end of @b @B is not set. "),
9495 PROMPT_FIX, PR_PREEN_OK },
9497 /* Block bitmap differences header */
9498 { PR_5_BLOCK_BITMAP_HEADER,
9499 N_("@b @B differences: "),
9500 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9502 /* Block not used, but marked in bitmap */
9503 { PR_5_BLOCK_UNUSED,
9505 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9507 /* Block used, but not marked used in bitmap */
9510 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9512 /* Block bitmap differences end */
9513 { PR_5_BLOCK_BITMAP_END,
9515 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9517 /* Inode bitmap differences header */
9518 { PR_5_INODE_BITMAP_HEADER,
9519 N_("@i @B differences: "),
9520 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9522 /* Inode not used, but marked in bitmap */
9523 { PR_5_INODE_UNUSED,
9525 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9527 /* Inode used, but not marked used in bitmap */
9530 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9532 /* Inode bitmap differences end */
9533 { PR_5_INODE_BITMAP_END,
9535 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9537 /* Free inodes count for group wrong */
9538 { PR_5_FREE_INODE_COUNT_GROUP,
9539 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9540 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9542 /* Directories count for group wrong */
9543 { PR_5_FREE_DIR_COUNT_GROUP,
9544 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9545 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9547 /* Free inodes count wrong */
9548 { PR_5_FREE_INODE_COUNT,
9549 N_("Free @is count wrong (%i, counted=%j).\n"),
9550 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9552 /* Free blocks count for group wrong */
9553 { PR_5_FREE_BLOCK_COUNT_GROUP,
9554 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9555 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9557 /* Free blocks count wrong */
9558 { PR_5_FREE_BLOCK_COUNT,
9559 N_("Free @bs count wrong (%b, counted=%c).\n"),
9560 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9562 /* Programming error: bitmap endpoints don't match */
9563 { PR_5_BMAP_ENDPOINTS,
9564 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9565 "match calculated @B endpoints (%i, %j)\n"),
9566 PROMPT_NONE, PR_FATAL },
9568 /* Internal error: fudging end of bitmap */
9569 { PR_5_FUDGE_BITMAP_ERROR,
9570 N_("Internal error: fudging end of bitmap (%N)\n"),
9571 PROMPT_NONE, PR_FATAL },
9573 /* Error copying in replacement inode bitmap */
9574 { PR_5_COPY_IBITMAP_ERROR,
9575 N_("Error copying in replacement @i @B: %m\n"),
9576 PROMPT_NONE, PR_FATAL },
9578 /* Error copying in replacement block bitmap */
9579 { PR_5_COPY_BBITMAP_ERROR,
9580 N_("Error copying in replacement @b @B: %m\n"),
9581 PROMPT_NONE, PR_FATAL },
9583 /* Block range not used, but marked in bitmap */
9584 { PR_5_BLOCK_RANGE_UNUSED,
9586 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9588 /* Block range used, but not marked used in bitmap */
9589 { PR_5_BLOCK_RANGE_USED,
9591 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9593 /* Inode range not used, but marked in bitmap */
9594 { PR_5_INODE_RANGE_UNUSED,
9596 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9598 /* Inode range used, but not marked used in bitmap */
9599 { PR_5_INODE_RANGE_USED,
9601 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9607 * This is the latch flags register. It allows several problems to be
9608 * "latched" together. This means that the user has to answer but one
9609 * question for the set of problems, and all of the associated
9610 * problems will be either fixed or not fixed.
9612 static struct latch_descr pr_latch_info[] = {
9613 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9614 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9615 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9616 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9617 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9618 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9619 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9620 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9621 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9625 static const struct e2fsck_problem *find_problem(problem_t code)
9629 for (i=0; problem_table[i].e2p_code; i++) {
9630 if (problem_table[i].e2p_code == code)
9631 return &problem_table[i];
9636 static struct latch_descr *find_latch(int code)
9640 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9641 if (pr_latch_info[i].latch_code == code)
9642 return &pr_latch_info[i];
9647 int end_problem_latch(e2fsck_t ctx, int mask)
9649 struct latch_descr *ldesc;
9650 struct problem_context pctx;
9653 ldesc = find_latch(mask);
9654 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9655 clear_problem_context(&pctx);
9656 answer = fix_problem(ctx, ldesc->end_message, &pctx);
9658 ldesc->flags &= ~(PRL_VARIABLE);
9662 int set_latch_flags(int mask, int setflags, int clearflags)
9664 struct latch_descr *ldesc;
9666 ldesc = find_latch(mask);
9669 ldesc->flags |= setflags;
9670 ldesc->flags &= ~clearflags;
9674 void clear_problem_context(struct problem_context *ctx)
9676 memset(ctx, 0, sizeof(struct problem_context));
9681 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9683 ext2_filsys fs = ctx->fs;
9684 const struct e2fsck_problem *ptr;
9685 struct latch_descr *ldesc = 0;
9686 const char *message;
9687 int def_yn, answer, ans;
9688 int print_answer = 0;
9691 ptr = find_problem(code);
9693 printf(_("Unhandled error code (0x%x)!\n"), code);
9697 if ((ptr->flags & PR_NO_DEFAULT) ||
9698 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9699 (ctx->options & E2F_OPT_NO))
9703 * Do special latch processing. This is where we ask the
9704 * latch question, if it exists
9706 if (ptr->flags & PR_LATCH_MASK) {
9707 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9708 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9709 ans = fix_problem(ctx, ldesc->question, pctx);
9711 ldesc->flags |= PRL_YES;
9713 ldesc->flags |= PRL_NO;
9714 ldesc->flags |= PRL_LATCHED;
9716 if (ldesc->flags & PRL_SUPPRESS)
9719 if ((ptr->flags & PR_PREEN_NOMSG) &&
9720 (ctx->options & E2F_OPT_PREEN))
9722 if ((ptr->flags & PR_NO_NOMSG) &&
9723 (ctx->options & E2F_OPT_NO))
9726 message = ptr->e2p_description;
9727 if ((ctx->options & E2F_OPT_PREEN) &&
9728 !(ptr->flags & PR_PREEN_NOHDR)) {
9729 printf("%s: ", ctx->device_name ?
9730 ctx->device_name : ctx->filesystem_name);
9733 print_e2fsck_message(ctx, _(message), pctx, 1);
9735 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9738 if (ptr->flags & PR_FATAL)
9739 bb_error_msg_and_die(0);
9741 if (ptr->prompt == PROMPT_NONE) {
9742 if (ptr->flags & PR_NOCOLLATE)
9747 if (ctx->options & E2F_OPT_PREEN) {
9749 if (!(ptr->flags & PR_PREEN_NOMSG))
9751 } else if ((ptr->flags & PR_LATCH_MASK) &&
9752 (ldesc->flags & (PRL_YES | PRL_NO))) {
9755 if (ldesc->flags & PRL_YES)
9760 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9761 if (!answer && !(ptr->flags & PR_NO_OK))
9762 ext2fs_unmark_valid(fs);
9765 printf("%s.\n", answer ?
9766 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9770 if ((ptr->prompt == PROMPT_ABORT) && answer)
9771 bb_error_msg_and_die(0);
9773 if (ptr->flags & PR_AFTER_CODE)
9774 answer = fix_problem(ctx, ptr->second_code, pctx);
9780 * linux/fs/recovery.c
9782 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9786 * Maintain information about the progress of the recovery job, so that
9787 * the different passes can carry information between them.
9789 struct recovery_info
9791 tid_t start_transaction;
9792 tid_t end_transaction;
9799 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9800 static int do_one_pass(journal_t *journal,
9801 struct recovery_info *info, enum passtype pass);
9802 static int scan_revoke_records(journal_t *, struct buffer_head *,
9803 tid_t, struct recovery_info *);
9806 * Read a block from the journal
9809 static int jread(struct buffer_head **bhp, journal_t *journal,
9810 unsigned int offset)
9813 unsigned long blocknr;
9814 struct buffer_head *bh;
9818 err = journal_bmap(journal, offset, &blocknr);
9821 printf("JBD: bad block at offset %u\n", offset);
9825 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9829 if (!buffer_uptodate(bh)) {
9830 /* If this is a brand new buffer, start readahead.
9831 Otherwise, we assume we are already reading it. */
9832 if (!buffer_req(bh))
9833 do_readahead(journal, offset);
9837 if (!buffer_uptodate(bh)) {
9838 printf("JBD: Failed to read block at offset %u\n", offset);
9849 * Count the number of in-use tags in a journal descriptor block.
9852 static int count_tags(struct buffer_head *bh, int size)
9855 journal_block_tag_t * tag;
9858 tagp = &bh->b_data[sizeof(journal_header_t)];
9860 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9861 tag = (journal_block_tag_t *) tagp;
9864 tagp += sizeof(journal_block_tag_t);
9865 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9868 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9876 /* Make sure we wrap around the log correctly! */
9877 #define wrap(journal, var) \
9879 if (var >= (journal)->j_last) \
9880 var -= ((journal)->j_last - (journal)->j_first); \
9884 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9885 * @journal: the journal to recover
9887 * The primary function for recovering the log contents when mounting a
9890 * Recovery is done in three passes. In the first pass, we look for the
9891 * end of the log. In the second, we assemble the list of revoke
9892 * blocks. In the third and final pass, we replay any un-revoked blocks
9895 int journal_recover(journal_t *journal)
9898 journal_superblock_t * sb;
9900 struct recovery_info info;
9902 memset(&info, 0, sizeof(info));
9903 sb = journal->j_superblock;
9906 * The journal superblock's s_start field (the current log head)
9907 * is always zero if, and only if, the journal was cleanly
9912 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9916 err = do_one_pass(journal, &info, PASS_SCAN);
9918 err = do_one_pass(journal, &info, PASS_REVOKE);
9920 err = do_one_pass(journal, &info, PASS_REPLAY);
9922 /* Restart the log at the next transaction ID, thus invalidating
9923 * any existing commit records in the log. */
9924 journal->j_transaction_sequence = ++info.end_transaction;
9926 journal_clear_revoke(journal);
9927 sync_blockdev(journal->j_fs_dev);
9931 static int do_one_pass(journal_t *journal,
9932 struct recovery_info *info, enum passtype pass)
9934 unsigned int first_commit_ID, next_commit_ID;
9935 unsigned long next_log_block;
9936 int err, success = 0;
9937 journal_superblock_t * sb;
9938 journal_header_t * tmp;
9939 struct buffer_head * bh;
9940 unsigned int sequence;
9943 /* Precompute the maximum metadata descriptors in a descriptor block */
9944 int MAX_BLOCKS_PER_DESC;
9945 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9946 / sizeof(journal_block_tag_t));
9949 * First thing is to establish what we expect to find in the log
9950 * (in terms of transaction IDs), and where (in terms of log
9951 * block offsets): query the superblock.
9954 sb = journal->j_superblock;
9955 next_commit_ID = ntohl(sb->s_sequence);
9956 next_log_block = ntohl(sb->s_start);
9958 first_commit_ID = next_commit_ID;
9959 if (pass == PASS_SCAN)
9960 info->start_transaction = first_commit_ID;
9963 * Now we walk through the log, transaction by transaction,
9964 * making sure that each transaction has a commit block in the
9965 * expected place. Each complete transaction gets replayed back
9966 * into the main filesystem.
9972 journal_block_tag_t * tag;
9973 struct buffer_head * obh;
9974 struct buffer_head * nbh;
9976 /* If we already know where to stop the log traversal,
9977 * check right now that we haven't gone past the end of
9980 if (pass != PASS_SCAN)
9981 if (tid_geq(next_commit_ID, info->end_transaction))
9984 /* Skip over each chunk of the transaction looking
9985 * either the next descriptor block or the final commit
9988 err = jread(&bh, journal, next_log_block);
9993 wrap(journal, next_log_block);
9995 /* What kind of buffer is it?
9997 * If it is a descriptor block, check that it has the
9998 * expected sequence number. Otherwise, we're all done
10001 tmp = (journal_header_t *)bh->b_data;
10003 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10008 blocktype = ntohl(tmp->h_blocktype);
10009 sequence = ntohl(tmp->h_sequence);
10011 if (sequence != next_commit_ID) {
10016 /* OK, we have a valid descriptor block which matches
10017 * all of the sequence number checks. What are we going
10018 * to do with it? That depends on the pass... */
10020 switch(blocktype) {
10021 case JFS_DESCRIPTOR_BLOCK:
10022 /* If it is a valid descriptor block, replay it
10023 * in pass REPLAY; otherwise, just skip over the
10024 * blocks it describes. */
10025 if (pass != PASS_REPLAY) {
10027 count_tags(bh, journal->j_blocksize);
10028 wrap(journal, next_log_block);
10033 /* A descriptor block: we can now write all of
10034 * the data blocks. Yay, useful work is finally
10035 * getting done here! */
10037 tagp = &bh->b_data[sizeof(journal_header_t)];
10038 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10039 <= journal->j_blocksize) {
10040 unsigned long io_block;
10042 tag = (journal_block_tag_t *) tagp;
10043 flags = ntohl(tag->t_flags);
10045 io_block = next_log_block++;
10046 wrap(journal, next_log_block);
10047 err = jread(&obh, journal, io_block);
10049 /* Recover what we can, but
10050 * report failure at the end. */
10052 printf("JBD: IO error %d recovering "
10053 "block %ld in log\n",
10056 unsigned long blocknr;
10058 blocknr = ntohl(tag->t_blocknr);
10060 /* If the block has been
10061 * revoked, then we're all done
10063 if (journal_test_revoke
10067 ++info->nr_revoke_hits;
10071 /* Find a buffer for the new
10072 * data being restored */
10073 nbh = getblk(journal->j_fs_dev,
10075 journal->j_blocksize);
10077 printf("JBD: Out of memory "
10078 "during recovery.\n");
10086 memcpy(nbh->b_data, obh->b_data,
10087 journal->j_blocksize);
10088 if (flags & JFS_FLAG_ESCAPE) {
10089 *((unsigned int *)bh->b_data) =
10090 htonl(JFS_MAGIC_NUMBER);
10093 mark_buffer_uptodate(nbh, 1);
10094 mark_buffer_dirty(nbh);
10095 ++info->nr_replays;
10096 /* ll_rw_block(WRITE, 1, &nbh); */
10097 unlock_buffer(nbh);
10103 tagp += sizeof(journal_block_tag_t);
10104 if (!(flags & JFS_FLAG_SAME_UUID))
10107 if (flags & JFS_FLAG_LAST_TAG)
10114 case JFS_COMMIT_BLOCK:
10115 /* Found an expected commit block: not much to
10116 * do other than move on to the next sequence
10122 case JFS_REVOKE_BLOCK:
10123 /* If we aren't in the REVOKE pass, then we can
10124 * just skip over this block. */
10125 if (pass != PASS_REVOKE) {
10130 err = scan_revoke_records(journal, bh,
10131 next_commit_ID, info);
10144 * We broke out of the log scan loop: either we came to the
10145 * known end of the log or we found an unexpected block in the
10146 * log. If the latter happened, then we know that the "current"
10147 * transaction marks the end of the valid log.
10150 if (pass == PASS_SCAN)
10151 info->end_transaction = next_commit_ID;
10153 /* It's really bad news if different passes end up at
10154 * different places (but possible due to IO errors). */
10155 if (info->end_transaction != next_commit_ID) {
10156 printf("JBD: recovery pass %d ended at "
10157 "transaction %u, expected %u\n",
10158 pass, next_commit_ID, info->end_transaction);
10171 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10173 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10174 tid_t sequence, struct recovery_info *info)
10176 journal_revoke_header_t *header;
10179 header = (journal_revoke_header_t *) bh->b_data;
10180 offset = sizeof(journal_revoke_header_t);
10181 max = ntohl(header->r_count);
10183 while (offset < max) {
10184 unsigned long blocknr;
10187 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10189 err = journal_set_revoke(journal, blocknr, sequence);
10192 ++info->nr_revokes;
10199 * rehash.c --- rebuild hash tree directories
10201 * This algorithm is designed for simplicity of implementation and to
10202 * pack the directory as much as possible. It however requires twice
10203 * as much memory as the size of the directory. The maximum size
10204 * directory supported using a 4k blocksize is roughly a gigabyte, and
10205 * so there may very well be problems with machines that don't have
10206 * virtual memory, and obscenely large directories.
10208 * An alternate algorithm which is much more disk intensive could be
10209 * written, and probably will need to be written in the future. The
10210 * design goals of such an algorithm are: (a) use (roughly) constant
10211 * amounts of memory, no matter how large the directory, (b) the
10212 * directory must be safe at all times, even if e2fsck is interrupted
10213 * in the middle, (c) we must use minimal amounts of extra disk
10214 * blocks. This pretty much requires an incremental approach, where
10215 * we are reading from one part of the directory, and inserting into
10216 * the front half. So the algorithm will have to keep track of a
10217 * moving block boundary between the new tree and the old tree, and
10218 * files will need to be moved from the old directory and inserted
10219 * into the new tree. If the new directory requires space which isn't
10220 * yet available, blocks from the beginning part of the old directory
10221 * may need to be moved to the end of the directory to make room for
10224 * --------------------------------------------------------
10225 * | new tree | | old tree |
10226 * --------------------------------------------------------
10228 * tail new head old
10230 * This is going to be a pain in the tuckus to implement, and will
10231 * require a lot more disk accesses. So I'm going to skip it for now;
10232 * it's only really going to be an issue for really, really big
10233 * filesystems (when we reach the level of tens of millions of files
10234 * in a single directory). It will probably be easier to simply
10235 * require that e2fsck use VM first.
10238 struct fill_dir_struct {
10240 struct ext2_inode *inode;
10243 struct hash_entry *harray;
10244 int max_array, num_array;
10250 struct hash_entry {
10251 ext2_dirhash_t hash;
10252 ext2_dirhash_t minor_hash;
10253 struct ext2_dir_entry *dir;
10260 ext2_dirhash_t *hashes;
10263 static int fill_dir_block(ext2_filsys fs,
10265 e2_blkcnt_t blockcnt,
10266 blk_t ref_block FSCK_ATTR((unused)),
10267 int ref_offset FSCK_ATTR((unused)),
10270 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10271 struct hash_entry *new_array, *ent;
10272 struct ext2_dir_entry *dirent;
10274 unsigned int offset, dir_offset;
10279 offset = blockcnt * fs->blocksize;
10280 if (offset + fs->blocksize > fd->inode->i_size) {
10281 fd->err = EXT2_ET_DIR_CORRUPTED;
10282 return BLOCK_ABORT;
10284 dir = (fd->buf+offset);
10285 if (HOLE_BLKADDR(*block_nr)) {
10286 memset(dir, 0, fs->blocksize);
10287 dirent = (struct ext2_dir_entry *) dir;
10288 dirent->rec_len = fs->blocksize;
10290 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10292 return BLOCK_ABORT;
10294 /* While the directory block is "hot", index it. */
10296 while (dir_offset < fs->blocksize) {
10297 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10298 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10299 (dirent->rec_len < 8) ||
10300 ((dirent->rec_len % 4) != 0) ||
10301 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10302 fd->err = EXT2_ET_DIR_CORRUPTED;
10303 return BLOCK_ABORT;
10305 dir_offset += dirent->rec_len;
10306 if (dirent->inode == 0)
10308 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10309 (dirent->name[0] == '.'))
10311 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10312 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10313 fd->parent = dirent->inode;
10316 if (fd->num_array >= fd->max_array) {
10317 new_array = realloc(fd->harray,
10318 sizeof(struct hash_entry) * (fd->max_array+500));
10321 return BLOCK_ABORT;
10323 fd->harray = new_array;
10324 fd->max_array += 500;
10326 ent = fd->harray + fd->num_array++;
10328 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10330 ent->hash = ent->minor_hash = 0;
10332 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10334 dirent->name_len & 0xFF,
10335 fs->super->s_hash_seed,
10336 &ent->hash, &ent->minor_hash);
10338 return BLOCK_ABORT;
10345 /* Used for sorting the hash entry */
10346 static int name_cmp(const void *a, const void *b)
10348 const struct hash_entry *he_a = (const struct hash_entry *) a;
10349 const struct hash_entry *he_b = (const struct hash_entry *) b;
10353 min_len = he_a->dir->name_len;
10354 if (min_len > he_b->dir->name_len)
10355 min_len = he_b->dir->name_len;
10357 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10359 if (he_a->dir->name_len > he_b->dir->name_len)
10361 else if (he_a->dir->name_len < he_b->dir->name_len)
10364 ret = he_b->dir->inode - he_a->dir->inode;
10369 /* Used for sorting the hash entry */
10370 static int hash_cmp(const void *a, const void *b)
10372 const struct hash_entry *he_a = (const struct hash_entry *) a;
10373 const struct hash_entry *he_b = (const struct hash_entry *) b;
10376 if (he_a->hash > he_b->hash)
10378 else if (he_a->hash < he_b->hash)
10381 if (he_a->minor_hash > he_b->minor_hash)
10383 else if (he_a->minor_hash < he_b->minor_hash)
10386 ret = name_cmp(a, b);
10391 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10397 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10400 outdir->buf = new_mem;
10401 new_mem = realloc(outdir->hashes,
10402 blocks * sizeof(ext2_dirhash_t));
10405 outdir->hashes = new_mem;
10407 outdir->buf = malloc(blocks * fs->blocksize);
10408 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10411 outdir->max = blocks;
10415 static void free_out_dir(struct out_dir *outdir)
10418 free(outdir->hashes);
10423 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10428 if (outdir->num >= outdir->max) {
10429 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10433 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10434 memset(*ret, 0, fs->blocksize);
10439 * This function is used to make a unique filename. We do this by
10440 * appending ~0, and then incrementing the number. However, we cannot
10441 * expand the length of the filename beyond the padding available in
10442 * the directory entry.
10444 static void mutate_name(char *str, __u16 *len)
10447 __u16 l = *len & 0xFF, h = *len & 0xff00;
10450 * First check to see if it looks the name has been mutated
10453 for (i = l-1; i > 0; i--) {
10454 if (!isdigit(str[i]))
10457 if ((i == l-1) || (str[i] != '~')) {
10458 if (((l-1) & 3) < 2)
10467 for (i = l-1; i >= 0; i--) {
10468 if (isdigit(str[i])) {
10480 else if (str[0] == 'Z') {
10485 } else if (i > 0) {
10498 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10500 struct fill_dir_struct *fd)
10502 struct problem_context pctx;
10503 struct hash_entry *ent, *prev;
10506 char new_name[256];
10509 clear_problem_context(&pctx);
10512 for (i=1; i < fd->num_array; i++) {
10513 ent = fd->harray + i;
10515 if (!ent->dir->inode ||
10516 ((ent->dir->name_len & 0xFF) !=
10517 (prev->dir->name_len & 0xFF)) ||
10518 (strncmp(ent->dir->name, prev->dir->name,
10519 ent->dir->name_len & 0xFF)))
10521 pctx.dirent = ent->dir;
10522 if ((ent->dir->inode == prev->dir->inode) &&
10523 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10524 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10525 ent->dir->inode = 0;
10529 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10530 new_len = ent->dir->name_len;
10531 mutate_name(new_name, &new_len);
10532 for (j=0; j < fd->num_array; j++) {
10534 ((ent->dir->name_len & 0xFF) !=
10535 (fd->harray[j].dir->name_len & 0xFF)) ||
10536 (strncmp(new_name, fd->harray[j].dir->name,
10539 mutate_name(new_name, &new_len);
10543 new_name[new_len & 0xFF] = 0;
10544 pctx.str = new_name;
10545 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10546 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10547 ent->dir->name_len = new_len;
10548 ext2fs_dirhash(fs->super->s_def_hash_version,
10550 ent->dir->name_len & 0xFF,
10551 fs->super->s_hash_seed,
10552 &ent->hash, &ent->minor_hash);
10560 static errcode_t copy_dir_entries(ext2_filsys fs,
10561 struct fill_dir_struct *fd,
10562 struct out_dir *outdir)
10566 struct hash_entry *ent;
10567 struct ext2_dir_entry *dirent;
10568 int i, rec_len, left;
10569 ext2_dirhash_t prev_hash;
10573 retval = alloc_size_dir(fs, outdir,
10574 (fd->dir_size / fs->blocksize) + 2);
10577 outdir->num = fd->compress ? 0 : 1;
10579 outdir->hashes[0] = 0;
10581 if ((retval = get_next_block(fs, outdir, &block_start)))
10583 dirent = (struct ext2_dir_entry *) block_start;
10584 left = fs->blocksize;
10585 for (i=0; i < fd->num_array; i++) {
10586 ent = fd->harray + i;
10587 if (ent->dir->inode == 0)
10589 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10590 if (rec_len > left) {
10592 dirent->rec_len += left;
10593 if ((retval = get_next_block(fs, outdir,
10598 left = fs->blocksize - offset;
10599 dirent = (struct ext2_dir_entry *) (block_start + offset);
10601 if (ent->hash == prev_hash)
10602 outdir->hashes[outdir->num-1] = ent->hash | 1;
10604 outdir->hashes[outdir->num-1] = ent->hash;
10606 dirent->inode = ent->dir->inode;
10607 dirent->name_len = ent->dir->name_len;
10608 dirent->rec_len = rec_len;
10609 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10613 dirent->rec_len += left;
10617 prev_hash = ent->hash;
10620 dirent->rec_len += left;
10626 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10627 ext2_ino_t ino, ext2_ino_t parent)
10629 struct ext2_dir_entry *dir;
10630 struct ext2_dx_root_info *root;
10631 struct ext2_dx_countlimit *limits;
10634 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10635 filetype = EXT2_FT_DIR << 8;
10637 memset(buf, 0, fs->blocksize);
10638 dir = (struct ext2_dir_entry *) buf;
10640 dir->name[0] = '.';
10641 dir->name_len = 1 | filetype;
10643 dir = (struct ext2_dir_entry *) (buf + 12);
10644 dir->inode = parent;
10645 dir->name[0] = '.';
10646 dir->name[1] = '.';
10647 dir->name_len = 2 | filetype;
10648 dir->rec_len = fs->blocksize - 12;
10650 root = (struct ext2_dx_root_info *) (buf+24);
10651 root->reserved_zero = 0;
10652 root->hash_version = fs->super->s_def_hash_version;
10653 root->info_length = 8;
10654 root->indirect_levels = 0;
10655 root->unused_flags = 0;
10657 limits = (struct ext2_dx_countlimit *) (buf+32);
10658 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10665 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10667 struct ext2_dir_entry *dir;
10668 struct ext2_dx_countlimit *limits;
10670 memset(buf, 0, fs->blocksize);
10671 dir = (struct ext2_dir_entry *) buf;
10673 dir->rec_len = fs->blocksize;
10675 limits = (struct ext2_dx_countlimit *) (buf+8);
10676 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10679 return (struct ext2_dx_entry *) limits;
10683 * This function takes the leaf nodes which have been written in
10684 * outdir, and populates the root node and any necessary interior nodes.
10686 static errcode_t calculate_tree(ext2_filsys fs,
10687 struct out_dir *outdir,
10691 struct ext2_dx_root_info *root_info;
10692 struct ext2_dx_entry *root, *dx_ent = 0;
10693 struct ext2_dx_countlimit *root_limit, *limit;
10695 char * block_start;
10696 int i, c1, c2, nblks;
10697 int limit_offset, root_offset;
10699 root_info = set_root_node(fs, outdir->buf, ino, parent);
10700 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10701 root_info->info_length;
10702 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10703 c1 = root_limit->limit;
10704 nblks = outdir->num;
10706 /* Write out the pointer blocks */
10707 if (nblks-1 <= c1) {
10708 /* Just write out the root block, and we're done */
10709 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10710 for (i=1; i < nblks; i++) {
10711 root->block = ext2fs_cpu_to_le32(i);
10714 ext2fs_cpu_to_le32(outdir->hashes[i]);
10721 root_info->indirect_levels = 1;
10722 for (i=1; i < nblks; i++) {
10727 limit->limit = limit->count =
10728 ext2fs_cpu_to_le16(limit->limit);
10729 root = (struct ext2_dx_entry *)
10730 (outdir->buf + root_offset);
10731 root->block = ext2fs_cpu_to_le32(outdir->num);
10734 ext2fs_cpu_to_le32(outdir->hashes[i]);
10735 if ((retval = get_next_block(fs, outdir,
10738 dx_ent = set_int_node(fs, block_start);
10739 limit = (struct ext2_dx_countlimit *) dx_ent;
10741 root_offset += sizeof(struct ext2_dx_entry);
10744 dx_ent->block = ext2fs_cpu_to_le32(i);
10745 if (c2 != limit->limit)
10747 ext2fs_cpu_to_le32(outdir->hashes[i]);
10751 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10752 limit->limit = ext2fs_cpu_to_le16(limit->limit);
10754 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10755 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10756 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10761 struct write_dir_struct {
10762 struct out_dir *outdir;
10769 * Helper function which writes out a directory block.
10771 static int write_dir_block(ext2_filsys fs,
10773 e2_blkcnt_t blockcnt,
10774 blk_t ref_block FSCK_ATTR((unused)),
10775 int ref_offset FSCK_ATTR((unused)),
10778 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10782 if (*block_nr == 0)
10784 if (blockcnt >= wd->outdir->num) {
10785 e2fsck_read_bitmaps(wd->ctx);
10787 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10788 ext2fs_block_alloc_stats(fs, blk, -1);
10791 return BLOCK_CHANGED;
10796 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10797 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10799 return BLOCK_ABORT;
10803 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10804 struct out_dir *outdir,
10805 ext2_ino_t ino, int compress)
10807 struct write_dir_struct wd;
10809 struct ext2_inode inode;
10811 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10815 wd.outdir = outdir;
10820 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10821 write_dir_block, &wd);
10827 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10829 inode.i_flags &= ~EXT2_INDEX_FL;
10831 inode.i_flags |= EXT2_INDEX_FL;
10832 inode.i_size = outdir->num * fs->blocksize;
10833 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10834 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10839 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10841 ext2_filsys fs = ctx->fs;
10843 struct ext2_inode inode;
10845 struct fill_dir_struct fd;
10846 struct out_dir outdir;
10848 outdir.max = outdir.num = 0;
10851 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10855 dir_buf = malloc(inode.i_size);
10859 fd.max_array = inode.i_size / 32;
10861 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
10871 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10872 (inode.i_size / fs->blocksize) < 2)
10876 /* Read in the entire directory into memory */
10877 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10878 fill_dir_block, &fd);
10884 /* Sort the list */
10887 qsort(fd.harray+2, fd.num_array-2,
10888 sizeof(struct hash_entry), name_cmp);
10890 qsort(fd.harray, fd.num_array,
10891 sizeof(struct hash_entry), hash_cmp);
10894 * Look for duplicates
10896 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10899 if (ctx->options & E2F_OPT_NO) {
10905 * Copy the directory entries. In a htree directory these
10906 * will become the leaf nodes.
10908 retval = copy_dir_entries(fs, &fd, &outdir);
10912 free(dir_buf); dir_buf = 0;
10914 if (!fd.compress) {
10915 /* Calculate the interior nodes */
10916 retval = calculate_tree(fs, &outdir, ino, fd.parent);
10921 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10927 free_out_dir(&outdir);
10931 void e2fsck_rehash_directories(e2fsck_t ctx)
10933 struct problem_context pctx;
10934 struct dir_info *dir;
10935 ext2_u32_iterate iter;
10938 int i, cur, max, all_dirs, dir_index, first = 1;
10940 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10942 if (!ctx->dirs_to_hash && !all_dirs)
10945 e2fsck_get_lost_and_found(ctx, 0);
10947 clear_problem_context(&pctx);
10949 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10953 max = e2fsck_get_num_dirinfo(ctx);
10955 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10958 pctx.errcode = retval;
10959 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10962 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10966 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10970 if (!ext2fs_u32_list_iterate(iter, &ino))
10973 if (ino == ctx->lost_and_found)
10977 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
10980 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
10981 if (pctx.errcode) {
10982 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10983 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
10985 if (ctx->progress && !ctx->progress_fd)
10986 e2fsck_simple_progress(ctx, "Rebuilding directory",
10987 100.0 * (float) (++cur) / (float) max, ino);
10989 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
10991 ext2fs_u32_list_iterate_end(iter);
10993 ext2fs_u32_list_free(ctx->dirs_to_hash);
10994 ctx->dirs_to_hash = 0;
10998 * linux/fs/revoke.c
11000 * Journal revoke routines for the generic filesystem journaling code;
11001 * part of the ext2fs journaling system.
11003 * Revoke is the mechanism used to prevent old log records for deleted
11004 * metadata from being replayed on top of newer data using the same
11005 * blocks. The revoke mechanism is used in two separate places:
11007 * + Commit: during commit we write the entire list of the current
11008 * transaction's revoked blocks to the journal
11010 * + Recovery: during recovery we record the transaction ID of all
11011 * revoked blocks. If there are multiple revoke records in the log
11012 * for a single block, only the last one counts, and if there is a log
11013 * entry for a block beyond the last revoke, then that log entry still
11016 * We can get interactions between revokes and new log data within a
11017 * single transaction:
11019 * Block is revoked and then journaled:
11020 * The desired end result is the journaling of the new block, so we
11021 * cancel the revoke before the transaction commits.
11023 * Block is journaled and then revoked:
11024 * The revoke must take precedence over the write of the block, so we
11025 * need either to cancel the journal entry or to write the revoke
11026 * later in the log than the log block. In this case, we choose the
11027 * latter: journaling a block cancels any revoke record for that block
11028 * in the current transaction, so any revoke for that block in the
11029 * transaction must have happened after the block was journaled and so
11030 * the revoke must take precedence.
11032 * Block is revoked and then written as data:
11033 * The data write is allowed to succeed, but the revoke is _not_
11034 * cancelled. We still need to prevent old log records from
11035 * overwriting the new data. We don't even need to clear the revoke
11038 * Revoke information on buffers is a tri-state value:
11040 * RevokeValid clear: no cached revoke status, need to look it up
11041 * RevokeValid set, Revoked clear:
11042 * buffer has not been revoked, and cancel_revoke
11044 * RevokeValid set, Revoked set:
11045 * buffer has been revoked.
11048 static kmem_cache_t *revoke_record_cache;
11049 static kmem_cache_t *revoke_table_cache;
11051 /* Each revoke record represents one single revoked block. During
11052 journal replay, this involves recording the transaction ID of the
11053 last transaction to revoke this block. */
11055 struct jbd_revoke_record_s
11057 struct list_head hash;
11058 tid_t sequence; /* Used for recovery only */
11059 unsigned long blocknr;
11063 /* The revoke table is just a simple hash table of revoke records. */
11064 struct jbd_revoke_table_s
11066 /* It is conceivable that we might want a larger hash table
11067 * for recovery. Must be a power of two. */
11070 struct list_head *hash_table;
11074 /* Utility functions to maintain the revoke table */
11076 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11077 static int hash(journal_t *journal, unsigned long block)
11079 struct jbd_revoke_table_s *table = journal->j_revoke;
11080 int hash_shift = table->hash_shift;
11082 return ((block << (hash_shift - 6)) ^
11084 (block << (hash_shift - 12))) & (table->hash_size - 1);
11087 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11090 struct list_head *hash_list;
11091 struct jbd_revoke_record_s *record;
11093 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11097 record->sequence = seq;
11098 record->blocknr = blocknr;
11099 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11100 list_add(&record->hash, hash_list);
11107 /* Find a revoke record in the journal's hash table. */
11109 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11110 unsigned long blocknr)
11112 struct list_head *hash_list;
11113 struct jbd_revoke_record_s *record;
11115 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11117 record = (struct jbd_revoke_record_s *) hash_list->next;
11118 while (&(record->hash) != hash_list) {
11119 if (record->blocknr == blocknr)
11121 record = (struct jbd_revoke_record_s *) record->hash.next;
11126 int journal_init_revoke_caches(void)
11128 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11129 if (revoke_record_cache == 0)
11132 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11133 if (revoke_table_cache == 0) {
11134 do_cache_destroy(revoke_record_cache);
11135 revoke_record_cache = NULL;
11141 void journal_destroy_revoke_caches(void)
11143 do_cache_destroy(revoke_record_cache);
11144 revoke_record_cache = 0;
11145 do_cache_destroy(revoke_table_cache);
11146 revoke_table_cache = 0;
11149 /* Initialise the revoke table for a given journal to a given size. */
11151 int journal_init_revoke(journal_t *journal, int hash_size)
11155 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11156 if (!journal->j_revoke)
11159 /* Check that the hash_size is a power of two */
11160 journal->j_revoke->hash_size = hash_size;
11164 while((tmp >>= 1UL) != 0UL)
11166 journal->j_revoke->hash_shift = shift;
11168 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11169 if (!journal->j_revoke->hash_table) {
11170 free(journal->j_revoke);
11171 journal->j_revoke = NULL;
11175 for (tmp = 0; tmp < hash_size; tmp++)
11176 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11181 /* Destoy a journal's revoke table. The table must already be empty! */
11183 void journal_destroy_revoke(journal_t *journal)
11185 struct jbd_revoke_table_s *table;
11186 struct list_head *hash_list;
11189 table = journal->j_revoke;
11193 for (i=0; i<table->hash_size; i++) {
11194 hash_list = &table->hash_table[i];
11197 free(table->hash_table);
11199 journal->j_revoke = NULL;
11203 * Revoke support for recovery.
11205 * Recovery needs to be able to:
11207 * record all revoke records, including the tid of the latest instance
11208 * of each revoke in the journal
11210 * check whether a given block in a given transaction should be replayed
11211 * (ie. has not been revoked by a revoke record in that or a subsequent
11214 * empty the revoke table after recovery.
11218 * First, setting revoke records. We create a new revoke record for
11219 * every block ever revoked in the log as we scan it for recovery, and
11220 * we update the existing records if we find multiple revokes for a
11224 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11227 struct jbd_revoke_record_s *record;
11229 record = find_revoke_record(journal, blocknr);
11231 /* If we have multiple occurences, only record the
11232 * latest sequence number in the hashed record */
11233 if (tid_gt(sequence, record->sequence))
11234 record->sequence = sequence;
11237 return insert_revoke_hash(journal, blocknr, sequence);
11241 * Test revoke records. For a given block referenced in the log, has
11242 * that block been revoked? A revoke record with a given transaction
11243 * sequence number revokes all blocks in that transaction and earlier
11244 * ones, but later transactions still need replayed.
11247 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11250 struct jbd_revoke_record_s *record;
11252 record = find_revoke_record(journal, blocknr);
11255 if (tid_gt(sequence, record->sequence))
11261 * Finally, once recovery is over, we need to clear the revoke table so
11262 * that it can be reused by the running filesystem.
11265 void journal_clear_revoke(journal_t *journal)
11268 struct list_head *hash_list;
11269 struct jbd_revoke_record_s *record;
11270 struct jbd_revoke_table_s *revoke_var;
11272 revoke_var = journal->j_revoke;
11274 for (i = 0; i < revoke_var->hash_size; i++) {
11275 hash_list = &revoke_var->hash_table[i];
11276 while (!list_empty(hash_list)) {
11277 record = (struct jbd_revoke_record_s*) hash_list->next;
11278 list_del(&record->hash);
11285 * e2fsck.c - superblock checks
11288 #define MIN_CHECK 1
11289 #define MAX_CHECK 2
11291 static void check_super_value(e2fsck_t ctx, const char *descr,
11292 unsigned long value, int flags,
11293 unsigned long min_val, unsigned long max_val)
11295 struct problem_context pctx;
11297 if (((flags & MIN_CHECK) && (value < min_val)) ||
11298 ((flags & MAX_CHECK) && (value > max_val))) {
11299 clear_problem_context(&pctx);
11302 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11303 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11308 * This routine may get stubbed out in special compilations of the
11311 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11312 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11314 return (ext2fs_get_device_size(ctx->filesystem_name,
11315 EXT2_BLOCK_SIZE(ctx->fs->super),
11316 &ctx->num_blocks));
11321 * helper function to release an inode
11323 struct process_block_struct {
11326 struct problem_context *pctx;
11328 int truncate_offset;
11329 e2_blkcnt_t truncate_block;
11330 int truncated_blocks;
11335 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11336 e2_blkcnt_t blockcnt,
11337 blk_t ref_blk FSCK_ATTR((unused)),
11338 int ref_offset FSCK_ATTR((unused)),
11341 struct process_block_struct *pb;
11343 struct problem_context *pctx;
11344 blk_t blk = *block_nr;
11347 pb = (struct process_block_struct *) priv_data;
11352 pctx->blkcount = blockcnt;
11354 if (HOLE_BLKADDR(blk))
11357 if ((blk < fs->super->s_first_data_block) ||
11358 (blk >= fs->super->s_blocks_count)) {
11359 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11362 return BLOCK_ABORT;
11365 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11366 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11371 * If we are deleting an orphan, then we leave the fields alone.
11372 * If we are truncating an orphan, then update the inode fields
11373 * and clean up any partial block data.
11375 if (pb->truncating) {
11377 * We only remove indirect blocks if they are
11378 * completely empty.
11380 if (blockcnt < 0) {
11384 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11389 limit = fs->blocksize >> 2;
11390 for (i = 0, bp = (blk_t *) pb->buf;
11391 i < limit; i++, bp++)
11396 * We don't remove direct blocks until we've reached
11397 * the truncation block.
11399 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11402 * If part of the last block needs truncating, we do
11405 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11406 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11410 memset(pb->buf + pb->truncate_offset, 0,
11411 fs->blocksize - pb->truncate_offset);
11412 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11417 pb->truncated_blocks++;
11419 retval |= BLOCK_CHANGED;
11422 ext2fs_block_alloc_stats(fs, blk, -1);
11427 * This function releases an inode. Returns 1 if an inconsistency was
11428 * found. If the inode has a link count, then it is being truncated and
11431 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11432 struct ext2_inode *inode, char *block_buf,
11433 struct problem_context *pctx)
11435 struct process_block_struct pb;
11436 ext2_filsys fs = ctx->fs;
11440 if (!ext2fs_inode_has_valid_blocks(inode))
11443 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11448 if (inode->i_links_count) {
11450 pb.truncate_block = (e2_blkcnt_t)
11451 ((((long long)inode->i_size_high << 32) +
11452 inode->i_size + fs->blocksize - 1) /
11454 pb.truncate_offset = inode->i_size % fs->blocksize;
11457 pb.truncate_block = 0;
11458 pb.truncate_offset = 0;
11460 pb.truncated_blocks = 0;
11461 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11462 block_buf, release_inode_block, &pb);
11464 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11471 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11472 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11474 if (pb.truncated_blocks)
11475 inode->i_blocks -= pb.truncated_blocks *
11476 (fs->blocksize / 512);
11478 if (inode->i_file_acl) {
11479 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11480 block_buf, -1, &count);
11481 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11486 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11491 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11492 inode->i_file_acl = 0;
11498 * This function releases all of the orphan inodes. It returns 1 if
11499 * it hit some error, and 0 on success.
11501 static int release_orphan_inodes(e2fsck_t ctx)
11503 ext2_filsys fs = ctx->fs;
11504 ext2_ino_t ino, next_ino;
11505 struct ext2_inode inode;
11506 struct problem_context pctx;
11509 if ((ino = fs->super->s_last_orphan) == 0)
11513 * Win or lose, we won't be using the head of the orphan inode
11516 fs->super->s_last_orphan = 0;
11517 ext2fs_mark_super_dirty(fs);
11520 * If the filesystem contains errors, don't run the orphan
11521 * list, since the orphan list can't be trusted; and we're
11522 * going to be running a full e2fsck run anyway...
11524 if (fs->super->s_state & EXT2_ERROR_FS)
11527 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11528 (ino > fs->super->s_inodes_count)) {
11529 clear_problem_context(&pctx);
11531 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11535 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11536 "block iterate buffer");
11537 e2fsck_read_bitmaps(ctx);
11540 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11541 clear_problem_context(&pctx);
11543 pctx.inode = &inode;
11544 pctx.str = inode.i_links_count ? _("Truncating") :
11547 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11549 next_ino = inode.i_dtime;
11551 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11552 (next_ino > fs->super->s_inodes_count))) {
11553 pctx.ino = next_ino;
11554 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11558 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11561 if (!inode.i_links_count) {
11562 ext2fs_inode_alloc_stats2(fs, ino, -1,
11563 LINUX_S_ISDIR(inode.i_mode));
11564 inode.i_dtime = time(0);
11568 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11571 ext2fs_free_mem(&block_buf);
11574 ext2fs_free_mem(&block_buf);
11579 * Check the resize inode to make sure it is sane. We check both for
11580 * the case where on-line resizing is not enabled (in which case the
11581 * resize inode should be cleared) as well as the case where on-line
11582 * resizing is enabled.
11584 static void check_resize_inode(e2fsck_t ctx)
11586 ext2_filsys fs = ctx->fs;
11587 struct ext2_inode inode;
11588 struct problem_context pctx;
11589 int i, j, gdt_off, ind_off;
11590 blk_t blk, pblk, expect;
11591 __u32 *dind_buf = 0, *ind_buf;
11594 clear_problem_context(&pctx);
11597 * If the resize inode feature isn't set, then
11598 * s_reserved_gdt_blocks must be zero.
11600 if (!(fs->super->s_feature_compat &
11601 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11602 if (fs->super->s_reserved_gdt_blocks) {
11603 pctx.num = fs->super->s_reserved_gdt_blocks;
11604 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11606 fs->super->s_reserved_gdt_blocks = 0;
11607 ext2fs_mark_super_dirty(fs);
11612 /* Read the resize inode */
11613 pctx.ino = EXT2_RESIZE_INO;
11614 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11616 if (fs->super->s_feature_compat &
11617 EXT2_FEATURE_COMPAT_RESIZE_INODE)
11618 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11623 * If the resize inode feature isn't set, check to make sure
11624 * the resize inode is cleared; then we're done.
11626 if (!(fs->super->s_feature_compat &
11627 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11628 for (i=0; i < EXT2_N_BLOCKS; i++) {
11629 if (inode.i_block[i])
11632 if ((i < EXT2_N_BLOCKS) &&
11633 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11634 memset(&inode, 0, sizeof(inode));
11635 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11642 * The resize inode feature is enabled; check to make sure the
11643 * only block in use is the double indirect block
11645 blk = inode.i_block[EXT2_DIND_BLOCK];
11646 for (i=0; i < EXT2_N_BLOCKS; i++) {
11647 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11650 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11651 !(inode.i_mode & LINUX_S_IFREG) ||
11652 (blk < fs->super->s_first_data_block ||
11653 blk >= fs->super->s_blocks_count)) {
11654 resize_inode_invalid:
11655 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11656 memset(&inode, 0, sizeof(inode));
11657 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11659 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11661 if (!(ctx->options & E2F_OPT_READONLY)) {
11662 fs->super->s_state &= ~EXT2_VALID_FS;
11663 ext2fs_mark_super_dirty(fs);
11667 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11668 "resize dind buffer");
11669 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11671 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11673 goto resize_inode_invalid;
11675 gdt_off = fs->desc_blocks;
11676 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11677 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11678 i++, gdt_off++, pblk++) {
11679 gdt_off %= fs->blocksize/4;
11680 if (dind_buf[gdt_off] != pblk)
11681 goto resize_inode_invalid;
11682 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11684 goto resize_inode_invalid;
11686 for (j = 1; j < fs->group_desc_count; j++) {
11687 if (!ext2fs_bg_has_super(fs, j))
11689 expect = pblk + (j * fs->super->s_blocks_per_group);
11690 if (ind_buf[ind_off] != expect)
11691 goto resize_inode_invalid;
11697 ext2fs_free_mem(&dind_buf);
11701 static void check_super_block(e2fsck_t ctx)
11703 ext2_filsys fs = ctx->fs;
11704 blk_t first_block, last_block;
11705 struct ext2_super_block *sb = fs->super;
11706 struct ext2_group_desc *gd;
11707 blk_t blocks_per_group = fs->super->s_blocks_per_group;
11709 int inodes_per_block;
11714 struct problem_context pctx;
11715 __u32 free_blocks = 0, free_inodes = 0;
11717 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11718 ipg_max = inodes_per_block * (blocks_per_group - 4);
11719 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11720 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11721 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11722 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11723 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11725 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11726 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11727 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11728 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11729 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11730 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11732 clear_problem_context(&pctx);
11735 * Verify the super block constants...
11737 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11739 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11741 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11742 MAX_CHECK, 0, sb->s_blocks_count);
11743 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11744 MIN_CHECK | MAX_CHECK, 0,
11745 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11746 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11747 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11748 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11749 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11751 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11752 MIN_CHECK | MAX_CHECK, 8, bpg_max);
11753 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11754 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11755 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11756 MAX_CHECK, 0, sb->s_blocks_count / 2);
11757 check_super_value(ctx, "reserved_gdt_blocks",
11758 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11760 inode_size = EXT2_INODE_SIZE(sb);
11761 check_super_value(ctx, "inode_size",
11762 inode_size, MIN_CHECK | MAX_CHECK,
11763 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11764 if (inode_size & (inode_size - 1)) {
11765 pctx.num = inode_size;
11766 pctx.str = "inode_size";
11767 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11768 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11772 if (!ctx->num_blocks) {
11773 pctx.errcode = e2fsck_get_device_size(ctx);
11774 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11775 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11776 ctx->flags |= E2F_FLAG_ABORT;
11779 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11780 (ctx->num_blocks < sb->s_blocks_count)) {
11781 pctx.blk = sb->s_blocks_count;
11782 pctx.blk2 = ctx->num_blocks;
11783 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11784 ctx->flags |= E2F_FLAG_ABORT;
11790 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11791 pctx.blk = EXT2_BLOCK_SIZE(sb);
11792 pctx.blk2 = EXT2_FRAG_SIZE(sb);
11793 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11794 ctx->flags |= E2F_FLAG_ABORT;
11798 should_be = sb->s_frags_per_group >>
11799 (sb->s_log_block_size - sb->s_log_frag_size);
11800 if (sb->s_blocks_per_group != should_be) {
11801 pctx.blk = sb->s_blocks_per_group;
11802 pctx.blk2 = should_be;
11803 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11804 ctx->flags |= E2F_FLAG_ABORT;
11808 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11809 if (sb->s_first_data_block != should_be) {
11810 pctx.blk = sb->s_first_data_block;
11811 pctx.blk2 = should_be;
11812 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11813 ctx->flags |= E2F_FLAG_ABORT;
11817 should_be = sb->s_inodes_per_group * fs->group_desc_count;
11818 if (sb->s_inodes_count != should_be) {
11819 pctx.ino = sb->s_inodes_count;
11820 pctx.ino2 = should_be;
11821 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11822 sb->s_inodes_count = should_be;
11823 ext2fs_mark_super_dirty(fs);
11828 * Verify the group descriptors....
11830 first_block = sb->s_first_data_block;
11831 last_block = first_block + blocks_per_group;
11833 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11836 if (i == fs->group_desc_count - 1)
11837 last_block = sb->s_blocks_count;
11838 if ((gd->bg_block_bitmap < first_block) ||
11839 (gd->bg_block_bitmap >= last_block)) {
11840 pctx.blk = gd->bg_block_bitmap;
11841 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11842 gd->bg_block_bitmap = 0;
11844 if (gd->bg_block_bitmap == 0) {
11845 ctx->invalid_block_bitmap_flag[i]++;
11846 ctx->invalid_bitmaps++;
11848 if ((gd->bg_inode_bitmap < first_block) ||
11849 (gd->bg_inode_bitmap >= last_block)) {
11850 pctx.blk = gd->bg_inode_bitmap;
11851 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11852 gd->bg_inode_bitmap = 0;
11854 if (gd->bg_inode_bitmap == 0) {
11855 ctx->invalid_inode_bitmap_flag[i]++;
11856 ctx->invalid_bitmaps++;
11858 if ((gd->bg_inode_table < first_block) ||
11859 ((gd->bg_inode_table +
11860 fs->inode_blocks_per_group - 1) >= last_block)) {
11861 pctx.blk = gd->bg_inode_table;
11862 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11863 gd->bg_inode_table = 0;
11865 if (gd->bg_inode_table == 0) {
11866 ctx->invalid_inode_table_flag[i]++;
11867 ctx->invalid_bitmaps++;
11869 free_blocks += gd->bg_free_blocks_count;
11870 free_inodes += gd->bg_free_inodes_count;
11871 first_block += sb->s_blocks_per_group;
11872 last_block += sb->s_blocks_per_group;
11874 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11875 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11876 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11877 ext2fs_unmark_valid(fs);
11882 * Update the global counts from the block group counts. This
11883 * is needed for an experimental patch which eliminates
11884 * locking the entire filesystem when allocating blocks or
11885 * inodes; if the filesystem is not unmounted cleanly, the
11886 * global counts may not be accurate.
11888 if ((free_blocks != sb->s_free_blocks_count) ||
11889 (free_inodes != sb->s_free_inodes_count)) {
11890 if (ctx->options & E2F_OPT_READONLY)
11891 ext2fs_unmark_valid(fs);
11893 sb->s_free_blocks_count = free_blocks;
11894 sb->s_free_inodes_count = free_inodes;
11895 ext2fs_mark_super_dirty(fs);
11899 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11900 (sb->s_free_inodes_count > sb->s_inodes_count))
11901 ext2fs_unmark_valid(fs);
11905 * If we have invalid bitmaps, set the error state of the
11908 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11909 sb->s_state &= ~EXT2_VALID_FS;
11910 ext2fs_mark_super_dirty(fs);
11913 clear_problem_context(&pctx);
11916 * If the UUID field isn't assigned, assign it.
11918 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11919 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11920 uuid_generate(sb->s_uuid);
11921 ext2fs_mark_super_dirty(fs);
11922 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11926 /* FIXME - HURD support?
11927 * For the Hurd, check to see if the filetype option is set,
11928 * since it doesn't support it.
11930 if (!(ctx->options & E2F_OPT_READONLY) &&
11931 fs->super->s_creator_os == EXT2_OS_HURD &&
11932 (fs->super->s_feature_incompat &
11933 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11934 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11935 fs->super->s_feature_incompat &=
11936 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11937 ext2fs_mark_super_dirty(fs);
11943 * If we have any of the compatibility flags set, we need to have a
11944 * revision 1 filesystem. Most kernels will not check the flags on
11945 * a rev 0 filesystem and we may have corruption issues because of
11946 * the incompatible changes to the filesystem.
11948 if (!(ctx->options & E2F_OPT_READONLY) &&
11949 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11950 (fs->super->s_feature_compat ||
11951 fs->super->s_feature_ro_compat ||
11952 fs->super->s_feature_incompat) &&
11953 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11954 ext2fs_update_dynamic_rev(fs);
11955 ext2fs_mark_super_dirty(fs);
11958 check_resize_inode(ctx);
11961 * Clean up any orphan inodes, if present.
11963 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11964 fs->super->s_state &= ~EXT2_VALID_FS;
11965 ext2fs_mark_super_dirty(fs);
11969 * Move the ext3 journal file, if necessary.
11971 e2fsck_move_ext3_journal(ctx);
11976 * swapfs.c --- byte-swap an ext2 filesystem
11979 #ifdef ENABLE_SWAPFS
11981 struct swap_block_struct {
11986 struct ext2_inode *inode;
11990 * This is a helper function for block_iterate. We mark all of the
11991 * indirect and direct blocks as changed, so that block_iterate will
11994 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
11999 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
12001 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
12002 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
12004 sb->errcode = retval;
12005 return BLOCK_ABORT;
12007 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
12009 sb->errcode = retval;
12010 return BLOCK_ABORT;
12013 if (blockcnt >= 0) {
12014 if (blockcnt < EXT2_NDIR_BLOCKS)
12016 return BLOCK_CHANGED;
12018 if (blockcnt == BLOCK_COUNT_IND) {
12019 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
12021 return BLOCK_CHANGED;
12023 if (blockcnt == BLOCK_COUNT_DIND) {
12024 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12026 return BLOCK_CHANGED;
12028 if (blockcnt == BLOCK_COUNT_TIND) {
12029 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12031 return BLOCK_CHANGED;
12033 return BLOCK_CHANGED;
12037 * This function is responsible for byte-swapping all of the indirect,
12038 * block pointers. It is also responsible for byte-swapping directories.
12040 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12041 struct ext2_inode *inode)
12044 struct swap_block_struct sb;
12048 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12051 if (LINUX_S_ISDIR(inode->i_mode))
12054 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12057 bb_error_msg(_("while calling ext2fs_block_iterate"));
12058 ctx->flags |= E2F_FLAG_ABORT;
12062 bb_error_msg(_("while calling iterator function"));
12063 ctx->flags |= E2F_FLAG_ABORT;
12068 static void swap_inodes(e2fsck_t ctx)
12070 ext2_filsys fs = ctx->fs;
12073 ext2_ino_t ino = 1;
12074 char *buf, *block_buf;
12076 struct ext2_inode * inode;
12078 e2fsck_use_inode_shortcuts(ctx, 1);
12080 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12083 bb_error_msg(_("while allocating inode buffer"));
12084 ctx->flags |= E2F_FLAG_ABORT;
12087 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12088 "block interate buffer");
12089 for (group = 0; group < fs->group_desc_count; group++) {
12090 retval = io_channel_read_blk(fs->io,
12091 fs->group_desc[group].bg_inode_table,
12092 fs->inode_blocks_per_group, buf);
12094 bb_error_msg(_("while reading inode table (group %d)"),
12096 ctx->flags |= E2F_FLAG_ABORT;
12099 inode = (struct ext2_inode *) buf;
12100 for (i=0; i < fs->super->s_inodes_per_group;
12101 i++, ino++, inode++) {
12102 ctx->stashed_ino = ino;
12103 ctx->stashed_inode = inode;
12105 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12106 ext2fs_swap_inode(fs, inode, inode, 0);
12109 * Skip deleted files.
12111 if (inode->i_links_count == 0)
12114 if (LINUX_S_ISDIR(inode->i_mode) ||
12115 ((inode->i_block[EXT2_IND_BLOCK] ||
12116 inode->i_block[EXT2_DIND_BLOCK] ||
12117 inode->i_block[EXT2_TIND_BLOCK]) &&
12118 ext2fs_inode_has_valid_blocks(inode)))
12119 swap_inode_blocks(ctx, ino, block_buf, inode);
12121 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12124 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12125 ext2fs_swap_inode(fs, inode, inode, 1);
12127 retval = io_channel_write_blk(fs->io,
12128 fs->group_desc[group].bg_inode_table,
12129 fs->inode_blocks_per_group, buf);
12131 bb_error_msg(_("while writing inode table (group %d)"),
12133 ctx->flags |= E2F_FLAG_ABORT;
12137 ext2fs_free_mem(&buf);
12138 ext2fs_free_mem(&block_buf);
12139 e2fsck_use_inode_shortcuts(ctx, 0);
12140 ext2fs_flush_icache(fs);
12143 #if defined(__powerpc__) && BB_BIG_ENDIAN
12145 * On the PowerPC, the big-endian variant of the ext2 filesystem
12146 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12147 * of each word. Thus a bitmap with only bit 0 set would be, as
12148 * a string of bytes, 00 00 00 01 00 ...
12149 * To cope with this, we byte-reverse each word of a bitmap if
12150 * we have a big-endian filesystem, that is, if we are *not*
12151 * byte-swapping other word-sized numbers.
12153 #define EXT2_BIG_ENDIAN_BITMAPS
12156 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12157 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12159 __u32 *p = (__u32 *) bmap->bitmap;
12160 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12162 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12163 *p = ext2fs_swab32(*p);
12168 #ifdef ENABLE_SWAPFS
12169 static void swap_filesys(e2fsck_t ctx)
12171 ext2_filsys fs = ctx->fs;
12172 if (!(ctx->options & E2F_OPT_PREEN))
12173 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12177 if (fs->super->s_mnt_count) {
12178 fprintf(stderr, _("%s: the filesystem must be freshly "
12179 "checked using fsck\n"
12180 "and not mounted before trying to "
12181 "byte-swap it.\n"), ctx->device_name);
12182 ctx->flags |= E2F_FLAG_ABORT;
12185 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12186 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12187 EXT2_FLAG_SWAP_BYTES_WRITE);
12188 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12190 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12191 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12194 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12196 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12197 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12198 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12199 EXT2_FLAG_SWAP_BYTES_WRITE);
12201 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12202 e2fsck_read_bitmaps(ctx);
12203 ext2fs_swap_bitmap(fs->inode_map);
12204 ext2fs_swap_bitmap(fs->block_map);
12205 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12207 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12209 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12211 #endif /* ENABLE_SWAPFS */
12216 * util.c --- miscellaneous utilities
12220 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12221 const char *description)
12226 ret = malloc(size);
12228 sprintf(buf, "Can't allocate %s\n", description);
12229 bb_error_msg_and_die(buf);
12231 memset(ret, 0, size);
12235 static char *string_copy(const char *str, int len)
12243 ret = malloc(len+1);
12245 strncpy(ret, str, len);
12251 #ifndef HAVE_CONIO_H
12252 static int read_a_char(void)
12259 if (e2fsck_global_ctx &&
12260 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12263 r = read(0, &c, 1);
12273 static int ask_yn(const char * string, int def)
12276 const char *defstr;
12277 static const char short_yes[] = "yY";
12278 static const char short_no[] = "nN";
12280 #ifdef HAVE_TERMIOS_H
12281 struct termios termios, tmp;
12283 tcgetattr (0, &termios);
12285 tmp.c_lflag &= ~(ICANON | ECHO);
12286 tmp.c_cc[VMIN] = 1;
12287 tmp.c_cc[VTIME] = 0;
12288 tcsetattr (0, TCSANOW, &tmp);
12297 printf("%s%s? ", string, defstr);
12300 if ((c = read_a_char()) == EOF)
12303 #ifdef HAVE_TERMIOS_H
12304 tcsetattr (0, TCSANOW, &termios);
12306 if (e2fsck_global_ctx &&
12307 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12309 longjmp(e2fsck_global_ctx->abort_loc, 1);
12311 puts(_("cancelled!\n"));
12314 if (strchr(short_yes, (char) c)) {
12318 else if (strchr(short_no, (char) c)) {
12322 else if ((c == ' ' || c == '\n') && (def != -1))
12329 #ifdef HAVE_TERMIOS_H
12330 tcsetattr (0, TCSANOW, &termios);
12335 int ask (e2fsck_t ctx, const char * string, int def)
12337 if (ctx->options & E2F_OPT_NO) {
12338 printf(_("%s? no\n\n"), string);
12341 if (ctx->options & E2F_OPT_YES) {
12342 printf(_("%s? yes\n\n"), string);
12345 if (ctx->options & E2F_OPT_PREEN) {
12346 printf("%s? %s\n\n", string, def ? _("yes") : _("no"));
12349 return ask_yn(string, def);
12352 void e2fsck_read_bitmaps(e2fsck_t ctx)
12354 ext2_filsys fs = ctx->fs;
12357 if (ctx->invalid_bitmaps) {
12358 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12360 bb_error_msg_and_die(0);
12363 ehandler_operation(_("reading inode and block bitmaps"));
12364 retval = ext2fs_read_bitmaps(fs);
12365 ehandler_operation(0);
12367 bb_error_msg(_("while retrying to read bitmaps for %s"),
12369 bb_error_msg_and_die(0);
12373 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12375 ext2_filsys fs = ctx->fs;
12378 if (ext2fs_test_bb_dirty(fs)) {
12379 ehandler_operation(_("writing block bitmaps"));
12380 retval = ext2fs_write_block_bitmap(fs);
12381 ehandler_operation(0);
12383 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12385 bb_error_msg_and_die(0);
12389 if (ext2fs_test_ib_dirty(fs)) {
12390 ehandler_operation(_("writing inode bitmaps"));
12391 retval = ext2fs_write_inode_bitmap(fs);
12392 ehandler_operation(0);
12394 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12396 bb_error_msg_and_die(0);
12401 void preenhalt(e2fsck_t ctx)
12403 ext2_filsys fs = ctx->fs;
12405 if (!(ctx->options & E2F_OPT_PREEN))
12407 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12408 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12411 fs->super->s_state |= EXT2_ERROR_FS;
12412 ext2fs_mark_super_dirty(fs);
12415 exit(EXIT_UNCORRECTED);
12418 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12419 struct ext2_inode * inode, const char *proc)
12423 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12425 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12426 bb_error_msg_and_die(0);
12430 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12431 struct ext2_inode * inode, int bufsize,
12436 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12438 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12439 bb_error_msg_and_die(0);
12443 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12444 struct ext2_inode * inode, const char *proc)
12448 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12450 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12451 bb_error_msg_and_die(0);
12455 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12456 io_manager manager)
12458 struct ext2_super_block *sb;
12459 io_channel io = NULL;
12462 blk_t superblock, ret_sb = 8193;
12464 if (fs && fs->super) {
12465 ret_sb = (fs->super->s_blocks_per_group +
12466 fs->super->s_first_data_block);
12468 ctx->superblock = ret_sb;
12469 ctx->blocksize = fs->blocksize;
12475 if (ctx->blocksize) {
12476 ret_sb = ctx->blocksize * 8;
12477 if (ctx->blocksize == 1024)
12479 ctx->superblock = ret_sb;
12482 ctx->superblock = ret_sb;
12483 ctx->blocksize = 1024;
12486 if (!name || !manager)
12489 if (manager->open(name, 0, &io) != 0)
12492 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12494 sb = (struct ext2_super_block *) buf;
12496 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12497 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
12498 superblock = blocksize*8;
12499 if (blocksize == 1024)
12501 io_channel_set_blksize(io, blocksize);
12502 if (io_channel_read_blk(io, superblock,
12503 -SUPERBLOCK_SIZE, buf))
12506 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12507 ext2fs_swap_super(sb);
12509 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12510 ret_sb = superblock;
12512 ctx->superblock = superblock;
12513 ctx->blocksize = blocksize;
12521 io_channel_close(io);
12522 ext2fs_free_mem(&buf);
12528 * This function runs through the e2fsck passes and calls them all,
12529 * returning restart, abort, or cancel as necessary...
12531 typedef void (*pass_t)(e2fsck_t ctx);
12533 static const pass_t e2fsck_passes[] = {
12534 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12537 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12539 static int e2fsck_run(e2fsck_t ctx)
12542 pass_t e2fsck_pass;
12544 if (setjmp(ctx->abort_loc)) {
12545 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12546 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12548 ctx->flags |= E2F_FLAG_SETJMP_OK;
12550 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12551 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12555 (void) (ctx->progress)(ctx, 0, 0, 0);
12557 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12559 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12560 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12566 * unix.c - The unix-specific code for e2fsck
12570 /* Command line options */
12572 #ifdef ENABLE_SWAPFS
12573 static int normalize_swapfs;
12575 static int cflag; /* check disk */
12576 static int show_version_only;
12577 static int verbose;
12579 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12581 static void show_stats(e2fsck_t ctx)
12583 ext2_filsys fs = ctx->fs;
12584 int inodes, inodes_used, blocks, blocks_used;
12586 int num_files, num_links;
12589 dir_links = 2 * ctx->fs_directory_count - 1;
12590 num_files = ctx->fs_total_count - dir_links;
12591 num_links = ctx->fs_links_count - dir_links;
12592 inodes = fs->super->s_inodes_count;
12593 inodes_used = (fs->super->s_inodes_count -
12594 fs->super->s_free_inodes_count);
12595 blocks = fs->super->s_blocks_count;
12596 blocks_used = (fs->super->s_blocks_count -
12597 fs->super->s_free_blocks_count);
12599 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12600 frag_percent = (frag_percent + 5) / 10;
12603 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12604 ctx->device_name, inodes_used, inodes,
12605 frag_percent / 10, frag_percent % 10,
12606 blocks_used, blocks);
12609 printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12610 100 * inodes_used / inodes);
12611 printf("%8d non-contiguous inode%s (%0d.%d%%)\n",
12612 P_E2("", "s", ctx->fs_fragmented),
12613 frag_percent / 10, frag_percent % 10);
12614 printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12615 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12616 printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12617 (int) ((long long) 100 * blocks_used / blocks));
12618 printf("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12619 printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12620 printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12621 printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12622 printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12623 printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12624 printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12625 printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12626 printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12627 printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12628 printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12631 static void check_mount(e2fsck_t ctx)
12636 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12637 &ctx->mount_flags);
12639 bb_error_msg(_("while determining whether %s is mounted."),
12640 ctx->filesystem_name);
12645 * If the filesystem isn't mounted, or it's the root filesystem
12646 * and it's mounted read-only, then everything's fine.
12648 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12649 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12650 (ctx->mount_flags & EXT2_MF_READONLY)))
12653 if (ctx->options & E2F_OPT_READONLY) {
12654 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
12658 printf(_("%s is mounted. "), ctx->filesystem_name);
12659 if (!ctx->interactive)
12660 bb_error_msg_and_die(_("Cannot continue, aborting."));
12661 printf(_("\n\n\007\007\007\007WARNING!!! "
12662 "Running e2fsck on a mounted filesystem may cause\n"
12663 "SEVERE filesystem damage.\007\007\007\n\n"));
12664 cont = ask_yn(_("Do you really want to continue"), -1);
12666 printf(_("check aborted.\n"));
12672 static int is_on_batt(void)
12676 char tmp[80], tmp2[80], fname[80];
12677 unsigned int acflag;
12680 f = fopen("/proc/apm", "r");
12682 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12685 return (acflag != 1);
12687 d = opendir("/proc/acpi/ac_adapter");
12689 while ((de=readdir(d)) != NULL) {
12690 if (!strncmp(".", de->d_name, 1))
12692 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12694 f = fopen(fname, "r");
12697 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12700 if (strncmp(tmp, "off-line", 8) == 0) {
12711 * This routine checks to see if a filesystem can be skipped; if so,
12712 * it will exit with EXIT_OK. Under some conditions it will print a
12713 * message explaining why a check is being forced.
12715 static void check_if_skip(e2fsck_t ctx)
12717 ext2_filsys fs = ctx->fs;
12718 const char *reason = NULL;
12719 unsigned int reason_arg = 0;
12721 int batt = is_on_batt();
12722 time_t now = time(0);
12724 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12727 if ((fs->super->s_state & EXT2_ERROR_FS) ||
12728 !ext2fs_test_valid(fs))
12729 reason = _(" contains a file system with errors");
12730 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12731 reason = _(" was not cleanly unmounted");
12732 else if ((fs->super->s_max_mnt_count > 0) &&
12733 (fs->super->s_mnt_count >=
12734 (unsigned) fs->super->s_max_mnt_count)) {
12735 reason = _(" has been mounted %u times without being checked");
12736 reason_arg = fs->super->s_mnt_count;
12737 if (batt && (fs->super->s_mnt_count <
12738 (unsigned) fs->super->s_max_mnt_count*2))
12740 } else if (fs->super->s_checkinterval &&
12741 ((now - fs->super->s_lastcheck) >=
12742 fs->super->s_checkinterval)) {
12743 reason = _(" has gone %u days without being checked");
12744 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12745 if (batt && ((now - fs->super->s_lastcheck) <
12746 fs->super->s_checkinterval*2))
12750 fputs(ctx->device_name, stdout);
12751 printf(reason, reason_arg);
12752 fputs(_(", check forced.\n"), stdout);
12755 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12756 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12757 fs->super->s_inodes_count,
12758 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12759 fs->super->s_blocks_count);
12760 next_check = 100000;
12761 if (fs->super->s_max_mnt_count > 0) {
12762 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12763 if (next_check <= 0)
12766 if (fs->super->s_checkinterval &&
12767 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12769 if (next_check <= 5) {
12770 if (next_check == 1)
12771 fputs(_(" (check after next mount)"), stdout);
12773 printf(_(" (check in %ld mounts)"), next_check);
12775 fputc('\n', stdout);
12778 e2fsck_free_context(ctx);
12783 * For completion notice
12785 struct percent_tbl {
12789 static const struct percent_tbl e2fsck_tbl = {
12790 5, { 0, 70, 90, 92, 95, 100 }
12793 static char bar[128], spaces[128];
12795 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12802 if (pass > tbl->max_pass || max == 0)
12804 percent = ((float) curr) / ((float) max);
12805 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12806 + tbl->table[pass-1]);
12809 void e2fsck_clear_progbar(e2fsck_t ctx)
12811 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12814 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12817 ctx->flags &= ~E2F_FLAG_PROG_BAR;
12820 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12821 unsigned int dpynum)
12823 static const char spinner[] = "\\|/-";
12830 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12834 * Calculate the new progress position. If the
12835 * percentage hasn't changed, then we skip out right
12838 fixed_percent = (int) ((10 * percent) + 0.5);
12839 if (ctx->progress_last_percent == fixed_percent)
12841 ctx->progress_last_percent = fixed_percent;
12844 * If we've already updated the spinner once within
12845 * the last 1/8th of a second, no point doing it
12848 gettimeofday(&tv, NULL);
12849 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12850 if ((tick == ctx->progress_last_time) &&
12851 (fixed_percent != 0) && (fixed_percent != 1000))
12853 ctx->progress_last_time = tick;
12856 * Advance the spinner, and note that the progress bar
12857 * will be on the screen
12859 ctx->progress_pos = (ctx->progress_pos+1) & 3;
12860 ctx->flags |= E2F_FLAG_PROG_BAR;
12862 dpywidth = 66 - strlen(label);
12863 dpywidth = 8 * (dpywidth / 8);
12867 i = ((percent * dpywidth) + 50) / 100;
12868 printf("%s%s: |%s%s", ctx->start_meta, label,
12869 bar + (sizeof(bar) - (i+1)),
12870 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12871 if (fixed_percent == 1000)
12872 fputc('|', stdout);
12874 fputc(spinner[ctx->progress_pos & 3], stdout);
12875 printf(" %4.1f%% ", percent);
12877 printf("%u\r", dpynum);
12879 fputs(" \r", stdout);
12880 fputs(ctx->stop_meta, stdout);
12882 if (fixed_percent == 1000)
12883 e2fsck_clear_progbar(ctx);
12889 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12890 unsigned long cur, unsigned long max)
12898 if (ctx->progress_fd) {
12899 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12900 write(ctx->progress_fd, buf, strlen(buf));
12902 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12903 e2fsck_simple_progress(ctx, ctx->device_name,
12909 static void reserve_stdio_fds(void)
12914 fd = open(bb_dev_null, O_RDWR);
12918 fprintf(stderr, _("ERROR: Cannot open "
12919 "/dev/null (%s)\n"),
12927 static void signal_progress_on(int sig FSCK_ATTR((unused)))
12929 e2fsck_t ctx = e2fsck_global_ctx;
12934 ctx->progress = e2fsck_update_progress;
12935 ctx->progress_fd = 0;
12938 static void signal_progress_off(int sig FSCK_ATTR((unused)))
12940 e2fsck_t ctx = e2fsck_global_ctx;
12945 e2fsck_clear_progbar(ctx);
12949 static void signal_cancel(int sig FSCK_ATTR((unused)))
12951 e2fsck_t ctx = e2fsck_global_ctx;
12954 exit(FSCK_CANCELED);
12956 ctx->flags |= E2F_FLAG_CANCEL;
12959 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12961 char *buf, *token, *next, *p, *arg;
12963 int extended_usage = 0;
12965 buf = string_copy(opts, 0);
12966 for (token = buf; token && *token; token = next) {
12967 p = strchr(token, ',');
12973 arg = strchr(token, '=');
12978 if (strcmp(token, "ea_ver") == 0) {
12983 ea_ver = strtoul(arg, &p, 0);
12985 ((ea_ver != 1) && (ea_ver != 2))) {
12987 _("Invalid EA version.\n"));
12991 ctx->ext_attr_ver = ea_ver;
12993 fprintf(stderr, _("Unknown extended option: %s\n"),
12998 if (extended_usage) {
12999 bb_error_msg_and_die(
13000 "Extended options are separated by commas, "
13001 "and may take an argument which\n"
13002 "is set off by an equals ('=') sign. "
13003 "Valid extended options are:\n"
13004 "\tea_ver=<ea_version (1 or 2)>\n\n");
13009 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
13015 struct sigaction sa;
13016 char *extended_opts = 0;
13018 retval = e2fsck_allocate_context(&ctx);
13024 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
13025 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
13026 if (isatty(0) && isatty(1)) {
13027 ctx->interactive = 1;
13029 ctx->start_meta[0] = '\001';
13030 ctx->stop_meta[0] = '\002';
13032 memset(bar, '=', sizeof(bar)-1);
13033 memset(spaces, ' ', sizeof(spaces)-1);
13034 blkid_get_cache(&ctx->blkid, NULL);
13037 ctx->program_name = *argv;
13039 ctx->program_name = "e2fsck";
13040 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13043 ctx->progress = e2fsck_update_progress;
13044 ctx->progress_fd = atoi(optarg);
13045 if (!ctx->progress_fd)
13047 /* Validate the file descriptor to avoid disasters */
13048 fd = dup(ctx->progress_fd);
13051 _("Error validating file descriptor %d: %s\n"),
13053 error_message(errno));
13054 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13059 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13062 extended_opts = optarg;
13066 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13068 bb_error_msg_and_die(_("Only one the options -p/-a, -n or -y may be specified."));
13070 ctx->options |= E2F_OPT_PREEN;
13073 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13075 ctx->options |= E2F_OPT_NO;
13078 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13080 ctx->options |= E2F_OPT_YES;
13083 /* FIXME - This needs to go away in a future path - will change binary */
13084 fprintf(stderr, _("The -t option is not "
13085 "supported on this version of e2fsck.\n"));
13089 ctx->options |= E2F_OPT_WRITECHECK;
13090 ctx->options |= E2F_OPT_CHECKBLOCKS;
13093 /* What we do by default, anyway! */
13096 ctx->use_superblock = atoi(optarg);
13097 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13100 ctx->blocksize = atoi(optarg);
13103 ctx->inode_buffer_blocks = atoi(optarg);
13106 ctx->journal_name = string_copy(optarg, 0);
13109 ctx->process_inode_size = atoi(optarg);
13112 ctx->options |= E2F_OPT_DEBUG;
13115 ctx->options |= E2F_OPT_FORCE;
13124 show_version_only = 1;
13127 ctx->device_name = optarg;
13129 #ifdef ENABLE_SWAPFS
13131 normalize_swapfs = 1;
13138 fprintf(stderr, _("Byte-swapping filesystems "
13139 "not compiled in this version "
13146 if (show_version_only)
13148 if (optind != argc - 1)
13150 if ((ctx->options & E2F_OPT_NO) &&
13151 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13152 ctx->options |= E2F_OPT_READONLY;
13153 ctx->io_options = strchr(argv[optind], '?');
13154 if (ctx->io_options)
13155 *ctx->io_options++ = 0;
13156 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13157 if (!ctx->filesystem_name) {
13158 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13159 bb_error_msg_and_die(0);
13162 parse_extended_opts(ctx, extended_opts);
13165 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13167 bb_error_msg(_("while opening %s for flushing"),
13168 ctx->filesystem_name);
13169 bb_error_msg_and_die(0);
13171 if ((retval = ext2fs_sync_device(fd, 1))) {
13172 bb_error_msg(_("while trying to flush %s"),
13173 ctx->filesystem_name);
13174 bb_error_msg_and_die(0);
13178 #ifdef ENABLE_SWAPFS
13179 if (swapfs && cflag) {
13180 fprintf(stderr, _("Incompatible options not "
13181 "allowed when byte-swapping.\n"));
13186 * Set up signal action
13188 memset(&sa, 0, sizeof(struct sigaction));
13189 sa.sa_handler = signal_cancel;
13190 sigaction(SIGINT, &sa, 0);
13191 sigaction(SIGTERM, &sa, 0);
13193 sa.sa_flags = SA_RESTART;
13195 e2fsck_global_ctx = ctx;
13196 sa.sa_handler = signal_progress_on;
13197 sigaction(SIGUSR1, &sa, 0);
13198 sa.sa_handler = signal_progress_off;
13199 sigaction(SIGUSR2, &sa, 0);
13201 /* Update our PATH to include /sbin if we need to run badblocks */
13203 e2fs_set_sbin_path();
13207 static const char my_ver_string[] = E2FSPROGS_VERSION;
13208 static const char my_ver_date[] = E2FSPROGS_DATE;
13210 int e2fsck_main (int argc, char *argv[])
13213 int exit_value = EXIT_OK;
13214 ext2_filsys fs = 0;
13216 struct ext2_super_block *sb;
13217 const char *lib_ver_date;
13218 int my_ver, lib_ver;
13220 struct problem_context pctx;
13221 int flags, run_result;
13223 clear_problem_context(&pctx);
13225 my_ver = ext2fs_parse_version_string(my_ver_string);
13226 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13227 if (my_ver > lib_ver) {
13228 fprintf( stderr, _("Error: ext2fs library version "
13229 "out of date!\n"));
13230 show_version_only++;
13233 retval = PRS(argc, argv, &ctx);
13235 bb_error_msg(_("while trying to initialize program"));
13238 reserve_stdio_fds();
13240 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13241 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13244 if (show_version_only) {
13245 fprintf(stderr, _("\tUsing %s, %s\n"),
13246 error_message(EXT2_ET_BASE), lib_ver_date);
13252 if (!(ctx->options & E2F_OPT_PREEN) &&
13253 !(ctx->options & E2F_OPT_NO) &&
13254 !(ctx->options & E2F_OPT_YES)) {
13255 if (!ctx->interactive)
13256 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13258 ctx->superblock = ctx->use_superblock;
13260 #ifdef CONFIG_TESTIO_DEBUG
13261 io_ptr = test_io_manager;
13262 test_io_backing_manager = unix_io_manager;
13264 io_ptr = unix_io_manager;
13267 if ((ctx->options & E2F_OPT_READONLY) == 0)
13268 flags |= EXT2_FLAG_RW;
13270 if (ctx->superblock && ctx->blocksize) {
13271 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13272 flags, ctx->superblock, ctx->blocksize,
13274 } else if (ctx->superblock) {
13276 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13277 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13278 retval = ext2fs_open2(ctx->filesystem_name,
13279 ctx->io_options, flags,
13280 ctx->superblock, blocksize,
13286 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13287 flags, 0, 0, io_ptr, &fs);
13288 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13289 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13290 ((retval == EXT2_ET_BAD_MAGIC) ||
13291 ((retval == 0) && ext2fs_check_desc(fs)))) {
13292 if (!fs || (fs->group_desc_count > 1)) {
13293 printf(_("%s trying backup blocks...\n"),
13294 retval ? _("Couldn't find ext2 superblock,") :
13295 _("Group descriptors look bad..."));
13296 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13303 bb_error_msg(_("while trying to open %s"),
13304 ctx->filesystem_name);
13305 if (retval == EXT2_ET_REV_TOO_HIGH) {
13306 printf(_("The filesystem revision is apparently "
13307 "too high for this version of e2fsck.\n"
13308 "(Or the filesystem superblock "
13309 "is corrupt)\n\n"));
13310 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13311 } else if (retval == EXT2_ET_SHORT_READ)
13312 printf(_("Could this be a zero-length partition?\n"));
13313 else if ((retval == EPERM) || (retval == EACCES))
13314 printf(_("You must have %s access to the "
13315 "filesystem or be root\n"),
13316 (ctx->options & E2F_OPT_READONLY) ?
13318 else if (retval == ENXIO)
13319 printf(_("Possibly non-existent or swap device?\n"));
13321 else if (retval == EROFS)
13322 printf(_("Disk write-protected; use the -n option "
13323 "to do a read-only\n"
13324 "check of the device.\n"));
13327 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13328 bb_error_msg_and_die(0);
13331 fs->priv_data = ctx;
13333 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13334 bb_error_msg(_("while trying to open %s"),
13335 ctx->filesystem_name);
13337 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13341 * Set the device name, which is used whenever we print error
13342 * or informational messages to the user.
13344 if (ctx->device_name == 0 &&
13345 (sb->s_volume_name[0] != 0)) {
13346 ctx->device_name = string_copy(sb->s_volume_name,
13347 sizeof(sb->s_volume_name));
13349 if (ctx->device_name == 0)
13350 ctx->device_name = ctx->filesystem_name;
13353 * Make sure the ext3 superblock fields are consistent.
13355 retval = e2fsck_check_ext3_journal(ctx);
13357 bb_error_msg(_("while checking ext3 journal for %s"),
13359 bb_error_msg_and_die(0);
13363 * Check to see if we need to do ext3-style recovery. If so,
13364 * do it, and then restart the fsck.
13366 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13367 if (ctx->options & E2F_OPT_READONLY) {
13368 printf(_("Warning: skipping journal recovery "
13369 "because doing a read-only filesystem "
13371 io_channel_flush(ctx->fs->io);
13373 if (ctx->flags & E2F_FLAG_RESTARTED) {
13375 * Whoops, we attempted to run the
13376 * journal twice. This should never
13377 * happen, unless the hardware or
13378 * device driver is being bogus.
13380 bb_error_msg(_("unable to set superblock flags on %s"), ctx->device_name);
13381 bb_error_msg_and_die(0);
13383 retval = e2fsck_run_ext3_journal(ctx);
13385 bb_error_msg(_("while recovering ext3 journal of %s"),
13387 bb_error_msg_and_die(0);
13389 ext2fs_close(ctx->fs);
13391 ctx->flags |= E2F_FLAG_RESTARTED;
13397 * Check for compatibility with the feature sets. We need to
13398 * be more stringent than ext2fs_open().
13400 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13401 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13402 bb_error_msg("(%s)", ctx->device_name);
13405 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13406 bb_error_msg("(%s)", ctx->device_name);
13409 #ifdef ENABLE_COMPRESSION
13410 /* FIXME - do we support this at all? */
13411 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13412 bb_error_msg(_("Warning: compression support is experimental."));
13414 #ifndef ENABLE_HTREE
13415 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13416 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13417 "but filesystem %s has HTREE directories."),
13424 * If the user specified a specific superblock, presumably the
13425 * master superblock has been trashed. So we mark the
13426 * superblock as dirty, so it can be written out.
13428 if (ctx->superblock &&
13429 !(ctx->options & E2F_OPT_READONLY))
13430 ext2fs_mark_super_dirty(fs);
13433 * We only update the master superblock because (a) paranoia;
13434 * we don't want to corrupt the backup superblocks, and (b) we
13435 * don't need to update the mount count and last checked
13436 * fields in the backup superblock (the kernel doesn't
13437 * update the backup superblocks anyway).
13439 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13441 ehandler_init(fs->io);
13443 if (ctx->superblock)
13444 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13445 ext2fs_mark_valid(fs);
13446 check_super_block(ctx);
13447 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13448 bb_error_msg_and_die(0);
13449 check_if_skip(ctx);
13450 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13451 bb_error_msg_and_die(0);
13452 #ifdef ENABLE_SWAPFS
13454 #ifdef WORDS_BIGENDIAN
13455 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13457 #define NATIVE_FLAG 0
13461 if (normalize_swapfs) {
13462 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13463 fprintf(stderr, _("%s: Filesystem byte order "
13464 "already normalized.\n"), ctx->device_name);
13465 bb_error_msg_and_die(0);
13470 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13471 bb_error_msg_and_die(0);
13476 * Mark the system as valid, 'til proven otherwise
13478 ext2fs_mark_valid(fs);
13480 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13482 bb_error_msg(_("while reading bad blocks inode"));
13484 printf(_("This doesn't bode well,"
13485 " but we'll try to go on...\n"));
13488 run_result = e2fsck_run(ctx);
13489 e2fsck_clear_progbar(ctx);
13490 if (run_result == E2F_FLAG_RESTART) {
13491 printf(_("Restarting e2fsck from the beginning...\n"));
13492 retval = e2fsck_reset_context(ctx);
13494 bb_error_msg(_("while resetting context"));
13495 bb_error_msg_and_die(0);
13500 if (run_result & E2F_FLAG_CANCEL) {
13501 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13502 ctx->device_name : ctx->filesystem_name);
13503 exit_value |= FSCK_CANCELED;
13505 if (run_result & E2F_FLAG_ABORT)
13506 bb_error_msg_and_die(_("aborted"));
13509 if (ext2fs_test_changed(fs)) {
13510 exit_value |= EXIT_NONDESTRUCT;
13511 if (!(ctx->options & E2F_OPT_PREEN))
13512 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13514 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13515 printf(_("%s: ***** REBOOT LINUX *****\n"),
13517 exit_value |= EXIT_DESTRUCT;
13520 if (!ext2fs_test_valid(fs)) {
13521 printf(_("\n%s: ********** WARNING: Filesystem still has "
13522 "errors **********\n\n"), ctx->device_name);
13523 exit_value |= EXIT_UNCORRECTED;
13524 exit_value &= ~EXIT_NONDESTRUCT;
13526 if (exit_value & FSCK_CANCELED)
13527 exit_value &= ~EXIT_NONDESTRUCT;
13530 if (!(ctx->options & E2F_OPT_READONLY)) {
13531 if (ext2fs_test_valid(fs)) {
13532 if (!(sb->s_state & EXT2_VALID_FS))
13533 exit_value |= EXIT_NONDESTRUCT;
13534 sb->s_state = EXT2_VALID_FS;
13536 sb->s_state &= ~EXT2_VALID_FS;
13537 sb->s_mnt_count = 0;
13538 sb->s_lastcheck = time(NULL);
13539 ext2fs_mark_super_dirty(fs);
13543 e2fsck_write_bitmaps(ctx);
13547 free(ctx->filesystem_name);
13548 free(ctx->journal_name);
13549 e2fsck_free_context(ctx);