4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
5 * Copyright (C) 2006 Garrett Kajmowicz
7 * redistributed under the terms of the GNU Public License.
10 * Dictionary Abstract Data Type
11 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
12 * Free Software License:
13 * All rights are reserved by the author, with the following exceptions:
14 * Permission is granted to freely reproduce and distribute this software,
15 * possibly in exchange for a fee, provided that this copyright notice appears
16 * intact. Permission is also granted to adapt this software to produce
17 * derivative works, as long as the modified versions carry this copyright
18 * notice and additional notices stating that the work has been modified.
19 * This source code may be translated into executable form and incorporated
20 * into proprietary software; there is no requirement for such software to
21 * contain a copyright notice related to this source.
23 * linux/fs/recovery and linux/fs/revoke
24 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
26 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
28 * This file is part of the Linux kernel and is made available under
29 * the terms of the GNU General Public License, version 2, or at your
30 * option, any later version, incorporated herein by reference.
32 * Journal recovery routines for the generic filesystem journaling code;
33 * part of the ext2fs journaling system.
37 #define _GNU_SOURCE 1 /* get strnlen() */
40 #include "e2fsck.h" /*Put all of our defines here to clean things up*/
46 * Procedure declarations
49 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
52 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
55 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
56 ext2_ino_t ino, char *buf);
59 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
60 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
61 int num, int gauranteed_size);
62 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
63 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
67 static void e2fsck_rehash_directories(e2fsck_t ctx);
70 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
71 const char *description);
72 static int ask(e2fsck_t ctx, const char * string, int def);
73 static void e2fsck_read_bitmaps(e2fsck_t ctx);
74 static void preenhalt(e2fsck_t ctx);
75 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
76 struct ext2_inode * inode, const char * proc);
77 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
78 struct ext2_inode * inode, const char * proc);
79 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
80 const char *name, io_manager manager);
83 static void e2fsck_clear_progbar(e2fsck_t ctx);
84 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
85 float percent, unsigned int dpynum);
89 * problem.h --- e2fsck problem error codes
92 typedef __u32 problem_t;
94 struct problem_context {
96 ext2_ino_t ino, ino2, dir;
97 struct ext2_inode *inode;
98 struct ext2_dir_entry *dirent;
100 e2_blkcnt_t blkcount;
108 * Function declarations
110 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
111 static int end_problem_latch(e2fsck_t ctx, int mask);
112 static int set_latch_flags(int mask, int setflags, int clearflags);
113 static void clear_problem_context(struct problem_context *ctx);
116 * Dictionary Abstract Data Type
117 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
119 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
127 * Blurb for inclusion into C++ translation units
130 typedef unsigned long dictcount_t;
131 #define DICTCOUNT_T_MAX ULONG_MAX
134 * The dictionary is implemented as a red-black tree
137 typedef enum { dnode_red, dnode_black } dnode_color_t;
139 typedef struct dnode_t {
140 struct dnode_t *dict_left;
141 struct dnode_t *dict_right;
142 struct dnode_t *dict_parent;
143 dnode_color_t dict_color;
144 const void *dict_key;
148 typedef int (*dict_comp_t)(const void *, const void *);
149 typedef void (*dnode_free_t)(dnode_t *);
151 typedef struct dict_t {
152 dnode_t dict_nilnode;
153 dictcount_t dict_nodecount;
154 dictcount_t dict_maxcount;
155 dict_comp_t dict_compare;
156 dnode_free_t dict_freenode;
160 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
162 typedef struct dict_load_t {
163 dict_t *dict_dictptr;
164 dnode_t dict_nilnode;
167 #define dict_count(D) ((D)->dict_nodecount)
168 #define dnode_get(N) ((N)->dict_data)
169 #define dnode_getkey(N) ((N)->dict_key)
174 * Compatibility header file for e2fsck which should be included
175 * instead of linux/jfs.h
177 * Copyright (C) 2000 Stephen C. Tweedie
181 * Pull in the definition of the e2fsck context structure
197 #define K_DEV_JOURNAL 2
199 #define lock_buffer(bh) do {} while(0)
200 #define unlock_buffer(bh) do {} while(0)
201 #define buffer_req(bh) 1
202 #define do_readahead(journal, start) do {} while(0)
204 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
210 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
213 * We use the standard libext2fs portability tricks for inline
217 static kmem_cache_t * do_cache_create(int len)
219 kmem_cache_t *new_cache;
221 new_cache = malloc(sizeof(*new_cache));
223 new_cache->object_length = len;
227 static void do_cache_destroy(kmem_cache_t *cache)
234 * Dictionary Abstract Data Type
239 * These macros provide short convenient names for structure members,
240 * which are embellished with dict_ prefixes so that they are
241 * properly confined to the documented namespace. It's legal for a
242 * program which uses dict to define, for instance, a macro called ``parent''.
243 * Such a macro would interfere with the dnode_t struct definition.
244 * In general, highly portable and reusable C modules which expose their
245 * structures need to confine structure member names to well-defined spaces.
246 * The resulting identifiers aren't necessarily convenient to use, nor
247 * readable, in the implementation, however!
250 #define left dict_left
251 #define right dict_right
252 #define parent dict_parent
253 #define color dict_color
255 #define data dict_data
257 #define nilnode dict_nilnode
258 #define maxcount dict_maxcount
259 #define compare dict_compare
260 #define dupes dict_dupes
262 #define dict_root(D) ((D)->nilnode.left)
263 #define dict_nil(D) (&(D)->nilnode)
265 static void dnode_free(dnode_t *node);
268 * Perform a ``left rotation'' adjustment on the tree. The given node P and
269 * its right child C are rearranged so that the P instead becomes the left
270 * child of C. The left subtree of C is inherited as the new right subtree
271 * for P. The ordering of the keys within the tree is thus preserved.
274 static void rotate_left(dnode_t *upper)
276 dnode_t *lower, *lowleft, *upparent;
278 lower = upper->right;
279 upper->right = lowleft = lower->left;
280 lowleft->parent = upper;
282 lower->parent = upparent = upper->parent;
284 /* don't need to check for root node here because root->parent is
285 the sentinel nil node, and root->parent->left points back to root */
287 if (upper == upparent->left) {
288 upparent->left = lower;
290 assert (upper == upparent->right);
291 upparent->right = lower;
295 upper->parent = lower;
299 * This operation is the ``mirror'' image of rotate_left. It is
300 * the same procedure, but with left and right interchanged.
303 static void rotate_right(dnode_t *upper)
305 dnode_t *lower, *lowright, *upparent;
308 upper->left = lowright = lower->right;
309 lowright->parent = upper;
311 lower->parent = upparent = upper->parent;
313 if (upper == upparent->right) {
314 upparent->right = lower;
316 assert (upper == upparent->left);
317 upparent->left = lower;
320 lower->right = upper;
321 upper->parent = lower;
325 * Do a postorder traversal of the tree rooted at the specified
326 * node and free everything under it. Used by dict_free().
329 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
333 free_nodes(dict, node->left, nil);
334 free_nodes(dict, node->right, nil);
335 dict->dict_freenode(node);
339 * Verify that the tree contains the given node. This is done by
340 * traversing all of the nodes and comparing their pointers to the
341 * given pointer. Returns 1 if the node is found, otherwise
342 * returns zero. It is intended for debugging purposes.
345 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
349 || verify_dict_has_node(nil, root->left, node)
350 || verify_dict_has_node(nil, root->right, node);
357 * Select a different set of node allocator routines.
360 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
362 assert (dict_count(dict) == 0);
363 dict->dict_freenode = fr;
367 * Free all the nodes in the dictionary by using the dictionary's
368 * installed free routine. The dictionary is emptied.
371 static void dict_free_nodes(dict_t *dict)
373 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
374 free_nodes(dict, root, nil);
375 dict->dict_nodecount = 0;
376 dict->nilnode.left = &dict->nilnode;
377 dict->nilnode.right = &dict->nilnode;
381 * Initialize a user-supplied dictionary object.
384 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
386 dict->compare = comp;
387 dict->dict_freenode = dnode_free;
388 dict->dict_nodecount = 0;
389 dict->maxcount = maxcount;
390 dict->nilnode.left = &dict->nilnode;
391 dict->nilnode.right = &dict->nilnode;
392 dict->nilnode.parent = &dict->nilnode;
393 dict->nilnode.color = dnode_black;
399 * Locate a node in the dictionary having the given key.
400 * If the node is not found, a null a pointer is returned (rather than
401 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
402 * located node is returned.
405 static dnode_t *dict_lookup(dict_t *dict, const void *key)
407 dnode_t *root = dict_root(dict);
408 dnode_t *nil = dict_nil(dict);
412 /* simple binary search adapted for trees that contain duplicate keys */
414 while (root != nil) {
415 result = dict->compare(key, root->key);
421 if (!dict->dupes) { /* no duplicates, return match */
423 } else { /* could be dupes, find leftmost one */
427 while (root != nil && dict->compare(key, root->key))
429 } while (root != nil);
439 * Insert a node into the dictionary. The node should have been
440 * initialized with a data field. All other fields are ignored.
441 * The behavior is undefined if the user attempts to insert into
442 * a dictionary that is already full (for which the dict_isfull()
443 * function returns true).
446 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
448 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
449 dnode_t *parent = nil, *uncle, *grandpa;
454 /* basic binary tree insert */
456 while (where != nil) {
458 result = dict->compare(key, where->key);
459 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
460 assert (dict->dupes || result != 0);
464 where = where->right;
467 assert (where == nil);
472 parent->right = node;
474 node->parent = parent;
478 dict->dict_nodecount++;
480 /* red black adjustments */
482 node->color = dnode_red;
484 while (parent->color == dnode_red) {
485 grandpa = parent->parent;
486 if (parent == grandpa->left) {
487 uncle = grandpa->right;
488 if (uncle->color == dnode_red) { /* red parent, red uncle */
489 parent->color = dnode_black;
490 uncle->color = dnode_black;
491 grandpa->color = dnode_red;
493 parent = grandpa->parent;
494 } else { /* red parent, black uncle */
495 if (node == parent->right) {
498 assert (grandpa == parent->parent);
499 /* rotation between parent and child preserves grandpa */
501 parent->color = dnode_black;
502 grandpa->color = dnode_red;
503 rotate_right(grandpa);
506 } else { /* symmetric cases: parent == parent->parent->right */
507 uncle = grandpa->left;
508 if (uncle->color == dnode_red) {
509 parent->color = dnode_black;
510 uncle->color = dnode_black;
511 grandpa->color = dnode_red;
513 parent = grandpa->parent;
515 if (node == parent->left) {
516 rotate_right(parent);
518 assert (grandpa == parent->parent);
520 parent->color = dnode_black;
521 grandpa->color = dnode_red;
522 rotate_left(grandpa);
528 dict_root(dict)->color = dnode_black;
533 * Allocate a node using the dictionary's allocator routine, give it
537 static dnode_t *dnode_init(dnode_t *dnode, void *data)
540 dnode->parent = NULL;
546 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
548 dnode_t *node = malloc(sizeof(dnode_t));
551 dnode_init(node, data);
552 dict_insert(dict, node, key);
559 * Return the node with the lowest (leftmost) key. If the dictionary is empty
560 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
563 static dnode_t *dict_first(dict_t *dict)
565 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
568 while ((left = root->left) != nil)
571 return (root == nil) ? NULL : root;
575 * Return the given node's successor node---the node which has the
576 * next key in the the left to right ordering. If the node has
577 * no successor, a null pointer is returned rather than a pointer to
581 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
583 dnode_t *nil = dict_nil(dict), *parent, *left;
585 if (curr->right != nil) {
587 while ((left = curr->left) != nil)
592 parent = curr->parent;
594 while (parent != nil && curr == parent->right) {
596 parent = curr->parent;
599 return (parent == nil) ? NULL : parent;
603 static void dnode_free(dnode_t *node)
623 * dirinfo.c --- maintains the directory information table for e2fsck.
627 * This subroutine is called during pass1 to create a directory info
628 * entry. During pass1, the passed-in parent is 0; it will get filled
631 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
633 struct dir_info *dir;
637 unsigned long old_size;
639 if (!ctx->dir_info) {
640 ctx->dir_info_count = 0;
641 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
643 num_dirs = 1024; /* Guess */
644 ctx->dir_info_size = num_dirs + 10;
645 ctx->dir_info = (struct dir_info *)
646 e2fsck_allocate_memory(ctx, ctx->dir_info_size
647 * sizeof (struct dir_info),
651 if (ctx->dir_info_count >= ctx->dir_info_size) {
652 old_size = ctx->dir_info_size * sizeof(struct dir_info);
653 ctx->dir_info_size += 10;
654 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
655 sizeof(struct dir_info),
658 ctx->dir_info_size -= 10;
664 * Normally, add_dir_info is called with each inode in
665 * sequential order; but once in a while (like when pass 3
666 * needs to recreate the root directory or lost+found
667 * directory) it is called out of order. In those cases, we
668 * need to move the dir_info entries down to make room, since
669 * the dir_info array needs to be sorted by inode number for
670 * get_dir_info()'s sake.
672 if (ctx->dir_info_count &&
673 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
674 for (i = ctx->dir_info_count-1; i > 0; i--)
675 if (ctx->dir_info[i-1].ino < ino)
677 dir = &ctx->dir_info[i];
679 for (j = ctx->dir_info_count++; j > i; j--)
680 ctx->dir_info[j] = ctx->dir_info[j-1];
682 dir = &ctx->dir_info[ctx->dir_info_count++];
685 dir->dotdot = parent;
686 dir->parent = parent;
690 * get_dir_info() --- given an inode number, try to find the directory
691 * information entry for it.
693 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
698 high = ctx->dir_info_count-1;
701 if (ino == ctx->dir_info[low].ino)
702 return &ctx->dir_info[low];
703 if (ino == ctx->dir_info[high].ino)
704 return &ctx->dir_info[high];
708 if (mid == low || mid == high)
710 if (ino == ctx->dir_info[mid].ino)
711 return &ctx->dir_info[mid];
712 if (ino < ctx->dir_info[mid].ino)
721 * Free the dir_info structure when it isn't needed any more.
723 static void e2fsck_free_dir_info(e2fsck_t ctx)
725 ext2fs_free_mem(&ctx->dir_info);
726 ctx->dir_info_size = 0;
727 ctx->dir_info_count = 0;
731 * Return the count of number of directories in the dir_info structure
733 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
735 return ctx->dir_info_count;
739 * A simple interator function
741 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
743 if (*control >= ctx->dir_info_count)
746 return(ctx->dir_info + (*control)++);
750 * dirinfo.c --- maintains the directory information table for e2fsck.
757 * This subroutine is called during pass1 to create a directory info
758 * entry. During pass1, the passed-in parent is 0; it will get filled
761 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
763 struct dx_dir_info *dir;
766 unsigned long old_size;
768 if (!ctx->dx_dir_info) {
769 ctx->dx_dir_info_count = 0;
770 ctx->dx_dir_info_size = 100; /* Guess */
771 ctx->dx_dir_info = (struct dx_dir_info *)
772 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
773 * sizeof (struct dx_dir_info),
777 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
778 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
779 ctx->dx_dir_info_size += 10;
780 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
781 sizeof(struct dx_dir_info),
784 ctx->dx_dir_info_size -= 10;
790 * Normally, add_dx_dir_info is called with each inode in
791 * sequential order; but once in a while (like when pass 3
792 * needs to recreate the root directory or lost+found
793 * directory) it is called out of order. In those cases, we
794 * need to move the dx_dir_info entries down to make room, since
795 * the dx_dir_info array needs to be sorted by inode number for
796 * get_dx_dir_info()'s sake.
798 if (ctx->dx_dir_info_count &&
799 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
800 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
801 if (ctx->dx_dir_info[i-1].ino < ino)
803 dir = &ctx->dx_dir_info[i];
805 for (j = ctx->dx_dir_info_count++; j > i; j--)
806 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
808 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
811 dir->numblocks = num_blocks;
812 dir->hashversion = 0;
813 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
814 * sizeof (struct dx_dirblock_info),
815 "dx_block info array");
820 * get_dx_dir_info() --- given an inode number, try to find the directory
821 * information entry for it.
823 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
828 high = ctx->dx_dir_info_count-1;
829 if (!ctx->dx_dir_info)
831 if (ino == ctx->dx_dir_info[low].ino)
832 return &ctx->dx_dir_info[low];
833 if (ino == ctx->dx_dir_info[high].ino)
834 return &ctx->dx_dir_info[high];
838 if (mid == low || mid == high)
840 if (ino == ctx->dx_dir_info[mid].ino)
841 return &ctx->dx_dir_info[mid];
842 if (ino < ctx->dx_dir_info[mid].ino)
851 * Free the dx_dir_info structure when it isn't needed any more.
853 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
856 struct dx_dir_info *dir;
858 if (ctx->dx_dir_info) {
859 dir = ctx->dx_dir_info;
860 for (i=0; i < ctx->dx_dir_info_count; i++) {
861 ext2fs_free_mem(&dir->dx_block);
863 ext2fs_free_mem(&ctx->dx_dir_info);
865 ctx->dx_dir_info_size = 0;
866 ctx->dx_dir_info_count = 0;
870 * A simple interator function
872 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
874 if (*control >= ctx->dx_dir_info_count)
877 return(ctx->dx_dir_info + (*control)++);
880 #endif /* ENABLE_HTREE */
882 * e2fsck.c - a consistency checker for the new extended file system.
887 * This function allocates an e2fsck context
889 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
894 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
898 memset(context, 0, sizeof(struct e2fsck_struct));
900 context->process_inode_size = 256;
901 context->ext_attr_ver = 2;
907 struct ea_refcount_el {
916 struct ea_refcount_el *list;
919 static void ea_refcount_free(ext2_refcount_t refcount)
924 ext2fs_free_mem(&refcount->list);
925 ext2fs_free_mem(&refcount);
929 * This function resets an e2fsck context; it is called when e2fsck
930 * needs to be restarted.
932 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
935 ctx->lost_and_found = 0;
936 ctx->bad_lost_and_found = 0;
937 ext2fs_free_inode_bitmap(ctx->inode_used_map);
938 ctx->inode_used_map = 0;
939 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
940 ctx->inode_dir_map = 0;
941 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
942 ctx->inode_reg_map = 0;
943 ext2fs_free_block_bitmap(ctx->block_found_map);
944 ctx->block_found_map = 0;
945 ext2fs_free_icount(ctx->inode_link_info);
946 ctx->inode_link_info = 0;
947 if (ctx->journal_io) {
948 if (ctx->fs && ctx->fs->io != ctx->journal_io)
949 io_channel_close(ctx->journal_io);
953 ext2fs_free_dblist(ctx->fs->dblist);
956 e2fsck_free_dir_info(ctx);
958 e2fsck_free_dx_dir_info(ctx);
960 ea_refcount_free(ctx->refcount);
962 ea_refcount_free(ctx->refcount_extra);
963 ctx->refcount_extra = 0;
964 ext2fs_free_block_bitmap(ctx->block_dup_map);
965 ctx->block_dup_map = 0;
966 ext2fs_free_block_bitmap(ctx->block_ea_map);
967 ctx->block_ea_map = 0;
968 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
969 ctx->inode_bad_map = 0;
970 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
971 ctx->inode_imagic_map = 0;
972 ext2fs_u32_list_free(ctx->dirs_to_hash);
973 ctx->dirs_to_hash = 0;
976 * Clear the array of invalid meta-data flags
978 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
979 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
980 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
982 /* Clear statistic counters */
983 ctx->fs_directory_count = 0;
984 ctx->fs_regular_count = 0;
985 ctx->fs_blockdev_count = 0;
986 ctx->fs_chardev_count = 0;
987 ctx->fs_links_count = 0;
988 ctx->fs_symlinks_count = 0;
989 ctx->fs_fast_symlinks_count = 0;
990 ctx->fs_fifo_count = 0;
991 ctx->fs_total_count = 0;
992 ctx->fs_sockets_count = 0;
993 ctx->fs_ind_count = 0;
994 ctx->fs_dind_count = 0;
995 ctx->fs_tind_count = 0;
996 ctx->fs_fragmented = 0;
997 ctx->large_files = 0;
999 /* Reset the superblock to the user's requested value */
1000 ctx->superblock = ctx->use_superblock;
1005 static void e2fsck_free_context(e2fsck_t ctx)
1010 e2fsck_reset_context(ctx);
1012 blkid_put_cache(ctx->blkid);
1014 ext2fs_free_mem(&ctx);
1022 * The strategy we use for keeping track of EA refcounts is as
1023 * follows. We keep a sorted array of first EA blocks and its
1024 * reference counts. Once the refcount has dropped to zero, it is
1025 * removed from the array to save memory space. Once the EA block is
1026 * checked, its bit is set in the block_ea_map bitmap.
1030 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1032 ext2_refcount_t refcount;
1036 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1039 memset(refcount, 0, sizeof(struct ea_refcount));
1043 refcount->size = size;
1044 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1046 printf("Refcount allocated %d entries, %d bytes.\n",
1047 refcount->size, bytes);
1049 retval = ext2fs_get_mem(bytes, &refcount->list);
1052 memset(refcount->list, 0, bytes);
1054 refcount->count = 0;
1055 refcount->cursor = 0;
1061 ea_refcount_free(refcount);
1066 * collapse_refcount() --- go through the refcount array, and get rid
1067 * of any count == zero entries
1069 static void refcount_collapse(ext2_refcount_t refcount)
1072 struct ea_refcount_el *list;
1074 list = refcount->list;
1075 for (i = 0, j = 0; i < refcount->count; i++) {
1076 if (list[i].ea_count) {
1082 #if defined(DEBUG) || defined(TEST_PROGRAM)
1083 printf("Refcount_collapse: size was %d, now %d\n",
1084 refcount->count, j);
1086 refcount->count = j;
1091 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1092 * specified position.
1094 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1097 struct ea_refcount_el *el;
1102 if (refcount->count >= refcount->size) {
1103 new_size = refcount->size + 100;
1105 printf("Reallocating refcount %d entries...\n", new_size);
1107 retval = ext2fs_resize_mem((size_t) refcount->size *
1108 sizeof(struct ea_refcount_el),
1110 sizeof(struct ea_refcount_el),
1114 refcount->size = new_size;
1116 num = (int) refcount->count - pos;
1118 return 0; /* should never happen */
1120 memmove(&refcount->list[pos+1], &refcount->list[pos],
1121 sizeof(struct ea_refcount_el) * num);
1124 el = &refcount->list[pos];
1132 * get_refcount_el() --- given an block number, try to find refcount
1133 * information in the sorted list. If the create flag is set,
1134 * and we can't find an entry, create one in the sorted list.
1136 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1137 blk_t blk, int create)
1141 blk_t lowval, highval;
1143 if (!refcount || !refcount->list)
1147 high = (int) refcount->count-1;
1148 if (create && ((refcount->count == 0) ||
1149 (blk > refcount->list[high].ea_blk))) {
1150 if (refcount->count >= refcount->size)
1151 refcount_collapse(refcount);
1153 return insert_refcount_el(refcount, blk,
1154 (unsigned) refcount->count);
1156 if (refcount->count == 0)
1159 if (refcount->cursor >= refcount->count)
1160 refcount->cursor = 0;
1161 if (blk == refcount->list[refcount->cursor].ea_blk)
1162 return &refcount->list[refcount->cursor++];
1164 printf("Non-cursor get_refcount_el: %u\n", blk);
1166 while (low <= high) {
1170 /* Interpolate for efficiency */
1171 lowval = refcount->list[low].ea_blk;
1172 highval = refcount->list[high].ea_blk;
1176 else if (blk > highval)
1179 range = ((float) (blk - lowval)) /
1181 mid = low + ((int) (range * (high-low)));
1184 if (blk == refcount->list[mid].ea_blk) {
1185 refcount->cursor = mid+1;
1186 return &refcount->list[mid];
1188 if (blk < refcount->list[mid].ea_blk)
1194 * If we need to create a new entry, it should be right at
1195 * low (where high will be left at low-1).
1198 if (refcount->count >= refcount->size) {
1199 refcount_collapse(refcount);
1200 if (refcount->count < refcount->size)
1203 return insert_refcount_el(refcount, blk, low);
1209 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1211 struct ea_refcount_el *el;
1213 el = get_refcount_el(refcount, blk, 1);
1215 return EXT2_ET_NO_MEMORY;
1219 *ret = el->ea_count;
1224 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1226 struct ea_refcount_el *el;
1228 el = get_refcount_el(refcount, blk, 0);
1229 if (!el || el->ea_count == 0)
1230 return EXT2_ET_INVALID_ARGUMENT;
1235 *ret = el->ea_count;
1240 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1242 struct ea_refcount_el *el;
1245 * Get the refcount element
1247 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1249 return count ? EXT2_ET_NO_MEMORY : 0;
1250 el->ea_count = count;
1254 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1256 refcount->cursor = 0;
1260 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1262 struct ea_refcount_el *list;
1265 if (refcount->cursor >= refcount->count)
1267 list = refcount->list;
1268 if (list[refcount->cursor].ea_count) {
1270 *ret = list[refcount->cursor].ea_count;
1271 return list[refcount->cursor++].ea_blk;
1279 * ehandler.c --- handle bad block errors which come up during the
1280 * course of an e2fsck session.
1284 static const char *operation;
1287 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1288 void *data, size_t size FSCK_ATTR((unused)),
1289 int actual FSCK_ATTR((unused)), errcode_t error)
1293 ext2_filsys fs = (ext2_filsys) channel->app_data;
1296 ctx = (e2fsck_t) fs->priv_data;
1299 * If more than one block was read, try reading each block
1300 * separately. We could use the actual bytes read to figure
1301 * out where to start, but we don't bother.
1305 for (i=0; i < count; i++, p += channel->block_size, block++) {
1306 error = io_channel_read_blk(channel, block,
1314 printf(_("Error reading block %lu (%s) while %s. "), block,
1315 error_message(error), operation);
1317 printf(_("Error reading block %lu (%s). "), block,
1318 error_message(error));
1320 if (ask(ctx, _("Ignore error"), 1)) {
1321 if (ask(ctx, _("Force rewrite"), 1))
1322 io_channel_write_blk(channel, block, 1, data);
1330 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1331 const void *data, size_t size FSCK_ATTR((unused)),
1332 int actual FSCK_ATTR((unused)), errcode_t error)
1336 ext2_filsys fs = (ext2_filsys) channel->app_data;
1339 ctx = (e2fsck_t) fs->priv_data;
1342 * If more than one block was written, try writing each block
1343 * separately. We could use the actual bytes read to figure
1344 * out where to start, but we don't bother.
1347 p = (const char *) data;
1348 for (i=0; i < count; i++, p += channel->block_size, block++) {
1349 error = io_channel_write_blk(channel, block,
1358 printf(_("Error writing block %lu (%s) while %s. "), block,
1359 error_message(error), operation);
1361 printf(_("Error writing block %lu (%s). "), block,
1362 error_message(error));
1364 if (ask(ctx, _("Ignore error"), 1))
1370 static inline const char *ehandler_operation(const char *op)
1372 const char *ret = operation;
1378 static void ehandler_init(io_channel channel)
1380 channel->read_error = e2fsck_handle_read_error;
1381 channel->write_error = e2fsck_handle_write_error;
1385 * journal.c --- code for handling the "ext3" journal
1387 * Copyright (C) 2000 Andreas Dilger
1388 * Copyright (C) 2000 Theodore Ts'o
1390 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1391 * Copyright (C) 1999 Red Hat Software
1393 * This file may be redistributed under the terms of the
1394 * GNU General Public License version 2 or at your discretion
1395 * any later version.
1399 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1400 * This creates a larger static binary, and a smaller binary using
1401 * shared libraries. It's also probably slightly less CPU-efficient,
1402 * which is why it's not on by default. But, it's a good way of
1403 * testing the functions in inode_io.c and fileio.c.
1407 /* Kernel compatibility functions for handling the journal. These allow us
1408 * to use the recovery.c file virtually unchanged from the kernel, so we
1409 * don't have to do much to keep kernel and user recovery in sync.
1411 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1417 struct inode *inode = journal->j_inode;
1426 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1427 &inode->i_ext2, NULL, 0, block, &pblk);
1433 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1435 struct buffer_head *bh;
1437 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1441 bh->b_ctx = kdev->k_ctx;
1442 if (kdev->k_dev == K_DEV_FS)
1443 bh->b_io = kdev->k_ctx->fs->io;
1445 bh->b_io = kdev->k_ctx->journal_io;
1446 bh->b_size = blocksize;
1447 bh->b_blocknr = blocknr;
1452 static void sync_blockdev(kdev_t kdev)
1456 if (kdev->k_dev == K_DEV_FS)
1457 io = kdev->k_ctx->fs->io;
1459 io = kdev->k_ctx->journal_io;
1461 io_channel_flush(io);
1464 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1467 struct buffer_head *bh;
1469 for (; nr > 0; --nr) {
1471 if (rw == READ && !bh->b_uptodate) {
1472 retval = io_channel_read_blk(bh->b_io,
1476 bb_error_msg("while reading block %lu\n",
1477 (unsigned long) bh->b_blocknr);
1482 } else if (rw == WRITE && bh->b_dirty) {
1483 retval = io_channel_write_blk(bh->b_io,
1487 bb_error_msg("while writing block %lu\n",
1488 (unsigned long) bh->b_blocknr);
1498 static inline void mark_buffer_dirty(struct buffer_head *bh)
1503 static inline void mark_buffer_clean(struct buffer_head * bh)
1508 static void brelse(struct buffer_head *bh)
1511 ll_rw_block(WRITE, 1, &bh);
1512 ext2fs_free_mem(&bh);
1515 static inline int buffer_uptodate(struct buffer_head *bh)
1517 return bh->b_uptodate;
1520 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1522 bh->b_uptodate = val;
1525 static void wait_on_buffer(struct buffer_head *bh)
1527 if (!bh->b_uptodate)
1528 ll_rw_block(READ, 1, &bh);
1532 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1534 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1536 /* if we had an error doing journal recovery, we need a full fsck */
1538 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1539 ext2fs_mark_super_dirty(ctx->fs);
1542 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1544 struct ext2_super_block *sb = ctx->fs->super;
1545 struct ext2_super_block jsuper;
1546 struct problem_context pctx;
1547 struct buffer_head *bh;
1548 struct inode *j_inode = NULL;
1549 struct kdev_s *dev_fs = NULL, *dev_journal;
1550 const char *journal_name = 0;
1551 journal_t *journal = NULL;
1552 errcode_t retval = 0;
1553 io_manager io_ptr = 0;
1554 unsigned long start = 0;
1556 int ext_journal = 0;
1557 int tried_backup_jnl = 0;
1560 clear_problem_context(&pctx);
1562 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1564 return EXT2_ET_NO_MEMORY;
1567 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1569 retval = EXT2_ET_NO_MEMORY;
1572 dev_journal = dev_fs+1;
1574 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1575 dev_fs->k_dev = K_DEV_FS;
1576 dev_journal->k_dev = K_DEV_JOURNAL;
1578 journal->j_dev = dev_journal;
1579 journal->j_fs_dev = dev_fs;
1580 journal->j_inode = NULL;
1581 journal->j_blocksize = ctx->fs->blocksize;
1583 if (uuid_is_null(sb->s_journal_uuid)) {
1584 if (!sb->s_journal_inum)
1585 return EXT2_ET_BAD_INODE_NUM;
1586 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1589 retval = EXT2_ET_NO_MEMORY;
1593 j_inode->i_ctx = ctx;
1594 j_inode->i_ino = sb->s_journal_inum;
1596 if ((retval = ext2fs_read_inode(ctx->fs,
1598 &j_inode->i_ext2))) {
1600 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1603 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1604 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1606 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1607 j_inode->i_ext2.i_links_count = 1;
1608 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1611 if (!j_inode->i_ext2.i_links_count ||
1612 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1613 retval = EXT2_ET_NO_JOURNAL;
1614 goto try_backup_journal;
1616 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1617 JFS_MIN_JOURNAL_BLOCKS) {
1618 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1619 goto try_backup_journal;
1621 for (i=0; i < EXT2_N_BLOCKS; i++) {
1622 blk = j_inode->i_ext2.i_block[i];
1624 if (i < EXT2_NDIR_BLOCKS) {
1625 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1626 goto try_backup_journal;
1630 if (blk < sb->s_first_data_block ||
1631 blk >= sb->s_blocks_count) {
1632 retval = EXT2_ET_BAD_BLOCK_NUM;
1633 goto try_backup_journal;
1636 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1639 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1645 io_ptr = inode_io_manager;
1647 journal->j_inode = j_inode;
1648 ctx->journal_io = ctx->fs->io;
1649 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1654 if (!ctx->journal_name) {
1657 uuid_unparse(sb->s_journal_uuid, uuid);
1658 ctx->journal_name = blkid_get_devname(ctx->blkid,
1660 if (!ctx->journal_name)
1661 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1663 journal_name = ctx->journal_name;
1665 if (!journal_name) {
1666 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1667 return EXT2_ET_LOAD_EXT_JOURNAL;
1670 io_ptr = unix_io_manager;
1673 #ifndef USE_INODE_IO
1676 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1681 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1684 if (ctx->fs->blocksize == 1024)
1686 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1688 retval = EXT2_ET_NO_MEMORY;
1691 ll_rw_block(READ, 1, &bh);
1692 if ((retval = bh->b_err) != 0)
1694 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1698 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1699 ext2fs_swap_super(&jsuper);
1701 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1702 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1703 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1704 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1707 /* Make sure the journal UUID is correct */
1708 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1709 sizeof(jsuper.s_uuid))) {
1710 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1711 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1715 journal->j_maxlen = jsuper.s_blocks_count;
1719 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1720 retval = EXT2_ET_NO_MEMORY;
1724 journal->j_sb_buffer = bh;
1725 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1728 ext2fs_free_mem(&j_inode);
1731 *ret_journal = journal;
1735 ext2fs_free_mem(&dev_fs);
1736 ext2fs_free_mem(&j_inode);
1737 ext2fs_free_mem(&journal);
1742 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1743 struct problem_context *pctx)
1745 struct ext2_super_block *sb = ctx->fs->super;
1746 int recover = ctx->fs->super->s_feature_incompat &
1747 EXT3_FEATURE_INCOMPAT_RECOVER;
1748 int has_journal = ctx->fs->super->s_feature_compat &
1749 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1751 if (has_journal || sb->s_journal_inum) {
1752 /* The journal inode is bogus, remove and force full fsck */
1753 pctx->ino = sb->s_journal_inum;
1754 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1755 if (has_journal && sb->s_journal_inum)
1756 printf("*** ext3 journal has been deleted - "
1757 "filesystem is now ext2 only ***\n\n");
1758 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1759 sb->s_journal_inum = 0;
1760 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1761 e2fsck_clear_recover(ctx, 1);
1764 return EXT2_ET_BAD_INODE_NUM;
1765 } else if (recover) {
1766 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1767 e2fsck_clear_recover(ctx, 1);
1770 return EXT2_ET_UNSUPP_FEATURE;
1775 #define V1_SB_SIZE 0x0024
1776 static void clear_v2_journal_fields(journal_t *journal)
1778 e2fsck_t ctx = journal->j_dev->k_ctx;
1779 struct problem_context pctx;
1781 clear_problem_context(&pctx);
1783 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1786 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1787 ctx->fs->blocksize-V1_SB_SIZE);
1788 mark_buffer_dirty(journal->j_sb_buffer);
1792 static errcode_t e2fsck_journal_load(journal_t *journal)
1794 e2fsck_t ctx = journal->j_dev->k_ctx;
1795 journal_superblock_t *jsb;
1796 struct buffer_head *jbh = journal->j_sb_buffer;
1797 struct problem_context pctx;
1799 clear_problem_context(&pctx);
1801 ll_rw_block(READ, 1, &jbh);
1803 bb_error_msg(_("reading journal superblock\n"));
1807 jsb = journal->j_superblock;
1808 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1809 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1810 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1812 switch (ntohl(jsb->s_header.h_blocktype)) {
1813 case JFS_SUPERBLOCK_V1:
1814 journal->j_format_version = 1;
1815 if (jsb->s_feature_compat ||
1816 jsb->s_feature_incompat ||
1817 jsb->s_feature_ro_compat ||
1819 clear_v2_journal_fields(journal);
1822 case JFS_SUPERBLOCK_V2:
1823 journal->j_format_version = 2;
1824 if (ntohl(jsb->s_nr_users) > 1 &&
1825 uuid_is_null(ctx->fs->super->s_journal_uuid))
1826 clear_v2_journal_fields(journal);
1827 if (ntohl(jsb->s_nr_users) > 1) {
1828 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1829 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1834 * These should never appear in a journal super block, so if
1835 * they do, the journal is badly corrupted.
1837 case JFS_DESCRIPTOR_BLOCK:
1838 case JFS_COMMIT_BLOCK:
1839 case JFS_REVOKE_BLOCK:
1840 return EXT2_ET_CORRUPT_SUPERBLOCK;
1842 /* If we don't understand the superblock major type, but there
1843 * is a magic number, then it is likely to be a new format we
1844 * just don't understand, so leave it alone. */
1846 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1849 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1850 return EXT2_ET_UNSUPP_FEATURE;
1852 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1853 return EXT2_ET_RO_UNSUPP_FEATURE;
1855 /* We have now checked whether we know enough about the journal
1856 * format to be able to proceed safely, so any other checks that
1857 * fail we should attempt to recover from. */
1858 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1859 bb_error_msg(_("%s: no valid journal superblock found\n"),
1861 return EXT2_ET_CORRUPT_SUPERBLOCK;
1864 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1865 journal->j_maxlen = ntohl(jsb->s_maxlen);
1866 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1867 bb_error_msg(_("%s: journal too short\n"),
1869 return EXT2_ET_CORRUPT_SUPERBLOCK;
1872 journal->j_tail_sequence = ntohl(jsb->s_sequence);
1873 journal->j_transaction_sequence = journal->j_tail_sequence;
1874 journal->j_tail = ntohl(jsb->s_start);
1875 journal->j_first = ntohl(jsb->s_first);
1876 journal->j_last = ntohl(jsb->s_maxlen);
1881 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
1892 /* Leave a valid existing V1 superblock signature alone.
1893 * Anything unrecognisable we overwrite with a new V2
1896 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
1897 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
1898 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
1899 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
1902 /* Zero out everything else beyond the superblock header */
1904 p = ((char *) jsb) + sizeof(journal_header_t);
1905 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
1907 jsb->s_blocksize = htonl(ctx->fs->blocksize);
1908 jsb->s_maxlen = htonl(journal->j_maxlen);
1909 jsb->s_first = htonl(1);
1911 /* Initialize the journal sequence number so that there is "no"
1912 * chance we will find old "valid" transactions in the journal.
1913 * This avoids the need to zero the whole journal (slow to do,
1914 * and risky when we are just recovering the filesystem).
1916 uuid_generate(u.uuid);
1917 for (i = 0; i < 4; i ++)
1918 new_seq ^= u.val[i];
1919 jsb->s_sequence = htonl(new_seq);
1921 mark_buffer_dirty(journal->j_sb_buffer);
1922 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
1925 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
1927 struct problem_context *pctx)
1929 struct ext2_super_block *sb = ctx->fs->super;
1930 int recover = ctx->fs->super->s_feature_incompat &
1931 EXT3_FEATURE_INCOMPAT_RECOVER;
1933 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
1934 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
1935 e2fsck_journal_reset_super(ctx, journal->j_superblock,
1937 journal->j_transaction_sequence = 1;
1938 e2fsck_clear_recover(ctx, recover);
1941 return EXT2_ET_CORRUPT_SUPERBLOCK;
1942 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
1943 return EXT2_ET_CORRUPT_SUPERBLOCK;
1948 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
1949 int reset, int drop)
1951 journal_superblock_t *jsb;
1954 mark_buffer_clean(journal->j_sb_buffer);
1955 else if (!(ctx->options & E2F_OPT_READONLY)) {
1956 jsb = journal->j_superblock;
1957 jsb->s_sequence = htonl(journal->j_transaction_sequence);
1959 jsb->s_start = 0; /* this marks the journal as empty */
1960 mark_buffer_dirty(journal->j_sb_buffer);
1962 brelse(journal->j_sb_buffer);
1964 if (ctx->journal_io) {
1965 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1966 io_channel_close(ctx->journal_io);
1967 ctx->journal_io = 0;
1970 #ifndef USE_INODE_IO
1971 ext2fs_free_mem(&journal->j_inode);
1973 ext2fs_free_mem(&journal->j_fs_dev);
1974 ext2fs_free_mem(&journal);
1978 * This function makes sure that the superblock fields regarding the
1979 * journal are consistent.
1981 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
1983 struct ext2_super_block *sb = ctx->fs->super;
1985 int recover = ctx->fs->super->s_feature_incompat &
1986 EXT3_FEATURE_INCOMPAT_RECOVER;
1987 struct problem_context pctx;
1989 int reset = 0, force_fsck = 0;
1992 /* If we don't have any journal features, don't do anything more */
1993 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
1994 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
1995 uuid_is_null(sb->s_journal_uuid))
1998 clear_problem_context(&pctx);
1999 pctx.num = sb->s_journal_inum;
2001 retval = e2fsck_get_journal(ctx, &journal);
2003 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2004 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2005 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2006 (retval == EXT2_ET_NO_JOURNAL))
2007 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2011 retval = e2fsck_journal_load(journal);
2013 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2014 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2015 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2017 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2018 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2020 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2021 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2022 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2024 e2fsck_journal_release(ctx, journal, 0, 1);
2029 * We want to make the flags consistent here. We will not leave with
2030 * needs_recovery set but has_journal clear. We can't get in a loop
2031 * with -y, -n, or -p, only if a user isn't making up their mind.
2034 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2035 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2037 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2039 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2040 goto no_has_journal;
2042 * Need a full fsck if we are releasing a
2043 * journal stored on a reserved inode.
2045 force_fsck = recover ||
2046 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2047 /* Clear all of the journal fields */
2048 sb->s_journal_inum = 0;
2049 sb->s_journal_dev = 0;
2050 memset(sb->s_journal_uuid, 0,
2051 sizeof(sb->s_journal_uuid));
2052 e2fsck_clear_recover(ctx, force_fsck);
2053 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2054 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2055 ext2fs_mark_super_dirty(ctx->fs);
2059 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2060 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2061 journal->j_superblock->s_start != 0) {
2062 /* Print status information */
2063 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2064 if (ctx->superblock)
2065 problem = PR_0_JOURNAL_RUN_DEFAULT;
2067 problem = PR_0_JOURNAL_RUN;
2068 if (fix_problem(ctx, problem, &pctx)) {
2069 ctx->options |= E2F_OPT_FORCE;
2070 sb->s_feature_incompat |=
2071 EXT3_FEATURE_INCOMPAT_RECOVER;
2072 ext2fs_mark_super_dirty(ctx->fs);
2073 } else if (fix_problem(ctx,
2074 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2076 sb->s_state &= ~EXT2_VALID_FS;
2077 ext2fs_mark_super_dirty(ctx->fs);
2080 * If the user answers no to the above question, we
2081 * ignore the fact that journal apparently has data;
2082 * accidentally replaying over valid data would be far
2083 * worse than skipping a questionable recovery.
2085 * XXX should we abort with a fatal error here? What
2086 * will the ext3 kernel code do if a filesystem with
2087 * !NEEDS_RECOVERY but with a non-zero
2088 * journal->j_superblock->s_start is mounted?
2092 e2fsck_journal_release(ctx, journal, reset, 0);
2096 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2101 journal_init_revoke_caches();
2102 retval = e2fsck_get_journal(ctx, &journal);
2106 retval = e2fsck_journal_load(journal);
2110 retval = journal_init_revoke(journal, 1024);
2114 retval = -journal_recover(journal);
2118 if (journal->j_superblock->s_errno) {
2119 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2120 ext2fs_mark_super_dirty(ctx->fs);
2121 journal->j_superblock->s_errno = 0;
2122 mark_buffer_dirty(journal->j_sb_buffer);
2126 journal_destroy_revoke(journal);
2127 journal_destroy_revoke_caches();
2128 e2fsck_journal_release(ctx, journal, 1, 0);
2132 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2134 io_manager io_ptr = ctx->fs->io->manager;
2135 int blocksize = ctx->fs->blocksize;
2136 errcode_t retval, recover_retval;
2138 printf(_("%s: recovering journal\n"), ctx->device_name);
2139 if (ctx->options & E2F_OPT_READONLY) {
2140 printf(_("%s: won't do journal recovery while read-only\n"),
2142 return EXT2_ET_FILE_RO;
2145 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2146 ext2fs_flush(ctx->fs); /* Force out any modifications */
2148 recover_retval = recover_ext3_journal(ctx);
2151 * Reload the filesystem context to get up-to-date data from disk
2152 * because journal recovery will change the filesystem under us.
2154 ext2fs_close(ctx->fs);
2155 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2156 ctx->superblock, blocksize, io_ptr,
2160 bb_error_msg(_("while trying to re-open %s"),
2162 bb_error_msg_and_die(0);
2164 ctx->fs->priv_data = ctx;
2166 /* Set the superblock flags */
2167 e2fsck_clear_recover(ctx, recover_retval);
2168 return recover_retval;
2172 * This function will move the journal inode from a visible file in
2173 * the filesystem directory hierarchy to the reserved inode if necessary.
2175 static const char * const journal_names[] = {
2176 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2178 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2180 struct ext2_super_block *sb = ctx->fs->super;
2181 struct problem_context pctx;
2182 struct ext2_inode inode;
2183 ext2_filsys fs = ctx->fs;
2186 const char * const * cpp;
2187 int group, mount_flags;
2189 clear_problem_context(&pctx);
2192 * If the filesystem is opened read-only, or there is no
2193 * journal, then do nothing.
2195 if ((ctx->options & E2F_OPT_READONLY) ||
2196 (sb->s_journal_inum == 0) ||
2197 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2201 * Read in the journal inode
2203 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2207 * If it's necessary to backup the journal inode, do so.
2209 if ((sb->s_jnl_backup_type == 0) ||
2210 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2211 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2212 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2213 memcpy(sb->s_jnl_blocks, inode.i_block,
2215 sb->s_jnl_blocks[16] = inode.i_size;
2216 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2217 ext2fs_mark_super_dirty(fs);
2218 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2223 * If the journal is already the hidden inode, then do nothing
2225 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2229 * The journal inode had better have only one link and not be readable.
2231 if (inode.i_links_count != 1)
2235 * If the filesystem is mounted, or we can't tell whether
2236 * or not it's mounted, do nothing.
2238 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2239 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2243 * If we can't find the name of the journal inode, then do
2246 for (cpp = journal_names; *cpp; cpp++) {
2247 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2248 strlen(*cpp), 0, &ino);
2249 if ((retval == 0) && (ino == sb->s_journal_inum))
2255 /* We need the inode bitmap to be loaded */
2256 retval = ext2fs_read_bitmaps(fs);
2261 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2265 * OK, we've done all the checks, let's actually move the
2266 * journal inode. Errors at this point mean we need to force
2267 * an ext2 filesystem check.
2269 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2271 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2273 sb->s_journal_inum = EXT2_JOURNAL_INO;
2274 ext2fs_mark_super_dirty(fs);
2275 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2276 inode.i_links_count = 0;
2277 inode.i_dtime = time(0);
2278 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2281 group = ext2fs_group_of_ino(fs, ino);
2282 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2283 ext2fs_mark_ib_dirty(fs);
2284 fs->group_desc[group].bg_free_inodes_count++;
2285 fs->super->s_free_inodes_count++;
2289 pctx.errcode = retval;
2290 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2291 fs->super->s_state &= ~EXT2_VALID_FS;
2292 ext2fs_mark_super_dirty(fs);
2297 * message.c --- print e2fsck messages (with compression)
2299 * print_e2fsck_message() prints a message to the user, using
2300 * compression techniques and expansions of abbreviations.
2302 * The following % expansions are supported:
2304 * %b <blk> block number
2305 * %B <blkcount> integer
2306 * %c <blk2> block number
2307 * %Di <dirent>->ino inode number
2308 * %Dn <dirent>->name string
2309 * %Dr <dirent>->rec_len
2310 * %Dl <dirent>->name_len
2311 * %Dt <dirent>->filetype
2312 * %d <dir> inode number
2313 * %g <group> integer
2314 * %i <ino> inode number
2315 * %Is <inode> -> i_size
2316 * %IS <inode> -> i_extra_isize
2317 * %Ib <inode> -> i_blocks
2318 * %Il <inode> -> i_links_count
2319 * %Im <inode> -> i_mode
2320 * %IM <inode> -> i_mtime
2321 * %IF <inode> -> i_faddr
2322 * %If <inode> -> i_file_acl
2323 * %Id <inode> -> i_dir_acl
2324 * %Iu <inode> -> i_uid
2325 * %Ig <inode> -> i_gid
2326 * %j <ino2> inode number
2327 * %m <com_err error message>
2329 * %p ext2fs_get_pathname of directory <ino>
2330 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2331 * the containing directory. (If dirent is NULL
2332 * then return the pathname of directory <ino2>)
2333 * %q ext2fs_get_pathname of directory <dir>
2334 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2335 * the containing directory.
2336 * %s <str> miscellaneous string
2337 * %S backup superblock
2338 * %X <num> hexadecimal format
2340 * The following '@' expansions are supported:
2342 * @a extended attribute
2343 * @A error allocating
2347 * @C conflicts with some other fs block
2351 * @E Entry '%Dn' in %p (%i)
2353 * @F for @i %i (%Q) is
2355 * @h HTREE directory inode
2361 * @m multiply-claimed
2375 * This structure defines the abbreviations used by the text strings
2376 * below. The first character in the string is the index letter. An
2377 * abbreviation of the form '@<i>' is expanded by looking up the index
2378 * letter <i> in the table below.
2380 static const char * const abbrevs[] = {
2381 N_("aextended attribute"),
2382 N_("Aerror allocating"),
2386 N_("Cconflicts with some other fs @b"),
2393 N_("E@e '%Dn' in %p (%i)"),
2395 N_("Ffor @i %i (%Q) is"),
2400 N_("mmultiply-claimed"),
2415 * Give more user friendly names to the "special" inodes.
2417 #define num_special_inodes 11
2418 static const char * const special_inode_name[] =
2420 N_("<The NULL inode>"), /* 0 */
2421 N_("<The bad blocks inode>"), /* 1 */
2423 N_("<The ACL index inode>"), /* 3 */
2424 N_("<The ACL data inode>"), /* 4 */
2425 N_("<The boot loader inode>"), /* 5 */
2426 N_("<The undelete directory inode>"), /* 6 */
2427 N_("<The group descriptor inode>"), /* 7 */
2428 N_("<The journal inode>"), /* 8 */
2429 N_("<Reserved inode 9>"), /* 9 */
2430 N_("<Reserved inode 10>"), /* 10 */
2434 * This function does "safe" printing. It will convert non-printable
2435 * ASCII characters using '^' and M- notation.
2437 static void safe_print(const char *cp, int len)
2447 fputs("M-", stdout);
2450 if ((ch < 32) || (ch == 0x7f)) {
2452 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2460 * This function prints a pathname, using the ext2fs_get_pathname
2463 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2468 if (!dir && (ino < num_special_inodes)) {
2469 fputs(_(special_inode_name[ino]), stdout);
2473 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2475 fputs("???", stdout);
2477 safe_print(path, -1);
2478 ext2fs_free_mem(&path);
2482 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2483 struct problem_context *pctx, int first);
2485 * This function handles the '@' expansion. We allow recursive
2486 * expansion; an @ expression can contain further '@' and '%'
2489 static void expand_at_expression(e2fsck_t ctx, char ch,
2490 struct problem_context *pctx,
2493 const char * const *cpp;
2496 /* Search for the abbreviation */
2497 for (cpp = abbrevs; *cpp; cpp++) {
2503 if (*first && islower(*str)) {
2505 fputc(toupper(*str++), stdout);
2507 print_e2fsck_message(ctx, str, pctx, *first);
2513 * This function expands '%IX' expressions
2515 static void expand_inode_expression(char ch,
2516 struct problem_context *ctx)
2518 struct ext2_inode *inode;
2519 struct ext2_inode_large *large_inode;
2524 if (!ctx || !ctx->inode)
2528 large_inode = (struct ext2_inode_large *) inode;
2532 if (LINUX_S_ISDIR(inode->i_mode))
2533 printf("%u", inode->i_size);
2535 #ifdef EXT2_NO_64_TYPE
2536 if (inode->i_size_high)
2537 printf("0x%x%08x", inode->i_size_high,
2540 printf("%u", inode->i_size);
2542 printf("%llu", (inode->i_size |
2543 ((__u64) inode->i_size_high << 32)));
2548 printf("%u", large_inode->i_extra_isize);
2551 printf("%u", inode->i_blocks);
2554 printf("%d", inode->i_links_count);
2557 printf("0%o", inode->i_mode);
2560 /* The diet libc doesn't respect the TZ environemnt variable */
2562 time_str = getenv("TZ");
2565 do_gmt = !strcmp(time_str, "GMT");
2568 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2569 printf("%.24s", time_str);
2572 printf("%u", inode->i_faddr);
2575 printf("%u", inode->i_file_acl);
2578 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2579 inode->i_dir_acl : 0));
2582 printf("%d", (inode->i_uid |
2583 (inode->osd2.linux2.l_i_uid_high << 16)));
2586 printf("%d", (inode->i_gid |
2587 (inode->osd2.linux2.l_i_gid_high << 16)));
2591 printf("%%I%c", ch);
2597 * This function expands '%dX' expressions
2599 static void expand_dirent_expression(char ch,
2600 struct problem_context *ctx)
2602 struct ext2_dir_entry *dirent;
2605 if (!ctx || !ctx->dirent)
2608 dirent = ctx->dirent;
2612 printf("%u", dirent->inode);
2615 len = dirent->name_len & 0xFF;
2616 if (len > EXT2_NAME_LEN)
2617 len = EXT2_NAME_LEN;
2618 if (len > dirent->rec_len)
2619 len = dirent->rec_len;
2620 safe_print(dirent->name, len);
2623 printf("%u", dirent->rec_len);
2626 printf("%u", dirent->name_len & 0xFF);
2629 printf("%u", dirent->name_len >> 8);
2633 printf("%%D%c", ch);
2638 static void expand_percent_expression(ext2_filsys fs, char ch,
2639 struct problem_context *ctx)
2649 printf("%u", ctx->blk);
2652 #ifdef EXT2_NO_64_TYPE
2653 printf("%d", ctx->blkcount);
2655 printf("%lld", ctx->blkcount);
2659 printf("%u", ctx->blk2);
2662 printf("%u", ctx->dir);
2665 printf("%d", ctx->group);
2668 printf("%u", ctx->ino);
2671 printf("%u", ctx->ino2);
2674 printf("%s", error_message(ctx->errcode));
2677 #ifdef EXT2_NO_64_TYPE
2678 printf("%u", ctx->num);
2680 printf("%llu", ctx->num);
2684 print_pathname(fs, ctx->ino, 0);
2687 print_pathname(fs, ctx->ino2,
2688 ctx->dirent ? ctx->dirent->inode : 0);
2691 print_pathname(fs, ctx->dir, 0);
2694 print_pathname(fs, ctx->dir, ctx->ino);
2697 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2700 printf("%s", ctx->str ? ctx->str : "NULL");
2703 #ifdef EXT2_NO_64_TYPE
2704 printf("0x%x", ctx->num);
2706 printf("0x%llx", ctx->num);
2717 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2718 struct problem_context *pctx, int first)
2720 ext2_filsys fs = ctx->fs;
2724 e2fsck_clear_progbar(ctx);
2725 for (cp = msg; *cp; cp++) {
2728 expand_at_expression(ctx, *cp, pctx, &first);
2729 } else if (cp[0] == '%' && cp[1] == 'I') {
2731 expand_inode_expression(*cp, pctx);
2732 } else if (cp[0] == '%' && cp[1] == 'D') {
2734 expand_dirent_expression(*cp, pctx);
2735 } else if ((cp[0] == '%')) {
2737 expand_percent_expression(fs, *cp, pctx);
2739 for (i=0; cp[i]; i++)
2740 if ((cp[i] == '@') || cp[i] == '%')
2742 printf("%.*s", i, cp);
2751 * region.c --- code which manages allocations within a region.
2755 region_addr_t start;
2757 struct region_el *next;
2760 struct region_struct {
2763 struct region_el *allocated;
2766 static region_t region_create(region_addr_t min, region_addr_t max)
2770 region = malloc(sizeof(struct region_struct));
2773 memset(region, 0, sizeof(struct region_struct));
2779 static void region_free(region_t region)
2781 struct region_el *r, *next;
2783 for (r = region->allocated; r; r = next) {
2787 memset(region, 0, sizeof(struct region_struct));
2791 static int region_allocate(region_t region, region_addr_t start, int n)
2793 struct region_el *r, *new_region, *prev, *next;
2797 if ((start < region->min) || (end > region->max))
2803 * Search through the linked list. If we find that it
2804 * conflicts witih something that's already allocated, return
2805 * 1; if we can find an existing region which we can grow, do
2806 * so. Otherwise, stop when we find the appropriate place
2807 * insert a new region element into the linked list.
2809 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2810 if (((start >= r->start) && (start < r->end)) ||
2811 ((end > r->start) && (end <= r->end)) ||
2812 ((start <= r->start) && (end >= r->end)))
2814 if (end == r->start) {
2818 if (start == r->end) {
2819 if ((next = r->next)) {
2820 if (end > next->start)
2822 if (end == next->start) {
2824 r->next = next->next;
2832 if (start < r->start)
2836 * Insert a new region element structure into the linked list
2838 new_region = malloc(sizeof(struct region_el));
2841 new_region->start = start;
2842 new_region->end = start + n;
2843 new_region->next = r;
2845 prev->next = new_region;
2847 region->allocated = new_region;
2852 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2854 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2855 * and applies the following tests to each inode:
2857 * - The mode field of the inode must be legal.
2858 * - The size and block count fields of the inode are correct.
2859 * - A data block must not be used by another inode
2861 * Pass 1 also gathers the collects the following information:
2863 * - A bitmap of which inodes are in use. (inode_used_map)
2864 * - A bitmap of which inodes are directories. (inode_dir_map)
2865 * - A bitmap of which inodes are regular files. (inode_reg_map)
2866 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2867 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2868 * - A bitmap of which blocks are in use. (block_found_map)
2869 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2870 * - The data blocks of the directory inodes. (dir_map)
2872 * Pass 1 is designed to stash away enough information so that the
2873 * other passes should not need to read in the inode information
2874 * during the normal course of a filesystem check. (Althogh if an
2875 * inconsistency is detected, other passes may need to read in an
2878 * Note that pass 1B will be invoked if there are any duplicate blocks
2883 static int process_block(ext2_filsys fs, blk_t *blocknr,
2884 e2_blkcnt_t blockcnt, blk_t ref_blk,
2885 int ref_offset, void *priv_data);
2886 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2887 e2_blkcnt_t blockcnt, blk_t ref_blk,
2888 int ref_offset, void *priv_data);
2889 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2891 static void mark_table_blocks(e2fsck_t ctx);
2892 static void alloc_imagic_map(e2fsck_t ctx);
2893 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2894 static void handle_fs_bad_blocks(e2fsck_t ctx);
2895 static void process_inodes(e2fsck_t ctx, char *block_buf);
2896 static int process_inode_cmp(const void *a, const void *b);
2897 static errcode_t scan_callback(ext2_filsys fs,
2898 dgrp_t group, void * priv_data);
2899 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2900 char *block_buf, int adjust_sign);
2901 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2903 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2904 struct ext2_inode * inode, int bufsize,
2907 struct process_block_struct_1 {
2909 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
2910 fragmented:1, compressed:1, bbcheck:1;
2913 e2_blkcnt_t last_block;
2914 int num_illegal_blocks;
2915 blk_t previous_block;
2916 struct ext2_inode *inode;
2917 struct problem_context *pctx;
2918 ext2fs_block_bitmap fs_meta_blocks;
2922 struct process_inode_block {
2924 struct ext2_inode inode;
2927 struct scan_callback_struct {
2933 * For the inodes to process list.
2935 static struct process_inode_block *inodes_to_process;
2936 static int process_inode_count;
2938 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2939 EXT2_MIN_BLOCK_LOG_SIZE + 1];
2942 * Free all memory allocated by pass1 in preparation for restarting
2945 static void unwind_pass1(void)
2947 ext2fs_free_mem(&inodes_to_process);
2951 * Check to make sure a device inode is real. Returns 1 if the device
2952 * checks out, 0 if not.
2954 * Note: this routine is now also used to check FIFO's and Sockets,
2955 * since they have the same requirement; the i_block fields should be
2959 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2964 * If i_blocks is non-zero, or the index flag is set, then
2965 * this is a bogus device/fifo/socket
2967 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2968 (inode->i_flags & EXT2_INDEX_FL))
2972 * We should be able to do the test below all the time, but
2973 * because the kernel doesn't forcibly clear the device
2974 * inode's additional i_block fields, there are some rare
2975 * occasions when a legitimate device inode will have non-zero
2976 * additional i_block fields. So for now, we only complain
2977 * when the immutable flag is set, which should never happen
2978 * for devices. (And that's when the problem is caused, since
2979 * you can't set or clear immutable flags for devices.) Once
2980 * the kernel has been fixed we can change this...
2982 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2983 for (i=4; i < EXT2_N_BLOCKS; i++)
2984 if (inode->i_block[i])
2991 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2992 * checks out, 0 if not.
2995 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
3001 if ((inode->i_size_high || inode->i_size == 0) ||
3002 (inode->i_flags & EXT2_INDEX_FL))
3005 blocks = ext2fs_inode_data_blocks(fs, inode);
3007 if ((inode->i_size >= fs->blocksize) ||
3008 (blocks != fs->blocksize >> 9) ||
3009 (inode->i_block[0] < fs->super->s_first_data_block) ||
3010 (inode->i_block[0] >= fs->super->s_blocks_count))
3013 for (i = 1; i < EXT2_N_BLOCKS; i++)
3014 if (inode->i_block[i])
3017 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
3020 len = strnlen(buf, fs->blocksize);
3021 if (len == fs->blocksize)
3024 if (inode->i_size >= sizeof(inode->i_block))
3027 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3028 if (len == sizeof(inode->i_block))
3031 if (len != inode->i_size)
3037 * If the immutable (or append-only) flag is set on the inode, offer
3040 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3041 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3043 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3046 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3049 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3050 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3054 * If device, fifo or socket, check size is zero -- if not offer to
3057 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3059 struct ext2_inode *inode = pctx->inode;
3061 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3064 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3068 inode->i_size_high = 0;
3069 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3072 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3074 struct ext2_super_block *sb = ctx->fs->super;
3075 struct ext2_inode_large *inode;
3076 struct ext2_ext_attr_entry *entry;
3078 int storage_size, remain, offs;
3081 inode = (struct ext2_inode_large *) pctx->inode;
3082 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3083 inode->i_extra_isize;
3084 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3085 inode->i_extra_isize + sizeof(__u32);
3086 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3087 entry = (struct ext2_ext_attr_entry *) start;
3089 /* scan all entry's headers first */
3091 /* take finish entry 0UL into account */
3092 remain = storage_size - sizeof(__u32);
3095 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3097 /* header eats this space */
3098 remain -= sizeof(struct ext2_ext_attr_entry);
3100 /* is attribute name valid? */
3101 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3102 pctx->num = entry->e_name_len;
3103 problem = PR_1_ATTR_NAME_LEN;
3107 /* attribute len eats this space */
3108 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3110 /* check value size */
3111 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3112 pctx->num = entry->e_value_size;
3113 problem = PR_1_ATTR_VALUE_SIZE;
3117 /* check value placement */
3118 if (entry->e_value_offs +
3119 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3120 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3121 pctx->num = entry->e_value_offs;
3122 problem = PR_1_ATTR_VALUE_OFFSET;
3126 /* e_value_block must be 0 in inode's ea */
3127 if (entry->e_value_block != 0) {
3128 pctx->num = entry->e_value_block;
3129 problem = PR_1_ATTR_VALUE_BLOCK;
3133 /* e_hash must be 0 in inode's ea */
3134 if (entry->e_hash != 0) {
3135 pctx->num = entry->e_hash;
3136 problem = PR_1_ATTR_HASH;
3140 remain -= entry->e_value_size;
3141 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3143 entry = EXT2_EXT_ATTR_NEXT(entry);
3147 * it seems like a corruption. it's very unlikely we could repair
3148 * EA(s) in automatic fashion -bzzz
3150 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3153 /* simple remove all possible EA(s) */
3154 *((__u32 *)start) = 0UL;
3155 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3156 EXT2_INODE_SIZE(sb), "pass1");
3159 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3161 struct ext2_super_block *sb = ctx->fs->super;
3162 struct ext2_inode_large *inode;
3166 inode = (struct ext2_inode_large *) pctx->inode;
3167 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3168 /* this isn't large inode. so, nothing to check */
3172 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3173 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3174 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3176 * For now we will allow i_extra_isize to be 0, but really
3177 * implementations should never allow i_extra_isize to be 0
3179 if (inode->i_extra_isize &&
3180 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3181 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3183 inode->i_extra_isize = min;
3184 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3185 EXT2_INODE_SIZE(sb), "pass1");
3189 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3190 inode->i_extra_isize);
3191 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3192 /* it seems inode has an extended attribute(s) in body */
3193 check_ea_in_inode(ctx, pctx);
3197 static void e2fsck_pass1(e2fsck_t ctx)
3201 ext2_filsys fs = ctx->fs;
3203 struct ext2_inode *inode;
3204 ext2_inode_scan scan;
3206 unsigned char frag, fsize;
3207 struct problem_context pctx;
3208 struct scan_callback_struct scan_struct;
3209 struct ext2_super_block *sb = ctx->fs->super;
3211 int busted_fs_time = 0;
3214 clear_problem_context(&pctx);
3216 if (!(ctx->options & E2F_OPT_PREEN))
3217 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3219 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3220 !(ctx->options & E2F_OPT_NO)) {
3221 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3222 ctx->dirs_to_hash = 0;
3227 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3229 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3230 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3231 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3232 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3233 max_sizes = (max_sizes * (1UL << i)) - 1;
3234 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3238 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3241 * Allocate bitmaps structures
3243 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3244 &ctx->inode_used_map);
3247 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3248 ctx->flags |= E2F_FLAG_ABORT;
3251 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3252 _("directory inode map"), &ctx->inode_dir_map);
3255 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3256 ctx->flags |= E2F_FLAG_ABORT;
3259 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3260 _("regular file inode map"), &ctx->inode_reg_map);
3263 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3264 ctx->flags |= E2F_FLAG_ABORT;
3267 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3268 &ctx->block_found_map);
3271 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3272 ctx->flags |= E2F_FLAG_ABORT;
3275 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3276 &ctx->inode_link_info);
3278 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3279 ctx->flags |= E2F_FLAG_ABORT;
3282 inode_size = EXT2_INODE_SIZE(fs->super);
3283 inode = (struct ext2_inode *)
3284 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3286 inodes_to_process = (struct process_inode_block *)
3287 e2fsck_allocate_memory(ctx,
3288 (ctx->process_inode_size *
3289 sizeof(struct process_inode_block)),
3290 "array of inodes to process");
3291 process_inode_count = 0;
3293 pctx.errcode = ext2fs_init_dblist(fs, 0);
3295 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3296 ctx->flags |= E2F_FLAG_ABORT;
3301 * If the last orphan field is set, clear it, since the pass1
3302 * processing will automatically find and clear the orphans.
3303 * In the future, we may want to try using the last_orphan
3304 * linked list ourselves, but for now, we clear it so that the
3305 * ext3 mount code won't get confused.
3307 if (!(ctx->options & E2F_OPT_READONLY)) {
3308 if (fs->super->s_last_orphan) {
3309 fs->super->s_last_orphan = 0;
3310 ext2fs_mark_super_dirty(fs);
3314 mark_table_blocks(ctx);
3315 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3316 "block interate buffer");
3317 e2fsck_use_inode_shortcuts(ctx, 1);
3318 ehandler_operation(_("doing inode scan"));
3319 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3322 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3323 ctx->flags |= E2F_FLAG_ABORT;
3326 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3327 ctx->stashed_inode = inode;
3328 scan_struct.ctx = ctx;
3329 scan_struct.block_buf = block_buf;
3330 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3332 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3334 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3335 (fs->super->s_mtime < fs->super->s_inodes_count))
3339 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3341 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3343 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3347 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3348 ctx->flags |= E2F_FLAG_ABORT;
3355 ctx->stashed_ino = ino;
3356 if (inode->i_links_count) {
3357 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3358 ino, inode->i_links_count);
3360 pctx.num = inode->i_links_count;
3361 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3362 ctx->flags |= E2F_FLAG_ABORT;
3366 if (ino == EXT2_BAD_INO) {
3367 struct process_block_struct_1 pb;
3369 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3370 &pb.fs_meta_blocks);
3373 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3374 ctx->flags |= E2F_FLAG_ABORT;
3377 pb.ino = EXT2_BAD_INO;
3378 pb.num_blocks = pb.last_block = 0;
3379 pb.num_illegal_blocks = 0;
3380 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3381 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3385 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3386 block_buf, process_bad_block, &pb);
3387 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3389 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3390 ctx->flags |= E2F_FLAG_ABORT;
3394 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3395 ctx->flags |= E2F_FLAG_ABORT;
3398 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3399 clear_problem_context(&pctx);
3401 } else if (ino == EXT2_ROOT_INO) {
3403 * Make sure the root inode is a directory; if
3404 * not, offer to clear it. It will be
3405 * regnerated in pass #3.
3407 if (!LINUX_S_ISDIR(inode->i_mode)) {
3408 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3409 inode->i_dtime = time(0);
3410 inode->i_links_count = 0;
3411 ext2fs_icount_store(ctx->inode_link_info,
3413 e2fsck_write_inode(ctx, ino, inode,
3419 * If dtime is set, offer to clear it. mke2fs
3420 * version 0.2b created filesystems with the
3421 * dtime field set for the root and lost+found
3422 * directories. We won't worry about
3423 * /lost+found, since that can be regenerated
3424 * easily. But we will fix the root directory
3425 * as a special case.
3427 if (inode->i_dtime && inode->i_links_count) {
3428 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3430 e2fsck_write_inode(ctx, ino, inode,
3434 } else if (ino == EXT2_JOURNAL_INO) {
3435 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3436 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3437 if (!LINUX_S_ISREG(inode->i_mode) &&
3438 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3440 inode->i_mode = LINUX_S_IFREG;
3441 e2fsck_write_inode(ctx, ino, inode,
3444 check_blocks(ctx, &pctx, block_buf);
3447 if ((inode->i_links_count || inode->i_blocks ||
3448 inode->i_blocks || inode->i_block[0]) &&
3449 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3451 memset(inode, 0, inode_size);
3452 ext2fs_icount_store(ctx->inode_link_info,
3454 e2fsck_write_inode_full(ctx, ino, inode,
3455 inode_size, "pass1");
3457 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3460 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3461 if (ino == EXT2_BOOT_LOADER_INO) {
3462 if (LINUX_S_ISDIR(inode->i_mode))
3463 problem = PR_1_RESERVED_BAD_MODE;
3464 } else if (ino == EXT2_RESIZE_INO) {
3465 if (inode->i_mode &&
3466 !LINUX_S_ISREG(inode->i_mode))
3467 problem = PR_1_RESERVED_BAD_MODE;
3469 if (inode->i_mode != 0)
3470 problem = PR_1_RESERVED_BAD_MODE;
3473 if (fix_problem(ctx, problem, &pctx)) {
3475 e2fsck_write_inode(ctx, ino, inode,
3479 check_blocks(ctx, &pctx, block_buf);
3483 * Check for inodes who might have been part of the
3484 * orphaned list linked list. They should have gotten
3485 * dealt with by now, unless the list had somehow been
3488 * FIXME: In the future, inodes which are still in use
3489 * (and which are therefore) pending truncation should
3490 * be handled specially. Right now we just clear the
3491 * dtime field, and the normal e2fsck handling of
3492 * inodes where i_size and the inode blocks are
3493 * inconsistent is to fix i_size, instead of releasing
3494 * the extra blocks. This won't catch the inodes that
3495 * was at the end of the orphan list, but it's better
3496 * than nothing. The right answer is that there
3497 * shouldn't be any bugs in the orphan list handling. :-)
3499 if (inode->i_dtime && !busted_fs_time &&
3500 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3501 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3502 inode->i_dtime = inode->i_links_count ?
3504 e2fsck_write_inode(ctx, ino, inode,
3510 * This code assumes that deleted inodes have
3511 * i_links_count set to 0.
3513 if (!inode->i_links_count) {
3514 if (!inode->i_dtime && inode->i_mode) {
3515 if (fix_problem(ctx,
3516 PR_1_ZERO_DTIME, &pctx)) {
3517 inode->i_dtime = time(0);
3518 e2fsck_write_inode(ctx, ino, inode,
3525 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3526 * deleted files. Oops.
3528 * Since all new ext2 implementations get this right,
3529 * we now assume that the case of non-zero
3530 * i_links_count and non-zero dtime means that we
3531 * should keep the file, not delete it.
3534 if (inode->i_dtime) {
3535 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3537 e2fsck_write_inode(ctx, ino, inode, "pass1");
3541 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3542 switch (fs->super->s_creator_os) {
3544 frag = inode->osd2.linux2.l_i_frag;
3545 fsize = inode->osd2.linux2.l_i_fsize;
3548 frag = inode->osd2.hurd2.h_i_frag;
3549 fsize = inode->osd2.hurd2.h_i_fsize;
3552 frag = inode->osd2.masix2.m_i_frag;
3553 fsize = inode->osd2.masix2.m_i_fsize;
3559 if (inode->i_faddr || frag || fsize ||
3560 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3561 mark_inode_bad(ctx, ino);
3562 if (inode->i_flags & EXT2_IMAGIC_FL) {
3564 if (!ctx->inode_imagic_map)
3565 alloc_imagic_map(ctx);
3566 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3569 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3570 inode->i_flags &= ~EXT2_IMAGIC_FL;
3571 e2fsck_write_inode(ctx, ino,
3577 check_inode_extra_space(ctx, &pctx);
3579 if (LINUX_S_ISDIR(inode->i_mode)) {
3580 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3581 e2fsck_add_dir_info(ctx, ino, 0);
3582 ctx->fs_directory_count++;
3583 } else if (LINUX_S_ISREG (inode->i_mode)) {
3584 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3585 ctx->fs_regular_count++;
3586 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3587 e2fsck_pass1_check_device_inode(fs, inode)) {
3588 check_immutable(ctx, &pctx);
3589 check_size(ctx, &pctx);
3590 ctx->fs_chardev_count++;
3591 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3592 e2fsck_pass1_check_device_inode(fs, inode)) {
3593 check_immutable(ctx, &pctx);
3594 check_size(ctx, &pctx);
3595 ctx->fs_blockdev_count++;
3596 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3597 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3598 check_immutable(ctx, &pctx);
3599 ctx->fs_symlinks_count++;
3600 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3601 ctx->fs_fast_symlinks_count++;
3602 check_blocks(ctx, &pctx, block_buf);
3606 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3607 e2fsck_pass1_check_device_inode(fs, inode)) {
3608 check_immutable(ctx, &pctx);
3609 check_size(ctx, &pctx);
3610 ctx->fs_fifo_count++;
3611 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3612 e2fsck_pass1_check_device_inode(fs, inode)) {
3613 check_immutable(ctx, &pctx);
3614 check_size(ctx, &pctx);
3615 ctx->fs_sockets_count++;
3617 mark_inode_bad(ctx, ino);
3618 if (inode->i_block[EXT2_IND_BLOCK])
3619 ctx->fs_ind_count++;
3620 if (inode->i_block[EXT2_DIND_BLOCK])
3621 ctx->fs_dind_count++;
3622 if (inode->i_block[EXT2_TIND_BLOCK])
3623 ctx->fs_tind_count++;
3624 if (inode->i_block[EXT2_IND_BLOCK] ||
3625 inode->i_block[EXT2_DIND_BLOCK] ||
3626 inode->i_block[EXT2_TIND_BLOCK] ||
3627 inode->i_file_acl) {
3628 inodes_to_process[process_inode_count].ino = ino;
3629 inodes_to_process[process_inode_count].inode = *inode;
3630 process_inode_count++;
3632 check_blocks(ctx, &pctx, block_buf);
3634 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3637 if (process_inode_count >= ctx->process_inode_size) {
3638 process_inodes(ctx, block_buf);
3640 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3644 process_inodes(ctx, block_buf);
3645 ext2fs_close_inode_scan(scan);
3646 ehandler_operation(0);
3649 * If any extended attribute blocks' reference counts need to
3650 * be adjusted, either up (ctx->refcount_extra), or down
3651 * (ctx->refcount), then fix them.
3653 if (ctx->refcount) {
3654 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3655 ea_refcount_free(ctx->refcount);
3658 if (ctx->refcount_extra) {
3659 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3661 ea_refcount_free(ctx->refcount_extra);
3662 ctx->refcount_extra = 0;
3665 if (ctx->invalid_bitmaps)
3666 handle_fs_bad_blocks(ctx);
3668 /* We don't need the block_ea_map any more */
3669 ext2fs_free_block_bitmap(ctx->block_ea_map);
3670 ctx->block_ea_map = 0;
3672 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3673 ext2fs_block_bitmap save_bmap;
3675 save_bmap = fs->block_map;
3676 fs->block_map = ctx->block_found_map;
3677 clear_problem_context(&pctx);
3678 pctx.errcode = ext2fs_create_resize_inode(fs);
3680 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3681 /* Should never get here */
3682 ctx->flags |= E2F_FLAG_ABORT;
3685 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3687 inode->i_mtime = time(0);
3688 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3690 fs->block_map = save_bmap;
3691 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3694 if (ctx->flags & E2F_FLAG_RESTART) {
3696 * Only the master copy of the superblock and block
3697 * group descriptors are going to be written during a
3698 * restart, so set the superblock to be used to be the
3699 * master superblock.
3701 ctx->use_superblock = 0;
3706 if (ctx->block_dup_map) {
3707 if (ctx->options & E2F_OPT_PREEN) {
3708 clear_problem_context(&pctx);
3709 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3711 e2fsck_pass1_dupblocks(ctx, block_buf);
3713 ext2fs_free_mem(&inodes_to_process);
3715 e2fsck_use_inode_shortcuts(ctx, 0);
3717 ext2fs_free_mem(&block_buf);
3718 ext2fs_free_mem(&inode);
3723 * When the inode_scan routines call this callback at the end of the
3724 * glock group, call process_inodes.
3726 static errcode_t scan_callback(ext2_filsys fs,
3727 dgrp_t group, void * priv_data)
3729 struct scan_callback_struct *scan_struct;
3732 scan_struct = (struct scan_callback_struct *) priv_data;
3733 ctx = scan_struct->ctx;
3735 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3738 if ((ctx->progress)(ctx, 1, group+1,
3739 ctx->fs->group_desc_count))
3740 return EXT2_ET_CANCEL_REQUESTED;
3746 * Process the inodes in the "inodes to process" list.
3748 static void process_inodes(e2fsck_t ctx, char *block_buf)
3751 struct ext2_inode *old_stashed_inode;
3752 ext2_ino_t old_stashed_ino;
3753 const char *old_operation;
3755 struct problem_context pctx;
3757 /* begin process_inodes */
3758 if (process_inode_count == 0)
3760 old_operation = ehandler_operation(0);
3761 old_stashed_inode = ctx->stashed_inode;
3762 old_stashed_ino = ctx->stashed_ino;
3763 qsort(inodes_to_process, process_inode_count,
3764 sizeof(struct process_inode_block), process_inode_cmp);
3765 clear_problem_context(&pctx);
3766 for (i=0; i < process_inode_count; i++) {
3767 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3768 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3769 sprintf(buf, _("reading indirect blocks of inode %u"),
3771 ehandler_operation(buf);
3772 check_blocks(ctx, &pctx, block_buf);
3773 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3776 ctx->stashed_inode = old_stashed_inode;
3777 ctx->stashed_ino = old_stashed_ino;
3778 process_inode_count = 0;
3779 /* end process inodes */
3781 ehandler_operation(old_operation);
3784 static int process_inode_cmp(const void *a, const void *b)
3786 const struct process_inode_block *ib_a =
3787 (const struct process_inode_block *) a;
3788 const struct process_inode_block *ib_b =
3789 (const struct process_inode_block *) b;
3792 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3793 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3795 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3800 * Mark an inode as being bad in some what
3802 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3804 struct problem_context pctx;
3806 if (!ctx->inode_bad_map) {
3807 clear_problem_context(&pctx);
3809 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3810 _("bad inode map"), &ctx->inode_bad_map);
3813 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3814 /* Should never get here */
3815 ctx->flags |= E2F_FLAG_ABORT;
3819 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3824 * This procedure will allocate the inode imagic table
3826 static void alloc_imagic_map(e2fsck_t ctx)
3828 struct problem_context pctx;
3830 clear_problem_context(&pctx);
3831 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3832 _("imagic inode map"),
3833 &ctx->inode_imagic_map);
3836 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3837 /* Should never get here */
3838 ctx->flags |= E2F_FLAG_ABORT;
3844 * Marks a block as in use, setting the dup_map if it's been set
3845 * already. Called by process_block and process_bad_block.
3847 * WARNING: Assumes checks have already been done to make sure block
3848 * is valid. This is true in both process_block and process_bad_block.
3850 static void mark_block_used(e2fsck_t ctx, blk_t block)
3852 struct problem_context pctx;
3854 clear_problem_context(&pctx);
3856 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3857 if (!ctx->block_dup_map) {
3858 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3859 _("multiply claimed block map"),
3860 &ctx->block_dup_map);
3863 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3865 /* Should never get here */
3866 ctx->flags |= E2F_FLAG_ABORT;
3870 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3872 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3877 * Adjust the extended attribute block's reference counts at the end
3878 * of pass 1, either by subtracting out references for EA blocks that
3879 * are still referenced in ctx->refcount, or by adding references for
3880 * EA blocks that had extra references as accounted for in
3881 * ctx->refcount_extra.
3883 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3884 char *block_buf, int adjust_sign)
3886 struct ext2_ext_attr_header *header;
3887 struct problem_context pctx;
3888 ext2_filsys fs = ctx->fs;
3893 clear_problem_context(&pctx);
3895 ea_refcount_intr_begin(refcount);
3897 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3900 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3902 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3905 header = (struct ext2_ext_attr_header *) block_buf;
3906 pctx.blkcount = header->h_refcount;
3907 should_be = header->h_refcount + adjust_sign * count;
3908 pctx.num = should_be;
3909 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3910 header->h_refcount = should_be;
3911 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3914 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3922 * Handle processing the extended attribute blocks
3924 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3927 ext2_filsys fs = ctx->fs;
3928 ext2_ino_t ino = pctx->ino;
3929 struct ext2_inode *inode = pctx->inode;
3932 struct ext2_ext_attr_header *header;
3933 struct ext2_ext_attr_entry *entry;
3937 blk = inode->i_file_acl;
3942 * If the Extended attribute flag isn't set, then a non-zero
3943 * file acl means that the inode is corrupted.
3945 * Or if the extended attribute block is an invalid block,
3946 * then the inode is also corrupted.
3948 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3949 (blk < fs->super->s_first_data_block) ||
3950 (blk >= fs->super->s_blocks_count)) {
3951 mark_inode_bad(ctx, ino);
3955 /* If ea bitmap hasn't been allocated, create it */
3956 if (!ctx->block_ea_map) {
3957 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3958 _("ext attr block map"),
3959 &ctx->block_ea_map);
3960 if (pctx->errcode) {
3962 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3963 ctx->flags |= E2F_FLAG_ABORT;
3968 /* Create the EA refcount structure if necessary */
3969 if (!ctx->refcount) {
3970 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3971 if (pctx->errcode) {
3973 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3974 ctx->flags |= E2F_FLAG_ABORT;
3979 /* Have we seen this EA block before? */
3980 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3981 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3983 /* Ooops, this EA was referenced more than it stated */
3984 if (!ctx->refcount_extra) {
3985 pctx->errcode = ea_refcount_create(0,
3986 &ctx->refcount_extra);
3987 if (pctx->errcode) {
3989 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3990 ctx->flags |= E2F_FLAG_ABORT;
3994 ea_refcount_increment(ctx->refcount_extra, blk, 0);
3999 * OK, we haven't seen this EA block yet. So we need to
4003 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4004 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
4006 header = (struct ext2_ext_attr_header *) block_buf;
4007 pctx->blk = inode->i_file_acl;
4008 if (((ctx->ext_attr_ver == 1) &&
4009 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
4010 ((ctx->ext_attr_ver == 2) &&
4011 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
4012 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
4016 if (header->h_blocks != 1) {
4017 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
4021 region = region_create(0, fs->blocksize);
4023 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
4024 ctx->flags |= E2F_FLAG_ABORT;
4027 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4028 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4032 entry = (struct ext2_ext_attr_entry *)(header+1);
4033 end = block_buf + fs->blocksize;
4034 while ((char *)entry < end && *(__u32 *)entry) {
4035 if (region_allocate(region, (char *)entry - (char *)header,
4036 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4037 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4040 if ((ctx->ext_attr_ver == 1 &&
4041 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4042 (ctx->ext_attr_ver == 2 &&
4043 entry->e_name_index == 0)) {
4044 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4047 if (entry->e_value_block != 0) {
4048 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4051 if (entry->e_value_size &&
4052 region_allocate(region, entry->e_value_offs,
4053 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4054 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4057 entry = EXT2_EXT_ATTR_NEXT(entry);
4059 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4060 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4063 region_free(region);
4065 count = header->h_refcount - 1;
4067 ea_refcount_store(ctx->refcount, blk, count);
4068 mark_block_used(ctx, blk);
4069 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4074 inode->i_file_acl = 0;
4075 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4079 /* Returns 1 if bad htree, 0 if OK */
4080 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4081 ext2_ino_t ino FSCK_ATTR((unused)),
4082 struct ext2_inode *inode,
4085 struct ext2_dx_root_info *root;
4086 ext2_filsys fs = ctx->fs;
4090 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4091 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4092 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4093 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4096 blk = inode->i_block[0];
4098 (blk < fs->super->s_first_data_block) ||
4099 (blk >= fs->super->s_blocks_count)) &&
4100 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4103 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4104 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4107 /* XXX should check that beginning matches a directory */
4108 root = (struct ext2_dx_root_info *) (block_buf + 24);
4110 if ((root->reserved_zero || root->info_length < 8) &&
4111 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4114 pctx->num = root->hash_version;
4115 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4116 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4117 (root->hash_version != EXT2_HASH_TEA) &&
4118 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4121 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4122 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4125 pctx->num = root->indirect_levels;
4126 if ((root->indirect_levels > 1) &&
4127 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4134 * This subroutine is called on each inode to account for all of the
4135 * blocks used by that inode.
4137 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4140 ext2_filsys fs = ctx->fs;
4141 struct process_block_struct_1 pb;
4142 ext2_ino_t ino = pctx->ino;
4143 struct ext2_inode *inode = pctx->inode;
4145 int dirty_inode = 0;
4151 pb.num_illegal_blocks = 0;
4152 pb.suppress = 0; pb.clear = 0;
4155 pb.previous_block = 0;
4156 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4157 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4158 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4165 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4166 if (fs->super->s_feature_incompat &
4167 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4170 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4171 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4177 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4180 if (ext2fs_inode_has_valid_blocks(inode))
4181 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4182 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4183 block_buf, process_block, &pb);
4184 end_problem_latch(ctx, PR_LATCH_BLOCK);
4185 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4186 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4189 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4191 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4192 ctx->fs_fragmented++;
4195 inode->i_links_count = 0;
4196 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4197 inode->i_dtime = time(0);
4199 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4200 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4201 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4203 * The inode was probably partially accounted for
4204 * before processing was aborted, so we need to
4205 * restart the pass 1 scan.
4207 ctx->flags |= E2F_FLAG_RESTART;
4211 if (inode->i_flags & EXT2_INDEX_FL) {
4212 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4213 inode->i_flags &= ~EXT2_INDEX_FL;
4217 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4221 if (ctx->dirs_to_hash && pb.is_dir &&
4222 !(inode->i_flags & EXT2_INDEX_FL) &&
4223 ((inode->i_size / fs->blocksize) >= 3))
4224 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4226 if (!pb.num_blocks && pb.is_dir) {
4227 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4228 inode->i_links_count = 0;
4229 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4230 inode->i_dtime = time(0);
4232 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4233 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4234 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4235 ctx->fs_directory_count--;
4240 pb.num_blocks *= (fs->blocksize / 512);
4243 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4244 if (nblock > (pb.last_block + 1))
4246 else if (nblock < (pb.last_block + 1)) {
4247 if (((pb.last_block + 1) - nblock) >
4248 fs->super->s_prealloc_dir_blocks)
4252 size = EXT2_I_SIZE(inode);
4253 if ((pb.last_block >= 0) &&
4254 (size < (__u64) pb.last_block * fs->blocksize))
4256 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4259 /* i_size for symlinks is checked elsewhere */
4260 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4261 pctx->num = (pb.last_block+1) * fs->blocksize;
4262 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4263 inode->i_size = pctx->num;
4264 if (!LINUX_S_ISDIR(inode->i_mode))
4265 inode->i_size_high = pctx->num >> 32;
4270 if (LINUX_S_ISREG(inode->i_mode) &&
4271 (inode->i_size_high || inode->i_size & 0x80000000UL))
4273 if (pb.num_blocks != inode->i_blocks) {
4274 pctx->num = pb.num_blocks;
4275 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4276 inode->i_blocks = pb.num_blocks;
4283 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4288 * This is a helper function for check_blocks().
4290 static int process_block(ext2_filsys fs,
4292 e2_blkcnt_t blockcnt,
4293 blk_t ref_block FSCK_ATTR((unused)),
4294 int ref_offset FSCK_ATTR((unused)),
4297 struct process_block_struct_1 *p;
4298 struct problem_context *pctx;
4299 blk_t blk = *block_nr;
4304 p = (struct process_block_struct_1 *) priv_data;
4308 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4309 /* todo: Check that the comprblk_fl is high, that the
4310 blkaddr pattern looks right (all non-holes up to
4311 first EXT2FS_COMPRESSED_BLKADDR, then all
4312 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4313 that the feature_incompat bit is high, and that the
4314 inode is a regular file. If we're doing a "full
4315 check" (a concept introduced to e2fsck by e2compr,
4316 meaning that we look at data blocks as well as
4317 metadata) then call some library routine that
4318 checks the compressed data. I'll have to think
4319 about this, because one particularly important
4320 problem to be able to fix is to recalculate the
4321 cluster size if necessary. I think that perhaps
4322 we'd better do most/all e2compr-specific checks
4323 separately, after the non-e2compr checks. If not
4324 doing a full check, it may be useful to test that
4325 the personality is linux; e.g. if it isn't then
4326 perhaps this really is just an illegal block. */
4331 if (p->is_dir == 0) {
4333 * Should never happen, since only directories
4334 * get called with BLOCK_FLAG_HOLE
4337 printf("process_block() called with blk == 0, "
4338 "blockcnt=%d, inode %lu???\n",
4345 if (blockcnt * fs->blocksize < p->inode->i_size) {
4352 * Simplistic fragmentation check. We merely require that the
4353 * file be contiguous. (Which can never be true for really
4354 * big files that are greater than a block group.)
4356 if (!HOLE_BLKADDR(p->previous_block)) {
4357 if (p->previous_block+1 != blk)
4360 p->previous_block = blk;
4362 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4363 problem = PR_1_TOOBIG_DIR;
4364 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4365 problem = PR_1_TOOBIG_REG;
4366 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4367 problem = PR_1_TOOBIG_SYMLINK;
4369 if (blk < fs->super->s_first_data_block ||
4370 blk >= fs->super->s_blocks_count)
4371 problem = PR_1_ILLEGAL_BLOCK_NUM;
4374 p->num_illegal_blocks++;
4375 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4376 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4380 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4382 set_latch_flags(PR_LATCH_BLOCK,
4387 pctx->blkcount = blockcnt;
4388 if (fix_problem(ctx, problem, pctx)) {
4389 blk = *block_nr = 0;
4390 ret_code = BLOCK_CHANGED;
4396 if (p->ino == EXT2_RESIZE_INO) {
4398 * The resize inode has already be sanity checked
4399 * during pass #0 (the superblock checks). All we
4400 * have to do is mark the double indirect block as
4401 * being in use; all of the other blocks are handled
4402 * by mark_table_blocks()).
4404 if (blockcnt == BLOCK_COUNT_DIND)
4405 mark_block_used(ctx, blk);
4407 mark_block_used(ctx, blk);
4410 p->last_block = blockcnt;
4412 if (p->is_dir && (blockcnt >= 0)) {
4413 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4415 if (pctx->errcode) {
4417 pctx->num = blockcnt;
4418 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4419 /* Should never get here */
4420 ctx->flags |= E2F_FLAG_ABORT;
4427 static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4429 e2_blkcnt_t blockcnt,
4430 blk_t ref_block FSCK_ATTR((unused)),
4431 int ref_offset FSCK_ATTR((unused)),
4432 void *priv_data EXT2FS_ATTR((unused)))
4435 * Note: This function processes blocks for the bad blocks
4436 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4439 printf("Unrecoverable Error: Found %lli bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4444 * This routine gets called at the end of pass 1 if bad blocks are
4445 * detected in the superblock, group descriptors, inode_bitmaps, or
4446 * block bitmaps. At this point, all of the blocks have been mapped
4447 * out, so we can try to allocate new block(s) to replace the bad
4450 static void handle_fs_bad_blocks(e2fsck_t ctx)
4452 printf("Bad blocks detected on your filesystem\n"
4453 "You should get your data off as the device will soon die\n");
4457 * This routine marks all blocks which are used by the superblock,
4458 * group descriptors, inode bitmaps, and block bitmaps.
4460 static void mark_table_blocks(e2fsck_t ctx)
4462 ext2_filsys fs = ctx->fs;
4466 struct problem_context pctx;
4468 clear_problem_context(&pctx);
4470 block = fs->super->s_first_data_block;
4471 for (i = 0; i < fs->group_desc_count; i++) {
4474 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4477 * Mark the blocks used for the inode table
4479 if (fs->group_desc[i].bg_inode_table) {
4480 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4481 j < fs->inode_blocks_per_group;
4483 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4486 if (fix_problem(ctx,
4487 PR_1_ITABLE_CONFLICT, &pctx)) {
4488 ctx->invalid_inode_table_flag[i]++;
4489 ctx->invalid_bitmaps++;
4492 ext2fs_mark_block_bitmap(ctx->block_found_map,
4499 * Mark block used for the block bitmap
4501 if (fs->group_desc[i].bg_block_bitmap) {
4502 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4503 fs->group_desc[i].bg_block_bitmap)) {
4504 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4505 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4506 ctx->invalid_block_bitmap_flag[i]++;
4507 ctx->invalid_bitmaps++;
4510 ext2fs_mark_block_bitmap(ctx->block_found_map,
4511 fs->group_desc[i].bg_block_bitmap);
4516 * Mark block used for the inode bitmap
4518 if (fs->group_desc[i].bg_inode_bitmap) {
4519 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4520 fs->group_desc[i].bg_inode_bitmap)) {
4521 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4522 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4523 ctx->invalid_inode_bitmap_flag[i]++;
4524 ctx->invalid_bitmaps++;
4527 ext2fs_mark_block_bitmap(ctx->block_found_map,
4528 fs->group_desc[i].bg_inode_bitmap);
4531 block += fs->super->s_blocks_per_group;
4536 * Thes subroutines short circuits ext2fs_get_blocks and
4537 * ext2fs_check_directory; we use them since we already have the inode
4538 * structure, so there's no point in letting the ext2fs library read
4541 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4544 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4547 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4548 return EXT2_ET_CALLBACK_NOTHANDLED;
4550 for (i=0; i < EXT2_N_BLOCKS; i++)
4551 blocks[i] = ctx->stashed_inode->i_block[i];
4555 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4556 struct ext2_inode *inode)
4558 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4560 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4561 return EXT2_ET_CALLBACK_NOTHANDLED;
4562 *inode = *ctx->stashed_inode;
4566 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4567 struct ext2_inode *inode)
4569 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4571 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4572 *ctx->stashed_inode = *inode;
4573 return EXT2_ET_CALLBACK_NOTHANDLED;
4576 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4578 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4580 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4581 return EXT2_ET_CALLBACK_NOTHANDLED;
4583 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4584 return EXT2_ET_NO_DIRECTORY;
4588 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4590 ext2_filsys fs = ctx->fs;
4593 fs->get_blocks = pass1_get_blocks;
4594 fs->check_directory = pass1_check_directory;
4595 fs->read_inode = pass1_read_inode;
4596 fs->write_inode = pass1_write_inode;
4597 ctx->stashed_ino = 0;
4600 fs->check_directory = 0;
4602 fs->write_inode = 0;
4607 * pass1b.c --- Pass #1b of e2fsck
4609 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4610 * only invoked if pass 1 discovered blocks which are in use by more
4613 * Pass1B scans the data blocks of all the inodes again, generating a
4614 * complete list of duplicate blocks and which inodes have claimed
4617 * Pass1C does a tree-traversal of the filesystem, to determine the
4618 * parent directories of these inodes. This step is necessary so that
4619 * e2fsck can print out the pathnames of affected inodes.
4621 * Pass1D is a reconciliation pass. For each inode with duplicate
4622 * blocks, the user is prompted if s/he would like to clone the file
4623 * (so that the file gets a fresh copy of the duplicated blocks) or
4624 * simply to delete the file.
4629 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4630 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4631 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4633 /* Define an extension to the ext2 library's block count information */
4634 #define BLOCK_COUNT_EXTATTR (-5)
4638 struct block_el *next;
4643 struct inode_el *next;
4648 struct inode_el *inode_list;
4652 * This structure stores information about a particular inode which
4653 * is sharing blocks with other inodes. This information is collected
4654 * to display to the user, so that the user knows what files he or she
4655 * is dealing with, when trying to decide how to resolve the conflict
4656 * of multiply-claimed blocks.
4661 struct ext2_inode inode;
4662 struct block_el *block_list;
4665 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
4666 e2_blkcnt_t blockcnt, blk_t ref_blk,
4667 int ref_offset, void *priv_data);
4668 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4669 struct dup_inode *dp, char *block_buf);
4670 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4671 struct dup_inode *dp, char* block_buf);
4672 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4674 static void pass1b(e2fsck_t ctx, char *block_buf);
4675 static void pass1c(e2fsck_t ctx, char *block_buf);
4676 static void pass1d(e2fsck_t ctx, char *block_buf);
4678 static int dup_inode_count = 0;
4680 static dict_t blk_dict, ino_dict;
4682 static ext2fs_inode_bitmap inode_dup_map;
4684 static int dict_int_cmp(const void *a, const void *b)
4695 * Add a duplicate block record
4697 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4698 struct ext2_inode *inode)
4701 struct dup_block *db;
4702 struct dup_inode *di;
4703 struct block_el *blk_el;
4704 struct inode_el *ino_el;
4706 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4708 db = (struct dup_block *) dnode_get(n);
4710 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4711 sizeof(struct dup_block), "duplicate block header");
4714 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4716 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4717 sizeof(struct inode_el), "inode element");
4718 ino_el->inode = ino;
4719 ino_el->next = db->inode_list;
4720 db->inode_list = ino_el;
4723 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4725 di = (struct dup_inode *) dnode_get(n);
4727 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4728 sizeof(struct dup_inode), "duplicate inode header");
4729 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
4730 di->num_dupblocks = 0;
4733 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4735 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4736 sizeof(struct block_el), "block element");
4737 blk_el->block = blk;
4738 blk_el->next = di->block_list;
4739 di->block_list = blk_el;
4740 di->num_dupblocks++;
4744 * Free a duplicate inode record
4746 static void inode_dnode_free(dnode_t *node)
4748 struct dup_inode *di;
4749 struct block_el *p, *next;
4751 di = (struct dup_inode *) dnode_get(node);
4752 for (p = di->block_list; p; p = next) {
4760 * Free a duplicate block record
4762 static void block_dnode_free(dnode_t *node)
4764 struct dup_block *db;
4765 struct inode_el *p, *next;
4767 db = (struct dup_block *) dnode_get(node);
4768 for (p = db->inode_list; p; p = next) {
4777 * Main procedure for handling duplicate blocks
4779 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4781 ext2_filsys fs = ctx->fs;
4782 struct problem_context pctx;
4784 clear_problem_context(&pctx);
4786 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4787 _("multiply claimed inode map"), &inode_dup_map);
4789 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4790 ctx->flags |= E2F_FLAG_ABORT;
4794 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4795 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4796 dict_set_allocator(&ino_dict, inode_dnode_free);
4797 dict_set_allocator(&blk_dict, block_dnode_free);
4799 pass1b(ctx, block_buf);
4800 pass1c(ctx, block_buf);
4801 pass1d(ctx, block_buf);
4804 * Time to free all of the accumulated data structures that we
4805 * don't need anymore.
4807 dict_free_nodes(&ino_dict);
4808 dict_free_nodes(&blk_dict);
4812 * Scan the inodes looking for inodes that contain duplicate blocks.
4814 struct process_block_struct_1b {
4818 struct ext2_inode *inode;
4819 struct problem_context *pctx;
4822 static void pass1b(e2fsck_t ctx, char *block_buf)
4824 ext2_filsys fs = ctx->fs;
4826 struct ext2_inode inode;
4827 ext2_inode_scan scan;
4828 struct process_block_struct_1b pb;
4829 struct problem_context pctx;
4831 clear_problem_context(&pctx);
4833 if (!(ctx->options & E2F_OPT_PREEN))
4834 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4835 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4838 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4839 ctx->flags |= E2F_FLAG_ABORT;
4842 ctx->stashed_inode = &inode;
4845 pctx.str = "pass1b";
4847 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4848 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4851 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4852 ctx->flags |= E2F_FLAG_ABORT;
4857 pctx.ino = ctx->stashed_ino = ino;
4858 if ((ino != EXT2_BAD_INO) &&
4859 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4866 if (ext2fs_inode_has_valid_blocks(&inode) ||
4867 (ino == EXT2_BAD_INO))
4868 pctx.errcode = ext2fs_block_iterate2(fs, ino,
4869 0, block_buf, process_pass1b_block, &pb);
4870 if (inode.i_file_acl)
4871 process_pass1b_block(fs, &inode.i_file_acl,
4872 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4873 if (pb.dup_blocks) {
4874 end_problem_latch(ctx, PR_LATCH_DBLOCK);
4875 if (ino >= EXT2_FIRST_INODE(fs->super) ||
4876 ino == EXT2_ROOT_INO)
4880 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4882 ext2fs_close_inode_scan(scan);
4883 e2fsck_use_inode_shortcuts(ctx, 0);
4886 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4888 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4889 blk_t ref_blk FSCK_ATTR((unused)),
4890 int ref_offset FSCK_ATTR((unused)),
4893 struct process_block_struct_1b *p;
4896 if (HOLE_BLKADDR(*block_nr))
4898 p = (struct process_block_struct_1b *) priv_data;
4901 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4904 /* OK, this is a duplicate block */
4905 if (p->ino != EXT2_BAD_INO) {
4906 p->pctx->blk = *block_nr;
4907 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4910 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4912 add_dupe(ctx, p->ino, *block_nr, p->inode);
4918 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4919 * is used so that we can print pathnames when prompting the user for
4922 struct search_dir_struct {
4924 ext2_ino_t first_inode;
4925 ext2_ino_t max_inode;
4928 static int search_dirent_proc(ext2_ino_t dir, int entry,
4929 struct ext2_dir_entry *dirent,
4930 int offset FSCK_ATTR((unused)),
4931 int blocksize FSCK_ATTR((unused)),
4932 char *buf FSCK_ATTR((unused)),
4935 struct search_dir_struct *sd;
4936 struct dup_inode *p;
4939 sd = (struct search_dir_struct *) priv_data;
4941 if (dirent->inode > sd->max_inode)
4942 /* Should abort this inode, but not everything */
4945 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4946 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4949 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4952 p = (struct dup_inode *) dnode_get(n);
4956 return(sd->count ? 0 : DIRENT_ABORT);
4960 static void pass1c(e2fsck_t ctx, char *block_buf)
4962 ext2_filsys fs = ctx->fs;
4963 struct search_dir_struct sd;
4964 struct problem_context pctx;
4966 clear_problem_context(&pctx);
4968 if (!(ctx->options & E2F_OPT_PREEN))
4969 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4972 * Search through all directories to translate inodes to names
4973 * (by searching for the containing directory for that inode.)
4975 sd.count = dup_inode_count;
4976 sd.first_inode = EXT2_FIRST_INODE(fs->super);
4977 sd.max_inode = fs->super->s_inodes_count;
4978 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4979 search_dirent_proc, &sd);
4982 static void pass1d(e2fsck_t ctx, char *block_buf)
4984 ext2_filsys fs = ctx->fs;
4985 struct dup_inode *p, *t;
4986 struct dup_block *q;
4987 ext2_ino_t *shared, ino;
4992 struct problem_context pctx;
4997 clear_problem_context(&pctx);
4999 if (!(ctx->options & E2F_OPT_PREEN))
5000 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
5001 e2fsck_read_bitmaps(ctx);
5003 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
5004 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
5005 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
5006 sizeof(ext2_ino_t) * dict_count(&ino_dict),
5007 "Shared inode list");
5008 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
5009 p = (struct dup_inode *) dnode_get(n);
5012 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
5013 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
5017 * Find all of the inodes which share blocks with this
5018 * one. First we find all of the duplicate blocks
5019 * belonging to this inode, and then search each block
5020 * get the list of inodes, and merge them together.
5022 for (s = p->block_list; s; s = s->next) {
5023 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5025 continue; /* Should never happen... */
5026 q = (struct dup_block *) dnode_get(m);
5029 if (check_if_fs_block(ctx, s->block)) {
5035 * Add all inodes used by this block to the
5036 * shared[] --- which is a unique list, so
5037 * if an inode is already in shared[], don't
5040 for (r = q->inode_list; r; r = r->next) {
5041 if (r->inode == ino)
5043 for (i = 0; i < shared_len; i++)
5044 if (shared[i] == r->inode)
5046 if (i == shared_len) {
5047 shared[shared_len++] = r->inode;
5053 * Report the inode that we are working on
5055 pctx.inode = &p->inode;
5058 pctx.blkcount = p->num_dupblocks;
5059 pctx.num = meta_data ? shared_len+1 : shared_len;
5060 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5065 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5067 for (i = 0; i < shared_len; i++) {
5068 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5070 continue; /* should never happen */
5071 t = (struct dup_inode *) dnode_get(m);
5073 * Report the inode that we are sharing with
5075 pctx.inode = &t->inode;
5076 pctx.ino = shared[i];
5078 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5081 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5084 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5085 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5087 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5091 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5092 delete_file(ctx, ino, p, block_buf);
5094 ext2fs_unmark_valid(fs);
5096 ext2fs_free_mem(&shared);
5100 * Drop the refcount on the dup_block structure, and clear the entry
5101 * in the block_dup_map if appropriate.
5103 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5106 if (p->num_bad <= 0 ||
5107 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5108 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5111 static int delete_file_block(ext2_filsys fs,
5113 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5114 blk_t ref_block FSCK_ATTR((unused)),
5115 int ref_offset FSCK_ATTR((unused)),
5118 struct process_block_struct_1b *pb;
5119 struct dup_block *p;
5123 pb = (struct process_block_struct_1b *) priv_data;
5126 if (HOLE_BLKADDR(*block_nr))
5129 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5130 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5132 p = (struct dup_block *) dnode_get(n);
5133 decrement_badcount(ctx, *block_nr, p);
5135 bb_error_msg(_("internal error; can't find dup_blk for %d\n"),
5138 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5139 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5145 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5146 struct dup_inode *dp, char* block_buf)
5148 ext2_filsys fs = ctx->fs;
5149 struct process_block_struct_1b pb;
5150 struct ext2_inode inode;
5151 struct problem_context pctx;
5154 clear_problem_context(&pctx);
5155 pctx.ino = pb.ino = ino;
5156 pb.dup_blocks = dp->num_dupblocks;
5158 pctx.str = "delete_file";
5160 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5161 if (ext2fs_inode_has_valid_blocks(&inode))
5162 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5163 delete_file_block, &pb);
5165 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5166 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5167 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5168 if (ctx->inode_bad_map)
5169 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5170 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5172 /* Inode may have changed by block_iterate, so reread it */
5173 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5174 inode.i_links_count = 0;
5175 inode.i_dtime = time(0);
5176 if (inode.i_file_acl &&
5177 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5179 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5180 block_buf, -1, &count);
5181 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5186 pctx.blk = inode.i_file_acl;
5187 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5190 * If the count is zero, then arrange to have the
5191 * block deleted. If the block is in the block_dup_map,
5192 * also call delete_file_block since it will take care
5193 * of keeping the accounting straight.
5196 ext2fs_test_block_bitmap(ctx->block_dup_map,
5198 delete_file_block(fs, &inode.i_file_acl,
5199 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5201 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5204 struct clone_struct {
5211 static int clone_file_block(ext2_filsys fs,
5213 e2_blkcnt_t blockcnt,
5214 blk_t ref_block FSCK_ATTR((unused)),
5215 int ref_offset FSCK_ATTR((unused)),
5218 struct dup_block *p;
5221 struct clone_struct *cs = (struct clone_struct *) priv_data;
5227 if (HOLE_BLKADDR(*block_nr))
5230 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5231 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5233 p = (struct dup_block *) dnode_get(n);
5234 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5237 cs->errcode = retval;
5240 if (cs->dir && (blockcnt >= 0)) {
5241 retval = ext2fs_set_dir_block(fs->dblist,
5242 cs->dir, new_block, blockcnt);
5244 cs->errcode = retval;
5249 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5252 cs->errcode = retval;
5255 retval = io_channel_write_blk(fs->io, new_block, 1,
5258 cs->errcode = retval;
5261 decrement_badcount(ctx, *block_nr, p);
5262 *block_nr = new_block;
5263 ext2fs_mark_block_bitmap(ctx->block_found_map,
5265 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5266 return BLOCK_CHANGED;
5268 bb_error_msg(_("internal error; can't find dup_blk for %d\n"),
5274 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5275 struct dup_inode *dp, char* block_buf)
5277 ext2_filsys fs = ctx->fs;
5279 struct clone_struct cs;
5280 struct problem_context pctx;
5283 struct inode_el *ino_el;
5284 struct dup_block *db;
5285 struct dup_inode *di;
5287 clear_problem_context(&pctx);
5291 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5295 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5299 pctx.str = "clone_file";
5300 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5301 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5302 clone_file_block, &cs);
5303 ext2fs_mark_bb_dirty(fs);
5305 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5306 retval = pctx.errcode;
5310 bb_error_msg(_("returned from clone_file_block"));
5311 retval = cs.errcode;
5314 /* The inode may have changed on disk, so we have to re-read it */
5315 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5316 blk = dp->inode.i_file_acl;
5317 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5318 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5320 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5322 * If we cloned the EA block, find all other inodes
5323 * which refered to that EA block, and modify
5324 * them to point to the new EA block.
5326 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5327 db = (struct dup_block *) dnode_get(n);
5328 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5329 if (ino_el->inode == ino)
5331 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5332 di = (struct dup_inode *) dnode_get(n);
5333 if (di->inode.i_file_acl == blk) {
5334 di->inode.i_file_acl = dp->inode.i_file_acl;
5335 e2fsck_write_inode(ctx, ino_el->inode,
5336 &di->inode, "clone file EA");
5337 decrement_badcount(ctx, blk, db);
5343 ext2fs_free_mem(&cs.buf);
5348 * This routine returns 1 if a block overlaps with one of the superblocks,
5349 * group descriptors, inode bitmaps, or block bitmaps.
5351 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5353 ext2_filsys fs = ctx->fs;
5357 block = fs->super->s_first_data_block;
5358 for (i = 0; i < fs->group_desc_count; i++) {
5360 /* Check superblocks/block group descriptros */
5361 if (ext2fs_bg_has_super(fs, i)) {
5362 if (test_block >= block &&
5363 (test_block <= block + fs->desc_blocks))
5367 /* Check the inode table */
5368 if ((fs->group_desc[i].bg_inode_table) &&
5369 (test_block >= fs->group_desc[i].bg_inode_table) &&
5370 (test_block < (fs->group_desc[i].bg_inode_table +
5371 fs->inode_blocks_per_group)))
5374 /* Check the bitmap blocks */
5375 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5376 (test_block == fs->group_desc[i].bg_inode_bitmap))
5379 block += fs->super->s_blocks_per_group;
5384 * pass2.c --- check directory structure
5386 * Pass 2 of e2fsck iterates through all active directory inodes, and
5387 * applies to following tests to each directory entry in the directory
5388 * blocks in the inodes:
5390 * - The length of the directory entry (rec_len) should be at
5391 * least 8 bytes, and no more than the remaining space
5392 * left in the directory block.
5393 * - The length of the name in the directory entry (name_len)
5394 * should be less than (rec_len - 8).
5395 * - The inode number in the directory entry should be within
5397 * - The inode number should refer to a in-use inode.
5398 * - The first entry should be '.', and its inode should be
5399 * the inode of the directory.
5400 * - The second entry should be '..'.
5402 * To minimize disk seek time, the directory blocks are processed in
5403 * sorted order of block numbers.
5405 * Pass 2 also collects the following information:
5406 * - The inode numbers of the subdirectories for each directory.
5408 * Pass 2 relies on the following information from previous passes:
5409 * - The directory information collected in pass 1.
5410 * - The inode_used_map bitmap
5411 * - The inode_bad_map bitmap
5412 * - The inode_dir_map bitmap
5414 * Pass 2 frees the following data structures
5415 * - The inode_bad_map bitmap
5416 * - The inode_reg_map bitmap
5420 * Keeps track of how many times an inode is referenced.
5422 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5423 static int check_dir_block(ext2_filsys fs,
5424 struct ext2_db_entry *dir_blocks_info,
5426 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5427 struct problem_context *pctx);
5428 static int update_dir_block(ext2_filsys fs,
5430 e2_blkcnt_t blockcnt,
5434 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5435 static int htree_depth(struct dx_dir_info *dx_dir,
5436 struct dx_dirblock_info *dx_db);
5437 static int special_dir_block_cmp(const void *a, const void *b);
5439 struct check_dir_struct {
5441 struct problem_context pctx;
5446 static void e2fsck_pass2(e2fsck_t ctx)
5448 struct ext2_super_block *sb = ctx->fs->super;
5449 struct problem_context pctx;
5450 ext2_filsys fs = ctx->fs;
5452 struct dir_info *dir;
5453 struct check_dir_struct cd;
5454 struct dx_dir_info *dx_dir;
5455 struct dx_dirblock_info *dx_db, *dx_parent;
5461 clear_problem_context(&cd.pctx);
5465 if (!(ctx->options & E2F_OPT_PREEN))
5466 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5468 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5469 0, ctx->inode_link_info,
5471 if (cd.pctx.errcode) {
5472 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5473 ctx->flags |= E2F_FLAG_ABORT;
5476 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5477 "directory scan buffer");
5480 * Set up the parent pointer for the root directory, if
5481 * present. (If the root directory is not present, we will
5482 * create it in pass 3.)
5484 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5486 dir->parent = EXT2_ROOT_INO;
5491 cd.max = ext2fs_dblist_count(fs->dblist);
5494 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5496 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5497 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5499 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5501 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5503 if (cd.pctx.errcode) {
5504 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5505 ctx->flags |= E2F_FLAG_ABORT;
5510 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5511 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5513 if (dx_dir->numblocks == 0)
5515 clear_problem_context(&pctx);
5517 pctx.dir = dx_dir->ino;
5518 dx_db = dx_dir->dx_block;
5519 if (dx_db->flags & DX_FLAG_REFERENCED)
5520 dx_db->flags |= DX_FLAG_DUP_REF;
5522 dx_db->flags |= DX_FLAG_REFERENCED;
5524 * Find all of the first and last leaf blocks, and
5525 * update their parent's min and max hash values
5527 for (b=0, dx_db = dx_dir->dx_block;
5528 b < dx_dir->numblocks;
5530 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5531 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5533 dx_parent = &dx_dir->dx_block[dx_db->parent];
5535 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5537 if (dx_db->flags & DX_FLAG_FIRST)
5538 dx_parent->min_hash = dx_db->min_hash;
5540 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5542 if (dx_db->flags & DX_FLAG_LAST)
5543 dx_parent->max_hash = dx_db->max_hash;
5546 for (b=0, dx_db = dx_dir->dx_block;
5547 b < dx_dir->numblocks;
5550 pctx.group = dx_db->parent;
5552 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5553 (dx_db->min_hash < dx_db->node_min_hash)) {
5554 pctx.blk = dx_db->min_hash;
5555 pctx.blk2 = dx_db->node_min_hash;
5556 code = PR_2_HTREE_MIN_HASH;
5557 fix_problem(ctx, code, &pctx);
5560 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5561 depth = htree_depth(dx_dir, dx_db);
5562 if (depth != dx_dir->depth) {
5563 code = PR_2_HTREE_BAD_DEPTH;
5564 fix_problem(ctx, code, &pctx);
5569 * This test doesn't apply for the root block
5573 (dx_db->max_hash > dx_db->node_max_hash)) {
5574 pctx.blk = dx_db->max_hash;
5575 pctx.blk2 = dx_db->node_max_hash;
5576 code = PR_2_HTREE_MAX_HASH;
5577 fix_problem(ctx, code, &pctx);
5580 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5581 code = PR_2_HTREE_NOTREF;
5582 fix_problem(ctx, code, &pctx);
5584 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5585 code = PR_2_HTREE_DUPREF;
5586 fix_problem(ctx, code, &pctx);
5592 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5593 clear_htree(ctx, dx_dir->ino);
5594 dx_dir->numblocks = 0;
5598 ext2fs_free_mem(&buf);
5599 ext2fs_free_dblist(fs->dblist);
5601 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5602 ctx->inode_bad_map = 0;
5603 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5604 ctx->inode_reg_map = 0;
5606 clear_problem_context(&pctx);
5607 if (ctx->large_files) {
5608 if (!(sb->s_feature_ro_compat &
5609 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5610 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5611 sb->s_feature_ro_compat |=
5612 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5613 ext2fs_mark_super_dirty(fs);
5615 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5616 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5617 ext2fs_update_dynamic_rev(fs);
5618 ext2fs_mark_super_dirty(fs);
5620 } else if (!ctx->large_files &&
5621 (sb->s_feature_ro_compat &
5622 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5623 if (fs->flags & EXT2_FLAG_RW) {
5624 sb->s_feature_ro_compat &=
5625 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5626 ext2fs_mark_super_dirty(fs);
5632 #define MAX_DEPTH 32000
5633 static int htree_depth(struct dx_dir_info *dx_dir,
5634 struct dx_dirblock_info *dx_db)
5638 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5639 dx_db = &dx_dir->dx_block[dx_db->parent];
5645 static int dict_de_cmp(const void *a, const void *b)
5647 const struct ext2_dir_entry *de_a, *de_b;
5650 de_a = (const struct ext2_dir_entry *) a;
5651 a_len = de_a->name_len & 0xFF;
5652 de_b = (const struct ext2_dir_entry *) b;
5653 b_len = de_b->name_len & 0xFF;
5656 return (a_len - b_len);
5658 return strncmp(de_a->name, de_b->name, a_len);
5662 * This is special sort function that makes sure that directory blocks
5663 * with a dirblock of zero are sorted to the beginning of the list.
5664 * This guarantees that the root node of the htree directories are
5665 * processed first, so we know what hash version to use.
5667 static int special_dir_block_cmp(const void *a, const void *b)
5669 const struct ext2_db_entry *db_a =
5670 (const struct ext2_db_entry *) a;
5671 const struct ext2_db_entry *db_b =
5672 (const struct ext2_db_entry *) b;
5674 if (db_a->blockcnt && !db_b->blockcnt)
5677 if (!db_a->blockcnt && db_b->blockcnt)
5680 if (db_a->blk != db_b->blk)
5681 return (int) (db_a->blk - db_b->blk);
5683 if (db_a->ino != db_b->ino)
5684 return (int) (db_a->ino - db_b->ino);
5686 return (int) (db_a->blockcnt - db_b->blockcnt);
5691 * Make sure the first entry in the directory is '.', and that the
5692 * directory entry is sane.
5694 static int check_dot(e2fsck_t ctx,
5695 struct ext2_dir_entry *dirent,
5696 ext2_ino_t ino, struct problem_context *pctx)
5698 struct ext2_dir_entry *nextdir;
5705 problem = PR_2_MISSING_DOT;
5706 else if (((dirent->name_len & 0xFF) != 1) ||
5707 (dirent->name[0] != '.'))
5708 problem = PR_2_1ST_NOT_DOT;
5709 else if (dirent->name[1] != '\0')
5710 problem = PR_2_DOT_NULL_TERM;
5713 if (fix_problem(ctx, problem, pctx)) {
5714 if (dirent->rec_len < 12)
5715 dirent->rec_len = 12;
5716 dirent->inode = ino;
5717 dirent->name_len = 1;
5718 dirent->name[0] = '.';
5719 dirent->name[1] = '\0';
5724 if (dirent->inode != ino) {
5725 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5726 dirent->inode = ino;
5730 if (dirent->rec_len > 12) {
5731 new_len = dirent->rec_len - 12;
5734 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5735 nextdir = (struct ext2_dir_entry *)
5736 ((char *) dirent + 12);
5737 dirent->rec_len = 12;
5738 nextdir->rec_len = new_len;
5740 nextdir->name_len = 0;
5749 * Make sure the second entry in the directory is '..', and that the
5750 * directory entry is sane. We do not check the inode number of '..'
5751 * here; this gets done in pass 3.
5753 static int check_dotdot(e2fsck_t ctx,
5754 struct ext2_dir_entry *dirent,
5755 struct dir_info *dir, struct problem_context *pctx)
5760 problem = PR_2_MISSING_DOT_DOT;
5761 else if (((dirent->name_len & 0xFF) != 2) ||
5762 (dirent->name[0] != '.') ||
5763 (dirent->name[1] != '.'))
5764 problem = PR_2_2ND_NOT_DOT_DOT;
5765 else if (dirent->name[2] != '\0')
5766 problem = PR_2_DOT_DOT_NULL_TERM;
5769 if (fix_problem(ctx, problem, pctx)) {
5770 if (dirent->rec_len < 12)
5771 dirent->rec_len = 12;
5773 * Note: we don't have the parent inode just
5774 * yet, so we will fill it in with the root
5775 * inode. This will get fixed in pass 3.
5777 dirent->inode = EXT2_ROOT_INO;
5778 dirent->name_len = 2;
5779 dirent->name[0] = '.';
5780 dirent->name[1] = '.';
5781 dirent->name[2] = '\0';
5786 dir->dotdot = dirent->inode;
5791 * Check to make sure a directory entry doesn't contain any illegal
5794 static int check_name(e2fsck_t ctx,
5795 struct ext2_dir_entry *dirent,
5796 struct problem_context *pctx)
5802 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5803 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5805 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5808 dirent->name[i] = '.';
5817 * Check the directory filetype (if present)
5821 * Given a mode, return the ext2 file type
5823 static int ext2_file_type(unsigned int mode)
5825 if (LINUX_S_ISREG(mode))
5826 return EXT2_FT_REG_FILE;
5828 if (LINUX_S_ISDIR(mode))
5831 if (LINUX_S_ISCHR(mode))
5832 return EXT2_FT_CHRDEV;
5834 if (LINUX_S_ISBLK(mode))
5835 return EXT2_FT_BLKDEV;
5837 if (LINUX_S_ISLNK(mode))
5838 return EXT2_FT_SYMLINK;
5840 if (LINUX_S_ISFIFO(mode))
5841 return EXT2_FT_FIFO;
5843 if (LINUX_S_ISSOCK(mode))
5844 return EXT2_FT_SOCK;
5849 static int check_filetype(e2fsck_t ctx,
5850 struct ext2_dir_entry *dirent,
5851 struct problem_context *pctx)
5853 int filetype = dirent->name_len >> 8;
5854 int should_be = EXT2_FT_UNKNOWN;
5855 struct ext2_inode inode;
5857 if (!(ctx->fs->super->s_feature_incompat &
5858 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5859 if (filetype == 0 ||
5860 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5862 dirent->name_len = dirent->name_len & 0xFF;
5866 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5867 should_be = EXT2_FT_DIR;
5868 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5870 should_be = EXT2_FT_REG_FILE;
5871 } else if (ctx->inode_bad_map &&
5872 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5876 e2fsck_read_inode(ctx, dirent->inode, &inode,
5878 should_be = ext2_file_type(inode.i_mode);
5880 if (filetype == should_be)
5882 pctx->num = should_be;
5884 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5888 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5893 static void parse_int_node(ext2_filsys fs,
5894 struct ext2_db_entry *db,
5895 struct check_dir_struct *cd,
5896 struct dx_dir_info *dx_dir,
5899 struct ext2_dx_root_info *root;
5900 struct ext2_dx_entry *ent;
5901 struct ext2_dx_countlimit *limit;
5902 struct dx_dirblock_info *dx_db;
5903 int i, expect_limit, count;
5905 ext2_dirhash_t min_hash = 0xffffffff;
5906 ext2_dirhash_t max_hash = 0;
5907 ext2_dirhash_t hash = 0, prev_hash;
5909 if (db->blockcnt == 0) {
5910 root = (struct ext2_dx_root_info *) (block_buf + 24);
5911 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5913 ent = (struct ext2_dx_entry *) (block_buf+8);
5915 limit = (struct ext2_dx_countlimit *) ent;
5917 count = ext2fs_le16_to_cpu(limit->count);
5918 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5919 sizeof(struct ext2_dx_entry);
5920 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5921 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5922 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5923 goto clear_and_exit;
5925 if (count > expect_limit) {
5926 cd->pctx.num = count;
5927 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5928 goto clear_and_exit;
5929 count = expect_limit;
5932 for (i=0; i < count; i++) {
5934 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5935 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5936 /* Check to make sure the block is valid */
5937 if (blk > (blk_t) dx_dir->numblocks) {
5939 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5941 goto clear_and_exit;
5943 if (hash < prev_hash &&
5944 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5945 goto clear_and_exit;
5946 dx_db = &dx_dir->dx_block[blk];
5947 if (dx_db->flags & DX_FLAG_REFERENCED) {
5948 dx_db->flags |= DX_FLAG_DUP_REF;
5950 dx_db->flags |= DX_FLAG_REFERENCED;
5951 dx_db->parent = db->blockcnt;
5953 if (hash < min_hash)
5955 if (hash > max_hash)
5957 dx_db->node_min_hash = hash;
5959 dx_db->node_max_hash =
5960 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5962 dx_db->node_max_hash = 0xfffffffe;
5963 dx_db->flags |= DX_FLAG_LAST;
5966 dx_db->flags |= DX_FLAG_FIRST;
5968 dx_db = &dx_dir->dx_block[db->blockcnt];
5969 dx_db->min_hash = min_hash;
5970 dx_db->max_hash = max_hash;
5974 clear_htree(cd->ctx, cd->pctx.ino);
5975 dx_dir->numblocks = 0;
5977 #endif /* ENABLE_HTREE */
5980 * Given a busted directory, try to salvage it somehow.
5983 static void salvage_directory(ext2_filsys fs,
5984 struct ext2_dir_entry *dirent,
5985 struct ext2_dir_entry *prev,
5986 unsigned int *offset)
5988 char *cp = (char *) dirent;
5989 int left = fs->blocksize - *offset - dirent->rec_len;
5990 int name_len = dirent->name_len & 0xFF;
5993 * Special case of directory entry of size 8: copy what's left
5994 * of the directory block up to cover up the invalid hole.
5996 if ((left >= 12) && (dirent->rec_len == 8)) {
5997 memmove(cp, cp+8, left);
5998 memset(cp + left, 0, 8);
6002 * If the directory entry overruns the end of the directory
6003 * block, and the name is small enough to fit, then adjust the
6007 (name_len + 8 <= dirent->rec_len + left) &&
6008 dirent->inode <= fs->super->s_inodes_count &&
6009 strnlen(dirent->name, name_len) == name_len) {
6010 dirent->rec_len += left;
6014 * If the directory entry is a multiple of four, so it is
6015 * valid, let the previous directory entry absorb the invalid
6018 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
6019 prev->rec_len += dirent->rec_len;
6020 *offset += dirent->rec_len;
6024 * Default salvage method --- kill all of the directory
6025 * entries for the rest of the block. We will either try to
6026 * absorb it into the previous directory entry, or create a
6027 * new empty directory entry the rest of the directory block.
6030 prev->rec_len += fs->blocksize - *offset;
6031 *offset = fs->blocksize;
6033 dirent->rec_len = fs->blocksize - *offset;
6034 dirent->name_len = 0;
6039 static int check_dir_block(ext2_filsys fs,
6040 struct ext2_db_entry *db,
6043 struct dir_info *subdir, *dir;
6044 struct dx_dir_info *dx_dir;
6046 struct dx_dirblock_info *dx_db = 0;
6047 #endif /* ENABLE_HTREE */
6048 struct ext2_dir_entry *dirent, *prev;
6049 ext2_dirhash_t hash;
6050 unsigned int offset = 0;
6051 int dir_modified = 0;
6053 blk_t block_nr = db->blk;
6054 ext2_ino_t ino = db->ino;
6056 struct check_dir_struct *cd;
6060 struct ext2_dx_root_info *root;
6061 struct ext2_dx_countlimit *limit;
6062 static dict_t de_dict;
6063 struct problem_context pctx;
6066 cd = (struct check_dir_struct *) priv_data;
6070 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6071 return DIRENT_ABORT;
6073 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6074 return DIRENT_ABORT;
6077 * Make sure the inode is still in use (could have been
6078 * deleted in the duplicate/bad blocks pass.
6080 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6084 cd->pctx.blk = block_nr;
6085 cd->pctx.blkcount = db->blockcnt;
6087 cd->pctx.dirent = 0;
6091 if (allocate_dir_block(ctx, db, &cd->pctx))
6101 if (ctx->dirs_to_hash &&
6102 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6105 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6106 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6107 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6108 if (cd->pctx.errcode) {
6109 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6110 ctx->flags |= E2F_FLAG_ABORT;
6111 return DIRENT_ABORT;
6113 memset(buf, 0, fs->blocksize);
6116 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6117 if (dx_dir && dx_dir->numblocks) {
6118 if (db->blockcnt >= dx_dir->numblocks) {
6119 printf("XXX should never happen!!!\n");
6122 dx_db = &dx_dir->dx_block[db->blockcnt];
6123 dx_db->type = DX_DIRBLOCK_LEAF;
6124 dx_db->phys = block_nr;
6125 dx_db->min_hash = ~0;
6126 dx_db->max_hash = 0;
6128 dirent = (struct ext2_dir_entry *) buf;
6129 limit = (struct ext2_dx_countlimit *) (buf+8);
6130 if (db->blockcnt == 0) {
6131 root = (struct ext2_dx_root_info *) (buf + 24);
6132 dx_db->type = DX_DIRBLOCK_ROOT;
6133 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6134 if ((root->reserved_zero ||
6135 root->info_length < 8 ||
6136 root->indirect_levels > 1) &&
6137 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6138 clear_htree(ctx, ino);
6139 dx_dir->numblocks = 0;
6142 dx_dir->hashversion = root->hash_version;
6143 dx_dir->depth = root->indirect_levels + 1;
6144 } else if ((dirent->inode == 0) &&
6145 (dirent->rec_len == fs->blocksize) &&
6146 (dirent->name_len == 0) &&
6147 (ext2fs_le16_to_cpu(limit->limit) ==
6148 ((fs->blocksize-8) /
6149 sizeof(struct ext2_dx_entry))))
6150 dx_db->type = DX_DIRBLOCK_NODE;
6152 #endif /* ENABLE_HTREE */
6154 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6158 dirent = (struct ext2_dir_entry *) (buf + offset);
6159 cd->pctx.dirent = dirent;
6160 cd->pctx.num = offset;
6161 if (((offset + dirent->rec_len) > fs->blocksize) ||
6162 (dirent->rec_len < 12) ||
6163 ((dirent->rec_len % 4) != 0) ||
6164 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6165 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6166 salvage_directory(fs, dirent, prev, &offset);
6170 goto abort_free_dict;
6172 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6173 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6174 dirent->name_len = EXT2_NAME_LEN;
6179 if (dot_state == 0) {
6180 if (check_dot(ctx, dirent, ino, &cd->pctx))
6182 } else if (dot_state == 1) {
6183 dir = e2fsck_get_dir_info(ctx, ino);
6185 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6186 goto abort_free_dict;
6188 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6190 } else if (dirent->inode == ino) {
6191 problem = PR_2_LINK_DOT;
6192 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6202 * Make sure the inode listed is a legal one.
6204 if (((dirent->inode != EXT2_ROOT_INO) &&
6205 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6206 (dirent->inode > fs->super->s_inodes_count)) {
6207 problem = PR_2_BAD_INO;
6208 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6211 * If the inode is unused, offer to clear it.
6213 problem = PR_2_UNUSED_INODE;
6214 } else if ((dot_state > 1) &&
6215 ((dirent->name_len & 0xFF) == 1) &&
6216 (dirent->name[0] == '.')) {
6218 * If there's a '.' entry in anything other
6219 * than the first directory entry, it's a
6220 * duplicate entry that should be removed.
6222 problem = PR_2_DUP_DOT;
6223 } else if ((dot_state > 1) &&
6224 ((dirent->name_len & 0xFF) == 2) &&
6225 (dirent->name[0] == '.') &&
6226 (dirent->name[1] == '.')) {
6228 * If there's a '..' entry in anything other
6229 * than the second directory entry, it's a
6230 * duplicate entry that should be removed.
6232 problem = PR_2_DUP_DOT_DOT;
6233 } else if ((dot_state > 1) &&
6234 (dirent->inode == EXT2_ROOT_INO)) {
6236 * Don't allow links to the root directory.
6237 * We check this specially to make sure we
6238 * catch this error case even if the root
6239 * directory hasn't been created yet.
6241 problem = PR_2_LINK_ROOT;
6242 } else if ((dot_state > 1) &&
6243 (dirent->name_len & 0xFF) == 0) {
6245 * Don't allow zero-length directory names.
6247 problem = PR_2_NULL_NAME;
6251 if (fix_problem(ctx, problem, &cd->pctx)) {
6256 ext2fs_unmark_valid(fs);
6257 if (problem == PR_2_BAD_INO)
6263 * If the inode was marked as having bad fields in
6264 * pass1, process it and offer to fix/clear it.
6265 * (We wait until now so that we can display the
6266 * pathname to the user.)
6268 if (ctx->inode_bad_map &&
6269 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6271 if (e2fsck_process_bad_inode(ctx, ino,
6273 buf + fs->blocksize)) {
6278 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6279 return DIRENT_ABORT;
6282 if (check_name(ctx, dirent, &cd->pctx))
6285 if (check_filetype(ctx, dirent, &cd->pctx))
6290 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6291 (dirent->name_len & 0xFF),
6292 fs->super->s_hash_seed, &hash, 0);
6293 if (hash < dx_db->min_hash)
6294 dx_db->min_hash = hash;
6295 if (hash > dx_db->max_hash)
6296 dx_db->max_hash = hash;
6301 * If this is a directory, then mark its parent in its
6302 * dir_info structure. If the parent field is already
6303 * filled in, then this directory has more than one
6304 * hard link. We assume the first link is correct,
6305 * and ask the user if he/she wants to clear this one.
6307 if ((dot_state > 1) &&
6308 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6310 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6312 cd->pctx.ino = dirent->inode;
6313 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6314 goto abort_free_dict;
6316 if (subdir->parent) {
6317 cd->pctx.ino2 = subdir->parent;
6318 if (fix_problem(ctx, PR_2_LINK_DIR,
6326 subdir->parent = ino;
6331 } else if (dict_lookup(&de_dict, dirent)) {
6332 clear_problem_context(&pctx);
6334 pctx.dirent = dirent;
6335 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6336 if (!ctx->dirs_to_hash)
6337 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6338 if (ctx->dirs_to_hash)
6339 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6342 dict_alloc_insert(&de_dict, dirent, dirent);
6344 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6347 ctx->fs_links_count++;
6348 ctx->fs_total_count++;
6351 offset += dirent->rec_len;
6353 } while (offset < fs->blocksize);
6356 cd->pctx.dir = cd->pctx.ino;
6357 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6358 (dx_db->type == DX_DIRBLOCK_NODE))
6359 parse_int_node(fs, db, cd, dx_dir, buf);
6361 #endif /* ENABLE_HTREE */
6362 if (offset != fs->blocksize) {
6363 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6364 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6365 dirent->rec_len = cd->pctx.num;
6370 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6371 if (cd->pctx.errcode) {
6372 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6374 goto abort_free_dict;
6376 ext2fs_mark_changed(fs);
6378 dict_free_nodes(&de_dict);
6381 dict_free_nodes(&de_dict);
6382 ctx->flags |= E2F_FLAG_ABORT;
6383 return DIRENT_ABORT;
6387 * This function is called to deallocate a block, and is an interator
6388 * functioned called by deallocate inode via ext2fs_iterate_block().
6390 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6391 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6392 blk_t ref_block FSCK_ATTR((unused)),
6393 int ref_offset FSCK_ATTR((unused)),
6396 e2fsck_t ctx = (e2fsck_t) priv_data;
6398 if (HOLE_BLKADDR(*block_nr))
6400 if ((*block_nr < fs->super->s_first_data_block) ||
6401 (*block_nr >= fs->super->s_blocks_count))
6403 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6404 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6409 * This fuction deallocates an inode
6411 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6413 ext2_filsys fs = ctx->fs;
6414 struct ext2_inode inode;
6415 struct problem_context pctx;
6418 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6419 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6420 inode.i_links_count = 0;
6421 inode.i_dtime = time(0);
6422 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6423 clear_problem_context(&pctx);
6427 * Fix up the bitmaps...
6429 e2fsck_read_bitmaps(ctx);
6430 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6431 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6432 if (ctx->inode_bad_map)
6433 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6434 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6436 if (inode.i_file_acl &&
6437 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6438 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6439 block_buf, -1, &count);
6440 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6445 pctx.blk = inode.i_file_acl;
6446 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6447 ctx->flags |= E2F_FLAG_ABORT;
6451 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6453 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6455 inode.i_file_acl = 0;
6458 if (!ext2fs_inode_has_valid_blocks(&inode))
6461 if (LINUX_S_ISREG(inode.i_mode) &&
6462 (inode.i_size_high || inode.i_size & 0x80000000UL))
6465 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6466 deallocate_inode_block, ctx);
6468 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6469 ctx->flags |= E2F_FLAG_ABORT;
6475 * This fuction clears the htree flag on an inode
6477 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6479 struct ext2_inode inode;
6481 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6482 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6483 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6484 if (ctx->dirs_to_hash)
6485 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6489 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6490 ext2_ino_t ino, char *buf)
6492 ext2_filsys fs = ctx->fs;
6493 struct ext2_inode inode;
6494 int inode_modified = 0;
6496 unsigned char *frag, *fsize;
6497 struct problem_context pctx;
6500 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6502 clear_problem_context(&pctx);
6505 pctx.inode = &inode;
6507 if (inode.i_file_acl &&
6508 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6509 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6510 inode.i_file_acl = 0;
6513 * This is a special kludge to deal with long symlinks
6514 * on big endian systems. i_blocks had already been
6515 * decremented earlier in pass 1, but since i_file_acl
6516 * hadn't yet been cleared, ext2fs_read_inode()
6517 * assumed that the file was short symlink and would
6518 * not have byte swapped i_block[0]. Hence, we have
6519 * to byte-swap it here.
6521 if (LINUX_S_ISLNK(inode.i_mode) &&
6522 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6523 (inode.i_blocks == fs->blocksize >> 9))
6524 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6530 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6531 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6532 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6533 !(LINUX_S_ISSOCK(inode.i_mode)))
6534 problem = PR_2_BAD_MODE;
6535 else if (LINUX_S_ISCHR(inode.i_mode)
6536 && !e2fsck_pass1_check_device_inode(fs, &inode))
6537 problem = PR_2_BAD_CHAR_DEV;
6538 else if (LINUX_S_ISBLK(inode.i_mode)
6539 && !e2fsck_pass1_check_device_inode(fs, &inode))
6540 problem = PR_2_BAD_BLOCK_DEV;
6541 else if (LINUX_S_ISFIFO(inode.i_mode)
6542 && !e2fsck_pass1_check_device_inode(fs, &inode))
6543 problem = PR_2_BAD_FIFO;
6544 else if (LINUX_S_ISSOCK(inode.i_mode)
6545 && !e2fsck_pass1_check_device_inode(fs, &inode))
6546 problem = PR_2_BAD_SOCKET;
6547 else if (LINUX_S_ISLNK(inode.i_mode)
6548 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6549 problem = PR_2_INVALID_SYMLINK;
6553 if (fix_problem(ctx, problem, &pctx)) {
6554 deallocate_inode(ctx, ino, 0);
6555 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6563 if (inode.i_faddr) {
6564 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6571 switch (fs->super->s_creator_os) {
6573 frag = &inode.osd2.linux2.l_i_frag;
6574 fsize = &inode.osd2.linux2.l_i_fsize;
6577 frag = &inode.osd2.hurd2.h_i_frag;
6578 fsize = &inode.osd2.hurd2.h_i_fsize;
6581 frag = &inode.osd2.masix2.m_i_frag;
6582 fsize = &inode.osd2.masix2.m_i_fsize;
6587 if (frag && *frag) {
6589 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6596 if (fsize && *fsize) {
6598 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6606 if (inode.i_file_acl &&
6607 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6608 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6609 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6610 inode.i_file_acl = 0;
6615 if (inode.i_dir_acl &&
6616 LINUX_S_ISDIR(inode.i_mode)) {
6617 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6618 inode.i_dir_acl = 0;
6625 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6627 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6633 * allocate_dir_block --- this function allocates a new directory
6634 * block for a particular inode; this is done if a directory has
6635 * a "hole" in it, or if a directory has a illegal block number
6636 * that was zeroed out and now needs to be replaced.
6638 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6639 struct problem_context *pctx)
6641 ext2_filsys fs = ctx->fs;
6644 struct ext2_inode inode;
6646 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6650 * Read the inode and block bitmaps in; we'll be messing with
6653 e2fsck_read_bitmaps(ctx);
6656 * First, find a free block
6658 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6659 if (pctx->errcode) {
6660 pctx->str = "ext2fs_new_block";
6661 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6664 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6665 ext2fs_mark_block_bitmap(fs->block_map, blk);
6666 ext2fs_mark_bb_dirty(fs);
6669 * Now let's create the actual data block for the inode
6672 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6674 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6675 EXT2_ROOT_INO, &block);
6677 if (pctx->errcode) {
6678 pctx->str = "ext2fs_new_dir_block";
6679 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6683 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6684 ext2fs_free_mem(&block);
6685 if (pctx->errcode) {
6686 pctx->str = "ext2fs_write_dir_block";
6687 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6692 * Update the inode block count
6694 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6695 inode.i_blocks += fs->blocksize / 512;
6696 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6697 inode.i_size = (db->blockcnt+1) * fs->blocksize;
6698 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6701 * Finally, update the block pointers for the inode
6704 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6705 0, update_dir_block, db);
6706 if (pctx->errcode) {
6707 pctx->str = "ext2fs_block_iterate";
6708 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6716 * This is a helper function for allocate_dir_block().
6718 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6720 e2_blkcnt_t blockcnt,
6721 blk_t ref_block FSCK_ATTR((unused)),
6722 int ref_offset FSCK_ATTR((unused)),
6725 struct ext2_db_entry *db;
6727 db = (struct ext2_db_entry *) priv_data;
6728 if (db->blockcnt == (int) blockcnt) {
6729 *block_nr = db->blk;
6730 return BLOCK_CHANGED;
6736 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6738 * Pass #3 assures that all directories are connected to the
6739 * filesystem tree, using the following algorithm:
6741 * First, the root directory is checked to make sure it exists; if
6742 * not, e2fsck will offer to create a new one. It is then marked as
6745 * Then, pass3 interates over all directory inodes; for each directory
6746 * it attempts to trace up the filesystem tree, using dirinfo.parent
6747 * until it reaches a directory which has been marked "done". If it
6748 * can not do so, then the directory must be disconnected, and e2fsck
6749 * will offer to reconnect it to /lost+found. While it is chasing
6750 * parent pointers up the filesystem tree, if pass3 sees a directory
6751 * twice, then it has detected a filesystem loop, and it will again
6752 * offer to reconnect the directory to /lost+found in to break the
6755 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6756 * reconnect inodes to /lost+found; this subroutine is also used by
6757 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6758 * is responsible for creating /lost+found if it does not exist.
6760 * Pass 3 frees the following data structures:
6761 * - The dirinfo directory information cache.
6764 static void check_root(e2fsck_t ctx);
6765 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6766 struct problem_context *pctx);
6767 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6769 static ext2fs_inode_bitmap inode_loop_detect;
6770 static ext2fs_inode_bitmap inode_done_map;
6772 static void e2fsck_pass3(e2fsck_t ctx)
6774 ext2_filsys fs = ctx->fs;
6776 struct problem_context pctx;
6777 struct dir_info *dir;
6778 unsigned long maxdirs, count;
6780 clear_problem_context(&pctx);
6784 if (!(ctx->options & E2F_OPT_PREEN))
6785 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6788 * Allocate some bitmaps to do loop detection.
6790 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6794 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6795 ctx->flags |= E2F_FLAG_ABORT;
6799 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6802 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6804 maxdirs = e2fsck_get_num_dirinfo(ctx);
6808 if ((ctx->progress)(ctx, 3, 0, maxdirs))
6811 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6812 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6814 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6816 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6817 if (check_directory(ctx, dir, &pctx))
6822 * Force the creation of /lost+found if not present
6824 if ((ctx->flags & E2F_OPT_READONLY) == 0)
6825 e2fsck_get_lost_and_found(ctx, 1);
6828 * If there are any directories that need to be indexed or
6829 * optimized, do it here.
6831 e2fsck_rehash_directories(ctx);
6834 e2fsck_free_dir_info(ctx);
6835 ext2fs_free_inode_bitmap(inode_loop_detect);
6836 inode_loop_detect = 0;
6837 ext2fs_free_inode_bitmap(inode_done_map);
6842 * This makes sure the root inode is present; if not, we ask if the
6843 * user wants us to create it. Not creating it is a fatal error.
6845 static void check_root(e2fsck_t ctx)
6847 ext2_filsys fs = ctx->fs;
6849 struct ext2_inode inode;
6851 struct problem_context pctx;
6853 clear_problem_context(&pctx);
6855 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6857 * If the root inode is not a directory, die here. The
6858 * user must have answered 'no' in pass1 when we
6859 * offered to clear it.
6861 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6863 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6864 ctx->flags |= E2F_FLAG_ABORT;
6869 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6870 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6871 ctx->flags |= E2F_FLAG_ABORT;
6875 e2fsck_read_bitmaps(ctx);
6878 * First, find a free block
6880 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6882 pctx.str = "ext2fs_new_block";
6883 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6884 ctx->flags |= E2F_FLAG_ABORT;
6887 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6888 ext2fs_mark_block_bitmap(fs->block_map, blk);
6889 ext2fs_mark_bb_dirty(fs);
6892 * Now let's create the actual data block for the inode
6894 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6897 pctx.str = "ext2fs_new_dir_block";
6898 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6899 ctx->flags |= E2F_FLAG_ABORT;
6903 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6905 pctx.str = "ext2fs_write_dir_block";
6906 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6907 ctx->flags |= E2F_FLAG_ABORT;
6910 ext2fs_free_mem(&block);
6913 * Set up the inode structure
6915 memset(&inode, 0, sizeof(inode));
6916 inode.i_mode = 040755;
6917 inode.i_size = fs->blocksize;
6918 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
6919 inode.i_links_count = 2;
6920 inode.i_blocks = fs->blocksize / 512;
6921 inode.i_block[0] = blk;
6924 * Write out the inode.
6926 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6928 pctx.str = "ext2fs_write_inode";
6929 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6930 ctx->flags |= E2F_FLAG_ABORT;
6935 * Miscellaneous bookkeeping...
6937 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6938 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6939 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6941 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6942 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6943 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6944 ext2fs_mark_ib_dirty(fs);
6948 * This subroutine is responsible for making sure that a particular
6949 * directory is connected to the root; if it isn't we trace it up as
6950 * far as we can go, and then offer to connect the resulting parent to
6951 * the lost+found. We have to do loop detection; if we ever discover
6952 * a loop, we treat that as a disconnected directory and offer to
6953 * reparent it to lost+found.
6955 * However, loop detection is expensive, because for very large
6956 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6957 * is non-trivial. Loops in filesystems are also a rare error case,
6958 * and we shouldn't optimize for error cases. So we try two passes of
6959 * the algorithm. The first time, we ignore loop detection and merely
6960 * increment a counter; if the counter exceeds some extreme threshold,
6961 * then we try again with the loop detection bitmap enabled.
6963 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6964 struct problem_context *pctx)
6966 ext2_filsys fs = ctx->fs;
6967 struct dir_info *p = dir;
6968 int loop_pass = 0, parent_count = 0;
6975 * Mark this inode as being "done"; by the time we
6976 * return from this function, the inode we either be
6977 * verified as being connected to the directory tree,
6978 * or we will have offered to reconnect this to
6981 * If it was marked done already, then we've reached a
6982 * parent we've already checked.
6984 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6988 * If this directory doesn't have a parent, or we've
6989 * seen the parent once already, then offer to
6990 * reparent it to lost+found
6994 (ext2fs_test_inode_bitmap(inode_loop_detect,
6997 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6998 if (e2fsck_reconnect_file(ctx, pctx->ino))
6999 ext2fs_unmark_valid(fs);
7001 p = e2fsck_get_dir_info(ctx, pctx->ino);
7002 p->parent = ctx->lost_and_found;
7003 fix_dotdot(ctx, p, ctx->lost_and_found);
7008 p = e2fsck_get_dir_info(ctx, p->parent);
7010 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
7014 ext2fs_mark_inode_bitmap(inode_loop_detect,
7016 } else if (parent_count++ > 2048) {
7018 * If we've run into a path depth that's
7019 * greater than 2048, try again with the inode
7020 * loop bitmap turned on and start from the
7024 if (inode_loop_detect)
7025 ext2fs_clear_inode_bitmap(inode_loop_detect);
7027 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7028 if (pctx->errcode) {
7031 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7032 ctx->flags |= E2F_FLAG_ABORT;
7041 * Make sure that .. and the parent directory are the same;
7042 * offer to fix it if not.
7044 if (dir->parent != dir->dotdot) {
7045 pctx->ino = dir->ino;
7046 pctx->ino2 = dir->dotdot;
7047 pctx->dir = dir->parent;
7048 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7049 fix_dotdot(ctx, dir, dir->parent);
7055 * This routine gets the lost_and_found inode, making it a directory
7058 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7060 ext2_filsys fs = ctx->fs;
7064 struct ext2_inode inode;
7066 static const char name[] = "lost+found";
7067 struct problem_context pctx;
7068 struct dir_info *dirinfo;
7070 if (ctx->lost_and_found)
7071 return ctx->lost_and_found;
7073 clear_problem_context(&pctx);
7075 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7076 sizeof(name)-1, 0, &ino);
7080 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7081 ctx->lost_and_found = ino;
7085 /* Lost+found isn't a directory! */
7089 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7092 /* OK, unlink the old /lost+found file. */
7093 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7095 pctx.str = "ext2fs_unlink";
7096 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7099 dirinfo = e2fsck_get_dir_info(ctx, ino);
7101 dirinfo->parent = 0;
7102 e2fsck_adjust_inode_count(ctx, ino, -1);
7103 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7104 pctx.errcode = retval;
7105 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7107 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7111 * Read the inode and block bitmaps in; we'll be messing with
7114 e2fsck_read_bitmaps(ctx);
7117 * First, find a free block
7119 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7121 pctx.errcode = retval;
7122 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7125 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7126 ext2fs_block_alloc_stats(fs, blk, +1);
7129 * Next find a free inode.
7131 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7132 ctx->inode_used_map, &ino);
7134 pctx.errcode = retval;
7135 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7138 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7139 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7140 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7143 * Now let's create the actual data block for the inode
7145 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7147 pctx.errcode = retval;
7148 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7152 retval = ext2fs_write_dir_block(fs, blk, block);
7153 ext2fs_free_mem(&block);
7155 pctx.errcode = retval;
7156 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7161 * Set up the inode structure
7163 memset(&inode, 0, sizeof(inode));
7164 inode.i_mode = 040700;
7165 inode.i_size = fs->blocksize;
7166 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7167 inode.i_links_count = 2;
7168 inode.i_blocks = fs->blocksize / 512;
7169 inode.i_block[0] = blk;
7172 * Next, write out the inode.
7174 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7176 pctx.str = "ext2fs_write_inode";
7177 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7181 * Finally, create the directory link
7183 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7185 pctx.str = "ext2fs_link";
7186 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7191 * Miscellaneous bookkeeping that needs to be kept straight.
7193 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7194 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7195 ext2fs_icount_store(ctx->inode_count, ino, 2);
7196 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7197 ctx->lost_and_found = ino;
7202 * This routine will connect a file to lost+found
7204 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7206 ext2_filsys fs = ctx->fs;
7209 struct problem_context pctx;
7210 struct ext2_inode inode;
7213 clear_problem_context(&pctx);
7216 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7217 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7218 ctx->bad_lost_and_found++;
7220 if (ctx->bad_lost_and_found) {
7221 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7225 sprintf(name, "#%u", ino);
7226 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7227 file_type = ext2_file_type(inode.i_mode);
7228 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7229 if (retval == EXT2_ET_DIR_NO_SPACE) {
7230 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7232 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7235 pctx.errcode = retval;
7236 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7239 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7243 pctx.errcode = retval;
7244 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7247 e2fsck_adjust_inode_count(ctx, ino, 1);
7253 * Utility routine to adjust the inode counts on an inode.
7255 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7257 ext2_filsys fs = ctx->fs;
7259 struct ext2_inode inode;
7264 retval = ext2fs_read_inode(fs, ino, &inode);
7269 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7270 if (inode.i_links_count == (__u16) ~0)
7272 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7273 inode.i_links_count++;
7274 } else if (adj == -1) {
7275 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7276 if (inode.i_links_count == 0)
7278 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7279 inode.i_links_count--;
7282 retval = ext2fs_write_inode(fs, ino, &inode);
7290 * Fix parent --- this routine fixes up the parent of a directory.
7292 struct fix_dotdot_struct {
7299 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7300 int offset FSCK_ATTR((unused)),
7301 int blocksize FSCK_ATTR((unused)),
7302 char *buf FSCK_ATTR((unused)),
7305 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7307 struct problem_context pctx;
7309 if ((dirent->name_len & 0xFF) != 2)
7311 if (strncmp(dirent->name, "..", 2))
7314 clear_problem_context(&pctx);
7316 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7318 pctx.errcode = retval;
7319 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7321 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7323 pctx.errcode = retval;
7324 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7326 dirent->inode = fp->parent;
7329 return DIRENT_ABORT | DIRENT_CHANGED;
7332 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7334 ext2_filsys fs = ctx->fs;
7336 struct fix_dotdot_struct fp;
7337 struct problem_context pctx;
7344 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7345 0, fix_dotdot_proc, &fp);
7346 if (retval || !fp.done) {
7347 clear_problem_context(&pctx);
7348 pctx.ino = dir->ino;
7349 pctx.errcode = retval;
7350 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7351 PR_3_FIX_PARENT_NOFIND, &pctx);
7352 ext2fs_unmark_valid(fs);
7354 dir->dotdot = parent;
7360 * These routines are responsible for expanding a /lost+found if it is
7364 struct expand_dir_struct {
7366 int guaranteed_size;
7373 static int expand_dir_proc(ext2_filsys fs,
7375 e2_blkcnt_t blockcnt,
7376 blk_t ref_block FSCK_ATTR((unused)),
7377 int ref_offset FSCK_ATTR((unused)),
7380 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7382 static blk_t last_blk = 0;
7389 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7393 es->last_block = blockcnt;
7395 last_blk = *blocknr;
7398 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7405 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7411 retval = ext2fs_write_dir_block(fs, new_blk, block);
7413 retval = ext2fs_get_mem(fs->blocksize, &block);
7418 memset(block, 0, fs->blocksize);
7419 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7425 ext2fs_free_mem(&block);
7427 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7428 ext2fs_block_alloc_stats(fs, new_blk, +1);
7432 return (BLOCK_CHANGED | BLOCK_ABORT);
7434 return BLOCK_CHANGED;
7437 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7438 int num, int guaranteed_size)
7440 ext2_filsys fs = ctx->fs;
7442 struct expand_dir_struct es;
7443 struct ext2_inode inode;
7445 if (!(fs->flags & EXT2_FLAG_RW))
7446 return EXT2_ET_RO_FILSYS;
7449 * Read the inode and block bitmaps in; we'll be messing with
7452 e2fsck_read_bitmaps(ctx);
7454 retval = ext2fs_check_directory(fs, dir);
7459 es.guaranteed_size = guaranteed_size;
7465 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7466 0, expand_dir_proc, &es);
7472 * Update the size and block count fields in the inode.
7474 retval = ext2fs_read_inode(fs, dir, &inode);
7478 inode.i_size = (es.last_block + 1) * fs->blocksize;
7479 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7481 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7487 * pass4.c -- pass #4 of e2fsck: Check reference counts
7489 * Pass 4 frees the following data structures:
7490 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7494 * This routine is called when an inode is not connected to the
7497 * This subroutine returns 1 then the caller shouldn't bother with the
7498 * rest of the pass 4 tests.
7500 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7502 ext2_filsys fs = ctx->fs;
7503 struct ext2_inode inode;
7504 struct problem_context pctx;
7506 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7507 clear_problem_context(&pctx);
7509 pctx.inode = &inode;
7512 * Offer to delete any zero-length files that does not have
7513 * blocks. If there is an EA block, it might have useful
7514 * information, so we won't prompt to delete it, but let it be
7515 * reconnected to lost+found.
7517 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7518 LINUX_S_ISDIR(inode.i_mode))) {
7519 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7520 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7521 inode.i_links_count = 0;
7522 inode.i_dtime = time(0);
7523 e2fsck_write_inode(ctx, i, &inode,
7524 "disconnect_inode");
7526 * Fix up the bitmaps...
7528 e2fsck_read_bitmaps(ctx);
7529 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7530 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7531 ext2fs_inode_alloc_stats2(fs, i, -1,
7532 LINUX_S_ISDIR(inode.i_mode));
7538 * Prompt to reconnect.
7540 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7541 if (e2fsck_reconnect_file(ctx, i))
7542 ext2fs_unmark_valid(fs);
7545 * If we don't attach the inode, then skip the
7546 * i_links_test since there's no point in trying to
7547 * force i_links_count to zero.
7549 ext2fs_unmark_valid(fs);
7556 static void e2fsck_pass4(e2fsck_t ctx)
7558 ext2_filsys fs = ctx->fs;
7560 struct ext2_inode inode;
7561 struct problem_context pctx;
7562 __u16 link_count, link_counted;
7564 int group, maxgroup;
7568 clear_problem_context(&pctx);
7570 if (!(ctx->options & E2F_OPT_PREEN))
7571 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7574 maxgroup = fs->group_desc_count;
7576 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7579 for (i=1; i <= fs->super->s_inodes_count; i++) {
7580 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7582 if ((i % fs->super->s_inodes_per_group) == 0) {
7585 if ((ctx->progress)(ctx, 4, group, maxgroup))
7588 if (i == EXT2_BAD_INO ||
7589 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7591 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7592 (ctx->inode_imagic_map &&
7593 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7595 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7596 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7597 if (link_counted == 0) {
7599 buf = e2fsck_allocate_memory(ctx,
7600 fs->blocksize, "bad_inode buffer");
7601 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7603 if (disconnect_inode(ctx, i))
7605 ext2fs_icount_fetch(ctx->inode_link_info, i,
7607 ext2fs_icount_fetch(ctx->inode_count, i,
7610 if (link_counted != link_count) {
7611 e2fsck_read_inode(ctx, i, &inode, "pass4");
7613 pctx.inode = &inode;
7614 if (link_count != inode.i_links_count) {
7615 pctx.num = link_count;
7617 PR_4_INCONSISTENT_COUNT, &pctx);
7619 pctx.num = link_counted;
7620 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7621 inode.i_links_count = link_counted;
7622 e2fsck_write_inode(ctx, i, &inode, "pass4");
7626 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7627 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7628 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7629 ctx->inode_imagic_map = 0;
7630 ext2fs_free_mem(&buf);
7634 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7637 #define NO_BLK ((blk_t) -1)
7639 static void print_bitmap_problem(e2fsck_t ctx, int problem,
7640 struct problem_context *pctx)
7643 case PR_5_BLOCK_UNUSED:
7644 if (pctx->blk == pctx->blk2)
7647 problem = PR_5_BLOCK_RANGE_UNUSED;
7649 case PR_5_BLOCK_USED:
7650 if (pctx->blk == pctx->blk2)
7653 problem = PR_5_BLOCK_RANGE_USED;
7655 case PR_5_INODE_UNUSED:
7656 if (pctx->ino == pctx->ino2)
7659 problem = PR_5_INODE_RANGE_UNUSED;
7661 case PR_5_INODE_USED:
7662 if (pctx->ino == pctx->ino2)
7665 problem = PR_5_INODE_RANGE_USED;
7668 fix_problem(ctx, problem, pctx);
7669 pctx->blk = pctx->blk2 = NO_BLK;
7670 pctx->ino = pctx->ino2 = 0;
7673 static void check_block_bitmaps(e2fsck_t ctx)
7675 ext2_filsys fs = ctx->fs;
7679 unsigned int blocks = 0;
7680 unsigned int free_blocks = 0;
7683 struct problem_context pctx;
7684 int problem, save_problem, fixit, had_problem;
7687 clear_problem_context(&pctx);
7688 free_array = (int *) e2fsck_allocate_memory(ctx,
7689 fs->group_desc_count * sizeof(int), "free block count array");
7691 if ((fs->super->s_first_data_block <
7692 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7693 (fs->super->s_blocks_count-1 >
7694 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7696 pctx.blk = fs->super->s_first_data_block;
7697 pctx.blk2 = fs->super->s_blocks_count -1;
7698 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7699 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7700 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7702 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7706 if ((fs->super->s_first_data_block <
7707 ext2fs_get_block_bitmap_start(fs->block_map)) ||
7708 (fs->super->s_blocks_count-1 >
7709 ext2fs_get_block_bitmap_end(fs->block_map))) {
7711 pctx.blk = fs->super->s_first_data_block;
7712 pctx.blk2 = fs->super->s_blocks_count -1;
7713 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7714 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7715 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7717 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7724 pctx.blk = pctx.blk2 = NO_BLK;
7725 for (i = fs->super->s_first_data_block;
7726 i < fs->super->s_blocks_count;
7728 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7729 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7731 if (actual == bitmap)
7734 if (!actual && bitmap) {
7736 * Block not used, but marked in use in the bitmap.
7738 problem = PR_5_BLOCK_UNUSED;
7741 * Block used, but not marked in use in the bitmap.
7743 problem = PR_5_BLOCK_USED;
7745 if (pctx.blk == NO_BLK) {
7746 pctx.blk = pctx.blk2 = i;
7747 save_problem = problem;
7749 if ((problem == save_problem) &&
7753 print_bitmap_problem(ctx, save_problem, &pctx);
7754 pctx.blk = pctx.blk2 = i;
7755 save_problem = problem;
7758 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7767 if ((blocks == fs->super->s_blocks_per_group) ||
7768 (i == fs->super->s_blocks_count-1)) {
7769 free_array[group] = group_free;
7774 if ((ctx->progress)(ctx, 5, group,
7775 fs->group_desc_count*2))
7779 if (pctx.blk != NO_BLK)
7780 print_bitmap_problem(ctx, save_problem, &pctx);
7782 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7785 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7788 ext2fs_free_block_bitmap(fs->block_map);
7789 retval = ext2fs_copy_bitmap(ctx->block_found_map,
7792 clear_problem_context(&pctx);
7793 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7794 ctx->flags |= E2F_FLAG_ABORT;
7797 ext2fs_set_bitmap_padding(fs->block_map);
7798 ext2fs_mark_bb_dirty(fs);
7800 /* Redo the counts */
7801 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7802 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7804 } else if (fixit == 0)
7805 ext2fs_unmark_valid(fs);
7807 for (i = 0; i < fs->group_desc_count; i++) {
7808 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7810 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7811 pctx.blk2 = free_array[i];
7813 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7815 fs->group_desc[i].bg_free_blocks_count =
7817 ext2fs_mark_super_dirty(fs);
7819 ext2fs_unmark_valid(fs);
7822 if (free_blocks != fs->super->s_free_blocks_count) {
7824 pctx.blk = fs->super->s_free_blocks_count;
7825 pctx.blk2 = free_blocks;
7827 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7828 fs->super->s_free_blocks_count = free_blocks;
7829 ext2fs_mark_super_dirty(fs);
7831 ext2fs_unmark_valid(fs);
7833 ext2fs_free_mem(&free_array);
7836 static void check_inode_bitmaps(e2fsck_t ctx)
7838 ext2_filsys fs = ctx->fs;
7840 unsigned int free_inodes = 0;
7844 unsigned int inodes = 0;
7849 struct problem_context pctx;
7850 int problem, save_problem, fixit, had_problem;
7852 clear_problem_context(&pctx);
7853 free_array = (int *) e2fsck_allocate_memory(ctx,
7854 fs->group_desc_count * sizeof(int), "free inode count array");
7856 dir_array = (int *) e2fsck_allocate_memory(ctx,
7857 fs->group_desc_count * sizeof(int), "directory count array");
7859 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7860 (fs->super->s_inodes_count >
7861 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7864 pctx.blk2 = fs->super->s_inodes_count;
7865 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7866 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7867 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7869 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7872 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7873 (fs->super->s_inodes_count >
7874 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7877 pctx.blk2 = fs->super->s_inodes_count;
7878 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7879 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7880 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7882 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7889 pctx.ino = pctx.ino2 = 0;
7890 for (i = 1; i <= fs->super->s_inodes_count; i++) {
7891 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7892 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7894 if (actual == bitmap)
7897 if (!actual && bitmap) {
7899 * Inode wasn't used, but marked in bitmap
7901 problem = PR_5_INODE_UNUSED;
7902 } else /* if (actual && !bitmap) */ {
7904 * Inode used, but not in bitmap
7906 problem = PR_5_INODE_USED;
7908 if (pctx.ino == 0) {
7909 pctx.ino = pctx.ino2 = i;
7910 save_problem = problem;
7912 if ((problem == save_problem) &&
7916 print_bitmap_problem(ctx, save_problem, &pctx);
7917 pctx.ino = pctx.ino2 = i;
7918 save_problem = problem;
7921 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7929 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7933 if ((inodes == fs->super->s_inodes_per_group) ||
7934 (i == fs->super->s_inodes_count)) {
7935 free_array[group] = group_free;
7936 dir_array[group] = dirs_count;
7942 if ((ctx->progress)(ctx, 5,
7943 group + fs->group_desc_count,
7944 fs->group_desc_count*2))
7949 print_bitmap_problem(ctx, save_problem, &pctx);
7952 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7955 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7958 ext2fs_free_inode_bitmap(fs->inode_map);
7959 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7962 clear_problem_context(&pctx);
7963 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7964 ctx->flags |= E2F_FLAG_ABORT;
7967 ext2fs_set_bitmap_padding(fs->inode_map);
7968 ext2fs_mark_ib_dirty(fs);
7971 inodes = 0; free_inodes = 0; group_free = 0;
7972 dirs_count = 0; group = 0;
7973 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7974 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7976 } else if (fixit == 0)
7977 ext2fs_unmark_valid(fs);
7979 for (i = 0; i < fs->group_desc_count; i++) {
7980 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7982 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7983 pctx.ino2 = free_array[i];
7984 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7986 fs->group_desc[i].bg_free_inodes_count =
7988 ext2fs_mark_super_dirty(fs);
7990 ext2fs_unmark_valid(fs);
7992 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7994 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7995 pctx.ino2 = dir_array[i];
7997 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7999 fs->group_desc[i].bg_used_dirs_count =
8001 ext2fs_mark_super_dirty(fs);
8003 ext2fs_unmark_valid(fs);
8006 if (free_inodes != fs->super->s_free_inodes_count) {
8008 pctx.ino = fs->super->s_free_inodes_count;
8009 pctx.ino2 = free_inodes;
8011 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
8012 fs->super->s_free_inodes_count = free_inodes;
8013 ext2fs_mark_super_dirty(fs);
8015 ext2fs_unmark_valid(fs);
8017 ext2fs_free_mem(&free_array);
8018 ext2fs_free_mem(&dir_array);
8021 static void check_inode_end(e2fsck_t ctx)
8023 ext2_filsys fs = ctx->fs;
8024 ext2_ino_t end, save_inodes_count, i;
8025 struct problem_context pctx;
8027 clear_problem_context(&pctx);
8029 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8030 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8031 &save_inodes_count);
8034 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8035 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8038 if (save_inodes_count == end)
8041 for (i = save_inodes_count + 1; i <= end; i++) {
8042 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8043 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8044 for (i = save_inodes_count + 1; i <= end; i++)
8045 ext2fs_mark_inode_bitmap(fs->inode_map,
8047 ext2fs_mark_ib_dirty(fs);
8049 ext2fs_unmark_valid(fs);
8054 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8055 save_inodes_count, 0);
8058 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8059 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8064 static void check_block_end(e2fsck_t ctx)
8066 ext2_filsys fs = ctx->fs;
8067 blk_t end, save_blocks_count, i;
8068 struct problem_context pctx;
8070 clear_problem_context(&pctx);
8072 end = fs->block_map->start +
8073 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8074 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8075 &save_blocks_count);
8078 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8079 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8082 if (save_blocks_count == end)
8085 for (i = save_blocks_count + 1; i <= end; i++) {
8086 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8087 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8088 for (i = save_blocks_count + 1; i <= end; i++)
8089 ext2fs_mark_block_bitmap(fs->block_map,
8091 ext2fs_mark_bb_dirty(fs);
8093 ext2fs_unmark_valid(fs);
8098 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8099 save_blocks_count, 0);
8102 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8103 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8108 static void e2fsck_pass5(e2fsck_t ctx)
8110 struct problem_context pctx;
8114 clear_problem_context(&pctx);
8116 if (!(ctx->options & E2F_OPT_PREEN))
8117 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8120 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8123 e2fsck_read_bitmaps(ctx);
8125 check_block_bitmaps(ctx);
8126 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8128 check_inode_bitmaps(ctx);
8129 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8131 check_inode_end(ctx);
8132 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8134 check_block_end(ctx);
8135 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8138 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8139 ctx->inode_used_map = 0;
8140 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8141 ctx->inode_dir_map = 0;
8142 ext2fs_free_block_bitmap(ctx->block_found_map);
8143 ctx->block_found_map = 0;
8147 * problem.c --- report filesystem problems to the user
8150 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8151 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8152 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8153 #define PR_MSG_ONLY 0x000008 /* Print message only */
8155 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8157 #define PR_FATAL 0x001000 /* Fatal error */
8158 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8160 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8161 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8162 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8163 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8164 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8167 #define PROMPT_NONE 0
8168 #define PROMPT_FIX 1
8169 #define PROMPT_CLEAR 2
8170 #define PROMPT_RELOCATE 3
8171 #define PROMPT_ALLOCATE 4
8172 #define PROMPT_EXPAND 5
8173 #define PROMPT_CONNECT 6
8174 #define PROMPT_CREATE 7
8175 #define PROMPT_SALVAGE 8
8176 #define PROMPT_TRUNCATE 9
8177 #define PROMPT_CLEAR_INODE 10
8178 #define PROMPT_ABORT 11
8179 #define PROMPT_SPLIT 12
8180 #define PROMPT_CONTINUE 13
8181 #define PROMPT_CLONE 14
8182 #define PROMPT_DELETE 15
8183 #define PROMPT_SUPPRESS 16
8184 #define PROMPT_UNLINK 17
8185 #define PROMPT_CLEAR_HTREE 18
8186 #define PROMPT_RECREATE 19
8187 #define PROMPT_NULL 20
8189 struct e2fsck_problem {
8191 const char * e2p_description;
8194 problem_t second_code;
8197 struct latch_descr {
8200 problem_t end_message;
8205 * These are the prompts which are used to ask the user if they want
8208 static const char * const prompt[] = {
8209 N_("(no prompt)"), /* 0 */
8211 N_("Clear"), /* 2 */
8212 N_("Relocate"), /* 3 */
8213 N_("Allocate"), /* 4 */
8214 N_("Expand"), /* 5 */
8215 N_("Connect to /lost+found"), /* 6 */
8216 N_("Create"), /* 7 */
8217 N_("Salvage"), /* 8 */
8218 N_("Truncate"), /* 9 */
8219 N_("Clear inode"), /* 10 */
8220 N_("Abort"), /* 11 */
8221 N_("Split"), /* 12 */
8222 N_("Continue"), /* 13 */
8223 N_("Clone multiply-claimed blocks"), /* 14 */
8224 N_("Delete file"), /* 15 */
8225 N_("Suppress messages"),/* 16 */
8226 N_("Unlink"), /* 17 */
8227 N_("Clear HTree index"),/* 18 */
8228 N_("Recreate"), /* 19 */
8233 * These messages are printed when we are preen mode and we will be
8234 * automatically fixing the problem.
8236 static const char * const preen_msg[] = {
8237 N_("(NONE)"), /* 0 */
8238 N_("FIXED"), /* 1 */
8239 N_("CLEARED"), /* 2 */
8240 N_("RELOCATED"), /* 3 */
8241 N_("ALLOCATED"), /* 4 */
8242 N_("EXPANDED"), /* 5 */
8243 N_("RECONNECTED"), /* 6 */
8244 N_("CREATED"), /* 7 */
8245 N_("SALVAGED"), /* 8 */
8246 N_("TRUNCATED"), /* 9 */
8247 N_("INODE CLEARED"), /* 10 */
8248 N_("ABORTED"), /* 11 */
8249 N_("SPLIT"), /* 12 */
8250 N_("CONTINUING"), /* 13 */
8251 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8252 N_("FILE DELETED"), /* 15 */
8253 N_("SUPPRESSED"), /* 16 */
8254 N_("UNLINKED"), /* 17 */
8255 N_("HTREE INDEX CLEARED"),/* 18 */
8256 N_("WILL RECREATE"), /* 19 */
8260 static const struct e2fsck_problem problem_table[] = {
8262 /* Pre-Pass 1 errors */
8264 /* Block bitmap not in group */
8265 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8266 PROMPT_RELOCATE, PR_LATCH_RELOC },
8268 /* Inode bitmap not in group */
8269 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8270 PROMPT_RELOCATE, PR_LATCH_RELOC },
8272 /* Inode table not in group */
8273 { PR_0_ITABLE_NOT_GROUP,
8274 N_("@i table for @g %g is not in @g. (@b %b)\n"
8275 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8276 PROMPT_RELOCATE, PR_LATCH_RELOC },
8278 /* Superblock corrupt */
8280 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8281 "@f. If the @v is valid and it really contains an ext2\n"
8282 "@f (and not swap or ufs or something else), then the @S\n"
8283 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8284 " e2fsck -b %S <@v>\n\n"),
8285 PROMPT_NONE, PR_FATAL },
8287 /* Filesystem size is wrong */
8288 { PR_0_FS_SIZE_WRONG,
8289 N_("The @f size (according to the @S) is %b @bs\n"
8290 "The physical size of the @v is %c @bs\n"
8291 "Either the @S or the partition table is likely to be corrupt!\n"),
8294 /* Fragments not supported */
8295 { PR_0_NO_FRAGMENTS,
8296 N_("@S @b_size = %b, fragsize = %c.\n"
8297 "This version of e2fsck does not support fragment sizes different\n"
8298 "from the @b size.\n"),
8299 PROMPT_NONE, PR_FATAL },
8301 /* Bad blocks_per_group */
8302 { PR_0_BLOCKS_PER_GROUP,
8303 N_("@S @bs_per_group = %b, should have been %c\n"),
8304 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8306 /* Bad first_data_block */
8307 { PR_0_FIRST_DATA_BLOCK,
8308 N_("@S first_data_@b = %b, should have been %c\n"),
8309 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8311 /* Adding UUID to filesystem */
8313 N_("@f did not have a UUID; generating one.\n\n"),
8317 { PR_0_RELOCATE_HINT,
8318 N_("Note: if several inode or block bitmap blocks or part\n"
8319 "of the inode table require relocation, you may wish to try\n"
8320 "running e2fsck with the '-b %S' option first. The problem\n"
8321 "may lie only with the primary block group descriptors, and\n"
8322 "the backup block group descriptors may be OK.\n\n"),
8323 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8325 /* Miscellaneous superblock corruption */
8326 { PR_0_MISC_CORRUPT_SUPER,
8327 N_("Corruption found in @S. (%s = %N).\n"),
8328 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8330 /* Error determing physical device size of filesystem */
8331 { PR_0_GETSIZE_ERROR,
8332 N_("Error determining size of the physical @v: %m\n"),
8333 PROMPT_NONE, PR_FATAL },
8335 /* Inode count in superblock is incorrect */
8336 { PR_0_INODE_COUNT_WRONG,
8337 N_("@i count in @S is %i, @s %j.\n"),
8340 { PR_0_HURD_CLEAR_FILETYPE,
8341 N_("The Hurd does not support the filetype feature.\n"),
8344 /* Journal inode is invalid */
8345 { PR_0_JOURNAL_BAD_INODE,
8346 N_("@S has an @n ext3 @j (@i %i).\n"),
8347 PROMPT_CLEAR, PR_PREEN_OK },
8349 /* The external journal has (unsupported) multiple filesystems */
8350 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8351 N_("External @j has multiple @f users (unsupported).\n"),
8352 PROMPT_NONE, PR_FATAL },
8354 /* Can't find external journal */
8355 { PR_0_CANT_FIND_JOURNAL,
8356 N_("Can't find external @j\n"),
8357 PROMPT_NONE, PR_FATAL },
8359 /* External journal has bad superblock */
8360 { PR_0_EXT_JOURNAL_BAD_SUPER,
8361 N_("External @j has bad @S\n"),
8362 PROMPT_NONE, PR_FATAL },
8364 /* Superblock has a bad journal UUID */
8365 { PR_0_JOURNAL_BAD_UUID,
8366 N_("External @j does not support this @f\n"),
8367 PROMPT_NONE, PR_FATAL },
8369 /* Journal has an unknown superblock type */
8370 { PR_0_JOURNAL_UNSUPP_SUPER,
8371 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8372 "It is likely that your copy of e2fsck is old and/or doesn't "
8373 "support this @j format.\n"
8374 "It is also possible the @j @S is corrupt.\n"),
8375 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8377 /* Journal superblock is corrupt */
8378 { PR_0_JOURNAL_BAD_SUPER,
8379 N_("Ext3 @j @S is corrupt.\n"),
8380 PROMPT_FIX, PR_PREEN_OK },
8382 /* Superblock flag should be cleared */
8383 { PR_0_JOURNAL_HAS_JOURNAL,
8384 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8385 PROMPT_CLEAR, PR_PREEN_OK },
8387 /* Superblock flag is incorrect */
8388 { PR_0_JOURNAL_RECOVER_SET,
8389 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8390 PROMPT_CLEAR, PR_PREEN_OK },
8392 /* Journal has data, but recovery flag is clear */
8393 { PR_0_JOURNAL_RECOVERY_CLEAR,
8394 N_("ext3 recovery flag is clear, but @j has data.\n"),
8397 /* Ask if we should clear the journal */
8398 { PR_0_JOURNAL_RESET_JOURNAL,
8400 PROMPT_NULL, PR_PREEN_NOMSG },
8402 /* Ask if we should run the journal anyway */
8404 N_("Run @j anyway"),
8407 /* Run the journal by default */
8408 { PR_0_JOURNAL_RUN_DEFAULT,
8409 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8412 /* Clearing orphan inode */
8413 { PR_0_ORPHAN_CLEAR_INODE,
8414 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8417 /* Illegal block found in orphaned inode */
8418 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8419 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8422 /* Already cleared block found in orphaned inode */
8423 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8424 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8427 /* Illegal orphan inode in superblock */
8428 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8429 N_("@I @o @i %i in @S.\n"),
8432 /* Illegal inode in orphaned inode list */
8433 { PR_0_ORPHAN_ILLEGAL_INODE,
8434 N_("@I @i %i in @o @i list.\n"),
8437 /* Filesystem revision is 0, but feature flags are set */
8438 { PR_0_FS_REV_LEVEL,
8439 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8440 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8442 /* Journal superblock has an unknown read-only feature flag set */
8443 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8444 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8447 /* Journal superblock has an unknown incompatible feature flag set */
8448 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8449 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8452 /* Journal has unsupported version number */
8453 { PR_0_JOURNAL_UNSUPP_VERSION,
8454 N_("@j version not supported by this e2fsck.\n"),
8457 /* Moving journal to hidden file */
8458 { PR_0_MOVE_JOURNAL,
8459 N_("Moving @j from /%s to hidden @i.\n\n"),
8462 /* Error moving journal to hidden file */
8463 { PR_0_ERR_MOVE_JOURNAL,
8464 N_("Error moving @j: %m\n\n"),
8467 /* Clearing V2 journal superblock */
8468 { PR_0_CLEAR_V2_JOURNAL,
8469 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8470 "Clearing fields beyond the V1 @j @S...\n\n"),
8473 /* Backup journal inode blocks */
8475 N_("Backing up @j @i @b information.\n\n"),
8478 /* Reserved blocks w/o resize_inode */
8479 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8480 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8481 "is %N; @s zero. "),
8484 /* Resize_inode not enabled, but resize inode is non-zero */
8485 { PR_0_CLEAR_RESIZE_INODE,
8486 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8489 /* Resize inode invalid */
8490 { PR_0_RESIZE_INODE_INVALID,
8491 N_("Resize @i not valid. "),
8492 PROMPT_RECREATE, 0 },
8496 /* Pass 1: Checking inodes, blocks, and sizes */
8498 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8501 /* Root directory is not an inode */
8502 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8505 /* Root directory has dtime set */
8507 N_("@r has dtime set (probably due to old mke2fs). "),
8508 PROMPT_FIX, PR_PREEN_OK },
8510 /* Reserved inode has bad mode */
8511 { PR_1_RESERVED_BAD_MODE,
8512 N_("Reserved @i %i (%Q) has @n mode. "),
8513 PROMPT_CLEAR, PR_PREEN_OK },
8515 /* Deleted inode has zero dtime */
8517 N_("@D @i %i has zero dtime. "),
8518 PROMPT_FIX, PR_PREEN_OK },
8520 /* Inode in use, but dtime set */
8522 N_("@i %i is in use, but has dtime set. "),
8523 PROMPT_FIX, PR_PREEN_OK },
8525 /* Zero-length directory */
8526 { PR_1_ZERO_LENGTH_DIR,
8527 N_("@i %i is a @z @d. "),
8528 PROMPT_CLEAR, PR_PREEN_OK },
8530 /* Block bitmap conflicts with some other fs block */
8532 N_("@g %g's @b @B at %b @C.\n"),
8533 PROMPT_RELOCATE, 0 },
8535 /* Inode bitmap conflicts with some other fs block */
8537 N_("@g %g's @i @B at %b @C.\n"),
8538 PROMPT_RELOCATE, 0 },
8540 /* Inode table conflicts with some other fs block */
8541 { PR_1_ITABLE_CONFLICT,
8542 N_("@g %g's @i table at %b @C.\n"),
8543 PROMPT_RELOCATE, 0 },
8545 /* Block bitmap is on a bad block */
8546 { PR_1_BB_BAD_BLOCK,
8547 N_("@g %g's @b @B (%b) is bad. "),
8548 PROMPT_RELOCATE, 0 },
8550 /* Inode bitmap is on a bad block */
8551 { PR_1_IB_BAD_BLOCK,
8552 N_("@g %g's @i @B (%b) is bad. "),
8553 PROMPT_RELOCATE, 0 },
8555 /* Inode has incorrect i_size */
8557 N_("@i %i, i_size is %Is, @s %N. "),
8558 PROMPT_FIX, PR_PREEN_OK },
8560 /* Inode has incorrect i_blocks */
8561 { PR_1_BAD_I_BLOCKS,
8562 N_("@i %i, i_@bs is %Ib, @s %N. "),
8563 PROMPT_FIX, PR_PREEN_OK },
8565 /* Illegal blocknumber in inode */
8566 { PR_1_ILLEGAL_BLOCK_NUM,
8567 N_("@I @b #%B (%b) in @i %i. "),
8568 PROMPT_CLEAR, PR_LATCH_BLOCK },
8570 /* Block number overlaps fs metadata */
8571 { PR_1_BLOCK_OVERLAPS_METADATA,
8572 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8573 PROMPT_CLEAR, PR_LATCH_BLOCK },
8575 /* Inode has illegal blocks (latch question) */
8576 { PR_1_INODE_BLOCK_LATCH,
8577 N_("@i %i has illegal @b(s). "),
8580 /* Too many bad blocks in inode */
8581 { PR_1_TOO_MANY_BAD_BLOCKS,
8582 N_("Too many illegal @bs in @i %i.\n"),
8583 PROMPT_CLEAR_INODE, PR_NO_OK },
8585 /* Illegal block number in bad block inode */
8586 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8587 N_("@I @b #%B (%b) in bad @b @i. "),
8588 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8590 /* Bad block inode has illegal blocks (latch question) */
8591 { PR_1_INODE_BBLOCK_LATCH,
8592 N_("Bad @b @i has illegal @b(s). "),
8595 /* Duplicate or bad blocks in use! */
8596 { PR_1_DUP_BLOCKS_PREENSTOP,
8597 N_("Duplicate or bad @b in use!\n"),
8600 /* Bad block used as bad block indirect block */
8601 { PR_1_BBINODE_BAD_METABLOCK,
8602 N_("Bad @b %b used as bad @b @i indirect @b. "),
8603 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8605 /* Inconsistency can't be fixed prompt */
8606 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8607 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8608 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8610 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8612 /* Bad primary block */
8613 { PR_1_BAD_PRIMARY_BLOCK,
8614 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
8615 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8617 /* Bad primary block prompt */
8618 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8619 N_("You can remove this @b from the bad @b list and hope\n"
8620 "that the @b is really OK. But there are no guarantees.\n\n"),
8621 PROMPT_CLEAR, PR_PREEN_NOMSG },
8623 /* Bad primary superblock */
8624 { PR_1_BAD_PRIMARY_SUPERBLOCK,
8625 N_("The primary @S (%b) is on the bad @b list.\n"),
8626 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8628 /* Bad primary block group descriptors */
8629 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8630 N_("Block %b in the primary @g descriptors "
8631 "is on the bad @b list\n"),
8632 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8634 /* Bad superblock in group */
8635 { PR_1_BAD_SUPERBLOCK,
8636 N_("Warning: Group %g's @S (%b) is bad.\n"),
8637 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8639 /* Bad block group descriptors in group */
8640 { PR_1_BAD_GROUP_DESCRIPTORS,
8641 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8643 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8645 /* Block claimed for no reason */
8646 { PR_1_PROGERR_CLAIMED_BLOCK,
8647 N_("Programming error? @b #%b claimed for no reason in "
8648 "process_bad_@b.\n"),
8649 PROMPT_NONE, PR_PREEN_OK },
8651 /* Error allocating blocks for relocating metadata */
8652 { PR_1_RELOC_BLOCK_ALLOCATE,
8653 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8654 PROMPT_NONE, PR_PREEN_OK },
8656 /* Error allocating block buffer during relocation process */
8657 { PR_1_RELOC_MEMORY_ALLOCATE,
8658 N_("@A @b buffer for relocating %s\n"),
8659 PROMPT_NONE, PR_PREEN_OK },
8661 /* Relocating metadata group information from X to Y */
8662 { PR_1_RELOC_FROM_TO,
8663 N_("Relocating @g %g's %s from %b to %c...\n"),
8664 PROMPT_NONE, PR_PREEN_OK },
8666 /* Relocating metatdata group information to X */
8668 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8669 PROMPT_NONE, PR_PREEN_OK },
8671 /* Block read error during relocation process */
8672 { PR_1_RELOC_READ_ERR,
8673 N_("Warning: could not read @b %b of %s: %m\n"),
8674 PROMPT_NONE, PR_PREEN_OK },
8676 /* Block write error during relocation process */
8677 { PR_1_RELOC_WRITE_ERR,
8678 N_("Warning: could not write @b %b for %s: %m\n"),
8679 PROMPT_NONE, PR_PREEN_OK },
8681 /* Error allocating inode bitmap */
8682 { PR_1_ALLOCATE_IBITMAP_ERROR,
8683 N_("@A @i @B (%N): %m\n"),
8684 PROMPT_NONE, PR_FATAL },
8686 /* Error allocating block bitmap */
8687 { PR_1_ALLOCATE_BBITMAP_ERROR,
8688 N_("@A @b @B (%N): %m\n"),
8689 PROMPT_NONE, PR_FATAL },
8691 /* Error allocating icount structure */
8692 { PR_1_ALLOCATE_ICOUNT,
8693 N_("@A icount link information: %m\n"),
8694 PROMPT_NONE, PR_FATAL },
8696 /* Error allocating dbcount */
8697 { PR_1_ALLOCATE_DBCOUNT,
8698 N_("@A @d @b array: %m\n"),
8699 PROMPT_NONE, PR_FATAL },
8701 /* Error while scanning inodes */
8703 N_("Error while scanning @is (%i): %m\n"),
8704 PROMPT_NONE, PR_FATAL },
8706 /* Error while iterating over blocks */
8707 { PR_1_BLOCK_ITERATE,
8708 N_("Error while iterating over @bs in @i %i: %m\n"),
8709 PROMPT_NONE, PR_FATAL },
8711 /* Error while storing inode count information */
8712 { PR_1_ICOUNT_STORE,
8713 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8714 PROMPT_NONE, PR_FATAL },
8716 /* Error while storing directory block information */
8718 N_("Error storing @d @b information "
8719 "(@i=%i, @b=%b, num=%N): %m\n"),
8720 PROMPT_NONE, PR_FATAL },
8722 /* Error while reading inode (for clearing) */
8724 N_("Error reading @i %i: %m\n"),
8725 PROMPT_NONE, PR_FATAL },
8727 /* Suppress messages prompt */
8728 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8730 /* Imagic flag set on an inode when filesystem doesn't support it */
8732 N_("@i %i has imagic flag set. "),
8735 /* Immutable flag set on a device or socket inode */
8736 { PR_1_SET_IMMUTABLE,
8737 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8738 "or append-only flag set. "),
8739 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8741 /* Compression flag set on an inode when filesystem doesn't support it */
8743 N_("@i %i has @cion flag set on @f without @cion support. "),
8746 /* Non-zero size for device, fifo or socket inode */
8747 { PR_1_SET_NONZSIZE,
8748 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8749 PROMPT_FIX, PR_PREEN_OK },
8751 /* Filesystem revision is 0, but feature flags are set */
8752 { PR_1_FS_REV_LEVEL,
8753 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8754 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8756 /* Journal inode is not in use, but contains data */
8757 { PR_1_JOURNAL_INODE_NOT_CLEAR,
8758 N_("@j @i is not in use, but contains data. "),
8759 PROMPT_CLEAR, PR_PREEN_OK },
8761 /* Journal has bad mode */
8762 { PR_1_JOURNAL_BAD_MODE,
8763 N_("@j is not regular file. "),
8764 PROMPT_FIX, PR_PREEN_OK },
8766 /* Deal with inodes that were part of orphan linked list */
8768 N_("@i %i was part of the @o @i list. "),
8769 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8771 /* Deal with inodes that were part of corrupted orphan linked
8772 list (latch question) */
8773 { PR_1_ORPHAN_LIST_REFUGEES,
8774 N_("@is that were part of a corrupted orphan linked list found. "),
8777 /* Error allocating refcount structure */
8778 { PR_1_ALLOCATE_REFCOUNT,
8779 N_("@A refcount structure (%N): %m\n"),
8780 PROMPT_NONE, PR_FATAL },
8782 /* Error reading extended attribute block */
8783 { PR_1_READ_EA_BLOCK,
8784 N_("Error reading @a @b %b for @i %i. "),
8787 /* Invalid extended attribute block */
8788 { PR_1_BAD_EA_BLOCK,
8789 N_("@i %i has a bad @a @b %b. "),
8792 /* Error reading Extended Attribute block while fixing refcount */
8793 { PR_1_EXTATTR_READ_ABORT,
8794 N_("Error reading @a @b %b (%m). "),
8797 /* Extended attribute reference count incorrect */
8798 { PR_1_EXTATTR_REFCOUNT,
8799 N_("@a @b %b has reference count %B, @s %N. "),
8802 /* Error writing Extended Attribute block while fixing refcount */
8803 { PR_1_EXTATTR_WRITE,
8804 N_("Error writing @a @b %b (%m). "),
8807 /* Multiple EA blocks not supported */
8808 { PR_1_EA_MULTI_BLOCK,
8809 N_("@a @b %b has h_@bs > 1. "),
8812 /* Error allocating EA region allocation structure */
8813 { PR_1_EA_ALLOC_REGION,
8814 N_("@A @a @b %b. "),
8817 /* Error EA allocation collision */
8818 { PR_1_EA_ALLOC_COLLISION,
8819 N_("@a @b %b is corrupt (allocation collision). "),
8822 /* Bad extended attribute name */
8824 N_("@a @b %b is corrupt (@n name). "),
8827 /* Bad extended attribute value */
8828 { PR_1_EA_BAD_VALUE,
8829 N_("@a @b %b is corrupt (@n value). "),
8832 /* Inode too big (latch question) */
8833 { PR_1_INODE_TOOBIG,
8834 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
8836 /* Directory too big */
8838 N_("@b #%B (%b) causes @d to be too big. "),
8839 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8841 /* Regular file too big */
8843 N_("@b #%B (%b) causes file to be too big. "),
8844 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8846 /* Symlink too big */
8847 { PR_1_TOOBIG_SYMLINK,
8848 N_("@b #%B (%b) causes symlink to be too big. "),
8849 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8851 /* INDEX_FL flag set on a non-HTREE filesystem */
8853 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8854 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8856 /* INDEX_FL flag set on a non-directory */
8858 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8859 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8861 /* Invalid root node in HTREE directory */
8862 { PR_1_HTREE_BADROOT,
8863 N_("@h %i has an @n root node.\n"),
8864 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8866 /* Unsupported hash version in HTREE directory */
8868 N_("@h %i has an unsupported hash version (%N)\n"),
8869 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8871 /* Incompatible flag in HTREE root node */
8872 { PR_1_HTREE_INCOMPAT,
8873 N_("@h %i uses an incompatible htree root node flag.\n"),
8874 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8876 /* HTREE too deep */
8878 N_("@h %i has a tree depth (%N) which is too big\n"),
8879 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8881 /* Bad block has indirect block that conflicts with filesystem block */
8883 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8885 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8887 /* Resize inode failed */
8888 { PR_1_RESIZE_INODE_CREATE,
8889 N_("Resize @i (re)creation failed: %m."),
8892 /* invalid inode->i_extra_isize */
8894 N_("@i %i has a extra size (%IS) which is @n\n"),
8895 PROMPT_FIX, PR_PREEN_OK },
8897 /* invalid ea entry->e_name_len */
8898 { PR_1_ATTR_NAME_LEN,
8899 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8900 PROMPT_CLEAR, PR_PREEN_OK },
8902 /* invalid ea entry->e_value_size */
8903 { PR_1_ATTR_VALUE_SIZE,
8904 N_("@a in @i %i has a value size (%N) which is @n\n"),
8905 PROMPT_CLEAR, PR_PREEN_OK },
8907 /* invalid ea entry->e_value_offs */
8908 { PR_1_ATTR_VALUE_OFFSET,
8909 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8910 PROMPT_CLEAR, PR_PREEN_OK },
8912 /* invalid ea entry->e_value_block */
8913 { PR_1_ATTR_VALUE_BLOCK,
8914 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8915 PROMPT_CLEAR, PR_PREEN_OK },
8917 /* invalid ea entry->e_hash */
8919 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8920 PROMPT_CLEAR, PR_PREEN_OK },
8922 /* Pass 1b errors */
8924 /* Pass 1B: Rescan for duplicate/bad blocks */
8925 { PR_1B_PASS_HEADER,
8926 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8927 "Pass 1B: Rescanning for @m @bs\n"),
8930 /* Duplicate/bad block(s) header */
8931 { PR_1B_DUP_BLOCK_HEADER,
8932 N_("@m @b(s) in @i %i:"),
8935 /* Duplicate/bad block(s) in inode */
8938 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8940 /* Duplicate/bad block(s) end */
8941 { PR_1B_DUP_BLOCK_END,
8943 PROMPT_NONE, PR_PREEN_NOHDR },
8945 /* Error while scanning inodes */
8946 { PR_1B_ISCAN_ERROR,
8947 N_("Error while scanning inodes (%i): %m\n"),
8948 PROMPT_NONE, PR_FATAL },
8950 /* Error allocating inode bitmap */
8951 { PR_1B_ALLOCATE_IBITMAP_ERROR,
8952 N_("@A @i @B (@i_dup_map): %m\n"),
8953 PROMPT_NONE, PR_FATAL },
8955 /* Error while iterating over blocks */
8956 { PR_1B_BLOCK_ITERATE,
8957 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8960 /* Error adjusting EA refcount */
8961 { PR_1B_ADJ_EA_REFCOUNT,
8962 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8966 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8967 { PR_1C_PASS_HEADER,
8968 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8972 /* Pass 1D: Reconciling multiply-claimed blocks */
8973 { PR_1D_PASS_HEADER,
8974 N_("Pass 1D: Reconciling @m @bs\n"),
8977 /* File has duplicate blocks */
8979 N_("File %Q (@i #%i, mod time %IM) \n"
8980 " has %B @m @b(s), shared with %N file(s):\n"),
8983 /* List of files sharing duplicate blocks */
8984 { PR_1D_DUP_FILE_LIST,
8985 N_("\t%Q (@i #%i, mod time %IM)\n"),
8988 /* File sharing blocks with filesystem metadata */
8989 { PR_1D_SHARE_METADATA,
8990 N_("\t<@f metadata>\n"),
8993 /* Report of how many duplicate/bad inodes */
8994 { PR_1D_NUM_DUP_INODES,
8995 N_("(There are %N @is containing @m @bs.)\n\n"),
8998 /* Duplicated blocks already reassigned or cloned. */
8999 { PR_1D_DUP_BLOCKS_DEALT,
9000 N_("@m @bs already reassigned or cloned.\n\n"),
9003 /* Clone duplicate/bad blocks? */
9004 { PR_1D_CLONE_QUESTION,
9005 "", PROMPT_CLONE, PR_NO_OK },
9008 { PR_1D_DELETE_QUESTION,
9009 "", PROMPT_DELETE, 0 },
9011 /* Couldn't clone file (error) */
9012 { PR_1D_CLONE_ERROR,
9013 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
9017 /* Pass 2: Checking directory structure */
9019 N_("Pass 2: Checking @d structure\n"),
9022 /* Bad inode number for '.' */
9023 { PR_2_BAD_INODE_DOT,
9024 N_("@n @i number for '.' in @d @i %i.\n"),
9027 /* Directory entry has bad inode number */
9029 N_("@E has @n @i #: %Di.\n"),
9032 /* Directory entry has deleted or unused inode */
9033 { PR_2_UNUSED_INODE,
9034 N_("@E has @D/unused @i %Di. "),
9035 PROMPT_CLEAR, PR_PREEN_OK },
9037 /* Directry entry is link to '.' */
9039 N_("@E @L to '.' "),
9042 /* Directory entry points to inode now located in a bad block */
9044 N_("@E points to @i (%Di) located in a bad @b.\n"),
9047 /* Directory entry contains a link to a directory */
9049 N_("@E @L to @d %P (%Di).\n"),
9052 /* Directory entry contains a link to the root directry */
9054 N_("@E @L to the @r.\n"),
9057 /* Directory entry has illegal characters in its name */
9059 N_("@E has illegal characters in its name.\n"),
9062 /* Missing '.' in directory inode */
9064 N_("Missing '.' in @d @i %i.\n"),
9067 /* Missing '..' in directory inode */
9068 { PR_2_MISSING_DOT_DOT,
9069 N_("Missing '..' in @d @i %i.\n"),
9072 /* First entry in directory inode doesn't contain '.' */
9074 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9077 /* Second entry in directory inode doesn't contain '..' */
9078 { PR_2_2ND_NOT_DOT_DOT,
9079 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9082 /* i_faddr should be zero */
9084 N_("i_faddr @F %IF, @s zero.\n"),
9087 /* i_file_acl should be zero */
9088 { PR_2_FILE_ACL_ZERO,
9089 N_("i_file_acl @F %If, @s zero.\n"),
9092 /* i_dir_acl should be zero */
9093 { PR_2_DIR_ACL_ZERO,
9094 N_("i_dir_acl @F %Id, @s zero.\n"),
9097 /* i_frag should be zero */
9099 N_("i_frag @F %N, @s zero.\n"),
9102 /* i_fsize should be zero */
9104 N_("i_fsize @F %N, @s zero.\n"),
9107 /* inode has bad mode */
9109 N_("@i %i (%Q) has @n mode (%Im).\n"),
9112 /* directory corrupted */
9113 { PR_2_DIR_CORRUPTED,
9114 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9115 PROMPT_SALVAGE, 0 },
9117 /* filename too long */
9118 { PR_2_FILENAME_LONG,
9119 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9120 PROMPT_TRUNCATE, 0 },
9122 /* Directory inode has a missing block (hole) */
9123 { PR_2_DIRECTORY_HOLE,
9124 N_("@d @i %i has an unallocated @b #%B. "),
9125 PROMPT_ALLOCATE, 0 },
9127 /* '.' is not NULL terminated */
9128 { PR_2_DOT_NULL_TERM,
9129 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9132 /* '..' is not NULL terminated */
9133 { PR_2_DOT_DOT_NULL_TERM,
9134 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9137 /* Illegal character device inode */
9138 { PR_2_BAD_CHAR_DEV,
9139 N_("@i %i (%Q) is an @I character @v.\n"),
9142 /* Illegal block device inode */
9143 { PR_2_BAD_BLOCK_DEV,
9144 N_("@i %i (%Q) is an @I @b @v.\n"),
9147 /* Duplicate '.' entry */
9149 N_("@E is duplicate '.' @e.\n"),
9152 /* Duplicate '..' entry */
9154 N_("@E is duplicate '..' @e.\n"),
9157 /* Internal error: couldn't find dir_info */
9159 N_("Internal error: couldn't find dir_info for %i.\n"),
9160 PROMPT_NONE, PR_FATAL },
9162 /* Final rec_len is wrong */
9163 { PR_2_FINAL_RECLEN,
9164 N_("@E has rec_len of %Dr, @s %N.\n"),
9167 /* Error allocating icount structure */
9168 { PR_2_ALLOCATE_ICOUNT,
9169 N_("@A icount structure: %m\n"),
9170 PROMPT_NONE, PR_FATAL },
9172 /* Error iterating over directory blocks */
9173 { PR_2_DBLIST_ITERATE,
9174 N_("Error iterating over @d @bs: %m\n"),
9175 PROMPT_NONE, PR_FATAL },
9177 /* Error reading directory block */
9178 { PR_2_READ_DIRBLOCK,
9179 N_("Error reading @d @b %b (@i %i): %m\n"),
9180 PROMPT_CONTINUE, 0 },
9182 /* Error writing directory block */
9183 { PR_2_WRITE_DIRBLOCK,
9184 N_("Error writing @d @b %b (@i %i): %m\n"),
9185 PROMPT_CONTINUE, 0 },
9187 /* Error allocating new directory block */
9188 { PR_2_ALLOC_DIRBOCK,
9189 N_("@A new @d @b for @i %i (%s): %m\n"),
9192 /* Error deallocating inode */
9193 { PR_2_DEALLOC_INODE,
9194 N_("Error deallocating @i %i: %m\n"),
9195 PROMPT_NONE, PR_FATAL },
9197 /* Directory entry for '.' is big. Split? */
9199 N_("@d @e for '.' is big. "),
9200 PROMPT_SPLIT, PR_NO_OK },
9202 /* Illegal FIFO inode */
9204 N_("@i %i (%Q) is an @I FIFO.\n"),
9207 /* Illegal socket inode */
9209 N_("@i %i (%Q) is an @I socket.\n"),
9212 /* Directory filetype not set */
9213 { PR_2_SET_FILETYPE,
9214 N_("Setting filetype for @E to %N.\n"),
9215 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9217 /* Directory filetype incorrect */
9218 { PR_2_BAD_FILETYPE,
9219 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9222 /* Directory filetype set on filesystem */
9223 { PR_2_CLEAR_FILETYPE,
9224 N_("@E has filetype set.\n"),
9225 PROMPT_CLEAR, PR_PREEN_OK },
9227 /* Directory filename is null */
9229 N_("@E has a @z name.\n"),
9232 /* Invalid symlink */
9233 { PR_2_INVALID_SYMLINK,
9234 N_("Symlink %Q (@i #%i) is @n.\n"),
9237 /* i_file_acl (extended attribute block) is bad */
9238 { PR_2_FILE_ACL_BAD,
9239 N_("@a @b @F @n (%If).\n"),
9242 /* Filesystem contains large files, but has no such flag in sb */
9243 { PR_2_FEATURE_LARGE_FILES,
9244 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9247 /* Node in HTREE directory not referenced */
9248 { PR_2_HTREE_NOTREF,
9249 N_("@p @h %d: node (%B) not referenced\n"),
9252 /* Node in HTREE directory referenced twice */
9253 { PR_2_HTREE_DUPREF,
9254 N_("@p @h %d: node (%B) referenced twice\n"),
9257 /* Node in HTREE directory has bad min hash */
9258 { PR_2_HTREE_MIN_HASH,
9259 N_("@p @h %d: node (%B) has bad min hash\n"),
9262 /* Node in HTREE directory has bad max hash */
9263 { PR_2_HTREE_MAX_HASH,
9264 N_("@p @h %d: node (%B) has bad max hash\n"),
9267 /* Clear invalid HTREE directory */
9269 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9271 /* Bad block in htree interior node */
9272 { PR_2_HTREE_BADBLK,
9273 N_("@p @h %d (%q): bad @b number %b.\n"),
9274 PROMPT_CLEAR_HTREE, 0 },
9276 /* Error adjusting EA refcount */
9277 { PR_2_ADJ_EA_REFCOUNT,
9278 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9279 PROMPT_NONE, PR_FATAL },
9281 /* Invalid HTREE root node */
9282 { PR_2_HTREE_BAD_ROOT,
9283 N_("@p @h %d: root node is @n\n"),
9284 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9286 /* Invalid HTREE limit */
9287 { PR_2_HTREE_BAD_LIMIT,
9288 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9289 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9291 /* Invalid HTREE count */
9292 { PR_2_HTREE_BAD_COUNT,
9293 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9294 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9296 /* HTREE interior node has out-of-order hashes in table */
9297 { PR_2_HTREE_HASH_ORDER,
9298 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9299 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9301 /* Node in HTREE directory has invalid depth */
9302 { PR_2_HTREE_BAD_DEPTH,
9303 N_("@p @h %d: node (%B) has @n depth\n"),
9306 /* Duplicate directory entry found */
9307 { PR_2_DUPLICATE_DIRENT,
9308 N_("Duplicate @E found. "),
9311 /* Non-unique filename found */
9312 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9313 N_("@E has a non-unique filename.\nRename to %s"),
9316 /* Duplicate directory entry found */
9317 { PR_2_REPORT_DUP_DIRENT,
9318 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9323 /* Pass 3: Checking directory connectivity */
9325 N_("Pass 3: Checking @d connectivity\n"),
9328 /* Root inode not allocated */
9329 { PR_3_NO_ROOT_INODE,
9330 N_("@r not allocated. "),
9331 PROMPT_ALLOCATE, 0 },
9333 /* No room in lost+found */
9334 { PR_3_EXPAND_LF_DIR,
9335 N_("No room in @l @d. "),
9338 /* Unconnected directory inode */
9339 { PR_3_UNCONNECTED_DIR,
9340 N_("Unconnected @d @i %i (%p)\n"),
9341 PROMPT_CONNECT, 0 },
9343 /* /lost+found not found */
9345 N_("/@l not found. "),
9346 PROMPT_CREATE, PR_PREEN_OK },
9348 /* .. entry is incorrect */
9350 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9353 /* Bad or non-existent /lost+found. Cannot reconnect */
9355 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9358 /* Could not expand /lost+found */
9359 { PR_3_CANT_EXPAND_LPF,
9360 N_("Could not expand /@l: %m\n"),
9363 /* Could not reconnect inode */
9364 { PR_3_CANT_RECONNECT,
9365 N_("Could not reconnect %i: %m\n"),
9368 /* Error while trying to find /lost+found */
9369 { PR_3_ERR_FIND_LPF,
9370 N_("Error while trying to find /@l: %m\n"),
9373 /* Error in ext2fs_new_block while creating /lost+found */
9374 { PR_3_ERR_LPF_NEW_BLOCK,
9375 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9378 /* Error in ext2fs_new_inode while creating /lost+found */
9379 { PR_3_ERR_LPF_NEW_INODE,
9380 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9383 /* Error in ext2fs_new_dir_block while creating /lost+found */
9384 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9385 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9388 /* Error while writing directory block for /lost+found */
9389 { PR_3_ERR_LPF_WRITE_BLOCK,
9390 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9393 /* Error while adjusting inode count */
9394 { PR_3_ADJUST_INODE,
9395 N_("Error while adjusting @i count on @i %i\n"),
9398 /* Couldn't fix parent directory -- error */
9399 { PR_3_FIX_PARENT_ERR,
9400 N_("Couldn't fix parent of @i %i: %m\n\n"),
9403 /* Couldn't fix parent directory -- couldn't find it */
9404 { PR_3_FIX_PARENT_NOFIND,
9405 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9408 /* Error allocating inode bitmap */
9409 { PR_3_ALLOCATE_IBITMAP_ERROR,
9410 N_("@A @i @B (%N): %m\n"),
9411 PROMPT_NONE, PR_FATAL },
9413 /* Error creating root directory */
9414 { PR_3_CREATE_ROOT_ERROR,
9415 N_("Error creating root @d (%s): %m\n"),
9416 PROMPT_NONE, PR_FATAL },
9418 /* Error creating lost and found directory */
9419 { PR_3_CREATE_LPF_ERROR,
9420 N_("Error creating /@l @d (%s): %m\n"),
9421 PROMPT_NONE, PR_FATAL },
9423 /* Root inode is not directory; aborting */
9424 { PR_3_ROOT_NOT_DIR_ABORT,
9425 N_("@r is not a @d; aborting.\n"),
9426 PROMPT_NONE, PR_FATAL },
9428 /* Cannot proceed without a root inode. */
9429 { PR_3_NO_ROOT_INODE_ABORT,
9430 N_("Cannot proceed without a @r.\n"),
9431 PROMPT_NONE, PR_FATAL },
9433 /* Internal error: couldn't find dir_info */
9435 N_("Internal error: couldn't find dir_info for %i.\n"),
9436 PROMPT_NONE, PR_FATAL },
9438 /* Lost+found not a directory */
9440 N_("/@l is not a @d (ino=%i)\n"),
9443 /* Pass 3A Directory Optimization */
9445 /* Pass 3A: Optimizing directories */
9446 { PR_3A_PASS_HEADER,
9447 N_("Pass 3A: Optimizing directories\n"),
9448 PROMPT_NONE, PR_PREEN_NOMSG },
9450 /* Error iterating over directories */
9451 { PR_3A_OPTIMIZE_ITER,
9452 N_("Failed to create dirs_to_hash iterator: %m"),
9455 /* Error rehash directory */
9456 { PR_3A_OPTIMIZE_DIR_ERR,
9457 N_("Failed to optimize directory %q (%d): %m"),
9460 /* Rehashing dir header */
9461 { PR_3A_OPTIMIZE_DIR_HEADER,
9462 N_("Optimizing directories: "),
9463 PROMPT_NONE, PR_MSG_ONLY },
9465 /* Rehashing directory %d */
9466 { PR_3A_OPTIMIZE_DIR,
9468 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9470 /* Rehashing dir end */
9471 { PR_3A_OPTIMIZE_DIR_END,
9473 PROMPT_NONE, PR_PREEN_NOHDR },
9477 /* Pass 4: Checking reference counts */
9479 N_("Pass 4: Checking reference counts\n"),
9482 /* Unattached zero-length inode */
9483 { PR_4_ZERO_LEN_INODE,
9484 N_("@u @z @i %i. "),
9485 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9487 /* Unattached inode */
9488 { PR_4_UNATTACHED_INODE,
9490 PROMPT_CONNECT, 0 },
9492 /* Inode ref count wrong */
9493 { PR_4_BAD_REF_COUNT,
9494 N_("@i %i ref count is %Il, @s %N. "),
9495 PROMPT_FIX, PR_PREEN_OK },
9497 { PR_4_INCONSISTENT_COUNT,
9498 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9499 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9500 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9501 "They @s the same!\n"),
9506 /* Pass 5: Checking group summary information */
9508 N_("Pass 5: Checking @g summary information\n"),
9511 /* Padding at end of inode bitmap is not set. */
9512 { PR_5_INODE_BMAP_PADDING,
9513 N_("Padding at end of @i @B is not set. "),
9514 PROMPT_FIX, PR_PREEN_OK },
9516 /* Padding at end of block bitmap is not set. */
9517 { PR_5_BLOCK_BMAP_PADDING,
9518 N_("Padding at end of @b @B is not set. "),
9519 PROMPT_FIX, PR_PREEN_OK },
9521 /* Block bitmap differences header */
9522 { PR_5_BLOCK_BITMAP_HEADER,
9523 N_("@b @B differences: "),
9524 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9526 /* Block not used, but marked in bitmap */
9527 { PR_5_BLOCK_UNUSED,
9529 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9531 /* Block used, but not marked used in bitmap */
9534 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9536 /* Block bitmap differences end */
9537 { PR_5_BLOCK_BITMAP_END,
9539 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9541 /* Inode bitmap differences header */
9542 { PR_5_INODE_BITMAP_HEADER,
9543 N_("@i @B differences: "),
9544 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9546 /* Inode not used, but marked in bitmap */
9547 { PR_5_INODE_UNUSED,
9549 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9551 /* Inode used, but not marked used in bitmap */
9554 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9556 /* Inode bitmap differences end */
9557 { PR_5_INODE_BITMAP_END,
9559 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9561 /* Free inodes count for group wrong */
9562 { PR_5_FREE_INODE_COUNT_GROUP,
9563 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9564 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9566 /* Directories count for group wrong */
9567 { PR_5_FREE_DIR_COUNT_GROUP,
9568 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9569 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9571 /* Free inodes count wrong */
9572 { PR_5_FREE_INODE_COUNT,
9573 N_("Free @is count wrong (%i, counted=%j).\n"),
9574 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9576 /* Free blocks count for group wrong */
9577 { PR_5_FREE_BLOCK_COUNT_GROUP,
9578 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9579 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9581 /* Free blocks count wrong */
9582 { PR_5_FREE_BLOCK_COUNT,
9583 N_("Free @bs count wrong (%b, counted=%c).\n"),
9584 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9586 /* Programming error: bitmap endpoints don't match */
9587 { PR_5_BMAP_ENDPOINTS,
9588 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9589 "match calculated @B endpoints (%i, %j)\n"),
9590 PROMPT_NONE, PR_FATAL },
9592 /* Internal error: fudging end of bitmap */
9593 { PR_5_FUDGE_BITMAP_ERROR,
9594 N_("Internal error: fudging end of bitmap (%N)\n"),
9595 PROMPT_NONE, PR_FATAL },
9597 /* Error copying in replacement inode bitmap */
9598 { PR_5_COPY_IBITMAP_ERROR,
9599 N_("Error copying in replacement @i @B: %m\n"),
9600 PROMPT_NONE, PR_FATAL },
9602 /* Error copying in replacement block bitmap */
9603 { PR_5_COPY_BBITMAP_ERROR,
9604 N_("Error copying in replacement @b @B: %m\n"),
9605 PROMPT_NONE, PR_FATAL },
9607 /* Block range not used, but marked in bitmap */
9608 { PR_5_BLOCK_RANGE_UNUSED,
9610 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9612 /* Block range used, but not marked used in bitmap */
9613 { PR_5_BLOCK_RANGE_USED,
9615 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9617 /* Inode range not used, but marked in bitmap */
9618 { PR_5_INODE_RANGE_UNUSED,
9620 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9622 /* Inode range used, but not marked used in bitmap */
9623 { PR_5_INODE_RANGE_USED,
9625 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9631 * This is the latch flags register. It allows several problems to be
9632 * "latched" together. This means that the user has to answer but one
9633 * question for the set of problems, and all of the associated
9634 * problems will be either fixed or not fixed.
9636 static struct latch_descr pr_latch_info[] = {
9637 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9638 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9639 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9640 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9641 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9642 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9643 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9644 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9645 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9649 static const struct e2fsck_problem *find_problem(problem_t code)
9653 for (i=0; problem_table[i].e2p_code; i++) {
9654 if (problem_table[i].e2p_code == code)
9655 return &problem_table[i];
9660 static struct latch_descr *find_latch(int code)
9664 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9665 if (pr_latch_info[i].latch_code == code)
9666 return &pr_latch_info[i];
9671 int end_problem_latch(e2fsck_t ctx, int mask)
9673 struct latch_descr *ldesc;
9674 struct problem_context pctx;
9677 ldesc = find_latch(mask);
9678 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9679 clear_problem_context(&pctx);
9680 answer = fix_problem(ctx, ldesc->end_message, &pctx);
9682 ldesc->flags &= ~(PRL_VARIABLE);
9686 int set_latch_flags(int mask, int setflags, int clearflags)
9688 struct latch_descr *ldesc;
9690 ldesc = find_latch(mask);
9693 ldesc->flags |= setflags;
9694 ldesc->flags &= ~clearflags;
9698 void clear_problem_context(struct problem_context *ctx)
9700 memset(ctx, 0, sizeof(struct problem_context));
9705 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9707 ext2_filsys fs = ctx->fs;
9708 const struct e2fsck_problem *ptr;
9709 struct latch_descr *ldesc = 0;
9710 const char *message;
9711 int def_yn, answer, ans;
9712 int print_answer = 0;
9715 ptr = find_problem(code);
9717 printf(_("Unhandled error code (0x%x)!\n"), code);
9721 if ((ptr->flags & PR_NO_DEFAULT) ||
9722 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9723 (ctx->options & E2F_OPT_NO))
9727 * Do special latch processing. This is where we ask the
9728 * latch question, if it exists
9730 if (ptr->flags & PR_LATCH_MASK) {
9731 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9732 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9733 ans = fix_problem(ctx, ldesc->question, pctx);
9735 ldesc->flags |= PRL_YES;
9737 ldesc->flags |= PRL_NO;
9738 ldesc->flags |= PRL_LATCHED;
9740 if (ldesc->flags & PRL_SUPPRESS)
9743 if ((ptr->flags & PR_PREEN_NOMSG) &&
9744 (ctx->options & E2F_OPT_PREEN))
9746 if ((ptr->flags & PR_NO_NOMSG) &&
9747 (ctx->options & E2F_OPT_NO))
9750 message = ptr->e2p_description;
9751 if ((ctx->options & E2F_OPT_PREEN) &&
9752 !(ptr->flags & PR_PREEN_NOHDR)) {
9753 printf("%s: ", ctx->device_name ?
9754 ctx->device_name : ctx->filesystem_name);
9757 print_e2fsck_message(ctx, _(message), pctx, 1);
9759 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9762 if (ptr->flags & PR_FATAL)
9763 bb_error_msg_and_die(0);
9765 if (ptr->prompt == PROMPT_NONE) {
9766 if (ptr->flags & PR_NOCOLLATE)
9771 if (ctx->options & E2F_OPT_PREEN) {
9773 if (!(ptr->flags & PR_PREEN_NOMSG))
9775 } else if ((ptr->flags & PR_LATCH_MASK) &&
9776 (ldesc->flags & (PRL_YES | PRL_NO))) {
9779 if (ldesc->flags & PRL_YES)
9784 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9785 if (!answer && !(ptr->flags & PR_NO_OK))
9786 ext2fs_unmark_valid(fs);
9789 printf("%s.\n", answer ?
9790 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9794 if ((ptr->prompt == PROMPT_ABORT) && answer)
9795 bb_error_msg_and_die(0);
9797 if (ptr->flags & PR_AFTER_CODE)
9798 answer = fix_problem(ctx, ptr->second_code, pctx);
9804 * linux/fs/recovery.c
9806 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9810 * Maintain information about the progress of the recovery job, so that
9811 * the different passes can carry information between them.
9813 struct recovery_info
9815 tid_t start_transaction;
9816 tid_t end_transaction;
9823 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9824 static int do_one_pass(journal_t *journal,
9825 struct recovery_info *info, enum passtype pass);
9826 static int scan_revoke_records(journal_t *, struct buffer_head *,
9827 tid_t, struct recovery_info *);
9830 * Read a block from the journal
9833 static int jread(struct buffer_head **bhp, journal_t *journal,
9834 unsigned int offset)
9837 unsigned long blocknr;
9838 struct buffer_head *bh;
9842 err = journal_bmap(journal, offset, &blocknr);
9845 printf ("JBD: bad block at offset %u\n", offset);
9849 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9853 if (!buffer_uptodate(bh)) {
9854 /* If this is a brand new buffer, start readahead.
9855 Otherwise, we assume we are already reading it. */
9856 if (!buffer_req(bh))
9857 do_readahead(journal, offset);
9861 if (!buffer_uptodate(bh)) {
9862 printf ("JBD: Failed to read block at offset %u\n", offset);
9873 * Count the number of in-use tags in a journal descriptor block.
9876 static int count_tags(struct buffer_head *bh, int size)
9879 journal_block_tag_t * tag;
9882 tagp = &bh->b_data[sizeof(journal_header_t)];
9884 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9885 tag = (journal_block_tag_t *) tagp;
9888 tagp += sizeof(journal_block_tag_t);
9889 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9892 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9900 /* Make sure we wrap around the log correctly! */
9901 #define wrap(journal, var) \
9903 if (var >= (journal)->j_last) \
9904 var -= ((journal)->j_last - (journal)->j_first); \
9908 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9909 * @journal: the journal to recover
9911 * The primary function for recovering the log contents when mounting a
9914 * Recovery is done in three passes. In the first pass, we look for the
9915 * end of the log. In the second, we assemble the list of revoke
9916 * blocks. In the third and final pass, we replay any un-revoked blocks
9919 int journal_recover(journal_t *journal)
9922 journal_superblock_t * sb;
9924 struct recovery_info info;
9926 memset(&info, 0, sizeof(info));
9927 sb = journal->j_superblock;
9930 * The journal superblock's s_start field (the current log head)
9931 * is always zero if, and only if, the journal was cleanly
9936 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9940 err = do_one_pass(journal, &info, PASS_SCAN);
9942 err = do_one_pass(journal, &info, PASS_REVOKE);
9944 err = do_one_pass(journal, &info, PASS_REPLAY);
9946 /* Restart the log at the next transaction ID, thus invalidating
9947 * any existing commit records in the log. */
9948 journal->j_transaction_sequence = ++info.end_transaction;
9950 journal_clear_revoke(journal);
9951 sync_blockdev(journal->j_fs_dev);
9955 static int do_one_pass(journal_t *journal,
9956 struct recovery_info *info, enum passtype pass)
9958 unsigned int first_commit_ID, next_commit_ID;
9959 unsigned long next_log_block;
9960 int err, success = 0;
9961 journal_superblock_t * sb;
9962 journal_header_t * tmp;
9963 struct buffer_head * bh;
9964 unsigned int sequence;
9967 /* Precompute the maximum metadata descriptors in a descriptor block */
9968 int MAX_BLOCKS_PER_DESC;
9969 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9970 / sizeof(journal_block_tag_t));
9973 * First thing is to establish what we expect to find in the log
9974 * (in terms of transaction IDs), and where (in terms of log
9975 * block offsets): query the superblock.
9978 sb = journal->j_superblock;
9979 next_commit_ID = ntohl(sb->s_sequence);
9980 next_log_block = ntohl(sb->s_start);
9982 first_commit_ID = next_commit_ID;
9983 if (pass == PASS_SCAN)
9984 info->start_transaction = first_commit_ID;
9987 * Now we walk through the log, transaction by transaction,
9988 * making sure that each transaction has a commit block in the
9989 * expected place. Each complete transaction gets replayed back
9990 * into the main filesystem.
9996 journal_block_tag_t * tag;
9997 struct buffer_head * obh;
9998 struct buffer_head * nbh;
10000 /* If we already know where to stop the log traversal,
10001 * check right now that we haven't gone past the end of
10004 if (pass != PASS_SCAN)
10005 if (tid_geq(next_commit_ID, info->end_transaction))
10008 /* Skip over each chunk of the transaction looking
10009 * either the next descriptor block or the final commit
10012 err = jread(&bh, journal, next_log_block);
10017 wrap(journal, next_log_block);
10019 /* What kind of buffer is it?
10021 * If it is a descriptor block, check that it has the
10022 * expected sequence number. Otherwise, we're all done
10025 tmp = (journal_header_t *)bh->b_data;
10027 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10032 blocktype = ntohl(tmp->h_blocktype);
10033 sequence = ntohl(tmp->h_sequence);
10035 if (sequence != next_commit_ID) {
10040 /* OK, we have a valid descriptor block which matches
10041 * all of the sequence number checks. What are we going
10042 * to do with it? That depends on the pass... */
10044 switch(blocktype) {
10045 case JFS_DESCRIPTOR_BLOCK:
10046 /* If it is a valid descriptor block, replay it
10047 * in pass REPLAY; otherwise, just skip over the
10048 * blocks it describes. */
10049 if (pass != PASS_REPLAY) {
10051 count_tags(bh, journal->j_blocksize);
10052 wrap(journal, next_log_block);
10057 /* A descriptor block: we can now write all of
10058 * the data blocks. Yay, useful work is finally
10059 * getting done here! */
10061 tagp = &bh->b_data[sizeof(journal_header_t)];
10062 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10063 <= journal->j_blocksize) {
10064 unsigned long io_block;
10066 tag = (journal_block_tag_t *) tagp;
10067 flags = ntohl(tag->t_flags);
10069 io_block = next_log_block++;
10070 wrap(journal, next_log_block);
10071 err = jread(&obh, journal, io_block);
10073 /* Recover what we can, but
10074 * report failure at the end. */
10076 printf ("JBD: IO error %d recovering "
10077 "block %ld in log\n",
10080 unsigned long blocknr;
10082 blocknr = ntohl(tag->t_blocknr);
10084 /* If the block has been
10085 * revoked, then we're all done
10087 if (journal_test_revoke
10091 ++info->nr_revoke_hits;
10095 /* Find a buffer for the new
10096 * data being restored */
10097 nbh = getblk(journal->j_fs_dev,
10099 journal->j_blocksize);
10101 printf ("JBD: Out of memory "
10102 "during recovery.\n");
10110 memcpy(nbh->b_data, obh->b_data,
10111 journal->j_blocksize);
10112 if (flags & JFS_FLAG_ESCAPE) {
10113 *((unsigned int *)bh->b_data) =
10114 htonl(JFS_MAGIC_NUMBER);
10117 mark_buffer_uptodate(nbh, 1);
10118 mark_buffer_dirty(nbh);
10119 ++info->nr_replays;
10120 /* ll_rw_block(WRITE, 1, &nbh); */
10121 unlock_buffer(nbh);
10127 tagp += sizeof(journal_block_tag_t);
10128 if (!(flags & JFS_FLAG_SAME_UUID))
10131 if (flags & JFS_FLAG_LAST_TAG)
10138 case JFS_COMMIT_BLOCK:
10139 /* Found an expected commit block: not much to
10140 * do other than move on to the next sequence
10146 case JFS_REVOKE_BLOCK:
10147 /* If we aren't in the REVOKE pass, then we can
10148 * just skip over this block. */
10149 if (pass != PASS_REVOKE) {
10154 err = scan_revoke_records(journal, bh,
10155 next_commit_ID, info);
10168 * We broke out of the log scan loop: either we came to the
10169 * known end of the log or we found an unexpected block in the
10170 * log. If the latter happened, then we know that the "current"
10171 * transaction marks the end of the valid log.
10174 if (pass == PASS_SCAN)
10175 info->end_transaction = next_commit_ID;
10177 /* It's really bad news if different passes end up at
10178 * different places (but possible due to IO errors). */
10179 if (info->end_transaction != next_commit_ID) {
10180 printf ("JBD: recovery pass %d ended at "
10181 "transaction %u, expected %u\n",
10182 pass, next_commit_ID, info->end_transaction);
10195 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10197 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10198 tid_t sequence, struct recovery_info *info)
10200 journal_revoke_header_t *header;
10203 header = (journal_revoke_header_t *) bh->b_data;
10204 offset = sizeof(journal_revoke_header_t);
10205 max = ntohl(header->r_count);
10207 while (offset < max) {
10208 unsigned long blocknr;
10211 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10213 err = journal_set_revoke(journal, blocknr, sequence);
10216 ++info->nr_revokes;
10223 * rehash.c --- rebuild hash tree directories
10225 * This algorithm is designed for simplicity of implementation and to
10226 * pack the directory as much as possible. It however requires twice
10227 * as much memory as the size of the directory. The maximum size
10228 * directory supported using a 4k blocksize is roughly a gigabyte, and
10229 * so there may very well be problems with machines that don't have
10230 * virtual memory, and obscenely large directories.
10232 * An alternate algorithm which is much more disk intensive could be
10233 * written, and probably will need to be written in the future. The
10234 * design goals of such an algorithm are: (a) use (roughly) constant
10235 * amounts of memory, no matter how large the directory, (b) the
10236 * directory must be safe at all times, even if e2fsck is interrupted
10237 * in the middle, (c) we must use minimal amounts of extra disk
10238 * blocks. This pretty much requires an incremental approach, where
10239 * we are reading from one part of the directory, and inserting into
10240 * the front half. So the algorithm will have to keep track of a
10241 * moving block boundary between the new tree and the old tree, and
10242 * files will need to be moved from the old directory and inserted
10243 * into the new tree. If the new directory requires space which isn't
10244 * yet available, blocks from the beginning part of the old directory
10245 * may need to be moved to the end of the directory to make room for
10248 * --------------------------------------------------------
10249 * | new tree | | old tree |
10250 * --------------------------------------------------------
10252 * tail new head old
10254 * This is going to be a pain in the tuckus to implement, and will
10255 * require a lot more disk accesses. So I'm going to skip it for now;
10256 * it's only really going to be an issue for really, really big
10257 * filesystems (when we reach the level of tens of millions of files
10258 * in a single directory). It will probably be easier to simply
10259 * require that e2fsck use VM first.
10262 struct fill_dir_struct {
10264 struct ext2_inode *inode;
10267 struct hash_entry *harray;
10268 int max_array, num_array;
10274 struct hash_entry {
10275 ext2_dirhash_t hash;
10276 ext2_dirhash_t minor_hash;
10277 struct ext2_dir_entry *dir;
10284 ext2_dirhash_t *hashes;
10287 static int fill_dir_block(ext2_filsys fs,
10289 e2_blkcnt_t blockcnt,
10290 blk_t ref_block FSCK_ATTR((unused)),
10291 int ref_offset FSCK_ATTR((unused)),
10294 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10295 struct hash_entry *new_array, *ent;
10296 struct ext2_dir_entry *dirent;
10298 unsigned int offset, dir_offset;
10303 offset = blockcnt * fs->blocksize;
10304 if (offset + fs->blocksize > fd->inode->i_size) {
10305 fd->err = EXT2_ET_DIR_CORRUPTED;
10306 return BLOCK_ABORT;
10308 dir = (fd->buf+offset);
10309 if (HOLE_BLKADDR(*block_nr)) {
10310 memset(dir, 0, fs->blocksize);
10311 dirent = (struct ext2_dir_entry *) dir;
10312 dirent->rec_len = fs->blocksize;
10314 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10316 return BLOCK_ABORT;
10318 /* While the directory block is "hot", index it. */
10320 while (dir_offset < fs->blocksize) {
10321 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10322 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10323 (dirent->rec_len < 8) ||
10324 ((dirent->rec_len % 4) != 0) ||
10325 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10326 fd->err = EXT2_ET_DIR_CORRUPTED;
10327 return BLOCK_ABORT;
10329 dir_offset += dirent->rec_len;
10330 if (dirent->inode == 0)
10332 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10333 (dirent->name[0] == '.'))
10335 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10336 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10337 fd->parent = dirent->inode;
10340 if (fd->num_array >= fd->max_array) {
10341 new_array = realloc(fd->harray,
10342 sizeof(struct hash_entry) * (fd->max_array+500));
10345 return BLOCK_ABORT;
10347 fd->harray = new_array;
10348 fd->max_array += 500;
10350 ent = fd->harray + fd->num_array++;
10352 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10354 ent->hash = ent->minor_hash = 0;
10356 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10358 dirent->name_len & 0xFF,
10359 fs->super->s_hash_seed,
10360 &ent->hash, &ent->minor_hash);
10362 return BLOCK_ABORT;
10369 /* Used for sorting the hash entry */
10370 static int name_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;
10377 min_len = he_a->dir->name_len;
10378 if (min_len > he_b->dir->name_len)
10379 min_len = he_b->dir->name_len;
10381 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10383 if (he_a->dir->name_len > he_b->dir->name_len)
10385 else if (he_a->dir->name_len < he_b->dir->name_len)
10388 ret = he_b->dir->inode - he_a->dir->inode;
10393 /* Used for sorting the hash entry */
10394 static int hash_cmp(const void *a, const void *b)
10396 const struct hash_entry *he_a = (const struct hash_entry *) a;
10397 const struct hash_entry *he_b = (const struct hash_entry *) b;
10400 if (he_a->hash > he_b->hash)
10402 else if (he_a->hash < he_b->hash)
10405 if (he_a->minor_hash > he_b->minor_hash)
10407 else if (he_a->minor_hash < he_b->minor_hash)
10410 ret = name_cmp(a, b);
10415 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10421 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10424 outdir->buf = new_mem;
10425 new_mem = realloc(outdir->hashes,
10426 blocks * sizeof(ext2_dirhash_t));
10429 outdir->hashes = new_mem;
10431 outdir->buf = malloc(blocks * fs->blocksize);
10432 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10435 outdir->max = blocks;
10439 static void free_out_dir(struct out_dir *outdir)
10442 free(outdir->hashes);
10447 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10452 if (outdir->num >= outdir->max) {
10453 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10457 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10458 memset(*ret, 0, fs->blocksize);
10463 * This function is used to make a unique filename. We do this by
10464 * appending ~0, and then incrementing the number. However, we cannot
10465 * expand the length of the filename beyond the padding available in
10466 * the directory entry.
10468 static void mutate_name(char *str, __u16 *len)
10471 __u16 l = *len & 0xFF, h = *len & 0xff00;
10474 * First check to see if it looks the name has been mutated
10477 for (i = l-1; i > 0; i--) {
10478 if (!isdigit(str[i]))
10481 if ((i == l-1) || (str[i] != '~')) {
10482 if (((l-1) & 3) < 2)
10491 for (i = l-1; i >= 0; i--) {
10492 if (isdigit(str[i])) {
10504 else if (str[0] == 'Z') {
10509 } else if (i > 0) {
10522 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10524 struct fill_dir_struct *fd)
10526 struct problem_context pctx;
10527 struct hash_entry *ent, *prev;
10530 char new_name[256];
10533 clear_problem_context(&pctx);
10536 for (i=1; i < fd->num_array; i++) {
10537 ent = fd->harray + i;
10539 if (!ent->dir->inode ||
10540 ((ent->dir->name_len & 0xFF) !=
10541 (prev->dir->name_len & 0xFF)) ||
10542 (strncmp(ent->dir->name, prev->dir->name,
10543 ent->dir->name_len & 0xFF)))
10545 pctx.dirent = ent->dir;
10546 if ((ent->dir->inode == prev->dir->inode) &&
10547 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10548 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10549 ent->dir->inode = 0;
10553 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10554 new_len = ent->dir->name_len;
10555 mutate_name(new_name, &new_len);
10556 for (j=0; j < fd->num_array; j++) {
10558 ((ent->dir->name_len & 0xFF) !=
10559 (fd->harray[j].dir->name_len & 0xFF)) ||
10560 (strncmp(new_name, fd->harray[j].dir->name,
10563 mutate_name(new_name, &new_len);
10567 new_name[new_len & 0xFF] = 0;
10568 pctx.str = new_name;
10569 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10570 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10571 ent->dir->name_len = new_len;
10572 ext2fs_dirhash(fs->super->s_def_hash_version,
10574 ent->dir->name_len & 0xFF,
10575 fs->super->s_hash_seed,
10576 &ent->hash, &ent->minor_hash);
10584 static errcode_t copy_dir_entries(ext2_filsys fs,
10585 struct fill_dir_struct *fd,
10586 struct out_dir *outdir)
10590 struct hash_entry *ent;
10591 struct ext2_dir_entry *dirent;
10592 int i, rec_len, left;
10593 ext2_dirhash_t prev_hash;
10597 retval = alloc_size_dir(fs, outdir,
10598 (fd->dir_size / fs->blocksize) + 2);
10601 outdir->num = fd->compress ? 0 : 1;
10603 outdir->hashes[0] = 0;
10605 if ((retval = get_next_block(fs, outdir, &block_start)))
10607 dirent = (struct ext2_dir_entry *) block_start;
10608 left = fs->blocksize;
10609 for (i=0; i < fd->num_array; i++) {
10610 ent = fd->harray + i;
10611 if (ent->dir->inode == 0)
10613 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10614 if (rec_len > left) {
10616 dirent->rec_len += left;
10617 if ((retval = get_next_block(fs, outdir,
10622 left = fs->blocksize - offset;
10623 dirent = (struct ext2_dir_entry *) (block_start + offset);
10625 if (ent->hash == prev_hash)
10626 outdir->hashes[outdir->num-1] = ent->hash | 1;
10628 outdir->hashes[outdir->num-1] = ent->hash;
10630 dirent->inode = ent->dir->inode;
10631 dirent->name_len = ent->dir->name_len;
10632 dirent->rec_len = rec_len;
10633 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10637 dirent->rec_len += left;
10641 prev_hash = ent->hash;
10644 dirent->rec_len += left;
10650 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10651 ext2_ino_t ino, ext2_ino_t parent)
10653 struct ext2_dir_entry *dir;
10654 struct ext2_dx_root_info *root;
10655 struct ext2_dx_countlimit *limits;
10658 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10659 filetype = EXT2_FT_DIR << 8;
10661 memset(buf, 0, fs->blocksize);
10662 dir = (struct ext2_dir_entry *) buf;
10664 dir->name[0] = '.';
10665 dir->name_len = 1 | filetype;
10667 dir = (struct ext2_dir_entry *) (buf + 12);
10668 dir->inode = parent;
10669 dir->name[0] = '.';
10670 dir->name[1] = '.';
10671 dir->name_len = 2 | filetype;
10672 dir->rec_len = fs->blocksize - 12;
10674 root = (struct ext2_dx_root_info *) (buf+24);
10675 root->reserved_zero = 0;
10676 root->hash_version = fs->super->s_def_hash_version;
10677 root->info_length = 8;
10678 root->indirect_levels = 0;
10679 root->unused_flags = 0;
10681 limits = (struct ext2_dx_countlimit *) (buf+32);
10682 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10689 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10691 struct ext2_dir_entry *dir;
10692 struct ext2_dx_countlimit *limits;
10694 memset(buf, 0, fs->blocksize);
10695 dir = (struct ext2_dir_entry *) buf;
10697 dir->rec_len = fs->blocksize;
10699 limits = (struct ext2_dx_countlimit *) (buf+8);
10700 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10703 return (struct ext2_dx_entry *) limits;
10707 * This function takes the leaf nodes which have been written in
10708 * outdir, and populates the root node and any necessary interior nodes.
10710 static errcode_t calculate_tree(ext2_filsys fs,
10711 struct out_dir *outdir,
10715 struct ext2_dx_root_info *root_info;
10716 struct ext2_dx_entry *root, *dx_ent = 0;
10717 struct ext2_dx_countlimit *root_limit, *limit;
10719 char * block_start;
10720 int i, c1, c2, nblks;
10721 int limit_offset, root_offset;
10723 root_info = set_root_node(fs, outdir->buf, ino, parent);
10724 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10725 root_info->info_length;
10726 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10727 c1 = root_limit->limit;
10728 nblks = outdir->num;
10730 /* Write out the pointer blocks */
10731 if (nblks-1 <= c1) {
10732 /* Just write out the root block, and we're done */
10733 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10734 for (i=1; i < nblks; i++) {
10735 root->block = ext2fs_cpu_to_le32(i);
10738 ext2fs_cpu_to_le32(outdir->hashes[i]);
10745 root_info->indirect_levels = 1;
10746 for (i=1; i < nblks; i++) {
10751 limit->limit = limit->count =
10752 ext2fs_cpu_to_le16(limit->limit);
10753 root = (struct ext2_dx_entry *)
10754 (outdir->buf + root_offset);
10755 root->block = ext2fs_cpu_to_le32(outdir->num);
10758 ext2fs_cpu_to_le32(outdir->hashes[i]);
10759 if ((retval = get_next_block(fs, outdir,
10762 dx_ent = set_int_node(fs, block_start);
10763 limit = (struct ext2_dx_countlimit *) dx_ent;
10765 root_offset += sizeof(struct ext2_dx_entry);
10768 dx_ent->block = ext2fs_cpu_to_le32(i);
10769 if (c2 != limit->limit)
10771 ext2fs_cpu_to_le32(outdir->hashes[i]);
10775 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10776 limit->limit = ext2fs_cpu_to_le16(limit->limit);
10778 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10779 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10780 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10785 struct write_dir_struct {
10786 struct out_dir *outdir;
10793 * Helper function which writes out a directory block.
10795 static int write_dir_block(ext2_filsys fs,
10797 e2_blkcnt_t blockcnt,
10798 blk_t ref_block FSCK_ATTR((unused)),
10799 int ref_offset FSCK_ATTR((unused)),
10802 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10806 if (*block_nr == 0)
10808 if (blockcnt >= wd->outdir->num) {
10809 e2fsck_read_bitmaps(wd->ctx);
10811 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10812 ext2fs_block_alloc_stats(fs, blk, -1);
10815 return BLOCK_CHANGED;
10820 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10821 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10823 return BLOCK_ABORT;
10827 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10828 struct out_dir *outdir,
10829 ext2_ino_t ino, int compress)
10831 struct write_dir_struct wd;
10833 struct ext2_inode inode;
10835 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10839 wd.outdir = outdir;
10844 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10845 write_dir_block, &wd);
10851 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10853 inode.i_flags &= ~EXT2_INDEX_FL;
10855 inode.i_flags |= EXT2_INDEX_FL;
10856 inode.i_size = outdir->num * fs->blocksize;
10857 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10858 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10863 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10865 ext2_filsys fs = ctx->fs;
10867 struct ext2_inode inode;
10869 struct fill_dir_struct fd;
10870 struct out_dir outdir;
10872 outdir.max = outdir.num = 0;
10875 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10879 dir_buf = malloc(inode.i_size);
10883 fd.max_array = inode.i_size / 32;
10885 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
10895 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10896 (inode.i_size / fs->blocksize) < 2)
10900 /* Read in the entire directory into memory */
10901 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10902 fill_dir_block, &fd);
10908 /* Sort the list */
10911 qsort(fd.harray+2, fd.num_array-2,
10912 sizeof(struct hash_entry), name_cmp);
10914 qsort(fd.harray, fd.num_array,
10915 sizeof(struct hash_entry), hash_cmp);
10918 * Look for duplicates
10920 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10923 if (ctx->options & E2F_OPT_NO) {
10929 * Copy the directory entries. In a htree directory these
10930 * will become the leaf nodes.
10932 retval = copy_dir_entries(fs, &fd, &outdir);
10936 free(dir_buf); dir_buf = 0;
10938 if (!fd.compress) {
10939 /* Calculate the interior nodes */
10940 retval = calculate_tree(fs, &outdir, ino, fd.parent);
10945 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10951 free_out_dir(&outdir);
10955 void e2fsck_rehash_directories(e2fsck_t ctx)
10957 struct problem_context pctx;
10958 struct dir_info *dir;
10959 ext2_u32_iterate iter;
10962 int i, cur, max, all_dirs, dir_index, first = 1;
10964 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10966 if (!ctx->dirs_to_hash && !all_dirs)
10969 e2fsck_get_lost_and_found(ctx, 0);
10971 clear_problem_context(&pctx);
10973 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10977 max = e2fsck_get_num_dirinfo(ctx);
10979 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10982 pctx.errcode = retval;
10983 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10986 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10990 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10994 if (!ext2fs_u32_list_iterate(iter, &ino))
10997 if (ino == ctx->lost_and_found)
11001 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
11004 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
11005 if (pctx.errcode) {
11006 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11007 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
11009 if (ctx->progress && !ctx->progress_fd)
11010 e2fsck_simple_progress(ctx, "Rebuilding directory",
11011 100.0 * (float) (++cur) / (float) max, ino);
11013 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11015 ext2fs_u32_list_iterate_end(iter);
11017 ext2fs_u32_list_free(ctx->dirs_to_hash);
11018 ctx->dirs_to_hash = 0;
11022 * linux/fs/revoke.c
11024 * Journal revoke routines for the generic filesystem journaling code;
11025 * part of the ext2fs journaling system.
11027 * Revoke is the mechanism used to prevent old log records for deleted
11028 * metadata from being replayed on top of newer data using the same
11029 * blocks. The revoke mechanism is used in two separate places:
11031 * + Commit: during commit we write the entire list of the current
11032 * transaction's revoked blocks to the journal
11034 * + Recovery: during recovery we record the transaction ID of all
11035 * revoked blocks. If there are multiple revoke records in the log
11036 * for a single block, only the last one counts, and if there is a log
11037 * entry for a block beyond the last revoke, then that log entry still
11040 * We can get interactions between revokes and new log data within a
11041 * single transaction:
11043 * Block is revoked and then journaled:
11044 * The desired end result is the journaling of the new block, so we
11045 * cancel the revoke before the transaction commits.
11047 * Block is journaled and then revoked:
11048 * The revoke must take precedence over the write of the block, so we
11049 * need either to cancel the journal entry or to write the revoke
11050 * later in the log than the log block. In this case, we choose the
11051 * latter: journaling a block cancels any revoke record for that block
11052 * in the current transaction, so any revoke for that block in the
11053 * transaction must have happened after the block was journaled and so
11054 * the revoke must take precedence.
11056 * Block is revoked and then written as data:
11057 * The data write is allowed to succeed, but the revoke is _not_
11058 * cancelled. We still need to prevent old log records from
11059 * overwriting the new data. We don't even need to clear the revoke
11062 * Revoke information on buffers is a tri-state value:
11064 * RevokeValid clear: no cached revoke status, need to look it up
11065 * RevokeValid set, Revoked clear:
11066 * buffer has not been revoked, and cancel_revoke
11068 * RevokeValid set, Revoked set:
11069 * buffer has been revoked.
11072 static kmem_cache_t *revoke_record_cache;
11073 static kmem_cache_t *revoke_table_cache;
11075 /* Each revoke record represents one single revoked block. During
11076 journal replay, this involves recording the transaction ID of the
11077 last transaction to revoke this block. */
11079 struct jbd_revoke_record_s
11081 struct list_head hash;
11082 tid_t sequence; /* Used for recovery only */
11083 unsigned long blocknr;
11087 /* The revoke table is just a simple hash table of revoke records. */
11088 struct jbd_revoke_table_s
11090 /* It is conceivable that we might want a larger hash table
11091 * for recovery. Must be a power of two. */
11094 struct list_head *hash_table;
11098 /* Utility functions to maintain the revoke table */
11100 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11101 static inline int hash(journal_t *journal, unsigned long block)
11103 struct jbd_revoke_table_s *table = journal->j_revoke;
11104 int hash_shift = table->hash_shift;
11106 return ((block << (hash_shift - 6)) ^
11108 (block << (hash_shift - 12))) & (table->hash_size - 1);
11111 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11114 struct list_head *hash_list;
11115 struct jbd_revoke_record_s *record;
11117 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11121 record->sequence = seq;
11122 record->blocknr = blocknr;
11123 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11124 list_add(&record->hash, hash_list);
11131 /* Find a revoke record in the journal's hash table. */
11133 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11134 unsigned long blocknr)
11136 struct list_head *hash_list;
11137 struct jbd_revoke_record_s *record;
11139 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11141 record = (struct jbd_revoke_record_s *) hash_list->next;
11142 while (&(record->hash) != hash_list) {
11143 if (record->blocknr == blocknr)
11145 record = (struct jbd_revoke_record_s *) record->hash.next;
11150 int journal_init_revoke_caches(void)
11152 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11153 if (revoke_record_cache == 0)
11156 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11157 if (revoke_table_cache == 0) {
11158 do_cache_destroy(revoke_record_cache);
11159 revoke_record_cache = NULL;
11165 void journal_destroy_revoke_caches(void)
11167 do_cache_destroy(revoke_record_cache);
11168 revoke_record_cache = 0;
11169 do_cache_destroy(revoke_table_cache);
11170 revoke_table_cache = 0;
11173 /* Initialise the revoke table for a given journal to a given size. */
11175 int journal_init_revoke(journal_t *journal, int hash_size)
11179 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11180 if (!journal->j_revoke)
11183 /* Check that the hash_size is a power of two */
11184 journal->j_revoke->hash_size = hash_size;
11188 while((tmp >>= 1UL) != 0UL)
11190 journal->j_revoke->hash_shift = shift;
11192 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11193 if (!journal->j_revoke->hash_table) {
11194 free(journal->j_revoke);
11195 journal->j_revoke = NULL;
11199 for (tmp = 0; tmp < hash_size; tmp++)
11200 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11205 /* Destoy a journal's revoke table. The table must already be empty! */
11207 void journal_destroy_revoke(journal_t *journal)
11209 struct jbd_revoke_table_s *table;
11210 struct list_head *hash_list;
11213 table = journal->j_revoke;
11217 for (i=0; i<table->hash_size; i++) {
11218 hash_list = &table->hash_table[i];
11221 free(table->hash_table);
11223 journal->j_revoke = NULL;
11227 * Revoke support for recovery.
11229 * Recovery needs to be able to:
11231 * record all revoke records, including the tid of the latest instance
11232 * of each revoke in the journal
11234 * check whether a given block in a given transaction should be replayed
11235 * (ie. has not been revoked by a revoke record in that or a subsequent
11238 * empty the revoke table after recovery.
11242 * First, setting revoke records. We create a new revoke record for
11243 * every block ever revoked in the log as we scan it for recovery, and
11244 * we update the existing records if we find multiple revokes for a
11248 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11251 struct jbd_revoke_record_s *record;
11253 record = find_revoke_record(journal, blocknr);
11255 /* If we have multiple occurences, only record the
11256 * latest sequence number in the hashed record */
11257 if (tid_gt(sequence, record->sequence))
11258 record->sequence = sequence;
11261 return insert_revoke_hash(journal, blocknr, sequence);
11265 * Test revoke records. For a given block referenced in the log, has
11266 * that block been revoked? A revoke record with a given transaction
11267 * sequence number revokes all blocks in that transaction and earlier
11268 * ones, but later transactions still need replayed.
11271 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11274 struct jbd_revoke_record_s *record;
11276 record = find_revoke_record(journal, blocknr);
11279 if (tid_gt(sequence, record->sequence))
11285 * Finally, once recovery is over, we need to clear the revoke table so
11286 * that it can be reused by the running filesystem.
11289 void journal_clear_revoke(journal_t *journal)
11292 struct list_head *hash_list;
11293 struct jbd_revoke_record_s *record;
11294 struct jbd_revoke_table_s *revoke_var;
11296 revoke_var = journal->j_revoke;
11298 for (i = 0; i < revoke_var->hash_size; i++) {
11299 hash_list = &revoke_var->hash_table[i];
11300 while (!list_empty(hash_list)) {
11301 record = (struct jbd_revoke_record_s*) hash_list->next;
11302 list_del(&record->hash);
11309 * e2fsck.c - superblock checks
11312 #define MIN_CHECK 1
11313 #define MAX_CHECK 2
11315 static void check_super_value(e2fsck_t ctx, const char *descr,
11316 unsigned long value, int flags,
11317 unsigned long min_val, unsigned long max_val)
11319 struct problem_context pctx;
11321 if (((flags & MIN_CHECK) && (value < min_val)) ||
11322 ((flags & MAX_CHECK) && (value > max_val))) {
11323 clear_problem_context(&pctx);
11326 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11327 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11332 * This routine may get stubbed out in special compilations of the
11335 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11336 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11338 return (ext2fs_get_device_size(ctx->filesystem_name,
11339 EXT2_BLOCK_SIZE(ctx->fs->super),
11340 &ctx->num_blocks));
11345 * helper function to release an inode
11347 struct process_block_struct {
11350 struct problem_context *pctx;
11352 int truncate_offset;
11353 e2_blkcnt_t truncate_block;
11354 int truncated_blocks;
11359 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11360 e2_blkcnt_t blockcnt,
11361 blk_t ref_blk FSCK_ATTR((unused)),
11362 int ref_offset FSCK_ATTR((unused)),
11365 struct process_block_struct *pb;
11367 struct problem_context *pctx;
11368 blk_t blk = *block_nr;
11371 pb = (struct process_block_struct *) priv_data;
11376 pctx->blkcount = blockcnt;
11378 if (HOLE_BLKADDR(blk))
11381 if ((blk < fs->super->s_first_data_block) ||
11382 (blk >= fs->super->s_blocks_count)) {
11383 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11386 return BLOCK_ABORT;
11389 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11390 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11395 * If we are deleting an orphan, then we leave the fields alone.
11396 * If we are truncating an orphan, then update the inode fields
11397 * and clean up any partial block data.
11399 if (pb->truncating) {
11401 * We only remove indirect blocks if they are
11402 * completely empty.
11404 if (blockcnt < 0) {
11408 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11413 limit = fs->blocksize >> 2;
11414 for (i = 0, bp = (blk_t *) pb->buf;
11415 i < limit; i++, bp++)
11420 * We don't remove direct blocks until we've reached
11421 * the truncation block.
11423 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11426 * If part of the last block needs truncating, we do
11429 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11430 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11434 memset(pb->buf + pb->truncate_offset, 0,
11435 fs->blocksize - pb->truncate_offset);
11436 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11441 pb->truncated_blocks++;
11443 retval |= BLOCK_CHANGED;
11446 ext2fs_block_alloc_stats(fs, blk, -1);
11451 * This function releases an inode. Returns 1 if an inconsistency was
11452 * found. If the inode has a link count, then it is being truncated and
11455 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11456 struct ext2_inode *inode, char *block_buf,
11457 struct problem_context *pctx)
11459 struct process_block_struct pb;
11460 ext2_filsys fs = ctx->fs;
11464 if (!ext2fs_inode_has_valid_blocks(inode))
11467 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11472 if (inode->i_links_count) {
11474 pb.truncate_block = (e2_blkcnt_t)
11475 ((((long long)inode->i_size_high << 32) +
11476 inode->i_size + fs->blocksize - 1) /
11478 pb.truncate_offset = inode->i_size % fs->blocksize;
11481 pb.truncate_block = 0;
11482 pb.truncate_offset = 0;
11484 pb.truncated_blocks = 0;
11485 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11486 block_buf, release_inode_block, &pb);
11488 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11495 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11496 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11498 if (pb.truncated_blocks)
11499 inode->i_blocks -= pb.truncated_blocks *
11500 (fs->blocksize / 512);
11502 if (inode->i_file_acl) {
11503 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11504 block_buf, -1, &count);
11505 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11510 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11515 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11516 inode->i_file_acl = 0;
11522 * This function releases all of the orphan inodes. It returns 1 if
11523 * it hit some error, and 0 on success.
11525 static int release_orphan_inodes(e2fsck_t ctx)
11527 ext2_filsys fs = ctx->fs;
11528 ext2_ino_t ino, next_ino;
11529 struct ext2_inode inode;
11530 struct problem_context pctx;
11533 if ((ino = fs->super->s_last_orphan) == 0)
11537 * Win or lose, we won't be using the head of the orphan inode
11540 fs->super->s_last_orphan = 0;
11541 ext2fs_mark_super_dirty(fs);
11544 * If the filesystem contains errors, don't run the orphan
11545 * list, since the orphan list can't be trusted; and we're
11546 * going to be running a full e2fsck run anyway...
11548 if (fs->super->s_state & EXT2_ERROR_FS)
11551 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11552 (ino > fs->super->s_inodes_count)) {
11553 clear_problem_context(&pctx);
11555 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11559 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11560 "block iterate buffer");
11561 e2fsck_read_bitmaps(ctx);
11564 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11565 clear_problem_context(&pctx);
11567 pctx.inode = &inode;
11568 pctx.str = inode.i_links_count ? _("Truncating") :
11571 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11573 next_ino = inode.i_dtime;
11575 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11576 (next_ino > fs->super->s_inodes_count))) {
11577 pctx.ino = next_ino;
11578 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11582 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11585 if (!inode.i_links_count) {
11586 ext2fs_inode_alloc_stats2(fs, ino, -1,
11587 LINUX_S_ISDIR(inode.i_mode));
11588 inode.i_dtime = time(0);
11592 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11595 ext2fs_free_mem(&block_buf);
11598 ext2fs_free_mem(&block_buf);
11603 * Check the resize inode to make sure it is sane. We check both for
11604 * the case where on-line resizing is not enabled (in which case the
11605 * resize inode should be cleared) as well as the case where on-line
11606 * resizing is enabled.
11608 static void check_resize_inode(e2fsck_t ctx)
11610 ext2_filsys fs = ctx->fs;
11611 struct ext2_inode inode;
11612 struct problem_context pctx;
11613 int i, j, gdt_off, ind_off;
11614 blk_t blk, pblk, expect;
11615 __u32 *dind_buf = 0, *ind_buf;
11618 clear_problem_context(&pctx);
11621 * If the resize inode feature isn't set, then
11622 * s_reserved_gdt_blocks must be zero.
11624 if (!(fs->super->s_feature_compat &
11625 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11626 if (fs->super->s_reserved_gdt_blocks) {
11627 pctx.num = fs->super->s_reserved_gdt_blocks;
11628 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11630 fs->super->s_reserved_gdt_blocks = 0;
11631 ext2fs_mark_super_dirty(fs);
11636 /* Read the resize inode */
11637 pctx.ino = EXT2_RESIZE_INO;
11638 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11640 if (fs->super->s_feature_compat &
11641 EXT2_FEATURE_COMPAT_RESIZE_INODE)
11642 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11647 * If the resize inode feature isn't set, check to make sure
11648 * the resize inode is cleared; then we're done.
11650 if (!(fs->super->s_feature_compat &
11651 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11652 for (i=0; i < EXT2_N_BLOCKS; i++) {
11653 if (inode.i_block[i])
11656 if ((i < EXT2_N_BLOCKS) &&
11657 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11658 memset(&inode, 0, sizeof(inode));
11659 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11666 * The resize inode feature is enabled; check to make sure the
11667 * only block in use is the double indirect block
11669 blk = inode.i_block[EXT2_DIND_BLOCK];
11670 for (i=0; i < EXT2_N_BLOCKS; i++) {
11671 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11674 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11675 !(inode.i_mode & LINUX_S_IFREG) ||
11676 (blk < fs->super->s_first_data_block ||
11677 blk >= fs->super->s_blocks_count)) {
11678 resize_inode_invalid:
11679 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11680 memset(&inode, 0, sizeof(inode));
11681 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11683 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11685 if (!(ctx->options & E2F_OPT_READONLY)) {
11686 fs->super->s_state &= ~EXT2_VALID_FS;
11687 ext2fs_mark_super_dirty(fs);
11691 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11692 "resize dind buffer");
11693 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11695 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11697 goto resize_inode_invalid;
11699 gdt_off = fs->desc_blocks;
11700 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11701 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11702 i++, gdt_off++, pblk++) {
11703 gdt_off %= fs->blocksize/4;
11704 if (dind_buf[gdt_off] != pblk)
11705 goto resize_inode_invalid;
11706 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11708 goto resize_inode_invalid;
11710 for (j = 1; j < fs->group_desc_count; j++) {
11711 if (!ext2fs_bg_has_super(fs, j))
11713 expect = pblk + (j * fs->super->s_blocks_per_group);
11714 if (ind_buf[ind_off] != expect)
11715 goto resize_inode_invalid;
11721 ext2fs_free_mem(&dind_buf);
11725 static void check_super_block(e2fsck_t ctx)
11727 ext2_filsys fs = ctx->fs;
11728 blk_t first_block, last_block;
11729 struct ext2_super_block *sb = fs->super;
11730 struct ext2_group_desc *gd;
11731 blk_t blocks_per_group = fs->super->s_blocks_per_group;
11733 int inodes_per_block;
11738 struct problem_context pctx;
11739 __u32 free_blocks = 0, free_inodes = 0;
11741 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11742 ipg_max = inodes_per_block * (blocks_per_group - 4);
11743 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11744 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11745 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11746 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11747 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11749 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11750 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11751 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11752 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11753 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11754 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11756 clear_problem_context(&pctx);
11759 * Verify the super block constants...
11761 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11763 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11765 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11766 MAX_CHECK, 0, sb->s_blocks_count);
11767 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11768 MIN_CHECK | MAX_CHECK, 0,
11769 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11770 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11771 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11772 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11773 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11775 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11776 MIN_CHECK | MAX_CHECK, 8, bpg_max);
11777 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11778 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11779 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11780 MAX_CHECK, 0, sb->s_blocks_count / 2);
11781 check_super_value(ctx, "reserved_gdt_blocks",
11782 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11784 inode_size = EXT2_INODE_SIZE(sb);
11785 check_super_value(ctx, "inode_size",
11786 inode_size, MIN_CHECK | MAX_CHECK,
11787 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11788 if (inode_size & (inode_size - 1)) {
11789 pctx.num = inode_size;
11790 pctx.str = "inode_size";
11791 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11792 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11796 if (!ctx->num_blocks) {
11797 pctx.errcode = e2fsck_get_device_size(ctx);
11798 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11799 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11800 ctx->flags |= E2F_FLAG_ABORT;
11803 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11804 (ctx->num_blocks < sb->s_blocks_count)) {
11805 pctx.blk = sb->s_blocks_count;
11806 pctx.blk2 = ctx->num_blocks;
11807 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11808 ctx->flags |= E2F_FLAG_ABORT;
11814 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11815 pctx.blk = EXT2_BLOCK_SIZE(sb);
11816 pctx.blk2 = EXT2_FRAG_SIZE(sb);
11817 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11818 ctx->flags |= E2F_FLAG_ABORT;
11822 should_be = sb->s_frags_per_group >>
11823 (sb->s_log_block_size - sb->s_log_frag_size);
11824 if (sb->s_blocks_per_group != should_be) {
11825 pctx.blk = sb->s_blocks_per_group;
11826 pctx.blk2 = should_be;
11827 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11828 ctx->flags |= E2F_FLAG_ABORT;
11832 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11833 if (sb->s_first_data_block != should_be) {
11834 pctx.blk = sb->s_first_data_block;
11835 pctx.blk2 = should_be;
11836 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11837 ctx->flags |= E2F_FLAG_ABORT;
11841 should_be = sb->s_inodes_per_group * fs->group_desc_count;
11842 if (sb->s_inodes_count != should_be) {
11843 pctx.ino = sb->s_inodes_count;
11844 pctx.ino2 = should_be;
11845 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11846 sb->s_inodes_count = should_be;
11847 ext2fs_mark_super_dirty(fs);
11852 * Verify the group descriptors....
11854 first_block = sb->s_first_data_block;
11855 last_block = first_block + blocks_per_group;
11857 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11860 if (i == fs->group_desc_count - 1)
11861 last_block = sb->s_blocks_count;
11862 if ((gd->bg_block_bitmap < first_block) ||
11863 (gd->bg_block_bitmap >= last_block)) {
11864 pctx.blk = gd->bg_block_bitmap;
11865 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11866 gd->bg_block_bitmap = 0;
11868 if (gd->bg_block_bitmap == 0) {
11869 ctx->invalid_block_bitmap_flag[i]++;
11870 ctx->invalid_bitmaps++;
11872 if ((gd->bg_inode_bitmap < first_block) ||
11873 (gd->bg_inode_bitmap >= last_block)) {
11874 pctx.blk = gd->bg_inode_bitmap;
11875 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11876 gd->bg_inode_bitmap = 0;
11878 if (gd->bg_inode_bitmap == 0) {
11879 ctx->invalid_inode_bitmap_flag[i]++;
11880 ctx->invalid_bitmaps++;
11882 if ((gd->bg_inode_table < first_block) ||
11883 ((gd->bg_inode_table +
11884 fs->inode_blocks_per_group - 1) >= last_block)) {
11885 pctx.blk = gd->bg_inode_table;
11886 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11887 gd->bg_inode_table = 0;
11889 if (gd->bg_inode_table == 0) {
11890 ctx->invalid_inode_table_flag[i]++;
11891 ctx->invalid_bitmaps++;
11893 free_blocks += gd->bg_free_blocks_count;
11894 free_inodes += gd->bg_free_inodes_count;
11895 first_block += sb->s_blocks_per_group;
11896 last_block += sb->s_blocks_per_group;
11898 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11899 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11900 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11901 ext2fs_unmark_valid(fs);
11906 * Update the global counts from the block group counts. This
11907 * is needed for an experimental patch which eliminates
11908 * locking the entire filesystem when allocating blocks or
11909 * inodes; if the filesystem is not unmounted cleanly, the
11910 * global counts may not be accurate.
11912 if ((free_blocks != sb->s_free_blocks_count) ||
11913 (free_inodes != sb->s_free_inodes_count)) {
11914 if (ctx->options & E2F_OPT_READONLY)
11915 ext2fs_unmark_valid(fs);
11917 sb->s_free_blocks_count = free_blocks;
11918 sb->s_free_inodes_count = free_inodes;
11919 ext2fs_mark_super_dirty(fs);
11923 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11924 (sb->s_free_inodes_count > sb->s_inodes_count))
11925 ext2fs_unmark_valid(fs);
11929 * If we have invalid bitmaps, set the error state of the
11932 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11933 sb->s_state &= ~EXT2_VALID_FS;
11934 ext2fs_mark_super_dirty(fs);
11937 clear_problem_context(&pctx);
11940 * If the UUID field isn't assigned, assign it.
11942 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11943 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11944 uuid_generate(sb->s_uuid);
11945 ext2fs_mark_super_dirty(fs);
11946 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11950 /* FIXME - HURD support?
11951 * For the Hurd, check to see if the filetype option is set,
11952 * since it doesn't support it.
11954 if (!(ctx->options & E2F_OPT_READONLY) &&
11955 fs->super->s_creator_os == EXT2_OS_HURD &&
11956 (fs->super->s_feature_incompat &
11957 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11958 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11959 fs->super->s_feature_incompat &=
11960 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11961 ext2fs_mark_super_dirty(fs);
11967 * If we have any of the compatibility flags set, we need to have a
11968 * revision 1 filesystem. Most kernels will not check the flags on
11969 * a rev 0 filesystem and we may have corruption issues because of
11970 * the incompatible changes to the filesystem.
11972 if (!(ctx->options & E2F_OPT_READONLY) &&
11973 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11974 (fs->super->s_feature_compat ||
11975 fs->super->s_feature_ro_compat ||
11976 fs->super->s_feature_incompat) &&
11977 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11978 ext2fs_update_dynamic_rev(fs);
11979 ext2fs_mark_super_dirty(fs);
11982 check_resize_inode(ctx);
11985 * Clean up any orphan inodes, if present.
11987 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11988 fs->super->s_state &= ~EXT2_VALID_FS;
11989 ext2fs_mark_super_dirty(fs);
11993 * Move the ext3 journal file, if necessary.
11995 e2fsck_move_ext3_journal(ctx);
12000 * swapfs.c --- byte-swap an ext2 filesystem
12003 #ifdef ENABLE_SWAPFS
12005 struct swap_block_struct {
12010 struct ext2_inode *inode;
12014 * This is a helper function for block_iterate. We mark all of the
12015 * indirect and direct blocks as changed, so that block_iterate will
12018 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
12023 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
12025 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
12026 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
12028 sb->errcode = retval;
12029 return BLOCK_ABORT;
12031 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
12033 sb->errcode = retval;
12034 return BLOCK_ABORT;
12037 if (blockcnt >= 0) {
12038 if (blockcnt < EXT2_NDIR_BLOCKS)
12040 return BLOCK_CHANGED;
12042 if (blockcnt == BLOCK_COUNT_IND) {
12043 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
12045 return BLOCK_CHANGED;
12047 if (blockcnt == BLOCK_COUNT_DIND) {
12048 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12050 return BLOCK_CHANGED;
12052 if (blockcnt == BLOCK_COUNT_TIND) {
12053 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12055 return BLOCK_CHANGED;
12057 return BLOCK_CHANGED;
12061 * This function is responsible for byte-swapping all of the indirect,
12062 * block pointers. It is also responsible for byte-swapping directories.
12064 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12065 struct ext2_inode *inode)
12068 struct swap_block_struct sb;
12072 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12075 if (LINUX_S_ISDIR(inode->i_mode))
12078 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12081 bb_error_msg(_("while calling ext2fs_block_iterate"));
12082 ctx->flags |= E2F_FLAG_ABORT;
12086 bb_error_msg(_("while calling iterator function"));
12087 ctx->flags |= E2F_FLAG_ABORT;
12092 static void swap_inodes(e2fsck_t ctx)
12094 ext2_filsys fs = ctx->fs;
12097 ext2_ino_t ino = 1;
12098 char *buf, *block_buf;
12100 struct ext2_inode * inode;
12102 e2fsck_use_inode_shortcuts(ctx, 1);
12104 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12107 bb_error_msg(_("while allocating inode buffer"));
12108 ctx->flags |= E2F_FLAG_ABORT;
12111 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12112 "block interate buffer");
12113 for (group = 0; group < fs->group_desc_count; group++) {
12114 retval = io_channel_read_blk(fs->io,
12115 fs->group_desc[group].bg_inode_table,
12116 fs->inode_blocks_per_group, buf);
12118 bb_error_msg(_("while reading inode table (group %d)"),
12120 ctx->flags |= E2F_FLAG_ABORT;
12123 inode = (struct ext2_inode *) buf;
12124 for (i=0; i < fs->super->s_inodes_per_group;
12125 i++, ino++, inode++) {
12126 ctx->stashed_ino = ino;
12127 ctx->stashed_inode = inode;
12129 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12130 ext2fs_swap_inode(fs, inode, inode, 0);
12133 * Skip deleted files.
12135 if (inode->i_links_count == 0)
12138 if (LINUX_S_ISDIR(inode->i_mode) ||
12139 ((inode->i_block[EXT2_IND_BLOCK] ||
12140 inode->i_block[EXT2_DIND_BLOCK] ||
12141 inode->i_block[EXT2_TIND_BLOCK]) &&
12142 ext2fs_inode_has_valid_blocks(inode)))
12143 swap_inode_blocks(ctx, ino, block_buf, inode);
12145 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12148 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12149 ext2fs_swap_inode(fs, inode, inode, 1);
12151 retval = io_channel_write_blk(fs->io,
12152 fs->group_desc[group].bg_inode_table,
12153 fs->inode_blocks_per_group, buf);
12155 bb_error_msg(_("while writing inode table (group %d)"),
12157 ctx->flags |= E2F_FLAG_ABORT;
12161 ext2fs_free_mem(&buf);
12162 ext2fs_free_mem(&block_buf);
12163 e2fsck_use_inode_shortcuts(ctx, 0);
12164 ext2fs_flush_icache(fs);
12167 #if defined(__powerpc__) && BB_BIG_ENDIAN
12169 * On the PowerPC, the big-endian variant of the ext2 filesystem
12170 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12171 * of each word. Thus a bitmap with only bit 0 set would be, as
12172 * a string of bytes, 00 00 00 01 00 ...
12173 * To cope with this, we byte-reverse each word of a bitmap if
12174 * we have a big-endian filesystem, that is, if we are *not*
12175 * byte-swapping other word-sized numbers.
12177 #define EXT2_BIG_ENDIAN_BITMAPS
12180 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12181 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12183 __u32 *p = (__u32 *) bmap->bitmap;
12184 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12186 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12187 *p = ext2fs_swab32(*p);
12192 #ifdef ENABLE_SWAPFS
12193 static void swap_filesys(e2fsck_t ctx)
12195 ext2_filsys fs = ctx->fs;
12196 if (!(ctx->options & E2F_OPT_PREEN))
12197 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12201 if (fs->super->s_mnt_count) {
12202 fprintf(stderr, _("%s: the filesystem must be freshly "
12203 "checked using fsck\n"
12204 "and not mounted before trying to "
12205 "byte-swap it.\n"), ctx->device_name);
12206 ctx->flags |= E2F_FLAG_ABORT;
12209 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12210 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12211 EXT2_FLAG_SWAP_BYTES_WRITE);
12212 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12214 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12215 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12218 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12220 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12221 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12222 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12223 EXT2_FLAG_SWAP_BYTES_WRITE);
12225 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12226 e2fsck_read_bitmaps(ctx);
12227 ext2fs_swap_bitmap(fs->inode_map);
12228 ext2fs_swap_bitmap(fs->block_map);
12229 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12231 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12233 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12235 #endif /* ENABLE_SWAPFS */
12240 * util.c --- miscellaneous utilities
12244 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12245 const char *description)
12250 ret = malloc(size);
12252 sprintf(buf, "Can't allocate %s\n", description);
12253 bb_error_msg_and_die(buf);
12255 memset(ret, 0, size);
12259 static char *string_copy(const char *str, int len)
12267 ret = malloc(len+1);
12269 strncpy(ret, str, len);
12275 #ifndef HAVE_CONIO_H
12276 static int read_a_char(void)
12283 if (e2fsck_global_ctx &&
12284 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12287 r = read(0, &c, 1);
12297 static int ask_yn(const char * string, int def)
12300 const char *defstr;
12301 static const char short_yes[] = "yY";
12302 static const char short_no[] = "nN";
12304 #ifdef HAVE_TERMIOS_H
12305 struct termios termios, tmp;
12307 tcgetattr (0, &termios);
12309 tmp.c_lflag &= ~(ICANON | ECHO);
12310 tmp.c_cc[VMIN] = 1;
12311 tmp.c_cc[VTIME] = 0;
12312 tcsetattr (0, TCSANOW, &tmp);
12321 printf("%s%s? ", string, defstr);
12324 if ((c = read_a_char()) == EOF)
12327 #ifdef HAVE_TERMIOS_H
12328 tcsetattr (0, TCSANOW, &termios);
12330 if (e2fsck_global_ctx &&
12331 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12333 longjmp(e2fsck_global_ctx->abort_loc, 1);
12335 puts(_("cancelled!\n"));
12338 if (strchr(short_yes, (char) c)) {
12342 else if (strchr(short_no, (char) c)) {
12346 else if ((c == ' ' || c == '\n') && (def != -1))
12353 #ifdef HAVE_TERMIOS_H
12354 tcsetattr (0, TCSANOW, &termios);
12359 int ask (e2fsck_t ctx, const char * string, int def)
12361 if (ctx->options & E2F_OPT_NO) {
12362 printf (_("%s? no\n\n"), string);
12365 if (ctx->options & E2F_OPT_YES) {
12366 printf (_("%s? yes\n\n"), string);
12369 if (ctx->options & E2F_OPT_PREEN) {
12370 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
12373 return ask_yn(string, def);
12376 void e2fsck_read_bitmaps(e2fsck_t ctx)
12378 ext2_filsys fs = ctx->fs;
12381 if (ctx->invalid_bitmaps) {
12382 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12384 bb_error_msg_and_die(0);
12387 ehandler_operation(_("reading inode and block bitmaps"));
12388 retval = ext2fs_read_bitmaps(fs);
12389 ehandler_operation(0);
12391 bb_error_msg(_("while retrying to read bitmaps for %s"),
12393 bb_error_msg_and_die(0);
12397 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12399 ext2_filsys fs = ctx->fs;
12402 if (ext2fs_test_bb_dirty(fs)) {
12403 ehandler_operation(_("writing block bitmaps"));
12404 retval = ext2fs_write_block_bitmap(fs);
12405 ehandler_operation(0);
12407 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12409 bb_error_msg_and_die(0);
12413 if (ext2fs_test_ib_dirty(fs)) {
12414 ehandler_operation(_("writing inode bitmaps"));
12415 retval = ext2fs_write_inode_bitmap(fs);
12416 ehandler_operation(0);
12418 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12420 bb_error_msg_and_die(0);
12425 void preenhalt(e2fsck_t ctx)
12427 ext2_filsys fs = ctx->fs;
12429 if (!(ctx->options & E2F_OPT_PREEN))
12431 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12432 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12435 fs->super->s_state |= EXT2_ERROR_FS;
12436 ext2fs_mark_super_dirty(fs);
12439 exit(EXIT_UNCORRECTED);
12442 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12443 struct ext2_inode * inode, const char *proc)
12447 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12449 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12450 bb_error_msg_and_die(0);
12454 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12455 struct ext2_inode * inode, int bufsize,
12460 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12462 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12463 bb_error_msg_and_die(0);
12467 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12468 struct ext2_inode * inode, const char *proc)
12472 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12474 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12475 bb_error_msg_and_die(0);
12479 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12480 io_manager manager)
12482 struct ext2_super_block *sb;
12483 io_channel io = NULL;
12486 blk_t superblock, ret_sb = 8193;
12488 if (fs && fs->super) {
12489 ret_sb = (fs->super->s_blocks_per_group +
12490 fs->super->s_first_data_block);
12492 ctx->superblock = ret_sb;
12493 ctx->blocksize = fs->blocksize;
12499 if (ctx->blocksize) {
12500 ret_sb = ctx->blocksize * 8;
12501 if (ctx->blocksize == 1024)
12503 ctx->superblock = ret_sb;
12506 ctx->superblock = ret_sb;
12507 ctx->blocksize = 1024;
12510 if (!name || !manager)
12513 if (manager->open(name, 0, &io) != 0)
12516 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12518 sb = (struct ext2_super_block *) buf;
12520 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12521 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
12522 superblock = blocksize*8;
12523 if (blocksize == 1024)
12525 io_channel_set_blksize(io, blocksize);
12526 if (io_channel_read_blk(io, superblock,
12527 -SUPERBLOCK_SIZE, buf))
12530 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12531 ext2fs_swap_super(sb);
12533 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12534 ret_sb = superblock;
12536 ctx->superblock = superblock;
12537 ctx->blocksize = blocksize;
12545 io_channel_close(io);
12546 ext2fs_free_mem(&buf);
12552 * This function runs through the e2fsck passes and calls them all,
12553 * returning restart, abort, or cancel as necessary...
12555 typedef void (*pass_t)(e2fsck_t ctx);
12557 static const pass_t e2fsck_passes[] = {
12558 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12561 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12563 static int e2fsck_run(e2fsck_t ctx)
12566 pass_t e2fsck_pass;
12568 if (setjmp(ctx->abort_loc)) {
12569 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12570 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12572 ctx->flags |= E2F_FLAG_SETJMP_OK;
12574 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12575 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12579 (void) (ctx->progress)(ctx, 0, 0, 0);
12581 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12583 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12584 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12590 * unix.c - The unix-specific code for e2fsck
12594 /* Command line options */
12596 #ifdef ENABLE_SWAPFS
12597 static int normalize_swapfs;
12599 static int cflag; /* check disk */
12600 static int show_version_only;
12601 static int verbose;
12603 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12605 static void show_stats(e2fsck_t ctx)
12607 ext2_filsys fs = ctx->fs;
12608 int inodes, inodes_used, blocks, blocks_used;
12610 int num_files, num_links;
12613 dir_links = 2 * ctx->fs_directory_count - 1;
12614 num_files = ctx->fs_total_count - dir_links;
12615 num_links = ctx->fs_links_count - dir_links;
12616 inodes = fs->super->s_inodes_count;
12617 inodes_used = (fs->super->s_inodes_count -
12618 fs->super->s_free_inodes_count);
12619 blocks = fs->super->s_blocks_count;
12620 blocks_used = (fs->super->s_blocks_count -
12621 fs->super->s_free_blocks_count);
12623 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12624 frag_percent = (frag_percent + 5) / 10;
12627 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12628 ctx->device_name, inodes_used, inodes,
12629 frag_percent / 10, frag_percent % 10,
12630 blocks_used, blocks);
12633 printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12634 100 * inodes_used / inodes);
12635 printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
12636 P_E2("", "s", ctx->fs_fragmented),
12637 frag_percent / 10, frag_percent % 10);
12638 printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12639 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12640 printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12641 (int) ((long long) 100 * blocks_used / blocks));
12642 printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12643 printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12644 printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12645 printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12646 printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12647 printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12648 printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12649 printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12650 printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12651 printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12652 printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12655 static void check_mount(e2fsck_t ctx)
12660 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12661 &ctx->mount_flags);
12663 bb_error_msg(_("while determining whether %s is mounted."),
12664 ctx->filesystem_name);
12669 * If the filesystem isn't mounted, or it's the root filesystem
12670 * and it's mounted read-only, then everything's fine.
12672 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12673 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12674 (ctx->mount_flags & EXT2_MF_READONLY)))
12677 if (ctx->options & E2F_OPT_READONLY) {
12678 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
12682 printf(_("%s is mounted. "), ctx->filesystem_name);
12683 if (!ctx->interactive)
12684 bb_error_msg_and_die(_("Cannot continue, aborting.\n\n"));
12685 printf(_("\n\n\007\007\007\007WARNING!!! "
12686 "Running e2fsck on a mounted filesystem may cause\n"
12687 "SEVERE filesystem damage.\007\007\007\n\n"));
12688 cont = ask_yn(_("Do you really want to continue"), -1);
12690 printf (_("check aborted.\n"));
12696 static int is_on_batt(void)
12700 char tmp[80], tmp2[80], fname[80];
12701 unsigned int acflag;
12704 f = fopen("/proc/apm", "r");
12706 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12709 return (acflag != 1);
12711 d = opendir("/proc/acpi/ac_adapter");
12713 while ((de=readdir(d)) != NULL) {
12714 if (!strncmp(".", de->d_name, 1))
12716 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12718 f = fopen(fname, "r");
12721 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12724 if (strncmp(tmp, "off-line", 8) == 0) {
12735 * This routine checks to see if a filesystem can be skipped; if so,
12736 * it will exit with EXIT_OK. Under some conditions it will print a
12737 * message explaining why a check is being forced.
12739 static void check_if_skip(e2fsck_t ctx)
12741 ext2_filsys fs = ctx->fs;
12742 const char *reason = NULL;
12743 unsigned int reason_arg = 0;
12745 int batt = is_on_batt();
12746 time_t now = time(0);
12748 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12751 if ((fs->super->s_state & EXT2_ERROR_FS) ||
12752 !ext2fs_test_valid(fs))
12753 reason = _(" contains a file system with errors");
12754 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12755 reason = _(" was not cleanly unmounted");
12756 else if ((fs->super->s_max_mnt_count > 0) &&
12757 (fs->super->s_mnt_count >=
12758 (unsigned) fs->super->s_max_mnt_count)) {
12759 reason = _(" has been mounted %u times without being checked");
12760 reason_arg = fs->super->s_mnt_count;
12761 if (batt && (fs->super->s_mnt_count <
12762 (unsigned) fs->super->s_max_mnt_count*2))
12764 } else if (fs->super->s_checkinterval &&
12765 ((now - fs->super->s_lastcheck) >=
12766 fs->super->s_checkinterval)) {
12767 reason = _(" has gone %u days without being checked");
12768 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12769 if (batt && ((now - fs->super->s_lastcheck) <
12770 fs->super->s_checkinterval*2))
12774 fputs(ctx->device_name, stdout);
12775 printf(reason, reason_arg);
12776 fputs(_(", check forced.\n"), stdout);
12779 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12780 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12781 fs->super->s_inodes_count,
12782 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12783 fs->super->s_blocks_count);
12784 next_check = 100000;
12785 if (fs->super->s_max_mnt_count > 0) {
12786 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12787 if (next_check <= 0)
12790 if (fs->super->s_checkinterval &&
12791 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12793 if (next_check <= 5) {
12794 if (next_check == 1)
12795 fputs(_(" (check after next mount)"), stdout);
12797 printf(_(" (check in %ld mounts)"), next_check);
12799 fputc('\n', stdout);
12802 e2fsck_free_context(ctx);
12807 * For completion notice
12809 struct percent_tbl {
12813 static const struct percent_tbl e2fsck_tbl = {
12814 5, { 0, 70, 90, 92, 95, 100 }
12817 static char bar[128], spaces[128];
12819 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12826 if (pass > tbl->max_pass || max == 0)
12828 percent = ((float) curr) / ((float) max);
12829 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12830 + tbl->table[pass-1]);
12833 void e2fsck_clear_progbar(e2fsck_t ctx)
12835 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12838 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12841 ctx->flags &= ~E2F_FLAG_PROG_BAR;
12844 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12845 unsigned int dpynum)
12847 static const char spinner[] = "\\|/-";
12854 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12858 * Calculate the new progress position. If the
12859 * percentage hasn't changed, then we skip out right
12862 fixed_percent = (int) ((10 * percent) + 0.5);
12863 if (ctx->progress_last_percent == fixed_percent)
12865 ctx->progress_last_percent = fixed_percent;
12868 * If we've already updated the spinner once within
12869 * the last 1/8th of a second, no point doing it
12872 gettimeofday(&tv, NULL);
12873 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12874 if ((tick == ctx->progress_last_time) &&
12875 (fixed_percent != 0) && (fixed_percent != 1000))
12877 ctx->progress_last_time = tick;
12880 * Advance the spinner, and note that the progress bar
12881 * will be on the screen
12883 ctx->progress_pos = (ctx->progress_pos+1) & 3;
12884 ctx->flags |= E2F_FLAG_PROG_BAR;
12886 dpywidth = 66 - strlen(label);
12887 dpywidth = 8 * (dpywidth / 8);
12891 i = ((percent * dpywidth) + 50) / 100;
12892 printf("%s%s: |%s%s", ctx->start_meta, label,
12893 bar + (sizeof(bar) - (i+1)),
12894 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12895 if (fixed_percent == 1000)
12896 fputc('|', stdout);
12898 fputc(spinner[ctx->progress_pos & 3], stdout);
12899 printf(" %4.1f%% ", percent);
12901 printf("%u\r", dpynum);
12903 fputs(" \r", stdout);
12904 fputs(ctx->stop_meta, stdout);
12906 if (fixed_percent == 1000)
12907 e2fsck_clear_progbar(ctx);
12913 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12914 unsigned long cur, unsigned long max)
12922 if (ctx->progress_fd) {
12923 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12924 write(ctx->progress_fd, buf, strlen(buf));
12926 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12927 e2fsck_simple_progress(ctx, ctx->device_name,
12933 static void reserve_stdio_fds(void)
12938 fd = open(bb_dev_null, O_RDWR);
12942 fprintf(stderr, _("ERROR: Couldn't open "
12943 "/dev/null (%s)\n"),
12951 static void signal_progress_on(int sig FSCK_ATTR((unused)))
12953 e2fsck_t ctx = e2fsck_global_ctx;
12958 ctx->progress = e2fsck_update_progress;
12959 ctx->progress_fd = 0;
12962 static void signal_progress_off(int sig FSCK_ATTR((unused)))
12964 e2fsck_t ctx = e2fsck_global_ctx;
12969 e2fsck_clear_progbar(ctx);
12973 static void signal_cancel(int sig FSCK_ATTR((unused)))
12975 e2fsck_t ctx = e2fsck_global_ctx;
12978 exit(FSCK_CANCELED);
12980 ctx->flags |= E2F_FLAG_CANCEL;
12983 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12985 char *buf, *token, *next, *p, *arg;
12987 int extended_usage = 0;
12989 buf = string_copy(opts, 0);
12990 for (token = buf; token && *token; token = next) {
12991 p = strchr(token, ',');
12997 arg = strchr(token, '=');
13002 if (strcmp(token, "ea_ver") == 0) {
13007 ea_ver = strtoul(arg, &p, 0);
13009 ((ea_ver != 1) && (ea_ver != 2))) {
13011 _("Invalid EA version.\n"));
13015 ctx->ext_attr_ver = ea_ver;
13017 fprintf(stderr, _("Unknown extended option: %s\n"),
13022 if (extended_usage) {
13023 bb_error_msg_and_die(
13024 "Extended options are separated by commas, "
13025 "and may take an argument which\n"
13026 "is set off by an equals ('=') sign. "
13027 "Valid extended options are:\n"
13028 "\tea_ver=<ea_version (1 or 2)>\n\n");
13033 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
13039 struct sigaction sa;
13040 char *extended_opts = 0;
13042 retval = e2fsck_allocate_context(&ctx);
13048 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
13049 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
13050 if (isatty(0) && isatty(1)) {
13051 ctx->interactive = 1;
13053 ctx->start_meta[0] = '\001';
13054 ctx->stop_meta[0] = '\002';
13056 memset(bar, '=', sizeof(bar)-1);
13057 memset(spaces, ' ', sizeof(spaces)-1);
13058 blkid_get_cache(&ctx->blkid, NULL);
13061 ctx->program_name = *argv;
13063 ctx->program_name = "e2fsck";
13064 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13067 ctx->progress = e2fsck_update_progress;
13068 ctx->progress_fd = atoi(optarg);
13069 if (!ctx->progress_fd)
13071 /* Validate the file descriptor to avoid disasters */
13072 fd = dup(ctx->progress_fd);
13075 _("Error validating file descriptor %d: %s\n"),
13077 error_message(errno));
13078 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13083 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13086 extended_opts = optarg;
13090 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13092 bb_error_msg_and_die(_("Only one the options -p/-a, -n or -y may be specified."));
13094 ctx->options |= E2F_OPT_PREEN;
13097 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13099 ctx->options |= E2F_OPT_NO;
13102 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13104 ctx->options |= E2F_OPT_YES;
13107 /* FIXME - This needs to go away in a future path - will change binary */
13108 fprintf(stderr, _("The -t option is not "
13109 "supported on this version of e2fsck.\n"));
13113 ctx->options |= E2F_OPT_WRITECHECK;
13114 ctx->options |= E2F_OPT_CHECKBLOCKS;
13117 /* What we do by default, anyway! */
13120 ctx->use_superblock = atoi(optarg);
13121 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13124 ctx->blocksize = atoi(optarg);
13127 ctx->inode_buffer_blocks = atoi(optarg);
13130 ctx->journal_name = string_copy(optarg, 0);
13133 ctx->process_inode_size = atoi(optarg);
13136 ctx->options |= E2F_OPT_DEBUG;
13139 ctx->options |= E2F_OPT_FORCE;
13148 show_version_only = 1;
13151 ctx->device_name = optarg;
13153 #ifdef ENABLE_SWAPFS
13155 normalize_swapfs = 1;
13162 fprintf(stderr, _("Byte-swapping filesystems "
13163 "not compiled in this version "
13170 if (show_version_only)
13172 if (optind != argc - 1)
13174 if ((ctx->options & E2F_OPT_NO) &&
13175 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13176 ctx->options |= E2F_OPT_READONLY;
13177 ctx->io_options = strchr(argv[optind], '?');
13178 if (ctx->io_options)
13179 *ctx->io_options++ = 0;
13180 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13181 if (!ctx->filesystem_name) {
13182 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13183 bb_error_msg_and_die(0);
13186 parse_extended_opts(ctx, extended_opts);
13189 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13191 bb_error_msg(_("while opening %s for flushing"),
13192 ctx->filesystem_name);
13193 bb_error_msg_and_die(0);
13195 if ((retval = ext2fs_sync_device(fd, 1))) {
13196 bb_error_msg(_("while trying to flush %s"),
13197 ctx->filesystem_name);
13198 bb_error_msg_and_die(0);
13202 #ifdef ENABLE_SWAPFS
13203 if (swapfs && cflag) {
13204 fprintf(stderr, _("Incompatible options not "
13205 "allowed when byte-swapping.\n"));
13210 * Set up signal action
13212 memset(&sa, 0, sizeof(struct sigaction));
13213 sa.sa_handler = signal_cancel;
13214 sigaction(SIGINT, &sa, 0);
13215 sigaction(SIGTERM, &sa, 0);
13217 sa.sa_flags = SA_RESTART;
13219 e2fsck_global_ctx = ctx;
13220 sa.sa_handler = signal_progress_on;
13221 sigaction(SIGUSR1, &sa, 0);
13222 sa.sa_handler = signal_progress_off;
13223 sigaction(SIGUSR2, &sa, 0);
13225 /* Update our PATH to include /sbin if we need to run badblocks */
13227 e2fs_set_sbin_path();
13231 static const char my_ver_string[] = E2FSPROGS_VERSION;
13232 static const char my_ver_date[] = E2FSPROGS_DATE;
13234 int e2fsck_main (int argc, char *argv[])
13237 int exit_value = EXIT_OK;
13238 ext2_filsys fs = 0;
13240 struct ext2_super_block *sb;
13241 const char *lib_ver_date;
13242 int my_ver, lib_ver;
13244 struct problem_context pctx;
13245 int flags, run_result;
13247 clear_problem_context(&pctx);
13249 my_ver = ext2fs_parse_version_string(my_ver_string);
13250 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13251 if (my_ver > lib_ver) {
13252 fprintf( stderr, _("Error: ext2fs library version "
13253 "out of date!\n"));
13254 show_version_only++;
13257 retval = PRS(argc, argv, &ctx);
13259 bb_error_msg(_("while trying to initialize program"));
13262 reserve_stdio_fds();
13264 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13265 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13268 if (show_version_only) {
13269 fprintf(stderr, _("\tUsing %s, %s\n"),
13270 error_message(EXT2_ET_BASE), lib_ver_date);
13276 if (!(ctx->options & E2F_OPT_PREEN) &&
13277 !(ctx->options & E2F_OPT_NO) &&
13278 !(ctx->options & E2F_OPT_YES)) {
13279 if (!ctx->interactive)
13280 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13282 ctx->superblock = ctx->use_superblock;
13284 #ifdef CONFIG_TESTIO_DEBUG
13285 io_ptr = test_io_manager;
13286 test_io_backing_manager = unix_io_manager;
13288 io_ptr = unix_io_manager;
13291 if ((ctx->options & E2F_OPT_READONLY) == 0)
13292 flags |= EXT2_FLAG_RW;
13294 if (ctx->superblock && ctx->blocksize) {
13295 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13296 flags, ctx->superblock, ctx->blocksize,
13298 } else if (ctx->superblock) {
13300 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13301 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13302 retval = ext2fs_open2(ctx->filesystem_name,
13303 ctx->io_options, flags,
13304 ctx->superblock, blocksize,
13310 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13311 flags, 0, 0, io_ptr, &fs);
13312 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13313 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13314 ((retval == EXT2_ET_BAD_MAGIC) ||
13315 ((retval == 0) && ext2fs_check_desc(fs)))) {
13316 if (!fs || (fs->group_desc_count > 1)) {
13317 printf(_("%s trying backup blocks...\n"),
13318 retval ? _("Couldn't find ext2 superblock,") :
13319 _("Group descriptors look bad..."));
13320 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13327 bb_error_msg(_("while trying to open %s"),
13328 ctx->filesystem_name);
13329 if (retval == EXT2_ET_REV_TOO_HIGH) {
13330 printf(_("The filesystem revision is apparently "
13331 "too high for this version of e2fsck.\n"
13332 "(Or the filesystem superblock "
13333 "is corrupt)\n\n"));
13334 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13335 } else if (retval == EXT2_ET_SHORT_READ)
13336 printf(_("Could this be a zero-length partition?\n"));
13337 else if ((retval == EPERM) || (retval == EACCES))
13338 printf(_("You must have %s access to the "
13339 "filesystem or be root\n"),
13340 (ctx->options & E2F_OPT_READONLY) ?
13342 else if (retval == ENXIO)
13343 printf(_("Possibly non-existent or swap device?\n"));
13345 else if (retval == EROFS)
13346 printf(_("Disk write-protected; use the -n option "
13347 "to do a read-only\n"
13348 "check of the device.\n"));
13351 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13352 bb_error_msg_and_die(0);
13355 fs->priv_data = ctx;
13357 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13358 bb_error_msg(_("while trying to open %s"),
13359 ctx->filesystem_name);
13361 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13365 * Set the device name, which is used whenever we print error
13366 * or informational messages to the user.
13368 if (ctx->device_name == 0 &&
13369 (sb->s_volume_name[0] != 0)) {
13370 ctx->device_name = string_copy(sb->s_volume_name,
13371 sizeof(sb->s_volume_name));
13373 if (ctx->device_name == 0)
13374 ctx->device_name = ctx->filesystem_name;
13377 * Make sure the ext3 superblock fields are consistent.
13379 retval = e2fsck_check_ext3_journal(ctx);
13381 bb_error_msg(_("while checking ext3 journal for %s"),
13383 bb_error_msg_and_die(0);
13387 * Check to see if we need to do ext3-style recovery. If so,
13388 * do it, and then restart the fsck.
13390 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13391 if (ctx->options & E2F_OPT_READONLY) {
13392 printf(_("Warning: skipping journal recovery "
13393 "because doing a read-only filesystem "
13395 io_channel_flush(ctx->fs->io);
13397 if (ctx->flags & E2F_FLAG_RESTARTED) {
13399 * Whoops, we attempted to run the
13400 * journal twice. This should never
13401 * happen, unless the hardware or
13402 * device driver is being bogus.
13404 bb_error_msg(_("unable to set superblock flags on %s\n"), ctx->device_name);
13405 bb_error_msg_and_die(0);
13407 retval = e2fsck_run_ext3_journal(ctx);
13409 bb_error_msg(_("while recovering ext3 journal of %s"),
13411 bb_error_msg_and_die(0);
13413 ext2fs_close(ctx->fs);
13415 ctx->flags |= E2F_FLAG_RESTARTED;
13421 * Check for compatibility with the feature sets. We need to
13422 * be more stringent than ext2fs_open().
13424 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13425 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13426 bb_error_msg("(%s)", ctx->device_name);
13429 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13430 bb_error_msg("(%s)", ctx->device_name);
13433 #ifdef ENABLE_COMPRESSION
13434 /* FIXME - do we support this at all? */
13435 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13436 bb_error_msg(_("Warning: compression support is experimental.\n"));
13438 #ifndef ENABLE_HTREE
13439 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13440 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13441 "but filesystem %s has HTREE directories.\n"),
13448 * If the user specified a specific superblock, presumably the
13449 * master superblock has been trashed. So we mark the
13450 * superblock as dirty, so it can be written out.
13452 if (ctx->superblock &&
13453 !(ctx->options & E2F_OPT_READONLY))
13454 ext2fs_mark_super_dirty(fs);
13457 * We only update the master superblock because (a) paranoia;
13458 * we don't want to corrupt the backup superblocks, and (b) we
13459 * don't need to update the mount count and last checked
13460 * fields in the backup superblock (the kernel doesn't
13461 * update the backup superblocks anyway).
13463 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13465 ehandler_init(fs->io);
13467 if (ctx->superblock)
13468 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13469 ext2fs_mark_valid(fs);
13470 check_super_block(ctx);
13471 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13472 bb_error_msg_and_die(0);
13473 check_if_skip(ctx);
13474 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13475 bb_error_msg_and_die(0);
13476 #ifdef ENABLE_SWAPFS
13478 #ifdef WORDS_BIGENDIAN
13479 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13481 #define NATIVE_FLAG 0
13485 if (normalize_swapfs) {
13486 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13487 fprintf(stderr, _("%s: Filesystem byte order "
13488 "already normalized.\n"), ctx->device_name);
13489 bb_error_msg_and_die(0);
13494 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13495 bb_error_msg_and_die(0);
13500 * Mark the system as valid, 'til proven otherwise
13502 ext2fs_mark_valid(fs);
13504 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13506 bb_error_msg(_("while reading bad blocks inode"));
13508 printf(_("This doesn't bode well,"
13509 " but we'll try to go on...\n"));
13512 run_result = e2fsck_run(ctx);
13513 e2fsck_clear_progbar(ctx);
13514 if (run_result == E2F_FLAG_RESTART) {
13515 printf(_("Restarting e2fsck from the beginning...\n"));
13516 retval = e2fsck_reset_context(ctx);
13518 bb_error_msg(_("while resetting context"));
13519 bb_error_msg_and_die(0);
13524 if (run_result & E2F_FLAG_CANCEL) {
13525 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13526 ctx->device_name : ctx->filesystem_name);
13527 exit_value |= FSCK_CANCELED;
13529 if (run_result & E2F_FLAG_ABORT)
13530 bb_error_msg_and_die(_("aborted"));
13533 if (ext2fs_test_changed(fs)) {
13534 exit_value |= EXIT_NONDESTRUCT;
13535 if (!(ctx->options & E2F_OPT_PREEN))
13536 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13538 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13539 printf(_("%s: ***** REBOOT LINUX *****\n"),
13541 exit_value |= EXIT_DESTRUCT;
13544 if (!ext2fs_test_valid(fs)) {
13545 printf(_("\n%s: ********** WARNING: Filesystem still has "
13546 "errors **********\n\n"), ctx->device_name);
13547 exit_value |= EXIT_UNCORRECTED;
13548 exit_value &= ~EXIT_NONDESTRUCT;
13550 if (exit_value & FSCK_CANCELED)
13551 exit_value &= ~EXIT_NONDESTRUCT;
13554 if (!(ctx->options & E2F_OPT_READONLY)) {
13555 if (ext2fs_test_valid(fs)) {
13556 if (!(sb->s_state & EXT2_VALID_FS))
13557 exit_value |= EXIT_NONDESTRUCT;
13558 sb->s_state = EXT2_VALID_FS;
13560 sb->s_state &= ~EXT2_VALID_FS;
13561 sb->s_mnt_count = 0;
13562 sb->s_lastcheck = time(NULL);
13563 ext2fs_mark_super_dirty(fs);
13567 e2fsck_write_bitmaps(ctx);
13571 free(ctx->filesystem_name);
13572 free(ctx->journal_name);
13573 e2fsck_free_context(ctx);