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*/
43 * Procedure declarations
46 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
49 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
52 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
53 ext2_ino_t ino, char *buf);
56 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
57 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
58 int num, int gauranteed_size);
59 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
60 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
64 static void e2fsck_rehash_directories(e2fsck_t ctx);
67 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
68 const char *description);
69 static int ask(e2fsck_t ctx, const char * string, int def);
70 static void e2fsck_read_bitmaps(e2fsck_t ctx);
71 static void preenhalt(e2fsck_t ctx);
72 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
73 struct ext2_inode * inode, const char * proc);
74 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
75 struct ext2_inode * inode, const char * proc);
76 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
77 const char *name, io_manager manager);
80 static void e2fsck_clear_progbar(e2fsck_t ctx);
81 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
82 float percent, unsigned int dpynum);
86 * problem.h --- e2fsck problem error codes
89 typedef __u32 problem_t;
91 struct problem_context {
93 ext2_ino_t ino, ino2, dir;
94 struct ext2_inode *inode;
95 struct ext2_dir_entry *dirent;
105 * Function declarations
107 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
108 static int end_problem_latch(e2fsck_t ctx, int mask);
109 static int set_latch_flags(int mask, int setflags, int clearflags);
110 static void clear_problem_context(struct problem_context *ctx);
113 * Dictionary Abstract Data Type
114 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
116 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
124 * Blurb for inclusion into C++ translation units
127 typedef unsigned long dictcount_t;
128 #define DICTCOUNT_T_MAX ULONG_MAX
131 * The dictionary is implemented as a red-black tree
134 typedef enum { dnode_red, dnode_black } dnode_color_t;
136 typedef struct dnode_t {
137 struct dnode_t *dict_left;
138 struct dnode_t *dict_right;
139 struct dnode_t *dict_parent;
140 dnode_color_t dict_color;
141 const void *dict_key;
145 typedef int (*dict_comp_t)(const void *, const void *);
146 typedef void (*dnode_free_t)(dnode_t *);
148 typedef struct dict_t {
149 dnode_t dict_nilnode;
150 dictcount_t dict_nodecount;
151 dictcount_t dict_maxcount;
152 dict_comp_t dict_compare;
153 dnode_free_t dict_freenode;
157 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
159 typedef struct dict_load_t {
160 dict_t *dict_dictptr;
161 dnode_t dict_nilnode;
164 #define dict_count(D) ((D)->dict_nodecount)
165 #define dnode_get(N) ((N)->dict_data)
166 #define dnode_getkey(N) ((N)->dict_key)
171 * Compatibility header file for e2fsck which should be included
172 * instead of linux/jfs.h
174 * Copyright (C) 2000 Stephen C. Tweedie
178 * Pull in the definition of the e2fsck context structure
194 #define K_DEV_JOURNAL 2
196 #define lock_buffer(bh) do {} while(0)
197 #define unlock_buffer(bh) do {} while(0)
198 #define buffer_req(bh) 1
199 #define do_readahead(journal, start) do {} while(0)
201 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
207 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
210 * We use the standard libext2fs portability tricks for inline
214 static kmem_cache_t * do_cache_create(int len)
216 kmem_cache_t *new_cache;
218 new_cache = malloc(sizeof(*new_cache));
220 new_cache->object_length = len;
224 static void do_cache_destroy(kmem_cache_t *cache)
231 * Dictionary Abstract Data Type
236 * These macros provide short convenient names for structure members,
237 * which are embellished with dict_ prefixes so that they are
238 * properly confined to the documented namespace. It's legal for a
239 * program which uses dict to define, for instance, a macro called ``parent''.
240 * Such a macro would interfere with the dnode_t struct definition.
241 * In general, highly portable and reusable C modules which expose their
242 * structures need to confine structure member names to well-defined spaces.
243 * The resulting identifiers aren't necessarily convenient to use, nor
244 * readable, in the implementation, however!
247 #define left dict_left
248 #define right dict_right
249 #define parent dict_parent
250 #define color dict_color
252 #define data dict_data
254 #define nilnode dict_nilnode
255 #define maxcount dict_maxcount
256 #define compare dict_compare
257 #define dupes dict_dupes
259 #define dict_root(D) ((D)->nilnode.left)
260 #define dict_nil(D) (&(D)->nilnode)
262 static void dnode_free(dnode_t *node);
265 * Perform a ``left rotation'' adjustment on the tree. The given node P and
266 * its right child C are rearranged so that the P instead becomes the left
267 * child of C. The left subtree of C is inherited as the new right subtree
268 * for P. The ordering of the keys within the tree is thus preserved.
271 static void rotate_left(dnode_t *upper)
273 dnode_t *lower, *lowleft, *upparent;
275 lower = upper->right;
276 upper->right = lowleft = lower->left;
277 lowleft->parent = upper;
279 lower->parent = upparent = upper->parent;
281 /* don't need to check for root node here because root->parent is
282 the sentinel nil node, and root->parent->left points back to root */
284 if (upper == upparent->left) {
285 upparent->left = lower;
287 assert (upper == upparent->right);
288 upparent->right = lower;
292 upper->parent = lower;
296 * This operation is the ``mirror'' image of rotate_left. It is
297 * the same procedure, but with left and right interchanged.
300 static void rotate_right(dnode_t *upper)
302 dnode_t *lower, *lowright, *upparent;
305 upper->left = lowright = lower->right;
306 lowright->parent = upper;
308 lower->parent = upparent = upper->parent;
310 if (upper == upparent->right) {
311 upparent->right = lower;
313 assert (upper == upparent->left);
314 upparent->left = lower;
317 lower->right = upper;
318 upper->parent = lower;
322 * Do a postorder traversal of the tree rooted at the specified
323 * node and free everything under it. Used by dict_free().
326 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
330 free_nodes(dict, node->left, nil);
331 free_nodes(dict, node->right, nil);
332 dict->dict_freenode(node);
336 * Verify that the tree contains the given node. This is done by
337 * traversing all of the nodes and comparing their pointers to the
338 * given pointer. Returns 1 if the node is found, otherwise
339 * returns zero. It is intended for debugging purposes.
342 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
346 || verify_dict_has_node(nil, root->left, node)
347 || verify_dict_has_node(nil, root->right, node);
354 * Select a different set of node allocator routines.
357 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
359 assert (dict_count(dict) == 0);
360 dict->dict_freenode = fr;
364 * Free all the nodes in the dictionary by using the dictionary's
365 * installed free routine. The dictionary is emptied.
368 static void dict_free_nodes(dict_t *dict)
370 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
371 free_nodes(dict, root, nil);
372 dict->dict_nodecount = 0;
373 dict->nilnode.left = &dict->nilnode;
374 dict->nilnode.right = &dict->nilnode;
378 * Initialize a user-supplied dictionary object.
381 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
383 dict->compare = comp;
384 dict->dict_freenode = dnode_free;
385 dict->dict_nodecount = 0;
386 dict->maxcount = maxcount;
387 dict->nilnode.left = &dict->nilnode;
388 dict->nilnode.right = &dict->nilnode;
389 dict->nilnode.parent = &dict->nilnode;
390 dict->nilnode.color = dnode_black;
396 * Locate a node in the dictionary having the given key.
397 * If the node is not found, a null a pointer is returned (rather than
398 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
399 * located node is returned.
402 static dnode_t *dict_lookup(dict_t *dict, const void *key)
404 dnode_t *root = dict_root(dict);
405 dnode_t *nil = dict_nil(dict);
409 /* simple binary search adapted for trees that contain duplicate keys */
411 while (root != nil) {
412 result = dict->compare(key, root->key);
418 if (!dict->dupes) { /* no duplicates, return match */
420 } else { /* could be dupes, find leftmost one */
424 while (root != nil && dict->compare(key, root->key))
426 } while (root != nil);
436 * Insert a node into the dictionary. The node should have been
437 * initialized with a data field. All other fields are ignored.
438 * The behavior is undefined if the user attempts to insert into
439 * a dictionary that is already full (for which the dict_isfull()
440 * function returns true).
443 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
445 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
446 dnode_t *parent = nil, *uncle, *grandpa;
451 /* basic binary tree insert */
453 while (where != nil) {
455 result = dict->compare(key, where->key);
456 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
457 assert (dict->dupes || result != 0);
461 where = where->right;
464 assert (where == nil);
469 parent->right = node;
471 node->parent = parent;
475 dict->dict_nodecount++;
477 /* red black adjustments */
479 node->color = dnode_red;
481 while (parent->color == dnode_red) {
482 grandpa = parent->parent;
483 if (parent == grandpa->left) {
484 uncle = grandpa->right;
485 if (uncle->color == dnode_red) { /* red parent, red uncle */
486 parent->color = dnode_black;
487 uncle->color = dnode_black;
488 grandpa->color = dnode_red;
490 parent = grandpa->parent;
491 } else { /* red parent, black uncle */
492 if (node == parent->right) {
495 assert (grandpa == parent->parent);
496 /* rotation between parent and child preserves grandpa */
498 parent->color = dnode_black;
499 grandpa->color = dnode_red;
500 rotate_right(grandpa);
503 } else { /* symmetric cases: parent == parent->parent->right */
504 uncle = grandpa->left;
505 if (uncle->color == dnode_red) {
506 parent->color = dnode_black;
507 uncle->color = dnode_black;
508 grandpa->color = dnode_red;
510 parent = grandpa->parent;
512 if (node == parent->left) {
513 rotate_right(parent);
515 assert (grandpa == parent->parent);
517 parent->color = dnode_black;
518 grandpa->color = dnode_red;
519 rotate_left(grandpa);
525 dict_root(dict)->color = dnode_black;
530 * Allocate a node using the dictionary's allocator routine, give it
534 static dnode_t *dnode_init(dnode_t *dnode, void *data)
537 dnode->parent = NULL;
543 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
545 dnode_t *node = malloc(sizeof(dnode_t));
548 dnode_init(node, data);
549 dict_insert(dict, node, key);
556 * Return the node with the lowest (leftmost) key. If the dictionary is empty
557 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
560 static dnode_t *dict_first(dict_t *dict)
562 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
565 while ((left = root->left) != nil)
568 return (root == nil) ? NULL : root;
572 * Return the given node's successor node---the node which has the
573 * next key in the the left to right ordering. If the node has
574 * no successor, a null pointer is returned rather than a pointer to
578 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
580 dnode_t *nil = dict_nil(dict), *parent, *left;
582 if (curr->right != nil) {
584 while ((left = curr->left) != nil)
589 parent = curr->parent;
591 while (parent != nil && curr == parent->right) {
593 parent = curr->parent;
596 return (parent == nil) ? NULL : parent;
600 static void dnode_free(dnode_t *node)
620 * dirinfo.c --- maintains the directory information table for e2fsck.
624 * This subroutine is called during pass1 to create a directory info
625 * entry. During pass1, the passed-in parent is 0; it will get filled
628 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
630 struct dir_info *dir;
634 unsigned long old_size;
636 if (!ctx->dir_info) {
637 ctx->dir_info_count = 0;
638 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
640 num_dirs = 1024; /* Guess */
641 ctx->dir_info_size = num_dirs + 10;
642 ctx->dir_info = (struct dir_info *)
643 e2fsck_allocate_memory(ctx, ctx->dir_info_size
644 * sizeof (struct dir_info),
648 if (ctx->dir_info_count >= ctx->dir_info_size) {
649 old_size = ctx->dir_info_size * sizeof(struct dir_info);
650 ctx->dir_info_size += 10;
651 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
652 sizeof(struct dir_info),
655 ctx->dir_info_size -= 10;
661 * Normally, add_dir_info is called with each inode in
662 * sequential order; but once in a while (like when pass 3
663 * needs to recreate the root directory or lost+found
664 * directory) it is called out of order. In those cases, we
665 * need to move the dir_info entries down to make room, since
666 * the dir_info array needs to be sorted by inode number for
667 * get_dir_info()'s sake.
669 if (ctx->dir_info_count &&
670 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
671 for (i = ctx->dir_info_count-1; i > 0; i--)
672 if (ctx->dir_info[i-1].ino < ino)
674 dir = &ctx->dir_info[i];
676 for (j = ctx->dir_info_count++; j > i; j--)
677 ctx->dir_info[j] = ctx->dir_info[j-1];
679 dir = &ctx->dir_info[ctx->dir_info_count++];
682 dir->dotdot = parent;
683 dir->parent = parent;
687 * get_dir_info() --- given an inode number, try to find the directory
688 * information entry for it.
690 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
695 high = ctx->dir_info_count-1;
698 if (ino == ctx->dir_info[low].ino)
699 return &ctx->dir_info[low];
700 if (ino == ctx->dir_info[high].ino)
701 return &ctx->dir_info[high];
705 if (mid == low || mid == high)
707 if (ino == ctx->dir_info[mid].ino)
708 return &ctx->dir_info[mid];
709 if (ino < ctx->dir_info[mid].ino)
718 * Free the dir_info structure when it isn't needed any more.
720 static void e2fsck_free_dir_info(e2fsck_t ctx)
722 ext2fs_free_mem(&ctx->dir_info);
723 ctx->dir_info_size = 0;
724 ctx->dir_info_count = 0;
728 * Return the count of number of directories in the dir_info structure
730 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
732 return ctx->dir_info_count;
736 * A simple interator function
738 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
740 if (*control >= ctx->dir_info_count)
743 return(ctx->dir_info + (*control)++);
747 * dirinfo.c --- maintains the directory information table for e2fsck.
754 * This subroutine is called during pass1 to create a directory info
755 * entry. During pass1, the passed-in parent is 0; it will get filled
758 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
760 struct dx_dir_info *dir;
763 unsigned long old_size;
765 if (!ctx->dx_dir_info) {
766 ctx->dx_dir_info_count = 0;
767 ctx->dx_dir_info_size = 100; /* Guess */
768 ctx->dx_dir_info = (struct dx_dir_info *)
769 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
770 * sizeof (struct dx_dir_info),
774 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
775 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
776 ctx->dx_dir_info_size += 10;
777 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
778 sizeof(struct dx_dir_info),
781 ctx->dx_dir_info_size -= 10;
787 * Normally, add_dx_dir_info is called with each inode in
788 * sequential order; but once in a while (like when pass 3
789 * needs to recreate the root directory or lost+found
790 * directory) it is called out of order. In those cases, we
791 * need to move the dx_dir_info entries down to make room, since
792 * the dx_dir_info array needs to be sorted by inode number for
793 * get_dx_dir_info()'s sake.
795 if (ctx->dx_dir_info_count &&
796 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
797 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
798 if (ctx->dx_dir_info[i-1].ino < ino)
800 dir = &ctx->dx_dir_info[i];
802 for (j = ctx->dx_dir_info_count++; j > i; j--)
803 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
805 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
808 dir->numblocks = num_blocks;
809 dir->hashversion = 0;
810 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
811 * sizeof (struct dx_dirblock_info),
812 "dx_block info array");
817 * get_dx_dir_info() --- given an inode number, try to find the directory
818 * information entry for it.
820 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
825 high = ctx->dx_dir_info_count-1;
826 if (!ctx->dx_dir_info)
828 if (ino == ctx->dx_dir_info[low].ino)
829 return &ctx->dx_dir_info[low];
830 if (ino == ctx->dx_dir_info[high].ino)
831 return &ctx->dx_dir_info[high];
835 if (mid == low || mid == high)
837 if (ino == ctx->dx_dir_info[mid].ino)
838 return &ctx->dx_dir_info[mid];
839 if (ino < ctx->dx_dir_info[mid].ino)
848 * Free the dx_dir_info structure when it isn't needed any more.
850 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
853 struct dx_dir_info *dir;
855 if (ctx->dx_dir_info) {
856 dir = ctx->dx_dir_info;
857 for (i=0; i < ctx->dx_dir_info_count; i++) {
858 ext2fs_free_mem(&dir->dx_block);
860 ext2fs_free_mem(&ctx->dx_dir_info);
862 ctx->dx_dir_info_size = 0;
863 ctx->dx_dir_info_count = 0;
867 * A simple interator function
869 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
871 if (*control >= ctx->dx_dir_info_count)
874 return(ctx->dx_dir_info + (*control)++);
877 #endif /* ENABLE_HTREE */
879 * e2fsck.c - a consistency checker for the new extended file system.
884 * This function allocates an e2fsck context
886 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
891 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
895 memset(context, 0, sizeof(struct e2fsck_struct));
897 context->process_inode_size = 256;
898 context->ext_attr_ver = 2;
904 struct ea_refcount_el {
913 struct ea_refcount_el *list;
916 static void ea_refcount_free(ext2_refcount_t refcount)
921 ext2fs_free_mem(&refcount->list);
922 ext2fs_free_mem(&refcount);
926 * This function resets an e2fsck context; it is called when e2fsck
927 * needs to be restarted.
929 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
932 ctx->lost_and_found = 0;
933 ctx->bad_lost_and_found = 0;
934 ext2fs_free_inode_bitmap(ctx->inode_used_map);
935 ctx->inode_used_map = 0;
936 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
937 ctx->inode_dir_map = 0;
938 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
939 ctx->inode_reg_map = 0;
940 ext2fs_free_block_bitmap(ctx->block_found_map);
941 ctx->block_found_map = 0;
942 ext2fs_free_icount(ctx->inode_link_info);
943 ctx->inode_link_info = 0;
944 if (ctx->journal_io) {
945 if (ctx->fs && ctx->fs->io != ctx->journal_io)
946 io_channel_close(ctx->journal_io);
950 ext2fs_free_dblist(ctx->fs->dblist);
953 e2fsck_free_dir_info(ctx);
955 e2fsck_free_dx_dir_info(ctx);
957 ea_refcount_free(ctx->refcount);
959 ea_refcount_free(ctx->refcount_extra);
960 ctx->refcount_extra = 0;
961 ext2fs_free_block_bitmap(ctx->block_dup_map);
962 ctx->block_dup_map = 0;
963 ext2fs_free_block_bitmap(ctx->block_ea_map);
964 ctx->block_ea_map = 0;
965 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
966 ctx->inode_bad_map = 0;
967 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
968 ctx->inode_imagic_map = 0;
969 ext2fs_u32_list_free(ctx->dirs_to_hash);
970 ctx->dirs_to_hash = 0;
973 * Clear the array of invalid meta-data flags
975 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
976 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
977 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
979 /* Clear statistic counters */
980 ctx->fs_directory_count = 0;
981 ctx->fs_regular_count = 0;
982 ctx->fs_blockdev_count = 0;
983 ctx->fs_chardev_count = 0;
984 ctx->fs_links_count = 0;
985 ctx->fs_symlinks_count = 0;
986 ctx->fs_fast_symlinks_count = 0;
987 ctx->fs_fifo_count = 0;
988 ctx->fs_total_count = 0;
989 ctx->fs_sockets_count = 0;
990 ctx->fs_ind_count = 0;
991 ctx->fs_dind_count = 0;
992 ctx->fs_tind_count = 0;
993 ctx->fs_fragmented = 0;
994 ctx->large_files = 0;
996 /* Reset the superblock to the user's requested value */
997 ctx->superblock = ctx->use_superblock;
1002 static void e2fsck_free_context(e2fsck_t ctx)
1007 e2fsck_reset_context(ctx);
1009 blkid_put_cache(ctx->blkid);
1011 ext2fs_free_mem(&ctx);
1019 * The strategy we use for keeping track of EA refcounts is as
1020 * follows. We keep a sorted array of first EA blocks and its
1021 * reference counts. Once the refcount has dropped to zero, it is
1022 * removed from the array to save memory space. Once the EA block is
1023 * checked, its bit is set in the block_ea_map bitmap.
1027 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
1029 ext2_refcount_t refcount;
1033 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
1036 memset(refcount, 0, sizeof(struct ea_refcount));
1040 refcount->size = size;
1041 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
1043 printf("Refcount allocated %d entries, %d bytes.\n",
1044 refcount->size, bytes);
1046 retval = ext2fs_get_mem(bytes, &refcount->list);
1049 memset(refcount->list, 0, bytes);
1051 refcount->count = 0;
1052 refcount->cursor = 0;
1058 ea_refcount_free(refcount);
1063 * collapse_refcount() --- go through the refcount array, and get rid
1064 * of any count == zero entries
1066 static void refcount_collapse(ext2_refcount_t refcount)
1069 struct ea_refcount_el *list;
1071 list = refcount->list;
1072 for (i = 0, j = 0; i < refcount->count; i++) {
1073 if (list[i].ea_count) {
1079 #if defined(DEBUG) || defined(TEST_PROGRAM)
1080 printf("Refcount_collapse: size was %d, now %d\n",
1081 refcount->count, j);
1083 refcount->count = j;
1088 * insert_refcount_el() --- Insert a new entry into the sorted list at a
1089 * specified position.
1091 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
1094 struct ea_refcount_el *el;
1099 if (refcount->count >= refcount->size) {
1100 new_size = refcount->size + 100;
1102 printf("Reallocating refcount %d entries...\n", new_size);
1104 retval = ext2fs_resize_mem((size_t) refcount->size *
1105 sizeof(struct ea_refcount_el),
1107 sizeof(struct ea_refcount_el),
1111 refcount->size = new_size;
1113 num = (int) refcount->count - pos;
1115 return 0; /* should never happen */
1117 memmove(&refcount->list[pos+1], &refcount->list[pos],
1118 sizeof(struct ea_refcount_el) * num);
1121 el = &refcount->list[pos];
1129 * get_refcount_el() --- given an block number, try to find refcount
1130 * information in the sorted list. If the create flag is set,
1131 * and we can't find an entry, create one in the sorted list.
1133 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
1134 blk_t blk, int create)
1138 blk_t lowval, highval;
1140 if (!refcount || !refcount->list)
1144 high = (int) refcount->count-1;
1145 if (create && ((refcount->count == 0) ||
1146 (blk > refcount->list[high].ea_blk))) {
1147 if (refcount->count >= refcount->size)
1148 refcount_collapse(refcount);
1150 return insert_refcount_el(refcount, blk,
1151 (unsigned) refcount->count);
1153 if (refcount->count == 0)
1156 if (refcount->cursor >= refcount->count)
1157 refcount->cursor = 0;
1158 if (blk == refcount->list[refcount->cursor].ea_blk)
1159 return &refcount->list[refcount->cursor++];
1161 printf("Non-cursor get_refcount_el: %u\n", blk);
1163 while (low <= high) {
1167 /* Interpolate for efficiency */
1168 lowval = refcount->list[low].ea_blk;
1169 highval = refcount->list[high].ea_blk;
1173 else if (blk > highval)
1176 range = ((float) (blk - lowval)) /
1178 mid = low + ((int) (range * (high-low)));
1181 if (blk == refcount->list[mid].ea_blk) {
1182 refcount->cursor = mid+1;
1183 return &refcount->list[mid];
1185 if (blk < refcount->list[mid].ea_blk)
1191 * If we need to create a new entry, it should be right at
1192 * low (where high will be left at low-1).
1195 if (refcount->count >= refcount->size) {
1196 refcount_collapse(refcount);
1197 if (refcount->count < refcount->size)
1200 return insert_refcount_el(refcount, blk, low);
1206 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
1208 struct ea_refcount_el *el;
1210 el = get_refcount_el(refcount, blk, 1);
1212 return EXT2_ET_NO_MEMORY;
1216 *ret = el->ea_count;
1221 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
1223 struct ea_refcount_el *el;
1225 el = get_refcount_el(refcount, blk, 0);
1226 if (!el || el->ea_count == 0)
1227 return EXT2_ET_INVALID_ARGUMENT;
1232 *ret = el->ea_count;
1237 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
1239 struct ea_refcount_el *el;
1242 * Get the refcount element
1244 el = get_refcount_el(refcount, blk, count ? 1 : 0);
1246 return count ? EXT2_ET_NO_MEMORY : 0;
1247 el->ea_count = count;
1251 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
1253 refcount->cursor = 0;
1257 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
1259 struct ea_refcount_el *list;
1262 if (refcount->cursor >= refcount->count)
1264 list = refcount->list;
1265 if (list[refcount->cursor].ea_count) {
1267 *ret = list[refcount->cursor].ea_count;
1268 return list[refcount->cursor++].ea_blk;
1276 * ehandler.c --- handle bad block errors which come up during the
1277 * course of an e2fsck session.
1281 static const char *operation;
1284 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
1285 void *data, size_t size FSCK_ATTR((unused)),
1286 int actual FSCK_ATTR((unused)), errcode_t error)
1290 ext2_filsys fs = (ext2_filsys) channel->app_data;
1293 ctx = (e2fsck_t) fs->priv_data;
1296 * If more than one block was read, try reading each block
1297 * separately. We could use the actual bytes read to figure
1298 * out where to start, but we don't bother.
1302 for (i=0; i < count; i++, p += channel->block_size, block++) {
1303 error = io_channel_read_blk(channel, block,
1311 printf(_("Error reading block %lu (%s) while %s. "), block,
1312 error_message(error), operation);
1314 printf(_("Error reading block %lu (%s). "), block,
1315 error_message(error));
1317 if (ask(ctx, _("Ignore error"), 1)) {
1318 if (ask(ctx, _("Force rewrite"), 1))
1319 io_channel_write_blk(channel, block, 1, data);
1327 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
1328 const void *data, size_t size FSCK_ATTR((unused)),
1329 int actual FSCK_ATTR((unused)), errcode_t error)
1333 ext2_filsys fs = (ext2_filsys) channel->app_data;
1336 ctx = (e2fsck_t) fs->priv_data;
1339 * If more than one block was written, try writing each block
1340 * separately. We could use the actual bytes read to figure
1341 * out where to start, but we don't bother.
1344 p = (const char *) data;
1345 for (i=0; i < count; i++, p += channel->block_size, block++) {
1346 error = io_channel_write_blk(channel, block,
1355 printf(_("Error writing block %lu (%s) while %s. "), block,
1356 error_message(error), operation);
1358 printf(_("Error writing block %lu (%s). "), block,
1359 error_message(error));
1361 if (ask(ctx, _("Ignore error"), 1))
1367 static inline const char *ehandler_operation(const char *op)
1369 const char *ret = operation;
1375 static void ehandler_init(io_channel channel)
1377 channel->read_error = e2fsck_handle_read_error;
1378 channel->write_error = e2fsck_handle_write_error;
1382 * journal.c --- code for handling the "ext3" journal
1384 * Copyright (C) 2000 Andreas Dilger
1385 * Copyright (C) 2000 Theodore Ts'o
1387 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
1388 * Copyright (C) 1999 Red Hat Software
1390 * This file may be redistributed under the terms of the
1391 * GNU General Public License version 2 or at your discretion
1392 * any later version.
1396 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
1397 * This creates a larger static binary, and a smaller binary using
1398 * shared libraries. It's also probably slightly less CPU-efficient,
1399 * which is why it's not on by default. But, it's a good way of
1400 * testing the functions in inode_io.c and fileio.c.
1404 /* Kernel compatibility functions for handling the journal. These allow us
1405 * to use the recovery.c file virtually unchanged from the kernel, so we
1406 * don't have to do much to keep kernel and user recovery in sync.
1408 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
1414 struct inode *inode = journal->j_inode;
1423 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
1424 &inode->i_ext2, NULL, 0, block, &pblk);
1430 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
1432 struct buffer_head *bh;
1434 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
1438 bh->b_ctx = kdev->k_ctx;
1439 if (kdev->k_dev == K_DEV_FS)
1440 bh->b_io = kdev->k_ctx->fs->io;
1442 bh->b_io = kdev->k_ctx->journal_io;
1443 bh->b_size = blocksize;
1444 bh->b_blocknr = blocknr;
1449 static void sync_blockdev(kdev_t kdev)
1453 if (kdev->k_dev == K_DEV_FS)
1454 io = kdev->k_ctx->fs->io;
1456 io = kdev->k_ctx->journal_io;
1458 io_channel_flush(io);
1461 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
1464 struct buffer_head *bh;
1466 for (; nr > 0; --nr) {
1468 if (rw == READ && !bh->b_uptodate) {
1469 retval = io_channel_read_blk(bh->b_io,
1473 bb_error_msg("while reading block %lu\n",
1474 (unsigned long) bh->b_blocknr);
1479 } else if (rw == WRITE && bh->b_dirty) {
1480 retval = io_channel_write_blk(bh->b_io,
1484 bb_error_msg("while writing block %lu\n",
1485 (unsigned long) bh->b_blocknr);
1495 static inline void mark_buffer_dirty(struct buffer_head *bh)
1500 static inline void mark_buffer_clean(struct buffer_head * bh)
1505 static void brelse(struct buffer_head *bh)
1508 ll_rw_block(WRITE, 1, &bh);
1509 ext2fs_free_mem(&bh);
1512 static inline int buffer_uptodate(struct buffer_head *bh)
1514 return bh->b_uptodate;
1517 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
1519 bh->b_uptodate = val;
1522 static void wait_on_buffer(struct buffer_head *bh)
1524 if (!bh->b_uptodate)
1525 ll_rw_block(READ, 1, &bh);
1529 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
1531 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
1533 /* if we had an error doing journal recovery, we need a full fsck */
1535 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
1536 ext2fs_mark_super_dirty(ctx->fs);
1539 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
1541 struct ext2_super_block *sb = ctx->fs->super;
1542 struct ext2_super_block jsuper;
1543 struct problem_context pctx;
1544 struct buffer_head *bh;
1545 struct inode *j_inode = NULL;
1546 struct kdev_s *dev_fs = NULL, *dev_journal;
1547 const char *journal_name = 0;
1548 journal_t *journal = NULL;
1549 errcode_t retval = 0;
1550 io_manager io_ptr = 0;
1551 unsigned long start = 0;
1553 int ext_journal = 0;
1554 int tried_backup_jnl = 0;
1557 clear_problem_context(&pctx);
1559 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
1561 return EXT2_ET_NO_MEMORY;
1564 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
1566 retval = EXT2_ET_NO_MEMORY;
1569 dev_journal = dev_fs+1;
1571 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
1572 dev_fs->k_dev = K_DEV_FS;
1573 dev_journal->k_dev = K_DEV_JOURNAL;
1575 journal->j_dev = dev_journal;
1576 journal->j_fs_dev = dev_fs;
1577 journal->j_inode = NULL;
1578 journal->j_blocksize = ctx->fs->blocksize;
1580 if (uuid_is_null(sb->s_journal_uuid)) {
1581 if (!sb->s_journal_inum)
1582 return EXT2_ET_BAD_INODE_NUM;
1583 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
1586 retval = EXT2_ET_NO_MEMORY;
1590 j_inode->i_ctx = ctx;
1591 j_inode->i_ino = sb->s_journal_inum;
1593 if ((retval = ext2fs_read_inode(ctx->fs,
1595 &j_inode->i_ext2))) {
1597 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
1600 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
1601 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
1603 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
1604 j_inode->i_ext2.i_links_count = 1;
1605 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
1608 if (!j_inode->i_ext2.i_links_count ||
1609 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
1610 retval = EXT2_ET_NO_JOURNAL;
1611 goto try_backup_journal;
1613 if (j_inode->i_ext2.i_size / journal->j_blocksize <
1614 JFS_MIN_JOURNAL_BLOCKS) {
1615 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1616 goto try_backup_journal;
1618 for (i=0; i < EXT2_N_BLOCKS; i++) {
1619 blk = j_inode->i_ext2.i_block[i];
1621 if (i < EXT2_NDIR_BLOCKS) {
1622 retval = EXT2_ET_JOURNAL_TOO_SMALL;
1623 goto try_backup_journal;
1627 if (blk < sb->s_first_data_block ||
1628 blk >= sb->s_blocks_count) {
1629 retval = EXT2_ET_BAD_BLOCK_NUM;
1630 goto try_backup_journal;
1633 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
1636 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
1642 io_ptr = inode_io_manager;
1644 journal->j_inode = j_inode;
1645 ctx->journal_io = ctx->fs->io;
1646 if ((retval = journal_bmap(journal, 0, &start)) != 0)
1651 if (!ctx->journal_name) {
1654 uuid_unparse(sb->s_journal_uuid, uuid);
1655 ctx->journal_name = blkid_get_devname(ctx->blkid,
1657 if (!ctx->journal_name)
1658 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
1660 journal_name = ctx->journal_name;
1662 if (!journal_name) {
1663 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
1664 return EXT2_ET_LOAD_EXT_JOURNAL;
1667 io_ptr = unix_io_manager;
1670 #ifndef USE_INODE_IO
1673 retval = io_ptr->open(journal_name, IO_FLAG_RW,
1678 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
1681 if (ctx->fs->blocksize == 1024)
1683 bh = getblk(dev_journal, start, ctx->fs->blocksize);
1685 retval = EXT2_ET_NO_MEMORY;
1688 ll_rw_block(READ, 1, &bh);
1689 if ((retval = bh->b_err) != 0)
1691 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
1695 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
1696 ext2fs_swap_super(&jsuper);
1698 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
1699 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
1700 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
1701 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1704 /* Make sure the journal UUID is correct */
1705 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
1706 sizeof(jsuper.s_uuid))) {
1707 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
1708 retval = EXT2_ET_LOAD_EXT_JOURNAL;
1712 journal->j_maxlen = jsuper.s_blocks_count;
1716 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
1717 retval = EXT2_ET_NO_MEMORY;
1721 journal->j_sb_buffer = bh;
1722 journal->j_superblock = (journal_superblock_t *)bh->b_data;
1725 ext2fs_free_mem(&j_inode);
1728 *ret_journal = journal;
1732 ext2fs_free_mem(&dev_fs);
1733 ext2fs_free_mem(&j_inode);
1734 ext2fs_free_mem(&journal);
1739 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
1740 struct problem_context *pctx)
1742 struct ext2_super_block *sb = ctx->fs->super;
1743 int recover = ctx->fs->super->s_feature_incompat &
1744 EXT3_FEATURE_INCOMPAT_RECOVER;
1745 int has_journal = ctx->fs->super->s_feature_compat &
1746 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1748 if (has_journal || sb->s_journal_inum) {
1749 /* The journal inode is bogus, remove and force full fsck */
1750 pctx->ino = sb->s_journal_inum;
1751 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
1752 if (has_journal && sb->s_journal_inum)
1753 printf("*** ext3 journal has been deleted - "
1754 "filesystem is now ext2 only ***\n\n");
1755 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
1756 sb->s_journal_inum = 0;
1757 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
1758 e2fsck_clear_recover(ctx, 1);
1761 return EXT2_ET_BAD_INODE_NUM;
1762 } else if (recover) {
1763 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
1764 e2fsck_clear_recover(ctx, 1);
1767 return EXT2_ET_UNSUPP_FEATURE;
1772 #define V1_SB_SIZE 0x0024
1773 static void clear_v2_journal_fields(journal_t *journal)
1775 e2fsck_t ctx = journal->j_dev->k_ctx;
1776 struct problem_context pctx;
1778 clear_problem_context(&pctx);
1780 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
1783 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
1784 ctx->fs->blocksize-V1_SB_SIZE);
1785 mark_buffer_dirty(journal->j_sb_buffer);
1789 static errcode_t e2fsck_journal_load(journal_t *journal)
1791 e2fsck_t ctx = journal->j_dev->k_ctx;
1792 journal_superblock_t *jsb;
1793 struct buffer_head *jbh = journal->j_sb_buffer;
1794 struct problem_context pctx;
1796 clear_problem_context(&pctx);
1798 ll_rw_block(READ, 1, &jbh);
1800 bb_error_msg(_("reading journal superblock\n"));
1804 jsb = journal->j_superblock;
1805 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
1806 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
1807 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
1809 switch (ntohl(jsb->s_header.h_blocktype)) {
1810 case JFS_SUPERBLOCK_V1:
1811 journal->j_format_version = 1;
1812 if (jsb->s_feature_compat ||
1813 jsb->s_feature_incompat ||
1814 jsb->s_feature_ro_compat ||
1816 clear_v2_journal_fields(journal);
1819 case JFS_SUPERBLOCK_V2:
1820 journal->j_format_version = 2;
1821 if (ntohl(jsb->s_nr_users) > 1 &&
1822 uuid_is_null(ctx->fs->super->s_journal_uuid))
1823 clear_v2_journal_fields(journal);
1824 if (ntohl(jsb->s_nr_users) > 1) {
1825 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
1826 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1831 * These should never appear in a journal super block, so if
1832 * they do, the journal is badly corrupted.
1834 case JFS_DESCRIPTOR_BLOCK:
1835 case JFS_COMMIT_BLOCK:
1836 case JFS_REVOKE_BLOCK:
1837 return EXT2_ET_CORRUPT_SUPERBLOCK;
1839 /* If we don't understand the superblock major type, but there
1840 * is a magic number, then it is likely to be a new format we
1841 * just don't understand, so leave it alone. */
1843 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
1846 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
1847 return EXT2_ET_UNSUPP_FEATURE;
1849 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
1850 return EXT2_ET_RO_UNSUPP_FEATURE;
1852 /* We have now checked whether we know enough about the journal
1853 * format to be able to proceed safely, so any other checks that
1854 * fail we should attempt to recover from. */
1855 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
1856 bb_error_msg(_("%s: no valid journal superblock found\n"),
1858 return EXT2_ET_CORRUPT_SUPERBLOCK;
1861 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
1862 journal->j_maxlen = ntohl(jsb->s_maxlen);
1863 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
1864 bb_error_msg(_("%s: journal too short\n"),
1866 return EXT2_ET_CORRUPT_SUPERBLOCK;
1869 journal->j_tail_sequence = ntohl(jsb->s_sequence);
1870 journal->j_transaction_sequence = journal->j_tail_sequence;
1871 journal->j_tail = ntohl(jsb->s_start);
1872 journal->j_first = ntohl(jsb->s_first);
1873 journal->j_last = ntohl(jsb->s_maxlen);
1878 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
1889 /* Leave a valid existing V1 superblock signature alone.
1890 * Anything unrecognisable we overwrite with a new V2
1893 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
1894 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
1895 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
1896 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
1899 /* Zero out everything else beyond the superblock header */
1901 p = ((char *) jsb) + sizeof(journal_header_t);
1902 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
1904 jsb->s_blocksize = htonl(ctx->fs->blocksize);
1905 jsb->s_maxlen = htonl(journal->j_maxlen);
1906 jsb->s_first = htonl(1);
1908 /* Initialize the journal sequence number so that there is "no"
1909 * chance we will find old "valid" transactions in the journal.
1910 * This avoids the need to zero the whole journal (slow to do,
1911 * and risky when we are just recovering the filesystem).
1913 uuid_generate(u.uuid);
1914 for (i = 0; i < 4; i ++)
1915 new_seq ^= u.val[i];
1916 jsb->s_sequence = htonl(new_seq);
1918 mark_buffer_dirty(journal->j_sb_buffer);
1919 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
1922 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
1924 struct problem_context *pctx)
1926 struct ext2_super_block *sb = ctx->fs->super;
1927 int recover = ctx->fs->super->s_feature_incompat &
1928 EXT3_FEATURE_INCOMPAT_RECOVER;
1930 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
1931 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
1932 e2fsck_journal_reset_super(ctx, journal->j_superblock,
1934 journal->j_transaction_sequence = 1;
1935 e2fsck_clear_recover(ctx, recover);
1938 return EXT2_ET_CORRUPT_SUPERBLOCK;
1939 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
1940 return EXT2_ET_CORRUPT_SUPERBLOCK;
1945 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
1946 int reset, int drop)
1948 journal_superblock_t *jsb;
1951 mark_buffer_clean(journal->j_sb_buffer);
1952 else if (!(ctx->options & E2F_OPT_READONLY)) {
1953 jsb = journal->j_superblock;
1954 jsb->s_sequence = htonl(journal->j_transaction_sequence);
1956 jsb->s_start = 0; /* this marks the journal as empty */
1957 mark_buffer_dirty(journal->j_sb_buffer);
1959 brelse(journal->j_sb_buffer);
1961 if (ctx->journal_io) {
1962 if (ctx->fs && ctx->fs->io != ctx->journal_io)
1963 io_channel_close(ctx->journal_io);
1964 ctx->journal_io = 0;
1967 #ifndef USE_INODE_IO
1968 ext2fs_free_mem(&journal->j_inode);
1970 ext2fs_free_mem(&journal->j_fs_dev);
1971 ext2fs_free_mem(&journal);
1975 * This function makes sure that the superblock fields regarding the
1976 * journal are consistent.
1978 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
1980 struct ext2_super_block *sb = ctx->fs->super;
1982 int recover = ctx->fs->super->s_feature_incompat &
1983 EXT3_FEATURE_INCOMPAT_RECOVER;
1984 struct problem_context pctx;
1986 int reset = 0, force_fsck = 0;
1989 /* If we don't have any journal features, don't do anything more */
1990 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
1991 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
1992 uuid_is_null(sb->s_journal_uuid))
1995 clear_problem_context(&pctx);
1996 pctx.num = sb->s_journal_inum;
1998 retval = e2fsck_get_journal(ctx, &journal);
2000 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
2001 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
2002 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
2003 (retval == EXT2_ET_NO_JOURNAL))
2004 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
2008 retval = e2fsck_journal_load(journal);
2010 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
2011 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
2012 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
2014 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
2015 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
2017 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
2018 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
2019 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
2021 e2fsck_journal_release(ctx, journal, 0, 1);
2026 * We want to make the flags consistent here. We will not leave with
2027 * needs_recovery set but has_journal clear. We can't get in a loop
2028 * with -y, -n, or -p, only if a user isn't making up their mind.
2031 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
2032 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
2034 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
2036 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
2037 goto no_has_journal;
2039 * Need a full fsck if we are releasing a
2040 * journal stored on a reserved inode.
2042 force_fsck = recover ||
2043 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
2044 /* Clear all of the journal fields */
2045 sb->s_journal_inum = 0;
2046 sb->s_journal_dev = 0;
2047 memset(sb->s_journal_uuid, 0,
2048 sizeof(sb->s_journal_uuid));
2049 e2fsck_clear_recover(ctx, force_fsck);
2050 } else if (!(ctx->options & E2F_OPT_READONLY)) {
2051 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
2052 ext2fs_mark_super_dirty(ctx->fs);
2056 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
2057 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
2058 journal->j_superblock->s_start != 0) {
2059 /* Print status information */
2060 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
2061 if (ctx->superblock)
2062 problem = PR_0_JOURNAL_RUN_DEFAULT;
2064 problem = PR_0_JOURNAL_RUN;
2065 if (fix_problem(ctx, problem, &pctx)) {
2066 ctx->options |= E2F_OPT_FORCE;
2067 sb->s_feature_incompat |=
2068 EXT3_FEATURE_INCOMPAT_RECOVER;
2069 ext2fs_mark_super_dirty(ctx->fs);
2070 } else if (fix_problem(ctx,
2071 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
2073 sb->s_state &= ~EXT2_VALID_FS;
2074 ext2fs_mark_super_dirty(ctx->fs);
2077 * If the user answers no to the above question, we
2078 * ignore the fact that journal apparently has data;
2079 * accidentally replaying over valid data would be far
2080 * worse than skipping a questionable recovery.
2082 * XXX should we abort with a fatal error here? What
2083 * will the ext3 kernel code do if a filesystem with
2084 * !NEEDS_RECOVERY but with a non-zero
2085 * journal->j_superblock->s_start is mounted?
2089 e2fsck_journal_release(ctx, journal, reset, 0);
2093 static errcode_t recover_ext3_journal(e2fsck_t ctx)
2098 journal_init_revoke_caches();
2099 retval = e2fsck_get_journal(ctx, &journal);
2103 retval = e2fsck_journal_load(journal);
2107 retval = journal_init_revoke(journal, 1024);
2111 retval = -journal_recover(journal);
2115 if (journal->j_superblock->s_errno) {
2116 ctx->fs->super->s_state |= EXT2_ERROR_FS;
2117 ext2fs_mark_super_dirty(ctx->fs);
2118 journal->j_superblock->s_errno = 0;
2119 mark_buffer_dirty(journal->j_sb_buffer);
2123 journal_destroy_revoke(journal);
2124 journal_destroy_revoke_caches();
2125 e2fsck_journal_release(ctx, journal, 1, 0);
2129 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
2131 io_manager io_ptr = ctx->fs->io->manager;
2132 int blocksize = ctx->fs->blocksize;
2133 errcode_t retval, recover_retval;
2135 printf(_("%s: recovering journal\n"), ctx->device_name);
2136 if (ctx->options & E2F_OPT_READONLY) {
2137 printf(_("%s: won't do journal recovery while read-only\n"),
2139 return EXT2_ET_FILE_RO;
2142 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
2143 ext2fs_flush(ctx->fs); /* Force out any modifications */
2145 recover_retval = recover_ext3_journal(ctx);
2148 * Reload the filesystem context to get up-to-date data from disk
2149 * because journal recovery will change the filesystem under us.
2151 ext2fs_close(ctx->fs);
2152 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
2153 ctx->superblock, blocksize, io_ptr,
2157 bb_error_msg(_("while trying to re-open %s"),
2159 bb_error_msg_and_die(0);
2161 ctx->fs->priv_data = ctx;
2163 /* Set the superblock flags */
2164 e2fsck_clear_recover(ctx, recover_retval);
2165 return recover_retval;
2169 * This function will move the journal inode from a visible file in
2170 * the filesystem directory hierarchy to the reserved inode if necessary.
2172 static const char * const journal_names[] = {
2173 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
2175 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
2177 struct ext2_super_block *sb = ctx->fs->super;
2178 struct problem_context pctx;
2179 struct ext2_inode inode;
2180 ext2_filsys fs = ctx->fs;
2183 const char * const * cpp;
2184 int group, mount_flags;
2186 clear_problem_context(&pctx);
2189 * If the filesystem is opened read-only, or there is no
2190 * journal, then do nothing.
2192 if ((ctx->options & E2F_OPT_READONLY) ||
2193 (sb->s_journal_inum == 0) ||
2194 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
2198 * Read in the journal inode
2200 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
2204 * If it's necessary to backup the journal inode, do so.
2206 if ((sb->s_jnl_backup_type == 0) ||
2207 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
2208 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
2209 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
2210 memcpy(sb->s_jnl_blocks, inode.i_block,
2212 sb->s_jnl_blocks[16] = inode.i_size;
2213 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
2214 ext2fs_mark_super_dirty(fs);
2215 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2220 * If the journal is already the hidden inode, then do nothing
2222 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
2226 * The journal inode had better have only one link and not be readable.
2228 if (inode.i_links_count != 1)
2232 * If the filesystem is mounted, or we can't tell whether
2233 * or not it's mounted, do nothing.
2235 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
2236 if (retval || (mount_flags & EXT2_MF_MOUNTED))
2240 * If we can't find the name of the journal inode, then do
2243 for (cpp = journal_names; *cpp; cpp++) {
2244 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
2245 strlen(*cpp), 0, &ino);
2246 if ((retval == 0) && (ino == sb->s_journal_inum))
2252 /* We need the inode bitmap to be loaded */
2253 retval = ext2fs_read_bitmaps(fs);
2258 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
2262 * OK, we've done all the checks, let's actually move the
2263 * journal inode. Errors at this point mean we need to force
2264 * an ext2 filesystem check.
2266 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
2268 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
2270 sb->s_journal_inum = EXT2_JOURNAL_INO;
2271 ext2fs_mark_super_dirty(fs);
2272 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
2273 inode.i_links_count = 0;
2274 inode.i_dtime = time(0);
2275 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
2278 group = ext2fs_group_of_ino(fs, ino);
2279 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
2280 ext2fs_mark_ib_dirty(fs);
2281 fs->group_desc[group].bg_free_inodes_count++;
2282 fs->super->s_free_inodes_count++;
2286 pctx.errcode = retval;
2287 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
2288 fs->super->s_state &= ~EXT2_VALID_FS;
2289 ext2fs_mark_super_dirty(fs);
2294 * message.c --- print e2fsck messages (with compression)
2296 * print_e2fsck_message() prints a message to the user, using
2297 * compression techniques and expansions of abbreviations.
2299 * The following % expansions are supported:
2301 * %b <blk> block number
2302 * %B <blkcount> integer
2303 * %c <blk2> block number
2304 * %Di <dirent>->ino inode number
2305 * %Dn <dirent>->name string
2306 * %Dr <dirent>->rec_len
2307 * %Dl <dirent>->name_len
2308 * %Dt <dirent>->filetype
2309 * %d <dir> inode number
2310 * %g <group> integer
2311 * %i <ino> inode number
2312 * %Is <inode> -> i_size
2313 * %IS <inode> -> i_extra_isize
2314 * %Ib <inode> -> i_blocks
2315 * %Il <inode> -> i_links_count
2316 * %Im <inode> -> i_mode
2317 * %IM <inode> -> i_mtime
2318 * %IF <inode> -> i_faddr
2319 * %If <inode> -> i_file_acl
2320 * %Id <inode> -> i_dir_acl
2321 * %Iu <inode> -> i_uid
2322 * %Ig <inode> -> i_gid
2323 * %j <ino2> inode number
2324 * %m <com_err error message>
2326 * %p ext2fs_get_pathname of directory <ino>
2327 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
2328 * the containing directory. (If dirent is NULL
2329 * then return the pathname of directory <ino2>)
2330 * %q ext2fs_get_pathname of directory <dir>
2331 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
2332 * the containing directory.
2333 * %s <str> miscellaneous string
2334 * %S backup superblock
2335 * %X <num> hexadecimal format
2337 * The following '@' expansions are supported:
2339 * @a extended attribute
2340 * @A error allocating
2344 * @C conflicts with some other fs block
2348 * @E Entry '%Dn' in %p (%i)
2350 * @F for @i %i (%Q) is
2352 * @h HTREE directory inode
2358 * @m multiply-claimed
2372 * This structure defines the abbreviations used by the text strings
2373 * below. The first character in the string is the index letter. An
2374 * abbreviation of the form '@<i>' is expanded by looking up the index
2375 * letter <i> in the table below.
2377 static const char * const abbrevs[] = {
2378 N_("aextended attribute"),
2379 N_("Aerror allocating"),
2383 N_("Cconflicts with some other fs @b"),
2390 N_("E@e '%Dn' in %p (%i)"),
2392 N_("Ffor @i %i (%Q) is"),
2397 N_("mmultiply-claimed"),
2412 * Give more user friendly names to the "special" inodes.
2414 #define num_special_inodes 11
2415 static const char * const special_inode_name[] =
2417 N_("<The NULL inode>"), /* 0 */
2418 N_("<The bad blocks inode>"), /* 1 */
2420 N_("<The ACL index inode>"), /* 3 */
2421 N_("<The ACL data inode>"), /* 4 */
2422 N_("<The boot loader inode>"), /* 5 */
2423 N_("<The undelete directory inode>"), /* 6 */
2424 N_("<The group descriptor inode>"), /* 7 */
2425 N_("<The journal inode>"), /* 8 */
2426 N_("<Reserved inode 9>"), /* 9 */
2427 N_("<Reserved inode 10>"), /* 10 */
2431 * This function does "safe" printing. It will convert non-printable
2432 * ASCII characters using '^' and M- notation.
2434 static void safe_print(const char *cp, int len)
2444 fputs("M-", stdout);
2447 if ((ch < 32) || (ch == 0x7f)) {
2449 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
2457 * This function prints a pathname, using the ext2fs_get_pathname
2460 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
2465 if (!dir && (ino < num_special_inodes)) {
2466 fputs(_(special_inode_name[ino]), stdout);
2470 retval = ext2fs_get_pathname(fs, dir, ino, &path);
2472 fputs("???", stdout);
2474 safe_print(path, -1);
2475 ext2fs_free_mem(&path);
2479 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2480 struct problem_context *pctx, int first);
2482 * This function handles the '@' expansion. We allow recursive
2483 * expansion; an @ expression can contain further '@' and '%'
2486 static void expand_at_expression(e2fsck_t ctx, char ch,
2487 struct problem_context *pctx,
2490 const char * const *cpp;
2493 /* Search for the abbreviation */
2494 for (cpp = abbrevs; *cpp; cpp++) {
2500 if (*first && islower(*str)) {
2502 fputc(toupper(*str++), stdout);
2504 print_e2fsck_message(ctx, str, pctx, *first);
2510 * This function expands '%IX' expressions
2512 static void expand_inode_expression(char ch,
2513 struct problem_context *ctx)
2515 struct ext2_inode *inode;
2516 struct ext2_inode_large *large_inode;
2521 if (!ctx || !ctx->inode)
2525 large_inode = (struct ext2_inode_large *) inode;
2529 if (LINUX_S_ISDIR(inode->i_mode))
2530 printf("%u", inode->i_size);
2532 #ifdef EXT2_NO_64_TYPE
2533 if (inode->i_size_high)
2534 printf("0x%x%08x", inode->i_size_high,
2537 printf("%u", inode->i_size);
2539 printf("%llu", (inode->i_size |
2540 ((__u64) inode->i_size_high << 32)));
2545 printf("%u", large_inode->i_extra_isize);
2548 printf("%u", inode->i_blocks);
2551 printf("%d", inode->i_links_count);
2554 printf("0%o", inode->i_mode);
2557 /* The diet libc doesn't respect the TZ environemnt variable */
2559 time_str = getenv("TZ");
2562 do_gmt = !strcmp(time_str, "GMT");
2565 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
2566 printf("%.24s", time_str);
2569 printf("%u", inode->i_faddr);
2572 printf("%u", inode->i_file_acl);
2575 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
2576 inode->i_dir_acl : 0));
2579 printf("%d", (inode->i_uid |
2580 (inode->osd2.linux2.l_i_uid_high << 16)));
2583 printf("%d", (inode->i_gid |
2584 (inode->osd2.linux2.l_i_gid_high << 16)));
2588 printf("%%I%c", ch);
2594 * This function expands '%dX' expressions
2596 static void expand_dirent_expression(char ch,
2597 struct problem_context *ctx)
2599 struct ext2_dir_entry *dirent;
2602 if (!ctx || !ctx->dirent)
2605 dirent = ctx->dirent;
2609 printf("%u", dirent->inode);
2612 len = dirent->name_len & 0xFF;
2613 if (len > EXT2_NAME_LEN)
2614 len = EXT2_NAME_LEN;
2615 if (len > dirent->rec_len)
2616 len = dirent->rec_len;
2617 safe_print(dirent->name, len);
2620 printf("%u", dirent->rec_len);
2623 printf("%u", dirent->name_len & 0xFF);
2626 printf("%u", dirent->name_len >> 8);
2630 printf("%%D%c", ch);
2635 static void expand_percent_expression(ext2_filsys fs, char ch,
2636 struct problem_context *ctx)
2646 printf("%u", ctx->blk);
2649 #ifdef EXT2_NO_64_TYPE
2650 printf("%d", ctx->blkcount);
2652 printf("%lld", ctx->blkcount);
2656 printf("%u", ctx->blk2);
2659 printf("%u", ctx->dir);
2662 printf("%d", ctx->group);
2665 printf("%u", ctx->ino);
2668 printf("%u", ctx->ino2);
2671 printf("%s", error_message(ctx->errcode));
2674 #ifdef EXT2_NO_64_TYPE
2675 printf("%u", ctx->num);
2677 printf("%llu", ctx->num);
2681 print_pathname(fs, ctx->ino, 0);
2684 print_pathname(fs, ctx->ino2,
2685 ctx->dirent ? ctx->dirent->inode : 0);
2688 print_pathname(fs, ctx->dir, 0);
2691 print_pathname(fs, ctx->dir, ctx->ino);
2694 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
2697 printf("%s", ctx->str ? ctx->str : "NULL");
2700 #ifdef EXT2_NO_64_TYPE
2701 printf("0x%x", ctx->num);
2703 printf("0x%llx", ctx->num);
2714 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
2715 struct problem_context *pctx, int first)
2717 ext2_filsys fs = ctx->fs;
2721 e2fsck_clear_progbar(ctx);
2722 for (cp = msg; *cp; cp++) {
2725 expand_at_expression(ctx, *cp, pctx, &first);
2726 } else if (cp[0] == '%' && cp[1] == 'I') {
2728 expand_inode_expression(*cp, pctx);
2729 } else if (cp[0] == '%' && cp[1] == 'D') {
2731 expand_dirent_expression(*cp, pctx);
2732 } else if ((cp[0] == '%')) {
2734 expand_percent_expression(fs, *cp, pctx);
2736 for (i=0; cp[i]; i++)
2737 if ((cp[i] == '@') || cp[i] == '%')
2739 printf("%.*s", i, cp);
2748 * region.c --- code which manages allocations within a region.
2752 region_addr_t start;
2754 struct region_el *next;
2757 struct region_struct {
2760 struct region_el *allocated;
2763 static region_t region_create(region_addr_t min, region_addr_t max)
2767 region = malloc(sizeof(struct region_struct));
2770 memset(region, 0, sizeof(struct region_struct));
2776 static void region_free(region_t region)
2778 struct region_el *r, *next;
2780 for (r = region->allocated; r; r = next) {
2784 memset(region, 0, sizeof(struct region_struct));
2788 static int region_allocate(region_t region, region_addr_t start, int n)
2790 struct region_el *r, *new_region, *prev, *next;
2794 if ((start < region->min) || (end > region->max))
2800 * Search through the linked list. If we find that it
2801 * conflicts witih something that's already allocated, return
2802 * 1; if we can find an existing region which we can grow, do
2803 * so. Otherwise, stop when we find the appropriate place
2804 * insert a new region element into the linked list.
2806 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
2807 if (((start >= r->start) && (start < r->end)) ||
2808 ((end > r->start) && (end <= r->end)) ||
2809 ((start <= r->start) && (end >= r->end)))
2811 if (end == r->start) {
2815 if (start == r->end) {
2816 if ((next = r->next)) {
2817 if (end > next->start)
2819 if (end == next->start) {
2821 r->next = next->next;
2829 if (start < r->start)
2833 * Insert a new region element structure into the linked list
2835 new_region = malloc(sizeof(struct region_el));
2838 new_region->start = start;
2839 new_region->end = start + n;
2840 new_region->next = r;
2842 prev->next = new_region;
2844 region->allocated = new_region;
2849 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
2851 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
2852 * and applies the following tests to each inode:
2854 * - The mode field of the inode must be legal.
2855 * - The size and block count fields of the inode are correct.
2856 * - A data block must not be used by another inode
2858 * Pass 1 also gathers the collects the following information:
2860 * - A bitmap of which inodes are in use. (inode_used_map)
2861 * - A bitmap of which inodes are directories. (inode_dir_map)
2862 * - A bitmap of which inodes are regular files. (inode_reg_map)
2863 * - A bitmap of which inodes have bad fields. (inode_bad_map)
2864 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
2865 * - A bitmap of which blocks are in use. (block_found_map)
2866 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
2867 * - The data blocks of the directory inodes. (dir_map)
2869 * Pass 1 is designed to stash away enough information so that the
2870 * other passes should not need to read in the inode information
2871 * during the normal course of a filesystem check. (Althogh if an
2872 * inconsistency is detected, other passes may need to read in an
2875 * Note that pass 1B will be invoked if there are any duplicate blocks
2880 static int process_block(ext2_filsys fs, blk_t *blocknr,
2881 e2_blkcnt_t blockcnt, blk_t ref_blk,
2882 int ref_offset, void *priv_data);
2883 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
2884 e2_blkcnt_t blockcnt, blk_t ref_blk,
2885 int ref_offset, void *priv_data);
2886 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
2888 static void mark_table_blocks(e2fsck_t ctx);
2889 static void alloc_imagic_map(e2fsck_t ctx);
2890 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
2891 static void handle_fs_bad_blocks(e2fsck_t ctx);
2892 static void process_inodes(e2fsck_t ctx, char *block_buf);
2893 static int process_inode_cmp(const void *a, const void *b);
2894 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
2895 dgrp_t group, void * priv_data);
2896 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
2897 char *block_buf, int adjust_sign);
2898 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
2900 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
2901 struct ext2_inode * inode, int bufsize,
2904 struct process_block_struct_1 {
2906 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
2907 fragmented:1, compressed:1, bbcheck:1;
2910 e2_blkcnt_t last_block;
2911 int num_illegal_blocks;
2912 blk_t previous_block;
2913 struct ext2_inode *inode;
2914 struct problem_context *pctx;
2915 ext2fs_block_bitmap fs_meta_blocks;
2919 struct process_inode_block {
2921 struct ext2_inode inode;
2924 struct scan_callback_struct {
2930 * For the inodes to process list.
2932 static struct process_inode_block *inodes_to_process;
2933 static int process_inode_count;
2935 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
2936 EXT2_MIN_BLOCK_LOG_SIZE + 1];
2939 * Free all memory allocated by pass1 in preparation for restarting
2942 static void unwind_pass1(void)
2944 ext2fs_free_mem(&inodes_to_process);
2948 * Check to make sure a device inode is real. Returns 1 if the device
2949 * checks out, 0 if not.
2951 * Note: this routine is now also used to check FIFO's and Sockets,
2952 * since they have the same requirement; the i_block fields should be
2956 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
2961 * If i_blocks is non-zero, or the index flag is set, then
2962 * this is a bogus device/fifo/socket
2964 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
2965 (inode->i_flags & EXT2_INDEX_FL))
2969 * We should be able to do the test below all the time, but
2970 * because the kernel doesn't forcibly clear the device
2971 * inode's additional i_block fields, there are some rare
2972 * occasions when a legitimate device inode will have non-zero
2973 * additional i_block fields. So for now, we only complain
2974 * when the immutable flag is set, which should never happen
2975 * for devices. (And that's when the problem is caused, since
2976 * you can't set or clear immutable flags for devices.) Once
2977 * the kernel has been fixed we can change this...
2979 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
2980 for (i=4; i < EXT2_N_BLOCKS; i++)
2981 if (inode->i_block[i])
2988 * Check to make sure a symlink inode is real. Returns 1 if the symlink
2989 * checks out, 0 if not.
2992 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
2998 if ((inode->i_size_high || inode->i_size == 0) ||
2999 (inode->i_flags & EXT2_INDEX_FL))
3002 blocks = ext2fs_inode_data_blocks(fs, inode);
3004 if ((inode->i_size >= fs->blocksize) ||
3005 (blocks != fs->blocksize >> 9) ||
3006 (inode->i_block[0] < fs->super->s_first_data_block) ||
3007 (inode->i_block[0] >= fs->super->s_blocks_count))
3010 for (i = 1; i < EXT2_N_BLOCKS; i++)
3011 if (inode->i_block[i])
3014 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
3017 len = strnlen(buf, fs->blocksize);
3018 if (len == fs->blocksize)
3021 if (inode->i_size >= sizeof(inode->i_block))
3024 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
3025 if (len == sizeof(inode->i_block))
3028 if (len != inode->i_size)
3034 * If the immutable (or append-only) flag is set on the inode, offer
3037 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
3038 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
3040 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
3043 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
3046 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
3047 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3051 * If device, fifo or socket, check size is zero -- if not offer to
3054 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
3056 struct ext2_inode *inode = pctx->inode;
3058 if ((inode->i_size == 0) && (inode->i_size_high == 0))
3061 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
3065 inode->i_size_high = 0;
3066 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
3069 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
3071 struct ext2_super_block *sb = ctx->fs->super;
3072 struct ext2_inode_large *inode;
3073 struct ext2_ext_attr_entry *entry;
3075 int storage_size, remain, offs;
3078 inode = (struct ext2_inode_large *) pctx->inode;
3079 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
3080 inode->i_extra_isize;
3081 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3082 inode->i_extra_isize + sizeof(__u32);
3083 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
3084 entry = (struct ext2_ext_attr_entry *) start;
3086 /* scan all entry's headers first */
3088 /* take finish entry 0UL into account */
3089 remain = storage_size - sizeof(__u32);
3092 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
3094 /* header eats this space */
3095 remain -= sizeof(struct ext2_ext_attr_entry);
3097 /* is attribute name valid? */
3098 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
3099 pctx->num = entry->e_name_len;
3100 problem = PR_1_ATTR_NAME_LEN;
3104 /* attribute len eats this space */
3105 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
3107 /* check value size */
3108 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
3109 pctx->num = entry->e_value_size;
3110 problem = PR_1_ATTR_VALUE_SIZE;
3114 /* check value placement */
3115 if (entry->e_value_offs +
3116 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
3117 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
3118 pctx->num = entry->e_value_offs;
3119 problem = PR_1_ATTR_VALUE_OFFSET;
3123 /* e_value_block must be 0 in inode's ea */
3124 if (entry->e_value_block != 0) {
3125 pctx->num = entry->e_value_block;
3126 problem = PR_1_ATTR_VALUE_BLOCK;
3130 /* e_hash must be 0 in inode's ea */
3131 if (entry->e_hash != 0) {
3132 pctx->num = entry->e_hash;
3133 problem = PR_1_ATTR_HASH;
3137 remain -= entry->e_value_size;
3138 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
3140 entry = EXT2_EXT_ATTR_NEXT(entry);
3144 * it seems like a corruption. it's very unlikely we could repair
3145 * EA(s) in automatic fashion -bzzz
3147 if (problem == 0 || !fix_problem(ctx, problem, pctx))
3150 /* simple remove all possible EA(s) */
3151 *((__u32 *)start) = 0UL;
3152 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
3153 EXT2_INODE_SIZE(sb), "pass1");
3156 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
3158 struct ext2_super_block *sb = ctx->fs->super;
3159 struct ext2_inode_large *inode;
3163 inode = (struct ext2_inode_large *) pctx->inode;
3164 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
3165 /* this isn't large inode. so, nothing to check */
3169 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
3170 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
3171 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
3173 * For now we will allow i_extra_isize to be 0, but really
3174 * implementations should never allow i_extra_isize to be 0
3176 if (inode->i_extra_isize &&
3177 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
3178 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
3180 inode->i_extra_isize = min;
3181 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
3182 EXT2_INODE_SIZE(sb), "pass1");
3186 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
3187 inode->i_extra_isize);
3188 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
3189 /* it seems inode has an extended attribute(s) in body */
3190 check_ea_in_inode(ctx, pctx);
3194 static void e2fsck_pass1(e2fsck_t ctx)
3198 ext2_filsys fs = ctx->fs;
3200 struct ext2_inode *inode;
3201 ext2_inode_scan scan;
3203 unsigned char frag, fsize;
3204 struct problem_context pctx;
3205 struct scan_callback_struct scan_struct;
3206 struct ext2_super_block *sb = ctx->fs->super;
3208 int busted_fs_time = 0;
3211 clear_problem_context(&pctx);
3213 if (!(ctx->options & E2F_OPT_PREEN))
3214 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
3216 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
3217 !(ctx->options & E2F_OPT_NO)) {
3218 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
3219 ctx->dirs_to_hash = 0;
3224 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
3226 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
3227 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
3228 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
3229 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
3230 max_sizes = (max_sizes * (1UL << i)) - 1;
3231 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
3235 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
3238 * Allocate bitmaps structures
3240 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
3241 &ctx->inode_used_map);
3244 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3245 ctx->flags |= E2F_FLAG_ABORT;
3248 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3249 _("directory inode map"), &ctx->inode_dir_map);
3252 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3253 ctx->flags |= E2F_FLAG_ABORT;
3256 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
3257 _("regular file inode map"), &ctx->inode_reg_map);
3260 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3261 ctx->flags |= E2F_FLAG_ABORT;
3264 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
3265 &ctx->block_found_map);
3268 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3269 ctx->flags |= E2F_FLAG_ABORT;
3272 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
3273 &ctx->inode_link_info);
3275 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
3276 ctx->flags |= E2F_FLAG_ABORT;
3279 inode_size = EXT2_INODE_SIZE(fs->super);
3280 inode = (struct ext2_inode *)
3281 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
3283 inodes_to_process = (struct process_inode_block *)
3284 e2fsck_allocate_memory(ctx,
3285 (ctx->process_inode_size *
3286 sizeof(struct process_inode_block)),
3287 "array of inodes to process");
3288 process_inode_count = 0;
3290 pctx.errcode = ext2fs_init_dblist(fs, 0);
3292 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
3293 ctx->flags |= E2F_FLAG_ABORT;
3298 * If the last orphan field is set, clear it, since the pass1
3299 * processing will automatically find and clear the orphans.
3300 * In the future, we may want to try using the last_orphan
3301 * linked list ourselves, but for now, we clear it so that the
3302 * ext3 mount code won't get confused.
3304 if (!(ctx->options & E2F_OPT_READONLY)) {
3305 if (fs->super->s_last_orphan) {
3306 fs->super->s_last_orphan = 0;
3307 ext2fs_mark_super_dirty(fs);
3311 mark_table_blocks(ctx);
3312 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
3313 "block interate buffer");
3314 e2fsck_use_inode_shortcuts(ctx, 1);
3315 ehandler_operation(_("doing inode scan"));
3316 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
3319 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3320 ctx->flags |= E2F_FLAG_ABORT;
3323 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
3324 ctx->stashed_inode = inode;
3325 scan_struct.ctx = ctx;
3326 scan_struct.block_buf = block_buf;
3327 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
3329 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
3331 if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
3332 (fs->super->s_mtime < fs->super->s_inodes_count))
3336 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
3338 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3340 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
3344 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
3345 ctx->flags |= E2F_FLAG_ABORT;
3352 ctx->stashed_ino = ino;
3353 if (inode->i_links_count) {
3354 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
3355 ino, inode->i_links_count);
3357 pctx.num = inode->i_links_count;
3358 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
3359 ctx->flags |= E2F_FLAG_ABORT;
3363 if (ino == EXT2_BAD_INO) {
3364 struct process_block_struct_1 pb;
3366 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
3367 &pb.fs_meta_blocks);
3370 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
3371 ctx->flags |= E2F_FLAG_ABORT;
3374 pb.ino = EXT2_BAD_INO;
3375 pb.num_blocks = pb.last_block = 0;
3376 pb.num_illegal_blocks = 0;
3377 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
3378 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
3382 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
3383 block_buf, process_bad_block, &pb);
3384 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
3386 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
3387 ctx->flags |= E2F_FLAG_ABORT;
3391 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
3392 ctx->flags |= E2F_FLAG_ABORT;
3395 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3396 clear_problem_context(&pctx);
3398 } else if (ino == EXT2_ROOT_INO) {
3400 * Make sure the root inode is a directory; if
3401 * not, offer to clear it. It will be
3402 * regnerated in pass #3.
3404 if (!LINUX_S_ISDIR(inode->i_mode)) {
3405 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
3406 inode->i_dtime = time(0);
3407 inode->i_links_count = 0;
3408 ext2fs_icount_store(ctx->inode_link_info,
3410 e2fsck_write_inode(ctx, ino, inode,
3416 * If dtime is set, offer to clear it. mke2fs
3417 * version 0.2b created filesystems with the
3418 * dtime field set for the root and lost+found
3419 * directories. We won't worry about
3420 * /lost+found, since that can be regenerated
3421 * easily. But we will fix the root directory
3422 * as a special case.
3424 if (inode->i_dtime && inode->i_links_count) {
3425 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
3427 e2fsck_write_inode(ctx, ino, inode,
3431 } else if (ino == EXT2_JOURNAL_INO) {
3432 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3433 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
3434 if (!LINUX_S_ISREG(inode->i_mode) &&
3435 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
3437 inode->i_mode = LINUX_S_IFREG;
3438 e2fsck_write_inode(ctx, ino, inode,
3441 check_blocks(ctx, &pctx, block_buf);
3444 if ((inode->i_links_count || inode->i_blocks ||
3445 inode->i_blocks || inode->i_block[0]) &&
3446 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
3448 memset(inode, 0, inode_size);
3449 ext2fs_icount_store(ctx->inode_link_info,
3451 e2fsck_write_inode_full(ctx, ino, inode,
3452 inode_size, "pass1");
3454 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
3457 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3458 if (ino == EXT2_BOOT_LOADER_INO) {
3459 if (LINUX_S_ISDIR(inode->i_mode))
3460 problem = PR_1_RESERVED_BAD_MODE;
3461 } else if (ino == EXT2_RESIZE_INO) {
3462 if (inode->i_mode &&
3463 !LINUX_S_ISREG(inode->i_mode))
3464 problem = PR_1_RESERVED_BAD_MODE;
3466 if (inode->i_mode != 0)
3467 problem = PR_1_RESERVED_BAD_MODE;
3470 if (fix_problem(ctx, problem, &pctx)) {
3472 e2fsck_write_inode(ctx, ino, inode,
3476 check_blocks(ctx, &pctx, block_buf);
3480 * Check for inodes who might have been part of the
3481 * orphaned list linked list. They should have gotten
3482 * dealt with by now, unless the list had somehow been
3485 * FIXME: In the future, inodes which are still in use
3486 * (and which are therefore) pending truncation should
3487 * be handled specially. Right now we just clear the
3488 * dtime field, and the normal e2fsck handling of
3489 * inodes where i_size and the inode blocks are
3490 * inconsistent is to fix i_size, instead of releasing
3491 * the extra blocks. This won't catch the inodes that
3492 * was at the end of the orphan list, but it's better
3493 * than nothing. The right answer is that there
3494 * shouldn't be any bugs in the orphan list handling. :-)
3496 if (inode->i_dtime && !busted_fs_time &&
3497 inode->i_dtime < ctx->fs->super->s_inodes_count) {
3498 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
3499 inode->i_dtime = inode->i_links_count ?
3501 e2fsck_write_inode(ctx, ino, inode,
3507 * This code assumes that deleted inodes have
3508 * i_links_count set to 0.
3510 if (!inode->i_links_count) {
3511 if (!inode->i_dtime && inode->i_mode) {
3512 if (fix_problem(ctx,
3513 PR_1_ZERO_DTIME, &pctx)) {
3514 inode->i_dtime = time(0);
3515 e2fsck_write_inode(ctx, ino, inode,
3522 * n.b. 0.3c ext2fs code didn't clear i_links_count for
3523 * deleted files. Oops.
3525 * Since all new ext2 implementations get this right,
3526 * we now assume that the case of non-zero
3527 * i_links_count and non-zero dtime means that we
3528 * should keep the file, not delete it.
3531 if (inode->i_dtime) {
3532 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
3534 e2fsck_write_inode(ctx, ino, inode, "pass1");
3538 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
3539 switch (fs->super->s_creator_os) {
3541 frag = inode->osd2.linux2.l_i_frag;
3542 fsize = inode->osd2.linux2.l_i_fsize;
3545 frag = inode->osd2.hurd2.h_i_frag;
3546 fsize = inode->osd2.hurd2.h_i_fsize;
3549 frag = inode->osd2.masix2.m_i_frag;
3550 fsize = inode->osd2.masix2.m_i_fsize;
3556 if (inode->i_faddr || frag || fsize ||
3557 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
3558 mark_inode_bad(ctx, ino);
3559 if (inode->i_flags & EXT2_IMAGIC_FL) {
3561 if (!ctx->inode_imagic_map)
3562 alloc_imagic_map(ctx);
3563 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
3566 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
3567 inode->i_flags &= ~EXT2_IMAGIC_FL;
3568 e2fsck_write_inode(ctx, ino,
3574 check_inode_extra_space(ctx, &pctx);
3576 if (LINUX_S_ISDIR(inode->i_mode)) {
3577 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
3578 e2fsck_add_dir_info(ctx, ino, 0);
3579 ctx->fs_directory_count++;
3580 } else if (LINUX_S_ISREG (inode->i_mode)) {
3581 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
3582 ctx->fs_regular_count++;
3583 } else if (LINUX_S_ISCHR (inode->i_mode) &&
3584 e2fsck_pass1_check_device_inode(fs, inode)) {
3585 check_immutable(ctx, &pctx);
3586 check_size(ctx, &pctx);
3587 ctx->fs_chardev_count++;
3588 } else if (LINUX_S_ISBLK (inode->i_mode) &&
3589 e2fsck_pass1_check_device_inode(fs, inode)) {
3590 check_immutable(ctx, &pctx);
3591 check_size(ctx, &pctx);
3592 ctx->fs_blockdev_count++;
3593 } else if (LINUX_S_ISLNK (inode->i_mode) &&
3594 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
3595 check_immutable(ctx, &pctx);
3596 ctx->fs_symlinks_count++;
3597 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
3598 ctx->fs_fast_symlinks_count++;
3599 check_blocks(ctx, &pctx, block_buf);
3603 else if (LINUX_S_ISFIFO (inode->i_mode) &&
3604 e2fsck_pass1_check_device_inode(fs, inode)) {
3605 check_immutable(ctx, &pctx);
3606 check_size(ctx, &pctx);
3607 ctx->fs_fifo_count++;
3608 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
3609 e2fsck_pass1_check_device_inode(fs, inode)) {
3610 check_immutable(ctx, &pctx);
3611 check_size(ctx, &pctx);
3612 ctx->fs_sockets_count++;
3614 mark_inode_bad(ctx, ino);
3615 if (inode->i_block[EXT2_IND_BLOCK])
3616 ctx->fs_ind_count++;
3617 if (inode->i_block[EXT2_DIND_BLOCK])
3618 ctx->fs_dind_count++;
3619 if (inode->i_block[EXT2_TIND_BLOCK])
3620 ctx->fs_tind_count++;
3621 if (inode->i_block[EXT2_IND_BLOCK] ||
3622 inode->i_block[EXT2_DIND_BLOCK] ||
3623 inode->i_block[EXT2_TIND_BLOCK] ||
3624 inode->i_file_acl) {
3625 inodes_to_process[process_inode_count].ino = ino;
3626 inodes_to_process[process_inode_count].inode = *inode;
3627 process_inode_count++;
3629 check_blocks(ctx, &pctx, block_buf);
3631 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3634 if (process_inode_count >= ctx->process_inode_size) {
3635 process_inodes(ctx, block_buf);
3637 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3641 process_inodes(ctx, block_buf);
3642 ext2fs_close_inode_scan(scan);
3643 ehandler_operation(0);
3646 * If any extended attribute blocks' reference counts need to
3647 * be adjusted, either up (ctx->refcount_extra), or down
3648 * (ctx->refcount), then fix them.
3650 if (ctx->refcount) {
3651 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
3652 ea_refcount_free(ctx->refcount);
3655 if (ctx->refcount_extra) {
3656 adjust_extattr_refcount(ctx, ctx->refcount_extra,
3658 ea_refcount_free(ctx->refcount_extra);
3659 ctx->refcount_extra = 0;
3662 if (ctx->invalid_bitmaps)
3663 handle_fs_bad_blocks(ctx);
3665 /* We don't need the block_ea_map any more */
3666 ext2fs_free_block_bitmap(ctx->block_ea_map);
3667 ctx->block_ea_map = 0;
3669 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
3670 ext2fs_block_bitmap save_bmap;
3672 save_bmap = fs->block_map;
3673 fs->block_map = ctx->block_found_map;
3674 clear_problem_context(&pctx);
3675 pctx.errcode = ext2fs_create_resize_inode(fs);
3677 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
3678 /* Should never get here */
3679 ctx->flags |= E2F_FLAG_ABORT;
3682 e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode,
3684 inode->i_mtime = time(0);
3685 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode,
3687 fs->block_map = save_bmap;
3688 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
3691 if (ctx->flags & E2F_FLAG_RESTART) {
3693 * Only the master copy of the superblock and block
3694 * group descriptors are going to be written during a
3695 * restart, so set the superblock to be used to be the
3696 * master superblock.
3698 ctx->use_superblock = 0;
3703 if (ctx->block_dup_map) {
3704 if (ctx->options & E2F_OPT_PREEN) {
3705 clear_problem_context(&pctx);
3706 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
3708 e2fsck_pass1_dupblocks(ctx, block_buf);
3710 ext2fs_free_mem(&inodes_to_process);
3712 e2fsck_use_inode_shortcuts(ctx, 0);
3714 ext2fs_free_mem(&block_buf);
3715 ext2fs_free_mem(&inode);
3720 * When the inode_scan routines call this callback at the end of the
3721 * glock group, call process_inodes.
3723 static errcode_t scan_callback(ext2_filsys fs,
3724 ext2_inode_scan scan FSCK_ATTR((unused)),
3725 dgrp_t group, void * priv_data)
3727 struct scan_callback_struct *scan_struct;
3730 scan_struct = (struct scan_callback_struct *) priv_data;
3731 ctx = scan_struct->ctx;
3733 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
3736 if ((ctx->progress)(ctx, 1, group+1,
3737 ctx->fs->group_desc_count))
3738 return EXT2_ET_CANCEL_REQUESTED;
3744 * Process the inodes in the "inodes to process" list.
3746 static void process_inodes(e2fsck_t ctx, char *block_buf)
3749 struct ext2_inode *old_stashed_inode;
3750 ext2_ino_t old_stashed_ino;
3751 const char *old_operation;
3753 struct problem_context pctx;
3755 /* begin process_inodes */
3756 if (process_inode_count == 0)
3758 old_operation = ehandler_operation(0);
3759 old_stashed_inode = ctx->stashed_inode;
3760 old_stashed_ino = ctx->stashed_ino;
3761 qsort(inodes_to_process, process_inode_count,
3762 sizeof(struct process_inode_block), process_inode_cmp);
3763 clear_problem_context(&pctx);
3764 for (i=0; i < process_inode_count; i++) {
3765 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
3766 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
3767 sprintf(buf, _("reading indirect blocks of inode %u"),
3769 ehandler_operation(buf);
3770 check_blocks(ctx, &pctx, block_buf);
3771 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
3774 ctx->stashed_inode = old_stashed_inode;
3775 ctx->stashed_ino = old_stashed_ino;
3776 process_inode_count = 0;
3777 /* end process inodes */
3779 ehandler_operation(old_operation);
3782 static int process_inode_cmp(const void *a, const void *b)
3784 const struct process_inode_block *ib_a =
3785 (const struct process_inode_block *) a;
3786 const struct process_inode_block *ib_b =
3787 (const struct process_inode_block *) b;
3790 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
3791 ib_b->inode.i_block[EXT2_IND_BLOCK]);
3793 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
3798 * Mark an inode as being bad in some what
3800 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
3802 struct problem_context pctx;
3804 if (!ctx->inode_bad_map) {
3805 clear_problem_context(&pctx);
3807 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3808 _("bad inode map"), &ctx->inode_bad_map);
3811 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3812 /* Should never get here */
3813 ctx->flags |= E2F_FLAG_ABORT;
3817 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
3822 * This procedure will allocate the inode imagic table
3824 static void alloc_imagic_map(e2fsck_t ctx)
3826 struct problem_context pctx;
3828 clear_problem_context(&pctx);
3829 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
3830 _("imagic inode map"),
3831 &ctx->inode_imagic_map);
3834 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
3835 /* Should never get here */
3836 ctx->flags |= E2F_FLAG_ABORT;
3842 * Marks a block as in use, setting the dup_map if it's been set
3843 * already. Called by process_block and process_bad_block.
3845 * WARNING: Assumes checks have already been done to make sure block
3846 * is valid. This is true in both process_block and process_bad_block.
3848 static void mark_block_used(e2fsck_t ctx, blk_t block)
3850 struct problem_context pctx;
3852 clear_problem_context(&pctx);
3854 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
3855 if (!ctx->block_dup_map) {
3856 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
3857 _("multiply claimed block map"),
3858 &ctx->block_dup_map);
3861 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
3863 /* Should never get here */
3864 ctx->flags |= E2F_FLAG_ABORT;
3868 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
3870 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
3875 * Adjust the extended attribute block's reference counts at the end
3876 * of pass 1, either by subtracting out references for EA blocks that
3877 * are still referenced in ctx->refcount, or by adding references for
3878 * EA blocks that had extra references as accounted for in
3879 * ctx->refcount_extra.
3881 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
3882 char *block_buf, int adjust_sign)
3884 struct ext2_ext_attr_header *header;
3885 struct problem_context pctx;
3886 ext2_filsys fs = ctx->fs;
3891 clear_problem_context(&pctx);
3893 ea_refcount_intr_begin(refcount);
3895 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
3898 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
3900 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
3903 header = (struct ext2_ext_attr_header *) block_buf;
3904 pctx.blkcount = header->h_refcount;
3905 should_be = header->h_refcount + adjust_sign * count;
3906 pctx.num = should_be;
3907 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
3908 header->h_refcount = should_be;
3909 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
3912 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
3920 * Handle processing the extended attribute blocks
3922 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
3925 ext2_filsys fs = ctx->fs;
3926 ext2_ino_t ino = pctx->ino;
3927 struct ext2_inode *inode = pctx->inode;
3930 struct ext2_ext_attr_header *header;
3931 struct ext2_ext_attr_entry *entry;
3935 blk = inode->i_file_acl;
3940 * If the Extended attribute flag isn't set, then a non-zero
3941 * file acl means that the inode is corrupted.
3943 * Or if the extended attribute block is an invalid block,
3944 * then the inode is also corrupted.
3946 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
3947 (blk < fs->super->s_first_data_block) ||
3948 (blk >= fs->super->s_blocks_count)) {
3949 mark_inode_bad(ctx, ino);
3953 /* If ea bitmap hasn't been allocated, create it */
3954 if (!ctx->block_ea_map) {
3955 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
3956 _("ext attr block map"),
3957 &ctx->block_ea_map);
3958 if (pctx->errcode) {
3960 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
3961 ctx->flags |= E2F_FLAG_ABORT;
3966 /* Create the EA refcount structure if necessary */
3967 if (!ctx->refcount) {
3968 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
3969 if (pctx->errcode) {
3971 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3972 ctx->flags |= E2F_FLAG_ABORT;
3977 /* Have we seen this EA block before? */
3978 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
3979 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
3981 /* Ooops, this EA was referenced more than it stated */
3982 if (!ctx->refcount_extra) {
3983 pctx->errcode = ea_refcount_create(0,
3984 &ctx->refcount_extra);
3985 if (pctx->errcode) {
3987 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
3988 ctx->flags |= E2F_FLAG_ABORT;
3992 ea_refcount_increment(ctx->refcount_extra, blk, 0);
3997 * OK, we haven't seen this EA block yet. So we need to
4001 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
4002 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
4004 header = (struct ext2_ext_attr_header *) block_buf;
4005 pctx->blk = inode->i_file_acl;
4006 if (((ctx->ext_attr_ver == 1) &&
4007 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
4008 ((ctx->ext_attr_ver == 2) &&
4009 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
4010 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
4014 if (header->h_blocks != 1) {
4015 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
4019 region = region_create(0, fs->blocksize);
4021 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
4022 ctx->flags |= E2F_FLAG_ABORT;
4025 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
4026 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4030 entry = (struct ext2_ext_attr_entry *)(header+1);
4031 end = block_buf + fs->blocksize;
4032 while ((char *)entry < end && *(__u32 *)entry) {
4033 if (region_allocate(region, (char *)entry - (char *)header,
4034 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
4035 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4038 if ((ctx->ext_attr_ver == 1 &&
4039 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
4040 (ctx->ext_attr_ver == 2 &&
4041 entry->e_name_index == 0)) {
4042 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
4045 if (entry->e_value_block != 0) {
4046 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
4049 if (entry->e_value_size &&
4050 region_allocate(region, entry->e_value_offs,
4051 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
4052 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4055 entry = EXT2_EXT_ATTR_NEXT(entry);
4057 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
4058 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
4061 region_free(region);
4063 count = header->h_refcount - 1;
4065 ea_refcount_store(ctx->refcount, blk, count);
4066 mark_block_used(ctx, blk);
4067 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
4072 inode->i_file_acl = 0;
4073 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
4077 /* Returns 1 if bad htree, 0 if OK */
4078 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
4079 ext2_ino_t ino FSCK_ATTR((unused)),
4080 struct ext2_inode *inode,
4083 struct ext2_dx_root_info *root;
4084 ext2_filsys fs = ctx->fs;
4088 if ((!LINUX_S_ISDIR(inode->i_mode) &&
4089 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
4090 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4091 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
4094 blk = inode->i_block[0];
4096 (blk < fs->super->s_first_data_block) ||
4097 (blk >= fs->super->s_blocks_count)) &&
4098 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4101 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
4102 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4105 /* XXX should check that beginning matches a directory */
4106 root = (struct ext2_dx_root_info *) (block_buf + 24);
4108 if ((root->reserved_zero || root->info_length < 8) &&
4109 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
4112 pctx->num = root->hash_version;
4113 if ((root->hash_version != EXT2_HASH_LEGACY) &&
4114 (root->hash_version != EXT2_HASH_HALF_MD4) &&
4115 (root->hash_version != EXT2_HASH_TEA) &&
4116 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
4119 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
4120 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
4123 pctx->num = root->indirect_levels;
4124 if ((root->indirect_levels > 1) &&
4125 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
4132 * This subroutine is called on each inode to account for all of the
4133 * blocks used by that inode.
4135 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4138 ext2_filsys fs = ctx->fs;
4139 struct process_block_struct_1 pb;
4140 ext2_ino_t ino = pctx->ino;
4141 struct ext2_inode *inode = pctx->inode;
4143 int dirty_inode = 0;
4149 pb.num_illegal_blocks = 0;
4150 pb.suppress = 0; pb.clear = 0;
4153 pb.previous_block = 0;
4154 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
4155 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
4156 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
4163 if (inode->i_flags & EXT2_COMPRBLK_FL) {
4164 if (fs->super->s_feature_incompat &
4165 EXT2_FEATURE_INCOMPAT_COMPRESSION)
4168 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
4169 inode->i_flags &= ~EXT2_COMPRBLK_FL;
4175 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
4178 if (ext2fs_inode_has_valid_blocks(inode))
4179 pctx->errcode = ext2fs_block_iterate2(fs, ino,
4180 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
4181 block_buf, process_block, &pb);
4182 end_problem_latch(ctx, PR_LATCH_BLOCK);
4183 end_problem_latch(ctx, PR_LATCH_TOOBIG);
4184 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4187 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
4189 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
4190 ctx->fs_fragmented++;
4193 inode->i_links_count = 0;
4194 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4195 inode->i_dtime = time(0);
4197 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4198 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4199 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4201 * The inode was probably partially accounted for
4202 * before processing was aborted, so we need to
4203 * restart the pass 1 scan.
4205 ctx->flags |= E2F_FLAG_RESTART;
4209 if (inode->i_flags & EXT2_INDEX_FL) {
4210 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
4211 inode->i_flags &= ~EXT2_INDEX_FL;
4215 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
4219 if (ctx->dirs_to_hash && pb.is_dir &&
4220 !(inode->i_flags & EXT2_INDEX_FL) &&
4221 ((inode->i_size / fs->blocksize) >= 3))
4222 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
4224 if (!pb.num_blocks && pb.is_dir) {
4225 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
4226 inode->i_links_count = 0;
4227 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
4228 inode->i_dtime = time(0);
4230 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
4231 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
4232 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
4233 ctx->fs_directory_count--;
4238 pb.num_blocks *= (fs->blocksize / 512);
4241 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
4242 if (nblock > (pb.last_block + 1))
4244 else if (nblock < (pb.last_block + 1)) {
4245 if (((pb.last_block + 1) - nblock) >
4246 fs->super->s_prealloc_dir_blocks)
4250 size = EXT2_I_SIZE(inode);
4251 if ((pb.last_block >= 0) &&
4252 (size < (__u64) pb.last_block * fs->blocksize))
4254 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
4257 /* i_size for symlinks is checked elsewhere */
4258 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
4259 pctx->num = (pb.last_block+1) * fs->blocksize;
4260 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
4261 inode->i_size = pctx->num;
4262 if (!LINUX_S_ISDIR(inode->i_mode))
4263 inode->i_size_high = pctx->num >> 32;
4268 if (LINUX_S_ISREG(inode->i_mode) &&
4269 (inode->i_size_high || inode->i_size & 0x80000000UL))
4271 if (pb.num_blocks != inode->i_blocks) {
4272 pctx->num = pb.num_blocks;
4273 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
4274 inode->i_blocks = pb.num_blocks;
4281 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
4286 * This is a helper function for check_blocks().
4288 static int process_block(ext2_filsys fs,
4290 e2_blkcnt_t blockcnt,
4291 blk_t ref_block FSCK_ATTR((unused)),
4292 int ref_offset FSCK_ATTR((unused)),
4295 struct process_block_struct_1 *p;
4296 struct problem_context *pctx;
4297 blk_t blk = *block_nr;
4302 p = (struct process_block_struct_1 *) priv_data;
4306 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
4307 /* todo: Check that the comprblk_fl is high, that the
4308 blkaddr pattern looks right (all non-holes up to
4309 first EXT2FS_COMPRESSED_BLKADDR, then all
4310 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
4311 that the feature_incompat bit is high, and that the
4312 inode is a regular file. If we're doing a "full
4313 check" (a concept introduced to e2fsck by e2compr,
4314 meaning that we look at data blocks as well as
4315 metadata) then call some library routine that
4316 checks the compressed data. I'll have to think
4317 about this, because one particularly important
4318 problem to be able to fix is to recalculate the
4319 cluster size if necessary. I think that perhaps
4320 we'd better do most/all e2compr-specific checks
4321 separately, after the non-e2compr checks. If not
4322 doing a full check, it may be useful to test that
4323 the personality is linux; e.g. if it isn't then
4324 perhaps this really is just an illegal block. */
4329 if (p->is_dir == 0) {
4331 * Should never happen, since only directories
4332 * get called with BLOCK_FLAG_HOLE
4335 printf("process_block() called with blk == 0, "
4336 "blockcnt=%d, inode %lu???\n",
4343 if (blockcnt * fs->blocksize < p->inode->i_size) {
4350 * Simplistic fragmentation check. We merely require that the
4351 * file be contiguous. (Which can never be true for really
4352 * big files that are greater than a block group.)
4354 if (!HOLE_BLKADDR(p->previous_block)) {
4355 if (p->previous_block+1 != blk)
4358 p->previous_block = blk;
4360 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
4361 problem = PR_1_TOOBIG_DIR;
4362 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
4363 problem = PR_1_TOOBIG_REG;
4364 if (!p->is_dir && !p->is_reg && blockcnt > 0)
4365 problem = PR_1_TOOBIG_SYMLINK;
4367 if (blk < fs->super->s_first_data_block ||
4368 blk >= fs->super->s_blocks_count)
4369 problem = PR_1_ILLEGAL_BLOCK_NUM;
4372 p->num_illegal_blocks++;
4373 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
4374 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
4378 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
4380 set_latch_flags(PR_LATCH_BLOCK,
4385 pctx->blkcount = blockcnt;
4386 if (fix_problem(ctx, problem, pctx)) {
4387 blk = *block_nr = 0;
4388 ret_code = BLOCK_CHANGED;
4394 if (p->ino == EXT2_RESIZE_INO) {
4396 * The resize inode has already be sanity checked
4397 * during pass #0 (the superblock checks). All we
4398 * have to do is mark the double indirect block as
4399 * being in use; all of the other blocks are handled
4400 * by mark_table_blocks()).
4402 if (blockcnt == BLOCK_COUNT_DIND)
4403 mark_block_used(ctx, blk);
4405 mark_block_used(ctx, blk);
4408 p->last_block = blockcnt;
4410 if (p->is_dir && (blockcnt >= 0)) {
4411 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
4413 if (pctx->errcode) {
4415 pctx->num = blockcnt;
4416 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
4417 /* Should never get here */
4418 ctx->flags |= E2F_FLAG_ABORT;
4425 static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)),
4427 e2_blkcnt_t blockcnt,
4428 blk_t ref_block FSCK_ATTR((unused)),
4429 int ref_offset FSCK_ATTR((unused)),
4430 void *priv_data EXT2FS_ATTR((unused)))
4433 * Note: This function processes blocks for the bad blocks
4434 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
4437 printf("Unrecoverable Error: Found %lli bad blocks starting at block number: %u\n", blockcnt, *block_nr);
4442 * This routine gets called at the end of pass 1 if bad blocks are
4443 * detected in the superblock, group descriptors, inode_bitmaps, or
4444 * block bitmaps. At this point, all of the blocks have been mapped
4445 * out, so we can try to allocate new block(s) to replace the bad
4448 static void handle_fs_bad_blocks(e2fsck_t ctx)
4450 printf("Bad blocks detected on your filesystem\n"
4451 "You should get your data off as the device will soon die\n");
4455 * This routine marks all blocks which are used by the superblock,
4456 * group descriptors, inode bitmaps, and block bitmaps.
4458 static void mark_table_blocks(e2fsck_t ctx)
4460 ext2_filsys fs = ctx->fs;
4464 struct problem_context pctx;
4466 clear_problem_context(&pctx);
4468 block = fs->super->s_first_data_block;
4469 for (i = 0; i < fs->group_desc_count; i++) {
4472 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
4475 * Mark the blocks used for the inode table
4477 if (fs->group_desc[i].bg_inode_table) {
4478 for (j = 0, b = fs->group_desc[i].bg_inode_table;
4479 j < fs->inode_blocks_per_group;
4481 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4484 if (fix_problem(ctx,
4485 PR_1_ITABLE_CONFLICT, &pctx)) {
4486 ctx->invalid_inode_table_flag[i]++;
4487 ctx->invalid_bitmaps++;
4490 ext2fs_mark_block_bitmap(ctx->block_found_map,
4497 * Mark block used for the block bitmap
4499 if (fs->group_desc[i].bg_block_bitmap) {
4500 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4501 fs->group_desc[i].bg_block_bitmap)) {
4502 pctx.blk = fs->group_desc[i].bg_block_bitmap;
4503 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
4504 ctx->invalid_block_bitmap_flag[i]++;
4505 ctx->invalid_bitmaps++;
4508 ext2fs_mark_block_bitmap(ctx->block_found_map,
4509 fs->group_desc[i].bg_block_bitmap);
4514 * Mark block used for the inode bitmap
4516 if (fs->group_desc[i].bg_inode_bitmap) {
4517 if (ext2fs_test_block_bitmap(ctx->block_found_map,
4518 fs->group_desc[i].bg_inode_bitmap)) {
4519 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
4520 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
4521 ctx->invalid_inode_bitmap_flag[i]++;
4522 ctx->invalid_bitmaps++;
4525 ext2fs_mark_block_bitmap(ctx->block_found_map,
4526 fs->group_desc[i].bg_inode_bitmap);
4529 block += fs->super->s_blocks_per_group;
4534 * Thes subroutines short circuits ext2fs_get_blocks and
4535 * ext2fs_check_directory; we use them since we already have the inode
4536 * structure, so there's no point in letting the ext2fs library read
4539 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
4542 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4545 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4546 return EXT2_ET_CALLBACK_NOTHANDLED;
4548 for (i=0; i < EXT2_N_BLOCKS; i++)
4549 blocks[i] = ctx->stashed_inode->i_block[i];
4553 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
4554 struct ext2_inode *inode)
4556 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4558 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4559 return EXT2_ET_CALLBACK_NOTHANDLED;
4560 *inode = *ctx->stashed_inode;
4564 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
4565 struct ext2_inode *inode)
4567 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4569 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
4570 *ctx->stashed_inode = *inode;
4571 return EXT2_ET_CALLBACK_NOTHANDLED;
4574 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
4576 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
4578 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
4579 return EXT2_ET_CALLBACK_NOTHANDLED;
4581 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
4582 return EXT2_ET_NO_DIRECTORY;
4586 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
4588 ext2_filsys fs = ctx->fs;
4591 fs->get_blocks = pass1_get_blocks;
4592 fs->check_directory = pass1_check_directory;
4593 fs->read_inode = pass1_read_inode;
4594 fs->write_inode = pass1_write_inode;
4595 ctx->stashed_ino = 0;
4598 fs->check_directory = 0;
4600 fs->write_inode = 0;
4605 * pass1b.c --- Pass #1b of e2fsck
4607 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
4608 * only invoked if pass 1 discovered blocks which are in use by more
4611 * Pass1B scans the data blocks of all the inodes again, generating a
4612 * complete list of duplicate blocks and which inodes have claimed
4615 * Pass1C does a tree-traversal of the filesystem, to determine the
4616 * parent directories of these inodes. This step is necessary so that
4617 * e2fsck can print out the pathnames of affected inodes.
4619 * Pass1D is a reconciliation pass. For each inode with duplicate
4620 * blocks, the user is prompted if s/he would like to clone the file
4621 * (so that the file gets a fresh copy of the duplicated blocks) or
4622 * simply to delete the file.
4627 /* Needed for architectures where sizeof(int) != sizeof(void *) */
4628 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
4629 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
4631 /* Define an extension to the ext2 library's block count information */
4632 #define BLOCK_COUNT_EXTATTR (-5)
4636 struct block_el *next;
4641 struct inode_el *next;
4646 struct inode_el *inode_list;
4650 * This structure stores information about a particular inode which
4651 * is sharing blocks with other inodes. This information is collected
4652 * to display to the user, so that the user knows what files he or she
4653 * is dealing with, when trying to decide how to resolve the conflict
4654 * of multiply-claimed blocks.
4659 struct ext2_inode inode;
4660 struct block_el *block_list;
4663 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
4664 e2_blkcnt_t blockcnt, blk_t ref_blk,
4665 int ref_offset, void *priv_data);
4666 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
4667 struct dup_inode *dp, char *block_buf);
4668 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
4669 struct dup_inode *dp, char* block_buf);
4670 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
4672 static void pass1b(e2fsck_t ctx, char *block_buf);
4673 static void pass1c(e2fsck_t ctx, char *block_buf);
4674 static void pass1d(e2fsck_t ctx, char *block_buf);
4676 static int dup_inode_count = 0;
4678 static dict_t blk_dict, ino_dict;
4680 static ext2fs_inode_bitmap inode_dup_map;
4682 static int dict_int_cmp(const void *a, const void *b)
4693 * Add a duplicate block record
4695 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
4696 struct ext2_inode *inode)
4699 struct dup_block *db;
4700 struct dup_inode *di;
4701 struct block_el *blk_el;
4702 struct inode_el *ino_el;
4704 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
4706 db = (struct dup_block *) dnode_get(n);
4708 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
4709 sizeof(struct dup_block), "duplicate block header");
4712 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
4714 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
4715 sizeof(struct inode_el), "inode element");
4716 ino_el->inode = ino;
4717 ino_el->next = db->inode_list;
4718 db->inode_list = ino_el;
4721 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
4723 di = (struct dup_inode *) dnode_get(n);
4725 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
4726 sizeof(struct dup_inode), "duplicate inode header");
4727 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
4728 di->num_dupblocks = 0;
4731 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
4733 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
4734 sizeof(struct block_el), "block element");
4735 blk_el->block = blk;
4736 blk_el->next = di->block_list;
4737 di->block_list = blk_el;
4738 di->num_dupblocks++;
4742 * Free a duplicate inode record
4744 static void inode_dnode_free(dnode_t *node)
4746 struct dup_inode *di;
4747 struct block_el *p, *next;
4749 di = (struct dup_inode *) dnode_get(node);
4750 for (p = di->block_list; p; p = next) {
4758 * Free a duplicate block record
4760 static void block_dnode_free(dnode_t *node)
4762 struct dup_block *db;
4763 struct inode_el *p, *next;
4765 db = (struct dup_block *) dnode_get(node);
4766 for (p = db->inode_list; p; p = next) {
4775 * Main procedure for handling duplicate blocks
4777 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
4779 ext2_filsys fs = ctx->fs;
4780 struct problem_context pctx;
4782 clear_problem_context(&pctx);
4784 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4785 _("multiply claimed inode map"), &inode_dup_map);
4787 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
4788 ctx->flags |= E2F_FLAG_ABORT;
4792 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4793 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
4794 dict_set_allocator(&ino_dict, inode_dnode_free);
4795 dict_set_allocator(&blk_dict, block_dnode_free);
4797 pass1b(ctx, block_buf);
4798 pass1c(ctx, block_buf);
4799 pass1d(ctx, block_buf);
4802 * Time to free all of the accumulated data structures that we
4803 * don't need anymore.
4805 dict_free_nodes(&ino_dict);
4806 dict_free_nodes(&blk_dict);
4810 * Scan the inodes looking for inodes that contain duplicate blocks.
4812 struct process_block_struct_1b {
4816 struct ext2_inode *inode;
4817 struct problem_context *pctx;
4820 static void pass1b(e2fsck_t ctx, char *block_buf)
4822 ext2_filsys fs = ctx->fs;
4824 struct ext2_inode inode;
4825 ext2_inode_scan scan;
4826 struct process_block_struct_1b pb;
4827 struct problem_context pctx;
4829 clear_problem_context(&pctx);
4831 if (!(ctx->options & E2F_OPT_PREEN))
4832 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
4833 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4836 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4837 ctx->flags |= E2F_FLAG_ABORT;
4840 ctx->stashed_inode = &inode;
4843 pctx.str = "pass1b";
4845 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
4846 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
4849 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
4850 ctx->flags |= E2F_FLAG_ABORT;
4855 pctx.ino = ctx->stashed_ino = ino;
4856 if ((ino != EXT2_BAD_INO) &&
4857 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
4864 if (ext2fs_inode_has_valid_blocks(&inode) ||
4865 (ino == EXT2_BAD_INO))
4866 pctx.errcode = ext2fs_block_iterate2(fs, ino,
4867 0, block_buf, process_pass1b_block, &pb);
4868 if (inode.i_file_acl)
4869 process_pass1b_block(fs, &inode.i_file_acl,
4870 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
4871 if (pb.dup_blocks) {
4872 end_problem_latch(ctx, PR_LATCH_DBLOCK);
4873 if (ino >= EXT2_FIRST_INODE(fs->super) ||
4874 ino == EXT2_ROOT_INO)
4878 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
4880 ext2fs_close_inode_scan(scan);
4881 e2fsck_use_inode_shortcuts(ctx, 0);
4884 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
4886 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
4887 blk_t ref_blk FSCK_ATTR((unused)),
4888 int ref_offset FSCK_ATTR((unused)),
4891 struct process_block_struct_1b *p;
4894 if (HOLE_BLKADDR(*block_nr))
4896 p = (struct process_block_struct_1b *) priv_data;
4899 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
4902 /* OK, this is a duplicate block */
4903 if (p->ino != EXT2_BAD_INO) {
4904 p->pctx->blk = *block_nr;
4905 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
4908 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
4910 add_dupe(ctx, p->ino, *block_nr, p->inode);
4916 * Pass 1c: Scan directories for inodes with duplicate blocks. This
4917 * is used so that we can print pathnames when prompting the user for
4920 struct search_dir_struct {
4922 ext2_ino_t first_inode;
4923 ext2_ino_t max_inode;
4926 static int search_dirent_proc(ext2_ino_t dir, int entry,
4927 struct ext2_dir_entry *dirent,
4928 int offset FSCK_ATTR((unused)),
4929 int blocksize FSCK_ATTR((unused)),
4930 char *buf FSCK_ATTR((unused)),
4933 struct search_dir_struct *sd;
4934 struct dup_inode *p;
4937 sd = (struct search_dir_struct *) priv_data;
4939 if (dirent->inode > sd->max_inode)
4940 /* Should abort this inode, but not everything */
4943 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
4944 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
4947 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
4950 p = (struct dup_inode *) dnode_get(n);
4954 return(sd->count ? 0 : DIRENT_ABORT);
4958 static void pass1c(e2fsck_t ctx, char *block_buf)
4960 ext2_filsys fs = ctx->fs;
4961 struct search_dir_struct sd;
4962 struct problem_context pctx;
4964 clear_problem_context(&pctx);
4966 if (!(ctx->options & E2F_OPT_PREEN))
4967 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
4970 * Search through all directories to translate inodes to names
4971 * (by searching for the containing directory for that inode.)
4973 sd.count = dup_inode_count;
4974 sd.first_inode = EXT2_FIRST_INODE(fs->super);
4975 sd.max_inode = fs->super->s_inodes_count;
4976 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
4977 search_dirent_proc, &sd);
4980 static void pass1d(e2fsck_t ctx, char *block_buf)
4982 ext2_filsys fs = ctx->fs;
4983 struct dup_inode *p, *t;
4984 struct dup_block *q;
4985 ext2_ino_t *shared, ino;
4990 struct problem_context pctx;
4995 clear_problem_context(&pctx);
4997 if (!(ctx->options & E2F_OPT_PREEN))
4998 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
4999 e2fsck_read_bitmaps(ctx);
5001 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
5002 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
5003 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
5004 sizeof(ext2_ino_t) * dict_count(&ino_dict),
5005 "Shared inode list");
5006 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
5007 p = (struct dup_inode *) dnode_get(n);
5010 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
5011 if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO)
5015 * Find all of the inodes which share blocks with this
5016 * one. First we find all of the duplicate blocks
5017 * belonging to this inode, and then search each block
5018 * get the list of inodes, and merge them together.
5020 for (s = p->block_list; s; s = s->next) {
5021 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
5023 continue; /* Should never happen... */
5024 q = (struct dup_block *) dnode_get(m);
5027 if (check_if_fs_block(ctx, s->block)) {
5033 * Add all inodes used by this block to the
5034 * shared[] --- which is a unique list, so
5035 * if an inode is already in shared[], don't
5038 for (r = q->inode_list; r; r = r->next) {
5039 if (r->inode == ino)
5041 for (i = 0; i < shared_len; i++)
5042 if (shared[i] == r->inode)
5044 if (i == shared_len) {
5045 shared[shared_len++] = r->inode;
5051 * Report the inode that we are working on
5053 pctx.inode = &p->inode;
5056 pctx.blkcount = p->num_dupblocks;
5057 pctx.num = meta_data ? shared_len+1 : shared_len;
5058 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
5063 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
5065 for (i = 0; i < shared_len; i++) {
5066 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
5068 continue; /* should never happen */
5069 t = (struct dup_inode *) dnode_get(m);
5071 * Report the inode that we are sharing with
5073 pctx.inode = &t->inode;
5074 pctx.ino = shared[i];
5076 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
5079 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
5082 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
5083 pctx.errcode = clone_file(ctx, ino, p, block_buf);
5085 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
5089 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
5090 delete_file(ctx, ino, p, block_buf);
5092 ext2fs_unmark_valid(fs);
5094 ext2fs_free_mem(&shared);
5098 * Drop the refcount on the dup_block structure, and clear the entry
5099 * in the block_dup_map if appropriate.
5101 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
5104 if (p->num_bad <= 0 ||
5105 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
5106 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
5109 static int delete_file_block(ext2_filsys fs,
5111 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
5112 blk_t ref_block FSCK_ATTR((unused)),
5113 int ref_offset FSCK_ATTR((unused)),
5116 struct process_block_struct_1b *pb;
5117 struct dup_block *p;
5121 pb = (struct process_block_struct_1b *) priv_data;
5124 if (HOLE_BLKADDR(*block_nr))
5127 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5128 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5130 p = (struct dup_block *) dnode_get(n);
5131 decrement_badcount(ctx, *block_nr, p);
5133 bb_error_msg(_("internal error; can't find dup_blk for %d\n"),
5136 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
5137 ext2fs_block_alloc_stats(fs, *block_nr, -1);
5143 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
5144 struct dup_inode *dp, char* block_buf)
5146 ext2_filsys fs = ctx->fs;
5147 struct process_block_struct_1b pb;
5148 struct ext2_inode inode;
5149 struct problem_context pctx;
5152 clear_problem_context(&pctx);
5153 pctx.ino = pb.ino = ino;
5154 pb.dup_blocks = dp->num_dupblocks;
5156 pctx.str = "delete_file";
5158 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5159 if (ext2fs_inode_has_valid_blocks(&inode))
5160 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5161 delete_file_block, &pb);
5163 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5164 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5165 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5166 if (ctx->inode_bad_map)
5167 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
5168 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
5170 /* Inode may have changed by block_iterate, so reread it */
5171 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
5172 inode.i_links_count = 0;
5173 inode.i_dtime = time(0);
5174 if (inode.i_file_acl &&
5175 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
5177 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
5178 block_buf, -1, &count);
5179 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
5184 pctx.blk = inode.i_file_acl;
5185 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
5188 * If the count is zero, then arrange to have the
5189 * block deleted. If the block is in the block_dup_map,
5190 * also call delete_file_block since it will take care
5191 * of keeping the accounting straight.
5194 ext2fs_test_block_bitmap(ctx->block_dup_map,
5196 delete_file_block(fs, &inode.i_file_acl,
5197 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
5199 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
5202 struct clone_struct {
5209 static int clone_file_block(ext2_filsys fs,
5211 e2_blkcnt_t blockcnt,
5212 blk_t ref_block FSCK_ATTR((unused)),
5213 int ref_offset FSCK_ATTR((unused)),
5216 struct dup_block *p;
5219 struct clone_struct *cs = (struct clone_struct *) priv_data;
5225 if (HOLE_BLKADDR(*block_nr))
5228 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
5229 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
5231 p = (struct dup_block *) dnode_get(n);
5232 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
5235 cs->errcode = retval;
5238 if (cs->dir && (blockcnt >= 0)) {
5239 retval = ext2fs_set_dir_block(fs->dblist,
5240 cs->dir, new_block, blockcnt);
5242 cs->errcode = retval;
5247 retval = io_channel_read_blk(fs->io, *block_nr, 1,
5250 cs->errcode = retval;
5253 retval = io_channel_write_blk(fs->io, new_block, 1,
5256 cs->errcode = retval;
5259 decrement_badcount(ctx, *block_nr, p);
5260 *block_nr = new_block;
5261 ext2fs_mark_block_bitmap(ctx->block_found_map,
5263 ext2fs_mark_block_bitmap(fs->block_map, new_block);
5264 return BLOCK_CHANGED;
5266 bb_error_msg(_("internal error; can't find dup_blk for %d\n"),
5272 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
5273 struct dup_inode *dp, char* block_buf)
5275 ext2_filsys fs = ctx->fs;
5277 struct clone_struct cs;
5278 struct problem_context pctx;
5281 struct inode_el *ino_el;
5282 struct dup_block *db;
5283 struct dup_inode *di;
5285 clear_problem_context(&pctx);
5289 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
5293 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
5297 pctx.str = "clone_file";
5298 if (ext2fs_inode_has_valid_blocks(&dp->inode))
5299 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
5300 clone_file_block, &cs);
5301 ext2fs_mark_bb_dirty(fs);
5303 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
5304 retval = pctx.errcode;
5308 bb_error_msg(_("returned from clone_file_block"));
5309 retval = cs.errcode;
5312 /* The inode may have changed on disk, so we have to re-read it */
5313 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
5314 blk = dp->inode.i_file_acl;
5315 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
5316 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
5318 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
5320 * If we cloned the EA block, find all other inodes
5321 * which refered to that EA block, and modify
5322 * them to point to the new EA block.
5324 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
5325 db = (struct dup_block *) dnode_get(n);
5326 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
5327 if (ino_el->inode == ino)
5329 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
5330 di = (struct dup_inode *) dnode_get(n);
5331 if (di->inode.i_file_acl == blk) {
5332 di->inode.i_file_acl = dp->inode.i_file_acl;
5333 e2fsck_write_inode(ctx, ino_el->inode,
5334 &di->inode, "clone file EA");
5335 decrement_badcount(ctx, blk, db);
5341 ext2fs_free_mem(&cs.buf);
5346 * This routine returns 1 if a block overlaps with one of the superblocks,
5347 * group descriptors, inode bitmaps, or block bitmaps.
5349 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
5351 ext2_filsys fs = ctx->fs;
5355 block = fs->super->s_first_data_block;
5356 for (i = 0; i < fs->group_desc_count; i++) {
5358 /* Check superblocks/block group descriptros */
5359 if (ext2fs_bg_has_super(fs, i)) {
5360 if (test_block >= block &&
5361 (test_block <= block + fs->desc_blocks))
5365 /* Check the inode table */
5366 if ((fs->group_desc[i].bg_inode_table) &&
5367 (test_block >= fs->group_desc[i].bg_inode_table) &&
5368 (test_block < (fs->group_desc[i].bg_inode_table +
5369 fs->inode_blocks_per_group)))
5372 /* Check the bitmap blocks */
5373 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
5374 (test_block == fs->group_desc[i].bg_inode_bitmap))
5377 block += fs->super->s_blocks_per_group;
5382 * pass2.c --- check directory structure
5384 * Pass 2 of e2fsck iterates through all active directory inodes, and
5385 * applies to following tests to each directory entry in the directory
5386 * blocks in the inodes:
5388 * - The length of the directory entry (rec_len) should be at
5389 * least 8 bytes, and no more than the remaining space
5390 * left in the directory block.
5391 * - The length of the name in the directory entry (name_len)
5392 * should be less than (rec_len - 8).
5393 * - The inode number in the directory entry should be within
5395 * - The inode number should refer to a in-use inode.
5396 * - The first entry should be '.', and its inode should be
5397 * the inode of the directory.
5398 * - The second entry should be '..'.
5400 * To minimize disk seek time, the directory blocks are processed in
5401 * sorted order of block numbers.
5403 * Pass 2 also collects the following information:
5404 * - The inode numbers of the subdirectories for each directory.
5406 * Pass 2 relies on the following information from previous passes:
5407 * - The directory information collected in pass 1.
5408 * - The inode_used_map bitmap
5409 * - The inode_bad_map bitmap
5410 * - The inode_dir_map bitmap
5412 * Pass 2 frees the following data structures
5413 * - The inode_bad_map bitmap
5414 * - The inode_reg_map bitmap
5418 * Keeps track of how many times an inode is referenced.
5420 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
5421 static int check_dir_block(ext2_filsys fs,
5422 struct ext2_db_entry *dir_blocks_info,
5424 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
5425 struct problem_context *pctx);
5426 static int update_dir_block(ext2_filsys fs,
5428 e2_blkcnt_t blockcnt,
5432 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
5433 static int htree_depth(struct dx_dir_info *dx_dir,
5434 struct dx_dirblock_info *dx_db);
5435 static int special_dir_block_cmp(const void *a, const void *b);
5437 struct check_dir_struct {
5439 struct problem_context pctx;
5444 static void e2fsck_pass2(e2fsck_t ctx)
5446 struct ext2_super_block *sb = ctx->fs->super;
5447 struct problem_context pctx;
5448 ext2_filsys fs = ctx->fs;
5450 struct dir_info *dir;
5451 struct check_dir_struct cd;
5452 struct dx_dir_info *dx_dir;
5453 struct dx_dirblock_info *dx_db, *dx_parent;
5459 clear_problem_context(&cd.pctx);
5463 if (!(ctx->options & E2F_OPT_PREEN))
5464 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
5466 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
5467 0, ctx->inode_link_info,
5469 if (cd.pctx.errcode) {
5470 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
5471 ctx->flags |= E2F_FLAG_ABORT;
5474 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
5475 "directory scan buffer");
5478 * Set up the parent pointer for the root directory, if
5479 * present. (If the root directory is not present, we will
5480 * create it in pass 3.)
5482 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
5484 dir->parent = EXT2_ROOT_INO;
5489 cd.max = ext2fs_dblist_count(fs->dblist);
5492 (void) (ctx->progress)(ctx, 2, 0, cd.max);
5494 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
5495 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
5497 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
5499 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5501 if (cd.pctx.errcode) {
5502 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
5503 ctx->flags |= E2F_FLAG_ABORT;
5508 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
5509 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5511 if (dx_dir->numblocks == 0)
5513 clear_problem_context(&pctx);
5515 pctx.dir = dx_dir->ino;
5516 dx_db = dx_dir->dx_block;
5517 if (dx_db->flags & DX_FLAG_REFERENCED)
5518 dx_db->flags |= DX_FLAG_DUP_REF;
5520 dx_db->flags |= DX_FLAG_REFERENCED;
5522 * Find all of the first and last leaf blocks, and
5523 * update their parent's min and max hash values
5525 for (b=0, dx_db = dx_dir->dx_block;
5526 b < dx_dir->numblocks;
5528 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
5529 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
5531 dx_parent = &dx_dir->dx_block[dx_db->parent];
5533 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
5535 if (dx_db->flags & DX_FLAG_FIRST)
5536 dx_parent->min_hash = dx_db->min_hash;
5538 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
5540 if (dx_db->flags & DX_FLAG_LAST)
5541 dx_parent->max_hash = dx_db->max_hash;
5544 for (b=0, dx_db = dx_dir->dx_block;
5545 b < dx_dir->numblocks;
5548 pctx.group = dx_db->parent;
5550 if (!(dx_db->flags & DX_FLAG_FIRST) &&
5551 (dx_db->min_hash < dx_db->node_min_hash)) {
5552 pctx.blk = dx_db->min_hash;
5553 pctx.blk2 = dx_db->node_min_hash;
5554 code = PR_2_HTREE_MIN_HASH;
5555 fix_problem(ctx, code, &pctx);
5558 if (dx_db->type == DX_DIRBLOCK_LEAF) {
5559 depth = htree_depth(dx_dir, dx_db);
5560 if (depth != dx_dir->depth) {
5561 code = PR_2_HTREE_BAD_DEPTH;
5562 fix_problem(ctx, code, &pctx);
5567 * This test doesn't apply for the root block
5571 (dx_db->max_hash > dx_db->node_max_hash)) {
5572 pctx.blk = dx_db->max_hash;
5573 pctx.blk2 = dx_db->node_max_hash;
5574 code = PR_2_HTREE_MAX_HASH;
5575 fix_problem(ctx, code, &pctx);
5578 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
5579 code = PR_2_HTREE_NOTREF;
5580 fix_problem(ctx, code, &pctx);
5582 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
5583 code = PR_2_HTREE_DUPREF;
5584 fix_problem(ctx, code, &pctx);
5590 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
5591 clear_htree(ctx, dx_dir->ino);
5592 dx_dir->numblocks = 0;
5596 ext2fs_free_mem(&buf);
5597 ext2fs_free_dblist(fs->dblist);
5599 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
5600 ctx->inode_bad_map = 0;
5601 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
5602 ctx->inode_reg_map = 0;
5604 clear_problem_context(&pctx);
5605 if (ctx->large_files) {
5606 if (!(sb->s_feature_ro_compat &
5607 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
5608 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
5609 sb->s_feature_ro_compat |=
5610 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5611 ext2fs_mark_super_dirty(fs);
5613 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
5614 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
5615 ext2fs_update_dynamic_rev(fs);
5616 ext2fs_mark_super_dirty(fs);
5618 } else if (!ctx->large_files &&
5619 (sb->s_feature_ro_compat &
5620 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
5621 if (fs->flags & EXT2_FLAG_RW) {
5622 sb->s_feature_ro_compat &=
5623 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
5624 ext2fs_mark_super_dirty(fs);
5630 #define MAX_DEPTH 32000
5631 static int htree_depth(struct dx_dir_info *dx_dir,
5632 struct dx_dirblock_info *dx_db)
5636 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
5637 dx_db = &dx_dir->dx_block[dx_db->parent];
5643 static int dict_de_cmp(const void *a, const void *b)
5645 const struct ext2_dir_entry *de_a, *de_b;
5648 de_a = (const struct ext2_dir_entry *) a;
5649 a_len = de_a->name_len & 0xFF;
5650 de_b = (const struct ext2_dir_entry *) b;
5651 b_len = de_b->name_len & 0xFF;
5654 return (a_len - b_len);
5656 return strncmp(de_a->name, de_b->name, a_len);
5660 * This is special sort function that makes sure that directory blocks
5661 * with a dirblock of zero are sorted to the beginning of the list.
5662 * This guarantees that the root node of the htree directories are
5663 * processed first, so we know what hash version to use.
5665 static int special_dir_block_cmp(const void *a, const void *b)
5667 const struct ext2_db_entry *db_a =
5668 (const struct ext2_db_entry *) a;
5669 const struct ext2_db_entry *db_b =
5670 (const struct ext2_db_entry *) b;
5672 if (db_a->blockcnt && !db_b->blockcnt)
5675 if (!db_a->blockcnt && db_b->blockcnt)
5678 if (db_a->blk != db_b->blk)
5679 return (int) (db_a->blk - db_b->blk);
5681 if (db_a->ino != db_b->ino)
5682 return (int) (db_a->ino - db_b->ino);
5684 return (int) (db_a->blockcnt - db_b->blockcnt);
5689 * Make sure the first entry in the directory is '.', and that the
5690 * directory entry is sane.
5692 static int check_dot(e2fsck_t ctx,
5693 struct ext2_dir_entry *dirent,
5694 ext2_ino_t ino, struct problem_context *pctx)
5696 struct ext2_dir_entry *nextdir;
5703 problem = PR_2_MISSING_DOT;
5704 else if (((dirent->name_len & 0xFF) != 1) ||
5705 (dirent->name[0] != '.'))
5706 problem = PR_2_1ST_NOT_DOT;
5707 else if (dirent->name[1] != '\0')
5708 problem = PR_2_DOT_NULL_TERM;
5711 if (fix_problem(ctx, problem, pctx)) {
5712 if (dirent->rec_len < 12)
5713 dirent->rec_len = 12;
5714 dirent->inode = ino;
5715 dirent->name_len = 1;
5716 dirent->name[0] = '.';
5717 dirent->name[1] = '\0';
5722 if (dirent->inode != ino) {
5723 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
5724 dirent->inode = ino;
5728 if (dirent->rec_len > 12) {
5729 new_len = dirent->rec_len - 12;
5732 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
5733 nextdir = (struct ext2_dir_entry *)
5734 ((char *) dirent + 12);
5735 dirent->rec_len = 12;
5736 nextdir->rec_len = new_len;
5738 nextdir->name_len = 0;
5747 * Make sure the second entry in the directory is '..', and that the
5748 * directory entry is sane. We do not check the inode number of '..'
5749 * here; this gets done in pass 3.
5751 static int check_dotdot(e2fsck_t ctx,
5752 struct ext2_dir_entry *dirent,
5753 struct dir_info *dir, struct problem_context *pctx)
5758 problem = PR_2_MISSING_DOT_DOT;
5759 else if (((dirent->name_len & 0xFF) != 2) ||
5760 (dirent->name[0] != '.') ||
5761 (dirent->name[1] != '.'))
5762 problem = PR_2_2ND_NOT_DOT_DOT;
5763 else if (dirent->name[2] != '\0')
5764 problem = PR_2_DOT_DOT_NULL_TERM;
5767 if (fix_problem(ctx, problem, pctx)) {
5768 if (dirent->rec_len < 12)
5769 dirent->rec_len = 12;
5771 * Note: we don't have the parent inode just
5772 * yet, so we will fill it in with the root
5773 * inode. This will get fixed in pass 3.
5775 dirent->inode = EXT2_ROOT_INO;
5776 dirent->name_len = 2;
5777 dirent->name[0] = '.';
5778 dirent->name[1] = '.';
5779 dirent->name[2] = '\0';
5784 dir->dotdot = dirent->inode;
5789 * Check to make sure a directory entry doesn't contain any illegal
5792 static int check_name(e2fsck_t ctx,
5793 struct ext2_dir_entry *dirent,
5794 struct problem_context *pctx)
5800 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
5801 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
5803 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
5806 dirent->name[i] = '.';
5815 * Check the directory filetype (if present)
5819 * Given a mode, return the ext2 file type
5821 static int ext2_file_type(unsigned int mode)
5823 if (LINUX_S_ISREG(mode))
5824 return EXT2_FT_REG_FILE;
5826 if (LINUX_S_ISDIR(mode))
5829 if (LINUX_S_ISCHR(mode))
5830 return EXT2_FT_CHRDEV;
5832 if (LINUX_S_ISBLK(mode))
5833 return EXT2_FT_BLKDEV;
5835 if (LINUX_S_ISLNK(mode))
5836 return EXT2_FT_SYMLINK;
5838 if (LINUX_S_ISFIFO(mode))
5839 return EXT2_FT_FIFO;
5841 if (LINUX_S_ISSOCK(mode))
5842 return EXT2_FT_SOCK;
5847 static int check_filetype(e2fsck_t ctx,
5848 struct ext2_dir_entry *dirent,
5849 struct problem_context *pctx)
5851 int filetype = dirent->name_len >> 8;
5852 int should_be = EXT2_FT_UNKNOWN;
5853 struct ext2_inode inode;
5855 if (!(ctx->fs->super->s_feature_incompat &
5856 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
5857 if (filetype == 0 ||
5858 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
5860 dirent->name_len = dirent->name_len & 0xFF;
5864 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
5865 should_be = EXT2_FT_DIR;
5866 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
5868 should_be = EXT2_FT_REG_FILE;
5869 } else if (ctx->inode_bad_map &&
5870 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
5874 e2fsck_read_inode(ctx, dirent->inode, &inode,
5876 should_be = ext2_file_type(inode.i_mode);
5878 if (filetype == should_be)
5880 pctx->num = should_be;
5882 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
5886 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
5891 static void parse_int_node(ext2_filsys fs,
5892 struct ext2_db_entry *db,
5893 struct check_dir_struct *cd,
5894 struct dx_dir_info *dx_dir,
5897 struct ext2_dx_root_info *root;
5898 struct ext2_dx_entry *ent;
5899 struct ext2_dx_countlimit *limit;
5900 struct dx_dirblock_info *dx_db;
5901 int i, expect_limit, count;
5903 ext2_dirhash_t min_hash = 0xffffffff;
5904 ext2_dirhash_t max_hash = 0;
5905 ext2_dirhash_t hash = 0, prev_hash;
5907 if (db->blockcnt == 0) {
5908 root = (struct ext2_dx_root_info *) (block_buf + 24);
5909 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
5911 ent = (struct ext2_dx_entry *) (block_buf+8);
5913 limit = (struct ext2_dx_countlimit *) ent;
5915 count = ext2fs_le16_to_cpu(limit->count);
5916 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
5917 sizeof(struct ext2_dx_entry);
5918 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
5919 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
5920 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
5921 goto clear_and_exit;
5923 if (count > expect_limit) {
5924 cd->pctx.num = count;
5925 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
5926 goto clear_and_exit;
5927 count = expect_limit;
5930 for (i=0; i < count; i++) {
5932 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
5933 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
5934 /* Check to make sure the block is valid */
5935 if (blk > (blk_t) dx_dir->numblocks) {
5937 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
5939 goto clear_and_exit;
5941 if (hash < prev_hash &&
5942 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
5943 goto clear_and_exit;
5944 dx_db = &dx_dir->dx_block[blk];
5945 if (dx_db->flags & DX_FLAG_REFERENCED) {
5946 dx_db->flags |= DX_FLAG_DUP_REF;
5948 dx_db->flags |= DX_FLAG_REFERENCED;
5949 dx_db->parent = db->blockcnt;
5951 if (hash < min_hash)
5953 if (hash > max_hash)
5955 dx_db->node_min_hash = hash;
5957 dx_db->node_max_hash =
5958 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
5960 dx_db->node_max_hash = 0xfffffffe;
5961 dx_db->flags |= DX_FLAG_LAST;
5964 dx_db->flags |= DX_FLAG_FIRST;
5966 dx_db = &dx_dir->dx_block[db->blockcnt];
5967 dx_db->min_hash = min_hash;
5968 dx_db->max_hash = max_hash;
5972 clear_htree(cd->ctx, cd->pctx.ino);
5973 dx_dir->numblocks = 0;
5975 #endif /* ENABLE_HTREE */
5978 * Given a busted directory, try to salvage it somehow.
5981 static void salvage_directory(ext2_filsys fs,
5982 struct ext2_dir_entry *dirent,
5983 struct ext2_dir_entry *prev,
5984 unsigned int *offset)
5986 char *cp = (char *) dirent;
5987 int left = fs->blocksize - *offset - dirent->rec_len;
5988 int name_len = dirent->name_len & 0xFF;
5991 * Special case of directory entry of size 8: copy what's left
5992 * of the directory block up to cover up the invalid hole.
5994 if ((left >= 12) && (dirent->rec_len == 8)) {
5995 memmove(cp, cp+8, left);
5996 memset(cp + left, 0, 8);
6000 * If the directory entry overruns the end of the directory
6001 * block, and the name is small enough to fit, then adjust the
6005 (name_len + 8 <= dirent->rec_len + left) &&
6006 dirent->inode <= fs->super->s_inodes_count &&
6007 strnlen(dirent->name, name_len) == name_len) {
6008 dirent->rec_len += left;
6012 * If the directory entry is a multiple of four, so it is
6013 * valid, let the previous directory entry absorb the invalid
6016 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
6017 prev->rec_len += dirent->rec_len;
6018 *offset += dirent->rec_len;
6022 * Default salvage method --- kill all of the directory
6023 * entries for the rest of the block. We will either try to
6024 * absorb it into the previous directory entry, or create a
6025 * new empty directory entry the rest of the directory block.
6028 prev->rec_len += fs->blocksize - *offset;
6029 *offset = fs->blocksize;
6031 dirent->rec_len = fs->blocksize - *offset;
6032 dirent->name_len = 0;
6037 static int check_dir_block(ext2_filsys fs,
6038 struct ext2_db_entry *db,
6041 struct dir_info *subdir, *dir;
6042 struct dx_dir_info *dx_dir;
6044 struct dx_dirblock_info *dx_db = 0;
6045 #endif /* ENABLE_HTREE */
6046 struct ext2_dir_entry *dirent, *prev;
6047 ext2_dirhash_t hash;
6048 unsigned int offset = 0;
6049 int dir_modified = 0;
6051 blk_t block_nr = db->blk;
6052 ext2_ino_t ino = db->ino;
6054 struct check_dir_struct *cd;
6058 struct ext2_dx_root_info *root;
6059 struct ext2_dx_countlimit *limit;
6060 static dict_t de_dict;
6061 struct problem_context pctx;
6064 cd = (struct check_dir_struct *) priv_data;
6068 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6069 return DIRENT_ABORT;
6071 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
6072 return DIRENT_ABORT;
6075 * Make sure the inode is still in use (could have been
6076 * deleted in the duplicate/bad blocks pass.
6078 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
6082 cd->pctx.blk = block_nr;
6083 cd->pctx.blkcount = db->blockcnt;
6085 cd->pctx.dirent = 0;
6089 if (allocate_dir_block(ctx, db, &cd->pctx))
6099 if (ctx->dirs_to_hash &&
6100 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
6103 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
6104 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
6105 cd->pctx.errcode = 0; /* We'll handle this ourselves */
6106 if (cd->pctx.errcode) {
6107 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
6108 ctx->flags |= E2F_FLAG_ABORT;
6109 return DIRENT_ABORT;
6111 memset(buf, 0, fs->blocksize);
6114 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
6115 if (dx_dir && dx_dir->numblocks) {
6116 if (db->blockcnt >= dx_dir->numblocks) {
6117 printf("XXX should never happen!!!\n");
6120 dx_db = &dx_dir->dx_block[db->blockcnt];
6121 dx_db->type = DX_DIRBLOCK_LEAF;
6122 dx_db->phys = block_nr;
6123 dx_db->min_hash = ~0;
6124 dx_db->max_hash = 0;
6126 dirent = (struct ext2_dir_entry *) buf;
6127 limit = (struct ext2_dx_countlimit *) (buf+8);
6128 if (db->blockcnt == 0) {
6129 root = (struct ext2_dx_root_info *) (buf + 24);
6130 dx_db->type = DX_DIRBLOCK_ROOT;
6131 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
6132 if ((root->reserved_zero ||
6133 root->info_length < 8 ||
6134 root->indirect_levels > 1) &&
6135 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
6136 clear_htree(ctx, ino);
6137 dx_dir->numblocks = 0;
6140 dx_dir->hashversion = root->hash_version;
6141 dx_dir->depth = root->indirect_levels + 1;
6142 } else if ((dirent->inode == 0) &&
6143 (dirent->rec_len == fs->blocksize) &&
6144 (dirent->name_len == 0) &&
6145 (ext2fs_le16_to_cpu(limit->limit) ==
6146 ((fs->blocksize-8) /
6147 sizeof(struct ext2_dx_entry))))
6148 dx_db->type = DX_DIRBLOCK_NODE;
6150 #endif /* ENABLE_HTREE */
6152 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
6156 dirent = (struct ext2_dir_entry *) (buf + offset);
6157 cd->pctx.dirent = dirent;
6158 cd->pctx.num = offset;
6159 if (((offset + dirent->rec_len) > fs->blocksize) ||
6160 (dirent->rec_len < 12) ||
6161 ((dirent->rec_len % 4) != 0) ||
6162 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
6163 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
6164 salvage_directory(fs, dirent, prev, &offset);
6168 goto abort_free_dict;
6170 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
6171 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
6172 dirent->name_len = EXT2_NAME_LEN;
6177 if (dot_state == 0) {
6178 if (check_dot(ctx, dirent, ino, &cd->pctx))
6180 } else if (dot_state == 1) {
6181 dir = e2fsck_get_dir_info(ctx, ino);
6183 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6184 goto abort_free_dict;
6186 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
6188 } else if (dirent->inode == ino) {
6189 problem = PR_2_LINK_DOT;
6190 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
6200 * Make sure the inode listed is a legal one.
6202 if (((dirent->inode != EXT2_ROOT_INO) &&
6203 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
6204 (dirent->inode > fs->super->s_inodes_count)) {
6205 problem = PR_2_BAD_INO;
6206 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
6209 * If the inode is unused, offer to clear it.
6211 problem = PR_2_UNUSED_INODE;
6212 } else if ((dot_state > 1) &&
6213 ((dirent->name_len & 0xFF) == 1) &&
6214 (dirent->name[0] == '.')) {
6216 * If there's a '.' entry in anything other
6217 * than the first directory entry, it's a
6218 * duplicate entry that should be removed.
6220 problem = PR_2_DUP_DOT;
6221 } else if ((dot_state > 1) &&
6222 ((dirent->name_len & 0xFF) == 2) &&
6223 (dirent->name[0] == '.') &&
6224 (dirent->name[1] == '.')) {
6226 * If there's a '..' entry in anything other
6227 * than the second directory entry, it's a
6228 * duplicate entry that should be removed.
6230 problem = PR_2_DUP_DOT_DOT;
6231 } else if ((dot_state > 1) &&
6232 (dirent->inode == EXT2_ROOT_INO)) {
6234 * Don't allow links to the root directory.
6235 * We check this specially to make sure we
6236 * catch this error case even if the root
6237 * directory hasn't been created yet.
6239 problem = PR_2_LINK_ROOT;
6240 } else if ((dot_state > 1) &&
6241 (dirent->name_len & 0xFF) == 0) {
6243 * Don't allow zero-length directory names.
6245 problem = PR_2_NULL_NAME;
6249 if (fix_problem(ctx, problem, &cd->pctx)) {
6254 ext2fs_unmark_valid(fs);
6255 if (problem == PR_2_BAD_INO)
6261 * If the inode was marked as having bad fields in
6262 * pass1, process it and offer to fix/clear it.
6263 * (We wait until now so that we can display the
6264 * pathname to the user.)
6266 if (ctx->inode_bad_map &&
6267 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
6269 if (e2fsck_process_bad_inode(ctx, ino,
6271 buf + fs->blocksize)) {
6276 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6277 return DIRENT_ABORT;
6280 if (check_name(ctx, dirent, &cd->pctx))
6283 if (check_filetype(ctx, dirent, &cd->pctx))
6288 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
6289 (dirent->name_len & 0xFF),
6290 fs->super->s_hash_seed, &hash, 0);
6291 if (hash < dx_db->min_hash)
6292 dx_db->min_hash = hash;
6293 if (hash > dx_db->max_hash)
6294 dx_db->max_hash = hash;
6299 * If this is a directory, then mark its parent in its
6300 * dir_info structure. If the parent field is already
6301 * filled in, then this directory has more than one
6302 * hard link. We assume the first link is correct,
6303 * and ask the user if he/she wants to clear this one.
6305 if ((dot_state > 1) &&
6306 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6308 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
6310 cd->pctx.ino = dirent->inode;
6311 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
6312 goto abort_free_dict;
6314 if (subdir->parent) {
6315 cd->pctx.ino2 = subdir->parent;
6316 if (fix_problem(ctx, PR_2_LINK_DIR,
6324 subdir->parent = ino;
6329 } else if (dict_lookup(&de_dict, dirent)) {
6330 clear_problem_context(&pctx);
6332 pctx.dirent = dirent;
6333 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
6334 if (!ctx->dirs_to_hash)
6335 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
6336 if (ctx->dirs_to_hash)
6337 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6340 dict_alloc_insert(&de_dict, dirent, dirent);
6342 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
6345 ctx->fs_links_count++;
6346 ctx->fs_total_count++;
6349 offset += dirent->rec_len;
6351 } while (offset < fs->blocksize);
6354 cd->pctx.dir = cd->pctx.ino;
6355 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
6356 (dx_db->type == DX_DIRBLOCK_NODE))
6357 parse_int_node(fs, db, cd, dx_dir, buf);
6359 #endif /* ENABLE_HTREE */
6360 if (offset != fs->blocksize) {
6361 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
6362 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
6363 dirent->rec_len = cd->pctx.num;
6368 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
6369 if (cd->pctx.errcode) {
6370 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
6372 goto abort_free_dict;
6374 ext2fs_mark_changed(fs);
6376 dict_free_nodes(&de_dict);
6379 dict_free_nodes(&de_dict);
6380 ctx->flags |= E2F_FLAG_ABORT;
6381 return DIRENT_ABORT;
6385 * This function is called to deallocate a block, and is an interator
6386 * functioned called by deallocate inode via ext2fs_iterate_block().
6388 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
6389 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6390 blk_t ref_block FSCK_ATTR((unused)),
6391 int ref_offset FSCK_ATTR((unused)),
6394 e2fsck_t ctx = (e2fsck_t) priv_data;
6396 if (HOLE_BLKADDR(*block_nr))
6398 if ((*block_nr < fs->super->s_first_data_block) ||
6399 (*block_nr >= fs->super->s_blocks_count))
6401 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6402 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6407 * This fuction deallocates an inode
6409 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
6411 ext2_filsys fs = ctx->fs;
6412 struct ext2_inode inode;
6413 struct problem_context pctx;
6416 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
6417 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
6418 inode.i_links_count = 0;
6419 inode.i_dtime = time(0);
6420 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
6421 clear_problem_context(&pctx);
6425 * Fix up the bitmaps...
6427 e2fsck_read_bitmaps(ctx);
6428 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6429 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6430 if (ctx->inode_bad_map)
6431 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6432 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6434 if (inode.i_file_acl &&
6435 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6436 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6437 block_buf, -1, &count);
6438 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6443 pctx.blk = inode.i_file_acl;
6444 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
6445 ctx->flags |= E2F_FLAG_ABORT;
6449 ext2fs_unmark_block_bitmap(ctx->block_found_map,
6451 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
6453 inode.i_file_acl = 0;
6456 if (!ext2fs_inode_has_valid_blocks(&inode))
6459 if (LINUX_S_ISREG(inode.i_mode) &&
6460 (inode.i_size_high || inode.i_size & 0x80000000UL))
6463 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6464 deallocate_inode_block, ctx);
6466 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
6467 ctx->flags |= E2F_FLAG_ABORT;
6473 * This fuction clears the htree flag on an inode
6475 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
6477 struct ext2_inode inode;
6479 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
6480 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
6481 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
6482 if (ctx->dirs_to_hash)
6483 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
6487 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
6488 ext2_ino_t ino, char *buf)
6490 ext2_filsys fs = ctx->fs;
6491 struct ext2_inode inode;
6492 int inode_modified = 0;
6494 unsigned char *frag, *fsize;
6495 struct problem_context pctx;
6498 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
6500 clear_problem_context(&pctx);
6503 pctx.inode = &inode;
6505 if (inode.i_file_acl &&
6506 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
6507 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
6508 inode.i_file_acl = 0;
6511 * This is a special kludge to deal with long symlinks
6512 * on big endian systems. i_blocks had already been
6513 * decremented earlier in pass 1, but since i_file_acl
6514 * hadn't yet been cleared, ext2fs_read_inode()
6515 * assumed that the file was short symlink and would
6516 * not have byte swapped i_block[0]. Hence, we have
6517 * to byte-swap it here.
6519 if (LINUX_S_ISLNK(inode.i_mode) &&
6520 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
6521 (inode.i_blocks == fs->blocksize >> 9))
6522 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
6528 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
6529 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
6530 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
6531 !(LINUX_S_ISSOCK(inode.i_mode)))
6532 problem = PR_2_BAD_MODE;
6533 else if (LINUX_S_ISCHR(inode.i_mode)
6534 && !e2fsck_pass1_check_device_inode(fs, &inode))
6535 problem = PR_2_BAD_CHAR_DEV;
6536 else if (LINUX_S_ISBLK(inode.i_mode)
6537 && !e2fsck_pass1_check_device_inode(fs, &inode))
6538 problem = PR_2_BAD_BLOCK_DEV;
6539 else if (LINUX_S_ISFIFO(inode.i_mode)
6540 && !e2fsck_pass1_check_device_inode(fs, &inode))
6541 problem = PR_2_BAD_FIFO;
6542 else if (LINUX_S_ISSOCK(inode.i_mode)
6543 && !e2fsck_pass1_check_device_inode(fs, &inode))
6544 problem = PR_2_BAD_SOCKET;
6545 else if (LINUX_S_ISLNK(inode.i_mode)
6546 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
6547 problem = PR_2_INVALID_SYMLINK;
6551 if (fix_problem(ctx, problem, &pctx)) {
6552 deallocate_inode(ctx, ino, 0);
6553 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6561 if (inode.i_faddr) {
6562 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
6569 switch (fs->super->s_creator_os) {
6571 frag = &inode.osd2.linux2.l_i_frag;
6572 fsize = &inode.osd2.linux2.l_i_fsize;
6575 frag = &inode.osd2.hurd2.h_i_frag;
6576 fsize = &inode.osd2.hurd2.h_i_fsize;
6579 frag = &inode.osd2.masix2.m_i_frag;
6580 fsize = &inode.osd2.masix2.m_i_fsize;
6585 if (frag && *frag) {
6587 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
6594 if (fsize && *fsize) {
6596 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
6604 if (inode.i_file_acl &&
6605 ((inode.i_file_acl < fs->super->s_first_data_block) ||
6606 (inode.i_file_acl >= fs->super->s_blocks_count))) {
6607 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
6608 inode.i_file_acl = 0;
6613 if (inode.i_dir_acl &&
6614 LINUX_S_ISDIR(inode.i_mode)) {
6615 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
6616 inode.i_dir_acl = 0;
6623 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
6625 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6631 * allocate_dir_block --- this function allocates a new directory
6632 * block for a particular inode; this is done if a directory has
6633 * a "hole" in it, or if a directory has a illegal block number
6634 * that was zeroed out and now needs to be replaced.
6636 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
6637 struct problem_context *pctx)
6639 ext2_filsys fs = ctx->fs;
6642 struct ext2_inode inode;
6644 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
6648 * Read the inode and block bitmaps in; we'll be messing with
6651 e2fsck_read_bitmaps(ctx);
6654 * First, find a free block
6656 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6657 if (pctx->errcode) {
6658 pctx->str = "ext2fs_new_block";
6659 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6662 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6663 ext2fs_mark_block_bitmap(fs->block_map, blk);
6664 ext2fs_mark_bb_dirty(fs);
6667 * Now let's create the actual data block for the inode
6670 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
6672 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
6673 EXT2_ROOT_INO, &block);
6675 if (pctx->errcode) {
6676 pctx->str = "ext2fs_new_dir_block";
6677 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6681 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
6682 ext2fs_free_mem(&block);
6683 if (pctx->errcode) {
6684 pctx->str = "ext2fs_write_dir_block";
6685 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6690 * Update the inode block count
6692 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
6693 inode.i_blocks += fs->blocksize / 512;
6694 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
6695 inode.i_size = (db->blockcnt+1) * fs->blocksize;
6696 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
6699 * Finally, update the block pointers for the inode
6702 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
6703 0, update_dir_block, db);
6704 if (pctx->errcode) {
6705 pctx->str = "ext2fs_block_iterate";
6706 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
6714 * This is a helper function for allocate_dir_block().
6716 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
6718 e2_blkcnt_t blockcnt,
6719 blk_t ref_block FSCK_ATTR((unused)),
6720 int ref_offset FSCK_ATTR((unused)),
6723 struct ext2_db_entry *db;
6725 db = (struct ext2_db_entry *) priv_data;
6726 if (db->blockcnt == (int) blockcnt) {
6727 *block_nr = db->blk;
6728 return BLOCK_CHANGED;
6734 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
6736 * Pass #3 assures that all directories are connected to the
6737 * filesystem tree, using the following algorithm:
6739 * First, the root directory is checked to make sure it exists; if
6740 * not, e2fsck will offer to create a new one. It is then marked as
6743 * Then, pass3 interates over all directory inodes; for each directory
6744 * it attempts to trace up the filesystem tree, using dirinfo.parent
6745 * until it reaches a directory which has been marked "done". If it
6746 * can not do so, then the directory must be disconnected, and e2fsck
6747 * will offer to reconnect it to /lost+found. While it is chasing
6748 * parent pointers up the filesystem tree, if pass3 sees a directory
6749 * twice, then it has detected a filesystem loop, and it will again
6750 * offer to reconnect the directory to /lost+found in to break the
6753 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
6754 * reconnect inodes to /lost+found; this subroutine is also used by
6755 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
6756 * is responsible for creating /lost+found if it does not exist.
6758 * Pass 3 frees the following data structures:
6759 * - The dirinfo directory information cache.
6762 static void check_root(e2fsck_t ctx);
6763 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6764 struct problem_context *pctx);
6765 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
6767 static ext2fs_inode_bitmap inode_loop_detect;
6768 static ext2fs_inode_bitmap inode_done_map;
6770 static void e2fsck_pass3(e2fsck_t ctx)
6772 ext2_filsys fs = ctx->fs;
6774 struct problem_context pctx;
6775 struct dir_info *dir;
6776 unsigned long maxdirs, count;
6778 clear_problem_context(&pctx);
6782 if (!(ctx->options & E2F_OPT_PREEN))
6783 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
6786 * Allocate some bitmaps to do loop detection.
6788 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
6792 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
6793 ctx->flags |= E2F_FLAG_ABORT;
6797 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6800 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
6802 maxdirs = e2fsck_get_num_dirinfo(ctx);
6806 if ((ctx->progress)(ctx, 3, 0, maxdirs))
6809 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
6810 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6812 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
6814 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
6815 if (check_directory(ctx, dir, &pctx))
6820 * Force the creation of /lost+found if not present
6822 if ((ctx->flags & E2F_OPT_READONLY) == 0)
6823 e2fsck_get_lost_and_found(ctx, 1);
6826 * If there are any directories that need to be indexed or
6827 * optimized, do it here.
6829 e2fsck_rehash_directories(ctx);
6832 e2fsck_free_dir_info(ctx);
6833 ext2fs_free_inode_bitmap(inode_loop_detect);
6834 inode_loop_detect = 0;
6835 ext2fs_free_inode_bitmap(inode_done_map);
6840 * This makes sure the root inode is present; if not, we ask if the
6841 * user wants us to create it. Not creating it is a fatal error.
6843 static void check_root(e2fsck_t ctx)
6845 ext2_filsys fs = ctx->fs;
6847 struct ext2_inode inode;
6849 struct problem_context pctx;
6851 clear_problem_context(&pctx);
6853 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
6855 * If the root inode is not a directory, die here. The
6856 * user must have answered 'no' in pass1 when we
6857 * offered to clear it.
6859 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
6861 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
6862 ctx->flags |= E2F_FLAG_ABORT;
6867 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
6868 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
6869 ctx->flags |= E2F_FLAG_ABORT;
6873 e2fsck_read_bitmaps(ctx);
6876 * First, find a free block
6878 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
6880 pctx.str = "ext2fs_new_block";
6881 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6882 ctx->flags |= E2F_FLAG_ABORT;
6885 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6886 ext2fs_mark_block_bitmap(fs->block_map, blk);
6887 ext2fs_mark_bb_dirty(fs);
6890 * Now let's create the actual data block for the inode
6892 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
6895 pctx.str = "ext2fs_new_dir_block";
6896 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6897 ctx->flags |= E2F_FLAG_ABORT;
6901 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
6903 pctx.str = "ext2fs_write_dir_block";
6904 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6905 ctx->flags |= E2F_FLAG_ABORT;
6908 ext2fs_free_mem(&block);
6911 * Set up the inode structure
6913 memset(&inode, 0, sizeof(inode));
6914 inode.i_mode = 040755;
6915 inode.i_size = fs->blocksize;
6916 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
6917 inode.i_links_count = 2;
6918 inode.i_blocks = fs->blocksize / 512;
6919 inode.i_block[0] = blk;
6922 * Write out the inode.
6924 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
6926 pctx.str = "ext2fs_write_inode";
6927 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
6928 ctx->flags |= E2F_FLAG_ABORT;
6933 * Miscellaneous bookkeeping...
6935 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
6936 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
6937 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
6939 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
6940 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
6941 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
6942 ext2fs_mark_ib_dirty(fs);
6946 * This subroutine is responsible for making sure that a particular
6947 * directory is connected to the root; if it isn't we trace it up as
6948 * far as we can go, and then offer to connect the resulting parent to
6949 * the lost+found. We have to do loop detection; if we ever discover
6950 * a loop, we treat that as a disconnected directory and offer to
6951 * reparent it to lost+found.
6953 * However, loop detection is expensive, because for very large
6954 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
6955 * is non-trivial. Loops in filesystems are also a rare error case,
6956 * and we shouldn't optimize for error cases. So we try two passes of
6957 * the algorithm. The first time, we ignore loop detection and merely
6958 * increment a counter; if the counter exceeds some extreme threshold,
6959 * then we try again with the loop detection bitmap enabled.
6961 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
6962 struct problem_context *pctx)
6964 ext2_filsys fs = ctx->fs;
6965 struct dir_info *p = dir;
6966 int loop_pass = 0, parent_count = 0;
6973 * Mark this inode as being "done"; by the time we
6974 * return from this function, the inode we either be
6975 * verified as being connected to the directory tree,
6976 * or we will have offered to reconnect this to
6979 * If it was marked done already, then we've reached a
6980 * parent we've already checked.
6982 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
6986 * If this directory doesn't have a parent, or we've
6987 * seen the parent once already, then offer to
6988 * reparent it to lost+found
6992 (ext2fs_test_inode_bitmap(inode_loop_detect,
6995 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
6996 if (e2fsck_reconnect_file(ctx, pctx->ino))
6997 ext2fs_unmark_valid(fs);
6999 p = e2fsck_get_dir_info(ctx, pctx->ino);
7000 p->parent = ctx->lost_and_found;
7001 fix_dotdot(ctx, p, ctx->lost_and_found);
7006 p = e2fsck_get_dir_info(ctx, p->parent);
7008 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
7012 ext2fs_mark_inode_bitmap(inode_loop_detect,
7014 } else if (parent_count++ > 2048) {
7016 * If we've run into a path depth that's
7017 * greater than 2048, try again with the inode
7018 * loop bitmap turned on and start from the
7022 if (inode_loop_detect)
7023 ext2fs_clear_inode_bitmap(inode_loop_detect);
7025 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
7026 if (pctx->errcode) {
7029 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
7030 ctx->flags |= E2F_FLAG_ABORT;
7039 * Make sure that .. and the parent directory are the same;
7040 * offer to fix it if not.
7042 if (dir->parent != dir->dotdot) {
7043 pctx->ino = dir->ino;
7044 pctx->ino2 = dir->dotdot;
7045 pctx->dir = dir->parent;
7046 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
7047 fix_dotdot(ctx, dir, dir->parent);
7053 * This routine gets the lost_and_found inode, making it a directory
7056 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
7058 ext2_filsys fs = ctx->fs;
7062 struct ext2_inode inode;
7064 static const char name[] = "lost+found";
7065 struct problem_context pctx;
7066 struct dir_info *dirinfo;
7068 if (ctx->lost_and_found)
7069 return ctx->lost_and_found;
7071 clear_problem_context(&pctx);
7073 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
7074 sizeof(name)-1, 0, &ino);
7078 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
7079 ctx->lost_and_found = ino;
7083 /* Lost+found isn't a directory! */
7087 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
7090 /* OK, unlink the old /lost+found file. */
7091 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
7093 pctx.str = "ext2fs_unlink";
7094 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7097 dirinfo = e2fsck_get_dir_info(ctx, ino);
7099 dirinfo->parent = 0;
7100 e2fsck_adjust_inode_count(ctx, ino, -1);
7101 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
7102 pctx.errcode = retval;
7103 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
7105 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
7109 * Read the inode and block bitmaps in; we'll be messing with
7112 e2fsck_read_bitmaps(ctx);
7115 * First, find a free block
7117 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
7119 pctx.errcode = retval;
7120 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
7123 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
7124 ext2fs_block_alloc_stats(fs, blk, +1);
7127 * Next find a free inode.
7129 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
7130 ctx->inode_used_map, &ino);
7132 pctx.errcode = retval;
7133 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
7136 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
7137 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
7138 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
7141 * Now let's create the actual data block for the inode
7143 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
7145 pctx.errcode = retval;
7146 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
7150 retval = ext2fs_write_dir_block(fs, blk, block);
7151 ext2fs_free_mem(&block);
7153 pctx.errcode = retval;
7154 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
7159 * Set up the inode structure
7161 memset(&inode, 0, sizeof(inode));
7162 inode.i_mode = 040700;
7163 inode.i_size = fs->blocksize;
7164 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
7165 inode.i_links_count = 2;
7166 inode.i_blocks = fs->blocksize / 512;
7167 inode.i_block[0] = blk;
7170 * Next, write out the inode.
7172 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
7174 pctx.str = "ext2fs_write_inode";
7175 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7179 * Finally, create the directory link
7181 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
7183 pctx.str = "ext2fs_link";
7184 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
7189 * Miscellaneous bookkeeping that needs to be kept straight.
7191 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
7192 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
7193 ext2fs_icount_store(ctx->inode_count, ino, 2);
7194 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
7195 ctx->lost_and_found = ino;
7200 * This routine will connect a file to lost+found
7202 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
7204 ext2_filsys fs = ctx->fs;
7207 struct problem_context pctx;
7208 struct ext2_inode inode;
7211 clear_problem_context(&pctx);
7214 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
7215 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
7216 ctx->bad_lost_and_found++;
7218 if (ctx->bad_lost_and_found) {
7219 fix_problem(ctx, PR_3_NO_LPF, &pctx);
7223 sprintf(name, "#%u", ino);
7224 if (ext2fs_read_inode(fs, ino, &inode) == 0)
7225 file_type = ext2_file_type(inode.i_mode);
7226 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
7227 if (retval == EXT2_ET_DIR_NO_SPACE) {
7228 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
7230 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
7233 pctx.errcode = retval;
7234 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
7237 retval = ext2fs_link(fs, ctx->lost_and_found, name,
7241 pctx.errcode = retval;
7242 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
7245 e2fsck_adjust_inode_count(ctx, ino, 1);
7251 * Utility routine to adjust the inode counts on an inode.
7253 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
7255 ext2_filsys fs = ctx->fs;
7257 struct ext2_inode inode;
7262 retval = ext2fs_read_inode(fs, ino, &inode);
7267 ext2fs_icount_increment(ctx->inode_count, ino, 0);
7268 if (inode.i_links_count == (__u16) ~0)
7270 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
7271 inode.i_links_count++;
7272 } else if (adj == -1) {
7273 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
7274 if (inode.i_links_count == 0)
7276 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
7277 inode.i_links_count--;
7280 retval = ext2fs_write_inode(fs, ino, &inode);
7288 * Fix parent --- this routine fixes up the parent of a directory.
7290 struct fix_dotdot_struct {
7297 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
7298 int offset FSCK_ATTR((unused)),
7299 int blocksize FSCK_ATTR((unused)),
7300 char *buf FSCK_ATTR((unused)),
7303 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
7305 struct problem_context pctx;
7307 if ((dirent->name_len & 0xFF) != 2)
7309 if (strncmp(dirent->name, "..", 2))
7312 clear_problem_context(&pctx);
7314 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
7316 pctx.errcode = retval;
7317 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7319 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
7321 pctx.errcode = retval;
7322 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
7324 dirent->inode = fp->parent;
7327 return DIRENT_ABORT | DIRENT_CHANGED;
7330 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
7332 ext2_filsys fs = ctx->fs;
7334 struct fix_dotdot_struct fp;
7335 struct problem_context pctx;
7342 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
7343 0, fix_dotdot_proc, &fp);
7344 if (retval || !fp.done) {
7345 clear_problem_context(&pctx);
7346 pctx.ino = dir->ino;
7347 pctx.errcode = retval;
7348 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
7349 PR_3_FIX_PARENT_NOFIND, &pctx);
7350 ext2fs_unmark_valid(fs);
7352 dir->dotdot = parent;
7358 * These routines are responsible for expanding a /lost+found if it is
7362 struct expand_dir_struct {
7364 int guaranteed_size;
7371 static int expand_dir_proc(ext2_filsys fs,
7373 e2_blkcnt_t blockcnt,
7374 blk_t ref_block FSCK_ATTR((unused)),
7375 int ref_offset FSCK_ATTR((unused)),
7378 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
7380 static blk_t last_blk = 0;
7387 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
7391 es->last_block = blockcnt;
7393 last_blk = *blocknr;
7396 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
7403 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
7409 retval = ext2fs_write_dir_block(fs, new_blk, block);
7411 retval = ext2fs_get_mem(fs->blocksize, &block);
7416 memset(block, 0, fs->blocksize);
7417 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
7423 ext2fs_free_mem(&block);
7425 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
7426 ext2fs_block_alloc_stats(fs, new_blk, +1);
7430 return (BLOCK_CHANGED | BLOCK_ABORT);
7432 return BLOCK_CHANGED;
7435 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
7436 int num, int guaranteed_size)
7438 ext2_filsys fs = ctx->fs;
7440 struct expand_dir_struct es;
7441 struct ext2_inode inode;
7443 if (!(fs->flags & EXT2_FLAG_RW))
7444 return EXT2_ET_RO_FILSYS;
7447 * Read the inode and block bitmaps in; we'll be messing with
7450 e2fsck_read_bitmaps(ctx);
7452 retval = ext2fs_check_directory(fs, dir);
7457 es.guaranteed_size = guaranteed_size;
7463 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
7464 0, expand_dir_proc, &es);
7470 * Update the size and block count fields in the inode.
7472 retval = ext2fs_read_inode(fs, dir, &inode);
7476 inode.i_size = (es.last_block + 1) * fs->blocksize;
7477 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
7479 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
7485 * pass4.c -- pass #4 of e2fsck: Check reference counts
7487 * Pass 4 frees the following data structures:
7488 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
7492 * This routine is called when an inode is not connected to the
7495 * This subroutine returns 1 then the caller shouldn't bother with the
7496 * rest of the pass 4 tests.
7498 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
7500 ext2_filsys fs = ctx->fs;
7501 struct ext2_inode inode;
7502 struct problem_context pctx;
7504 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
7505 clear_problem_context(&pctx);
7507 pctx.inode = &inode;
7510 * Offer to delete any zero-length files that does not have
7511 * blocks. If there is an EA block, it might have useful
7512 * information, so we won't prompt to delete it, but let it be
7513 * reconnected to lost+found.
7515 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
7516 LINUX_S_ISDIR(inode.i_mode))) {
7517 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
7518 ext2fs_icount_store(ctx->inode_link_info, i, 0);
7519 inode.i_links_count = 0;
7520 inode.i_dtime = time(0);
7521 e2fsck_write_inode(ctx, i, &inode,
7522 "disconnect_inode");
7524 * Fix up the bitmaps...
7526 e2fsck_read_bitmaps(ctx);
7527 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
7528 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
7529 ext2fs_inode_alloc_stats2(fs, i, -1,
7530 LINUX_S_ISDIR(inode.i_mode));
7536 * Prompt to reconnect.
7538 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
7539 if (e2fsck_reconnect_file(ctx, i))
7540 ext2fs_unmark_valid(fs);
7543 * If we don't attach the inode, then skip the
7544 * i_links_test since there's no point in trying to
7545 * force i_links_count to zero.
7547 ext2fs_unmark_valid(fs);
7554 static void e2fsck_pass4(e2fsck_t ctx)
7556 ext2_filsys fs = ctx->fs;
7558 struct ext2_inode inode;
7559 struct problem_context pctx;
7560 __u16 link_count, link_counted;
7562 int group, maxgroup;
7566 clear_problem_context(&pctx);
7568 if (!(ctx->options & E2F_OPT_PREEN))
7569 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
7572 maxgroup = fs->group_desc_count;
7574 if ((ctx->progress)(ctx, 4, 0, maxgroup))
7577 for (i=1; i <= fs->super->s_inodes_count; i++) {
7578 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7580 if ((i % fs->super->s_inodes_per_group) == 0) {
7583 if ((ctx->progress)(ctx, 4, group, maxgroup))
7586 if (i == EXT2_BAD_INO ||
7587 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
7589 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
7590 (ctx->inode_imagic_map &&
7591 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)))
7593 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
7594 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
7595 if (link_counted == 0) {
7597 buf = e2fsck_allocate_memory(ctx,
7598 fs->blocksize, "bad_inode buffer");
7599 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
7601 if (disconnect_inode(ctx, i))
7603 ext2fs_icount_fetch(ctx->inode_link_info, i,
7605 ext2fs_icount_fetch(ctx->inode_count, i,
7608 if (link_counted != link_count) {
7609 e2fsck_read_inode(ctx, i, &inode, "pass4");
7611 pctx.inode = &inode;
7612 if (link_count != inode.i_links_count) {
7613 pctx.num = link_count;
7615 PR_4_INCONSISTENT_COUNT, &pctx);
7617 pctx.num = link_counted;
7618 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
7619 inode.i_links_count = link_counted;
7620 e2fsck_write_inode(ctx, i, &inode, "pass4");
7624 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
7625 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
7626 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
7627 ctx->inode_imagic_map = 0;
7628 ext2fs_free_mem(&buf);
7632 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
7635 #define NO_BLK ((blk_t) -1)
7637 static void print_bitmap_problem(e2fsck_t ctx, int problem,
7638 struct problem_context *pctx)
7641 case PR_5_BLOCK_UNUSED:
7642 if (pctx->blk == pctx->blk2)
7645 problem = PR_5_BLOCK_RANGE_UNUSED;
7647 case PR_5_BLOCK_USED:
7648 if (pctx->blk == pctx->blk2)
7651 problem = PR_5_BLOCK_RANGE_USED;
7653 case PR_5_INODE_UNUSED:
7654 if (pctx->ino == pctx->ino2)
7657 problem = PR_5_INODE_RANGE_UNUSED;
7659 case PR_5_INODE_USED:
7660 if (pctx->ino == pctx->ino2)
7663 problem = PR_5_INODE_RANGE_USED;
7666 fix_problem(ctx, problem, pctx);
7667 pctx->blk = pctx->blk2 = NO_BLK;
7668 pctx->ino = pctx->ino2 = 0;
7671 static void check_block_bitmaps(e2fsck_t ctx)
7673 ext2_filsys fs = ctx->fs;
7677 unsigned int blocks = 0;
7678 unsigned int free_blocks = 0;
7681 struct problem_context pctx;
7682 int problem, save_problem, fixit, had_problem;
7685 clear_problem_context(&pctx);
7686 free_array = (int *) e2fsck_allocate_memory(ctx,
7687 fs->group_desc_count * sizeof(int), "free block count array");
7689 if ((fs->super->s_first_data_block <
7690 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
7691 (fs->super->s_blocks_count-1 >
7692 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
7694 pctx.blk = fs->super->s_first_data_block;
7695 pctx.blk2 = fs->super->s_blocks_count -1;
7696 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
7697 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
7698 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7700 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7704 if ((fs->super->s_first_data_block <
7705 ext2fs_get_block_bitmap_start(fs->block_map)) ||
7706 (fs->super->s_blocks_count-1 >
7707 ext2fs_get_block_bitmap_end(fs->block_map))) {
7709 pctx.blk = fs->super->s_first_data_block;
7710 pctx.blk2 = fs->super->s_blocks_count -1;
7711 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
7712 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
7713 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7715 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7722 pctx.blk = pctx.blk2 = NO_BLK;
7723 for (i = fs->super->s_first_data_block;
7724 i < fs->super->s_blocks_count;
7726 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
7727 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
7729 if (actual == bitmap)
7732 if (!actual && bitmap) {
7734 * Block not used, but marked in use in the bitmap.
7736 problem = PR_5_BLOCK_UNUSED;
7739 * Block used, but not marked in use in the bitmap.
7741 problem = PR_5_BLOCK_USED;
7743 if (pctx.blk == NO_BLK) {
7744 pctx.blk = pctx.blk2 = i;
7745 save_problem = problem;
7747 if ((problem == save_problem) &&
7751 print_bitmap_problem(ctx, save_problem, &pctx);
7752 pctx.blk = pctx.blk2 = i;
7753 save_problem = problem;
7756 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7765 if ((blocks == fs->super->s_blocks_per_group) ||
7766 (i == fs->super->s_blocks_count-1)) {
7767 free_array[group] = group_free;
7772 if ((ctx->progress)(ctx, 5, group,
7773 fs->group_desc_count*2))
7777 if (pctx.blk != NO_BLK)
7778 print_bitmap_problem(ctx, save_problem, &pctx);
7780 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
7783 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7786 ext2fs_free_block_bitmap(fs->block_map);
7787 retval = ext2fs_copy_bitmap(ctx->block_found_map,
7790 clear_problem_context(&pctx);
7791 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
7792 ctx->flags |= E2F_FLAG_ABORT;
7795 ext2fs_set_bitmap_padding(fs->block_map);
7796 ext2fs_mark_bb_dirty(fs);
7798 /* Redo the counts */
7799 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
7800 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7802 } else if (fixit == 0)
7803 ext2fs_unmark_valid(fs);
7805 for (i = 0; i < fs->group_desc_count; i++) {
7806 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
7808 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
7809 pctx.blk2 = free_array[i];
7811 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
7813 fs->group_desc[i].bg_free_blocks_count =
7815 ext2fs_mark_super_dirty(fs);
7817 ext2fs_unmark_valid(fs);
7820 if (free_blocks != fs->super->s_free_blocks_count) {
7822 pctx.blk = fs->super->s_free_blocks_count;
7823 pctx.blk2 = free_blocks;
7825 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
7826 fs->super->s_free_blocks_count = free_blocks;
7827 ext2fs_mark_super_dirty(fs);
7829 ext2fs_unmark_valid(fs);
7831 ext2fs_free_mem(&free_array);
7834 static void check_inode_bitmaps(e2fsck_t ctx)
7836 ext2_filsys fs = ctx->fs;
7838 unsigned int free_inodes = 0;
7842 unsigned int inodes = 0;
7847 struct problem_context pctx;
7848 int problem, save_problem, fixit, had_problem;
7850 clear_problem_context(&pctx);
7851 free_array = (int *) e2fsck_allocate_memory(ctx,
7852 fs->group_desc_count * sizeof(int), "free inode count array");
7854 dir_array = (int *) e2fsck_allocate_memory(ctx,
7855 fs->group_desc_count * sizeof(int), "directory count array");
7857 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
7858 (fs->super->s_inodes_count >
7859 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
7862 pctx.blk2 = fs->super->s_inodes_count;
7863 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
7864 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
7865 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7867 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7870 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
7871 (fs->super->s_inodes_count >
7872 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
7875 pctx.blk2 = fs->super->s_inodes_count;
7876 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
7877 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
7878 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
7880 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
7887 pctx.ino = pctx.ino2 = 0;
7888 for (i = 1; i <= fs->super->s_inodes_count; i++) {
7889 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
7890 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
7892 if (actual == bitmap)
7895 if (!actual && bitmap) {
7897 * Inode wasn't used, but marked in bitmap
7899 problem = PR_5_INODE_UNUSED;
7900 } else /* if (actual && !bitmap) */ {
7902 * Inode used, but not in bitmap
7904 problem = PR_5_INODE_USED;
7906 if (pctx.ino == 0) {
7907 pctx.ino = pctx.ino2 = i;
7908 save_problem = problem;
7910 if ((problem == save_problem) &&
7914 print_bitmap_problem(ctx, save_problem, &pctx);
7915 pctx.ino = pctx.ino2 = i;
7916 save_problem = problem;
7919 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
7927 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
7931 if ((inodes == fs->super->s_inodes_per_group) ||
7932 (i == fs->super->s_inodes_count)) {
7933 free_array[group] = group_free;
7934 dir_array[group] = dirs_count;
7940 if ((ctx->progress)(ctx, 5,
7941 group + fs->group_desc_count,
7942 fs->group_desc_count*2))
7947 print_bitmap_problem(ctx, save_problem, &pctx);
7950 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
7953 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
7956 ext2fs_free_inode_bitmap(fs->inode_map);
7957 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
7960 clear_problem_context(&pctx);
7961 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
7962 ctx->flags |= E2F_FLAG_ABORT;
7965 ext2fs_set_bitmap_padding(fs->inode_map);
7966 ext2fs_mark_ib_dirty(fs);
7969 inodes = 0; free_inodes = 0; group_free = 0;
7970 dirs_count = 0; group = 0;
7971 memset(free_array, 0, fs->group_desc_count * sizeof(int));
7972 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
7974 } else if (fixit == 0)
7975 ext2fs_unmark_valid(fs);
7977 for (i = 0; i < fs->group_desc_count; i++) {
7978 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
7980 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
7981 pctx.ino2 = free_array[i];
7982 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
7984 fs->group_desc[i].bg_free_inodes_count =
7986 ext2fs_mark_super_dirty(fs);
7988 ext2fs_unmark_valid(fs);
7990 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
7992 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
7993 pctx.ino2 = dir_array[i];
7995 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
7997 fs->group_desc[i].bg_used_dirs_count =
7999 ext2fs_mark_super_dirty(fs);
8001 ext2fs_unmark_valid(fs);
8004 if (free_inodes != fs->super->s_free_inodes_count) {
8006 pctx.ino = fs->super->s_free_inodes_count;
8007 pctx.ino2 = free_inodes;
8009 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
8010 fs->super->s_free_inodes_count = free_inodes;
8011 ext2fs_mark_super_dirty(fs);
8013 ext2fs_unmark_valid(fs);
8015 ext2fs_free_mem(&free_array);
8016 ext2fs_free_mem(&dir_array);
8019 static void check_inode_end(e2fsck_t ctx)
8021 ext2_filsys fs = ctx->fs;
8022 ext2_ino_t end, save_inodes_count, i;
8023 struct problem_context pctx;
8025 clear_problem_context(&pctx);
8027 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
8028 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
8029 &save_inodes_count);
8032 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8033 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8036 if (save_inodes_count == end)
8039 for (i = save_inodes_count + 1; i <= end; i++) {
8040 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
8041 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
8042 for (i = save_inodes_count + 1; i <= end; i++)
8043 ext2fs_mark_inode_bitmap(fs->inode_map,
8045 ext2fs_mark_ib_dirty(fs);
8047 ext2fs_unmark_valid(fs);
8052 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
8053 save_inodes_count, 0);
8056 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8057 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8062 static void check_block_end(e2fsck_t ctx)
8064 ext2_filsys fs = ctx->fs;
8065 blk_t end, save_blocks_count, i;
8066 struct problem_context pctx;
8068 clear_problem_context(&pctx);
8070 end = fs->block_map->start +
8071 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
8072 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
8073 &save_blocks_count);
8076 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8077 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8080 if (save_blocks_count == end)
8083 for (i = save_blocks_count + 1; i <= end; i++) {
8084 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
8085 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
8086 for (i = save_blocks_count + 1; i <= end; i++)
8087 ext2fs_mark_block_bitmap(fs->block_map,
8089 ext2fs_mark_bb_dirty(fs);
8091 ext2fs_unmark_valid(fs);
8096 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
8097 save_blocks_count, 0);
8100 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
8101 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
8106 static void e2fsck_pass5(e2fsck_t ctx)
8108 struct problem_context pctx;
8112 clear_problem_context(&pctx);
8114 if (!(ctx->options & E2F_OPT_PREEN))
8115 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
8118 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
8121 e2fsck_read_bitmaps(ctx);
8123 check_block_bitmaps(ctx);
8124 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8126 check_inode_bitmaps(ctx);
8127 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8129 check_inode_end(ctx);
8130 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8132 check_block_end(ctx);
8133 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8136 ext2fs_free_inode_bitmap(ctx->inode_used_map);
8137 ctx->inode_used_map = 0;
8138 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
8139 ctx->inode_dir_map = 0;
8140 ext2fs_free_block_bitmap(ctx->block_found_map);
8141 ctx->block_found_map = 0;
8145 * problem.c --- report filesystem problems to the user
8148 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
8149 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
8150 #define PR_NO_DEFAULT 0x000004 /* Default to no */
8151 #define PR_MSG_ONLY 0x000008 /* Print message only */
8153 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
8155 #define PR_FATAL 0x001000 /* Fatal error */
8156 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
8158 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
8159 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
8160 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
8161 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
8162 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
8165 #define PROMPT_NONE 0
8166 #define PROMPT_FIX 1
8167 #define PROMPT_CLEAR 2
8168 #define PROMPT_RELOCATE 3
8169 #define PROMPT_ALLOCATE 4
8170 #define PROMPT_EXPAND 5
8171 #define PROMPT_CONNECT 6
8172 #define PROMPT_CREATE 7
8173 #define PROMPT_SALVAGE 8
8174 #define PROMPT_TRUNCATE 9
8175 #define PROMPT_CLEAR_INODE 10
8176 #define PROMPT_ABORT 11
8177 #define PROMPT_SPLIT 12
8178 #define PROMPT_CONTINUE 13
8179 #define PROMPT_CLONE 14
8180 #define PROMPT_DELETE 15
8181 #define PROMPT_SUPPRESS 16
8182 #define PROMPT_UNLINK 17
8183 #define PROMPT_CLEAR_HTREE 18
8184 #define PROMPT_RECREATE 19
8185 #define PROMPT_NULL 20
8187 struct e2fsck_problem {
8189 const char * e2p_description;
8192 problem_t second_code;
8195 struct latch_descr {
8198 problem_t end_message;
8203 * These are the prompts which are used to ask the user if they want
8206 static const char * const prompt[] = {
8207 N_("(no prompt)"), /* 0 */
8209 N_("Clear"), /* 2 */
8210 N_("Relocate"), /* 3 */
8211 N_("Allocate"), /* 4 */
8212 N_("Expand"), /* 5 */
8213 N_("Connect to /lost+found"), /* 6 */
8214 N_("Create"), /* 7 */
8215 N_("Salvage"), /* 8 */
8216 N_("Truncate"), /* 9 */
8217 N_("Clear inode"), /* 10 */
8218 N_("Abort"), /* 11 */
8219 N_("Split"), /* 12 */
8220 N_("Continue"), /* 13 */
8221 N_("Clone multiply-claimed blocks"), /* 14 */
8222 N_("Delete file"), /* 15 */
8223 N_("Suppress messages"),/* 16 */
8224 N_("Unlink"), /* 17 */
8225 N_("Clear HTree index"),/* 18 */
8226 N_("Recreate"), /* 19 */
8231 * These messages are printed when we are preen mode and we will be
8232 * automatically fixing the problem.
8234 static const char * const preen_msg[] = {
8235 N_("(NONE)"), /* 0 */
8236 N_("FIXED"), /* 1 */
8237 N_("CLEARED"), /* 2 */
8238 N_("RELOCATED"), /* 3 */
8239 N_("ALLOCATED"), /* 4 */
8240 N_("EXPANDED"), /* 5 */
8241 N_("RECONNECTED"), /* 6 */
8242 N_("CREATED"), /* 7 */
8243 N_("SALVAGED"), /* 8 */
8244 N_("TRUNCATED"), /* 9 */
8245 N_("INODE CLEARED"), /* 10 */
8246 N_("ABORTED"), /* 11 */
8247 N_("SPLIT"), /* 12 */
8248 N_("CONTINUING"), /* 13 */
8249 N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */
8250 N_("FILE DELETED"), /* 15 */
8251 N_("SUPPRESSED"), /* 16 */
8252 N_("UNLINKED"), /* 17 */
8253 N_("HTREE INDEX CLEARED"),/* 18 */
8254 N_("WILL RECREATE"), /* 19 */
8258 static const struct e2fsck_problem problem_table[] = {
8260 /* Pre-Pass 1 errors */
8262 /* Block bitmap not in group */
8263 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
8264 PROMPT_RELOCATE, PR_LATCH_RELOC },
8266 /* Inode bitmap not in group */
8267 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
8268 PROMPT_RELOCATE, PR_LATCH_RELOC },
8270 /* Inode table not in group */
8271 { PR_0_ITABLE_NOT_GROUP,
8272 N_("@i table for @g %g is not in @g. (@b %b)\n"
8273 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
8274 PROMPT_RELOCATE, PR_LATCH_RELOC },
8276 /* Superblock corrupt */
8278 N_("\nThe @S could not be read or does not describe a correct ext2\n"
8279 "@f. If the @v is valid and it really contains an ext2\n"
8280 "@f (and not swap or ufs or something else), then the @S\n"
8281 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
8282 " e2fsck -b %S <@v>\n\n"),
8283 PROMPT_NONE, PR_FATAL },
8285 /* Filesystem size is wrong */
8286 { PR_0_FS_SIZE_WRONG,
8287 N_("The @f size (according to the @S) is %b @bs\n"
8288 "The physical size of the @v is %c @bs\n"
8289 "Either the @S or the partition table is likely to be corrupt!\n"),
8292 /* Fragments not supported */
8293 { PR_0_NO_FRAGMENTS,
8294 N_("@S @b_size = %b, fragsize = %c.\n"
8295 "This version of e2fsck does not support fragment sizes different\n"
8296 "from the @b size.\n"),
8297 PROMPT_NONE, PR_FATAL },
8299 /* Bad blocks_per_group */
8300 { PR_0_BLOCKS_PER_GROUP,
8301 N_("@S @bs_per_group = %b, should have been %c\n"),
8302 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8304 /* Bad first_data_block */
8305 { PR_0_FIRST_DATA_BLOCK,
8306 N_("@S first_data_@b = %b, should have been %c\n"),
8307 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8309 /* Adding UUID to filesystem */
8311 N_("@f did not have a UUID; generating one.\n\n"),
8315 { PR_0_RELOCATE_HINT,
8316 N_("Note: if several inode or block bitmap blocks or part\n"
8317 "of the inode table require relocation, you may wish to try\n"
8318 "running e2fsck with the '-b %S' option first. The problem\n"
8319 "may lie only with the primary block group descriptors, and\n"
8320 "the backup block group descriptors may be OK.\n\n"),
8321 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
8323 /* Miscellaneous superblock corruption */
8324 { PR_0_MISC_CORRUPT_SUPER,
8325 N_("Corruption found in @S. (%s = %N).\n"),
8326 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
8328 /* Error determing physical device size of filesystem */
8329 { PR_0_GETSIZE_ERROR,
8330 N_("Error determining size of the physical @v: %m\n"),
8331 PROMPT_NONE, PR_FATAL },
8333 /* Inode count in superblock is incorrect */
8334 { PR_0_INODE_COUNT_WRONG,
8335 N_("@i count in @S is %i, @s %j.\n"),
8338 { PR_0_HURD_CLEAR_FILETYPE,
8339 N_("The Hurd does not support the filetype feature.\n"),
8342 /* Journal inode is invalid */
8343 { PR_0_JOURNAL_BAD_INODE,
8344 N_("@S has an @n ext3 @j (@i %i).\n"),
8345 PROMPT_CLEAR, PR_PREEN_OK },
8347 /* The external journal has (unsupported) multiple filesystems */
8348 { PR_0_JOURNAL_UNSUPP_MULTIFS,
8349 N_("External @j has multiple @f users (unsupported).\n"),
8350 PROMPT_NONE, PR_FATAL },
8352 /* Can't find external journal */
8353 { PR_0_CANT_FIND_JOURNAL,
8354 N_("Can't find external @j\n"),
8355 PROMPT_NONE, PR_FATAL },
8357 /* External journal has bad superblock */
8358 { PR_0_EXT_JOURNAL_BAD_SUPER,
8359 N_("External @j has bad @S\n"),
8360 PROMPT_NONE, PR_FATAL },
8362 /* Superblock has a bad journal UUID */
8363 { PR_0_JOURNAL_BAD_UUID,
8364 N_("External @j does not support this @f\n"),
8365 PROMPT_NONE, PR_FATAL },
8367 /* Journal has an unknown superblock type */
8368 { PR_0_JOURNAL_UNSUPP_SUPER,
8369 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
8370 "It is likely that your copy of e2fsck is old and/or doesn't "
8371 "support this @j format.\n"
8372 "It is also possible the @j @S is corrupt.\n"),
8373 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
8375 /* Journal superblock is corrupt */
8376 { PR_0_JOURNAL_BAD_SUPER,
8377 N_("Ext3 @j @S is corrupt.\n"),
8378 PROMPT_FIX, PR_PREEN_OK },
8380 /* Superblock flag should be cleared */
8381 { PR_0_JOURNAL_HAS_JOURNAL,
8382 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
8383 PROMPT_CLEAR, PR_PREEN_OK },
8385 /* Superblock flag is incorrect */
8386 { PR_0_JOURNAL_RECOVER_SET,
8387 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
8388 PROMPT_CLEAR, PR_PREEN_OK },
8390 /* Journal has data, but recovery flag is clear */
8391 { PR_0_JOURNAL_RECOVERY_CLEAR,
8392 N_("ext3 recovery flag is clear, but @j has data.\n"),
8395 /* Ask if we should clear the journal */
8396 { PR_0_JOURNAL_RESET_JOURNAL,
8398 PROMPT_NULL, PR_PREEN_NOMSG },
8400 /* Ask if we should run the journal anyway */
8402 N_("Run @j anyway"),
8405 /* Run the journal by default */
8406 { PR_0_JOURNAL_RUN_DEFAULT,
8407 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
8410 /* Clearing orphan inode */
8411 { PR_0_ORPHAN_CLEAR_INODE,
8412 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
8415 /* Illegal block found in orphaned inode */
8416 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
8417 N_("@I @b #%B (%b) found in @o @i %i.\n"),
8420 /* Already cleared block found in orphaned inode */
8421 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
8422 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
8425 /* Illegal orphan inode in superblock */
8426 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
8427 N_("@I @o @i %i in @S.\n"),
8430 /* Illegal inode in orphaned inode list */
8431 { PR_0_ORPHAN_ILLEGAL_INODE,
8432 N_("@I @i %i in @o @i list.\n"),
8435 /* Filesystem revision is 0, but feature flags are set */
8436 { PR_0_FS_REV_LEVEL,
8437 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8438 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8440 /* Journal superblock has an unknown read-only feature flag set */
8441 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
8442 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
8445 /* Journal superblock has an unknown incompatible feature flag set */
8446 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
8447 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
8450 /* Journal has unsupported version number */
8451 { PR_0_JOURNAL_UNSUPP_VERSION,
8452 N_("@j version not supported by this e2fsck.\n"),
8455 /* Moving journal to hidden file */
8456 { PR_0_MOVE_JOURNAL,
8457 N_("Moving @j from /%s to hidden @i.\n\n"),
8460 /* Error moving journal to hidden file */
8461 { PR_0_ERR_MOVE_JOURNAL,
8462 N_("Error moving @j: %m\n\n"),
8465 /* Clearing V2 journal superblock */
8466 { PR_0_CLEAR_V2_JOURNAL,
8467 N_("Found @n V2 @j @S fields (from V1 @j).\n"
8468 "Clearing fields beyond the V1 @j @S...\n\n"),
8471 /* Backup journal inode blocks */
8473 N_("Backing up @j @i @b information.\n\n"),
8476 /* Reserved blocks w/o resize_inode */
8477 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
8478 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
8479 "is %N; @s zero. "),
8482 /* Resize_inode not enabled, but resize inode is non-zero */
8483 { PR_0_CLEAR_RESIZE_INODE,
8484 N_("Resize_@i not enabled, but the resize @i is non-zero. "),
8487 /* Resize inode invalid */
8488 { PR_0_RESIZE_INODE_INVALID,
8489 N_("Resize @i not valid. "),
8490 PROMPT_RECREATE, 0 },
8494 /* Pass 1: Checking inodes, blocks, and sizes */
8496 N_("Pass 1: Checking @is, @bs, and sizes\n"),
8499 /* Root directory is not an inode */
8500 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
8503 /* Root directory has dtime set */
8505 N_("@r has dtime set (probably due to old mke2fs). "),
8506 PROMPT_FIX, PR_PREEN_OK },
8508 /* Reserved inode has bad mode */
8509 { PR_1_RESERVED_BAD_MODE,
8510 N_("Reserved @i %i (%Q) has @n mode. "),
8511 PROMPT_CLEAR, PR_PREEN_OK },
8513 /* Deleted inode has zero dtime */
8515 N_("@D @i %i has zero dtime. "),
8516 PROMPT_FIX, PR_PREEN_OK },
8518 /* Inode in use, but dtime set */
8520 N_("@i %i is in use, but has dtime set. "),
8521 PROMPT_FIX, PR_PREEN_OK },
8523 /* Zero-length directory */
8524 { PR_1_ZERO_LENGTH_DIR,
8525 N_("@i %i is a @z @d. "),
8526 PROMPT_CLEAR, PR_PREEN_OK },
8528 /* Block bitmap conflicts with some other fs block */
8530 N_("@g %g's @b @B at %b @C.\n"),
8531 PROMPT_RELOCATE, 0 },
8533 /* Inode bitmap conflicts with some other fs block */
8535 N_("@g %g's @i @B at %b @C.\n"),
8536 PROMPT_RELOCATE, 0 },
8538 /* Inode table conflicts with some other fs block */
8539 { PR_1_ITABLE_CONFLICT,
8540 N_("@g %g's @i table at %b @C.\n"),
8541 PROMPT_RELOCATE, 0 },
8543 /* Block bitmap is on a bad block */
8544 { PR_1_BB_BAD_BLOCK,
8545 N_("@g %g's @b @B (%b) is bad. "),
8546 PROMPT_RELOCATE, 0 },
8548 /* Inode bitmap is on a bad block */
8549 { PR_1_IB_BAD_BLOCK,
8550 N_("@g %g's @i @B (%b) is bad. "),
8551 PROMPT_RELOCATE, 0 },
8553 /* Inode has incorrect i_size */
8555 N_("@i %i, i_size is %Is, @s %N. "),
8556 PROMPT_FIX, PR_PREEN_OK },
8558 /* Inode has incorrect i_blocks */
8559 { PR_1_BAD_I_BLOCKS,
8560 N_("@i %i, i_@bs is %Ib, @s %N. "),
8561 PROMPT_FIX, PR_PREEN_OK },
8563 /* Illegal blocknumber in inode */
8564 { PR_1_ILLEGAL_BLOCK_NUM,
8565 N_("@I @b #%B (%b) in @i %i. "),
8566 PROMPT_CLEAR, PR_LATCH_BLOCK },
8568 /* Block number overlaps fs metadata */
8569 { PR_1_BLOCK_OVERLAPS_METADATA,
8570 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
8571 PROMPT_CLEAR, PR_LATCH_BLOCK },
8573 /* Inode has illegal blocks (latch question) */
8574 { PR_1_INODE_BLOCK_LATCH,
8575 N_("@i %i has illegal @b(s). "),
8578 /* Too many bad blocks in inode */
8579 { PR_1_TOO_MANY_BAD_BLOCKS,
8580 N_("Too many illegal @bs in @i %i.\n"),
8581 PROMPT_CLEAR_INODE, PR_NO_OK },
8583 /* Illegal block number in bad block inode */
8584 { PR_1_BB_ILLEGAL_BLOCK_NUM,
8585 N_("@I @b #%B (%b) in bad @b @i. "),
8586 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8588 /* Bad block inode has illegal blocks (latch question) */
8589 { PR_1_INODE_BBLOCK_LATCH,
8590 N_("Bad @b @i has illegal @b(s). "),
8593 /* Duplicate or bad blocks in use! */
8594 { PR_1_DUP_BLOCKS_PREENSTOP,
8595 N_("Duplicate or bad @b in use!\n"),
8598 /* Bad block used as bad block indirect block */
8599 { PR_1_BBINODE_BAD_METABLOCK,
8600 N_("Bad @b %b used as bad @b @i indirect @b. "),
8601 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8603 /* Inconsistency can't be fixed prompt */
8604 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
8605 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
8606 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
8608 PROMPT_CONTINUE, PR_PREEN_NOMSG },
8610 /* Bad primary block */
8611 { PR_1_BAD_PRIMARY_BLOCK,
8612 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
8613 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
8615 /* Bad primary block prompt */
8616 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
8617 N_("You can remove this @b from the bad @b list and hope\n"
8618 "that the @b is really OK. But there are no guarantees.\n\n"),
8619 PROMPT_CLEAR, PR_PREEN_NOMSG },
8621 /* Bad primary superblock */
8622 { PR_1_BAD_PRIMARY_SUPERBLOCK,
8623 N_("The primary @S (%b) is on the bad @b list.\n"),
8624 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8626 /* Bad primary block group descriptors */
8627 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
8628 N_("Block %b in the primary @g descriptors "
8629 "is on the bad @b list\n"),
8630 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
8632 /* Bad superblock in group */
8633 { PR_1_BAD_SUPERBLOCK,
8634 N_("Warning: Group %g's @S (%b) is bad.\n"),
8635 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8637 /* Bad block group descriptors in group */
8638 { PR_1_BAD_GROUP_DESCRIPTORS,
8639 N_("Warning: Group %g's copy of the @g descriptors has a bad "
8641 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
8643 /* Block claimed for no reason */
8644 { PR_1_PROGERR_CLAIMED_BLOCK,
8645 N_("Programming error? @b #%b claimed for no reason in "
8646 "process_bad_@b.\n"),
8647 PROMPT_NONE, PR_PREEN_OK },
8649 /* Error allocating blocks for relocating metadata */
8650 { PR_1_RELOC_BLOCK_ALLOCATE,
8651 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
8652 PROMPT_NONE, PR_PREEN_OK },
8654 /* Error allocating block buffer during relocation process */
8655 { PR_1_RELOC_MEMORY_ALLOCATE,
8656 N_("@A @b buffer for relocating %s\n"),
8657 PROMPT_NONE, PR_PREEN_OK },
8659 /* Relocating metadata group information from X to Y */
8660 { PR_1_RELOC_FROM_TO,
8661 N_("Relocating @g %g's %s from %b to %c...\n"),
8662 PROMPT_NONE, PR_PREEN_OK },
8664 /* Relocating metatdata group information to X */
8666 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
8667 PROMPT_NONE, PR_PREEN_OK },
8669 /* Block read error during relocation process */
8670 { PR_1_RELOC_READ_ERR,
8671 N_("Warning: could not read @b %b of %s: %m\n"),
8672 PROMPT_NONE, PR_PREEN_OK },
8674 /* Block write error during relocation process */
8675 { PR_1_RELOC_WRITE_ERR,
8676 N_("Warning: could not write @b %b for %s: %m\n"),
8677 PROMPT_NONE, PR_PREEN_OK },
8679 /* Error allocating inode bitmap */
8680 { PR_1_ALLOCATE_IBITMAP_ERROR,
8681 N_("@A @i @B (%N): %m\n"),
8682 PROMPT_NONE, PR_FATAL },
8684 /* Error allocating block bitmap */
8685 { PR_1_ALLOCATE_BBITMAP_ERROR,
8686 N_("@A @b @B (%N): %m\n"),
8687 PROMPT_NONE, PR_FATAL },
8689 /* Error allocating icount structure */
8690 { PR_1_ALLOCATE_ICOUNT,
8691 N_("@A icount link information: %m\n"),
8692 PROMPT_NONE, PR_FATAL },
8694 /* Error allocating dbcount */
8695 { PR_1_ALLOCATE_DBCOUNT,
8696 N_("@A @d @b array: %m\n"),
8697 PROMPT_NONE, PR_FATAL },
8699 /* Error while scanning inodes */
8701 N_("Error while scanning @is (%i): %m\n"),
8702 PROMPT_NONE, PR_FATAL },
8704 /* Error while iterating over blocks */
8705 { PR_1_BLOCK_ITERATE,
8706 N_("Error while iterating over @bs in @i %i: %m\n"),
8707 PROMPT_NONE, PR_FATAL },
8709 /* Error while storing inode count information */
8710 { PR_1_ICOUNT_STORE,
8711 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
8712 PROMPT_NONE, PR_FATAL },
8714 /* Error while storing directory block information */
8716 N_("Error storing @d @b information "
8717 "(@i=%i, @b=%b, num=%N): %m\n"),
8718 PROMPT_NONE, PR_FATAL },
8720 /* Error while reading inode (for clearing) */
8722 N_("Error reading @i %i: %m\n"),
8723 PROMPT_NONE, PR_FATAL },
8725 /* Suppress messages prompt */
8726 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
8728 /* Imagic flag set on an inode when filesystem doesn't support it */
8730 N_("@i %i has imagic flag set. "),
8733 /* Immutable flag set on a device or socket inode */
8734 { PR_1_SET_IMMUTABLE,
8735 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
8736 "or append-only flag set. "),
8737 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
8739 /* Compression flag set on an inode when filesystem doesn't support it */
8741 N_("@i %i has @cion flag set on @f without @cion support. "),
8744 /* Non-zero size for device, fifo or socket inode */
8745 { PR_1_SET_NONZSIZE,
8746 N_("Special (@v/socket/fifo) @i %i has non-zero size. "),
8747 PROMPT_FIX, PR_PREEN_OK },
8749 /* Filesystem revision is 0, but feature flags are set */
8750 { PR_1_FS_REV_LEVEL,
8751 N_("@f has feature flag(s) set, but is a revision 0 @f. "),
8752 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
8754 /* Journal inode is not in use, but contains data */
8755 { PR_1_JOURNAL_INODE_NOT_CLEAR,
8756 N_("@j @i is not in use, but contains data. "),
8757 PROMPT_CLEAR, PR_PREEN_OK },
8759 /* Journal has bad mode */
8760 { PR_1_JOURNAL_BAD_MODE,
8761 N_("@j is not regular file. "),
8762 PROMPT_FIX, PR_PREEN_OK },
8764 /* Deal with inodes that were part of orphan linked list */
8766 N_("@i %i was part of the @o @i list. "),
8767 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
8769 /* Deal with inodes that were part of corrupted orphan linked
8770 list (latch question) */
8771 { PR_1_ORPHAN_LIST_REFUGEES,
8772 N_("@is that were part of a corrupted orphan linked list found. "),
8775 /* Error allocating refcount structure */
8776 { PR_1_ALLOCATE_REFCOUNT,
8777 N_("@A refcount structure (%N): %m\n"),
8778 PROMPT_NONE, PR_FATAL },
8780 /* Error reading extended attribute block */
8781 { PR_1_READ_EA_BLOCK,
8782 N_("Error reading @a @b %b for @i %i. "),
8785 /* Invalid extended attribute block */
8786 { PR_1_BAD_EA_BLOCK,
8787 N_("@i %i has a bad @a @b %b. "),
8790 /* Error reading Extended Attribute block while fixing refcount */
8791 { PR_1_EXTATTR_READ_ABORT,
8792 N_("Error reading @a @b %b (%m). "),
8795 /* Extended attribute reference count incorrect */
8796 { PR_1_EXTATTR_REFCOUNT,
8797 N_("@a @b %b has reference count %B, @s %N. "),
8800 /* Error writing Extended Attribute block while fixing refcount */
8801 { PR_1_EXTATTR_WRITE,
8802 N_("Error writing @a @b %b (%m). "),
8805 /* Multiple EA blocks not supported */
8806 { PR_1_EA_MULTI_BLOCK,
8807 N_("@a @b %b has h_@bs > 1. "),
8810 /* Error allocating EA region allocation structure */
8811 { PR_1_EA_ALLOC_REGION,
8812 N_("@A @a @b %b. "),
8815 /* Error EA allocation collision */
8816 { PR_1_EA_ALLOC_COLLISION,
8817 N_("@a @b %b is corrupt (allocation collision). "),
8820 /* Bad extended attribute name */
8822 N_("@a @b %b is corrupt (@n name). "),
8825 /* Bad extended attribute value */
8826 { PR_1_EA_BAD_VALUE,
8827 N_("@a @b %b is corrupt (@n value). "),
8830 /* Inode too big (latch question) */
8831 { PR_1_INODE_TOOBIG,
8832 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
8834 /* Directory too big */
8836 N_("@b #%B (%b) causes @d to be too big. "),
8837 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8839 /* Regular file too big */
8841 N_("@b #%B (%b) causes file to be too big. "),
8842 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8844 /* Symlink too big */
8845 { PR_1_TOOBIG_SYMLINK,
8846 N_("@b #%B (%b) causes symlink to be too big. "),
8847 PROMPT_CLEAR, PR_LATCH_TOOBIG },
8849 /* INDEX_FL flag set on a non-HTREE filesystem */
8851 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
8852 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8854 /* INDEX_FL flag set on a non-directory */
8856 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
8857 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8859 /* Invalid root node in HTREE directory */
8860 { PR_1_HTREE_BADROOT,
8861 N_("@h %i has an @n root node.\n"),
8862 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8864 /* Unsupported hash version in HTREE directory */
8866 N_("@h %i has an unsupported hash version (%N)\n"),
8867 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8869 /* Incompatible flag in HTREE root node */
8870 { PR_1_HTREE_INCOMPAT,
8871 N_("@h %i uses an incompatible htree root node flag.\n"),
8872 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8874 /* HTREE too deep */
8876 N_("@h %i has a tree depth (%N) which is too big\n"),
8877 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
8879 /* Bad block has indirect block that conflicts with filesystem block */
8881 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
8883 PROMPT_CLEAR, PR_LATCH_BBLOCK },
8885 /* Resize inode failed */
8886 { PR_1_RESIZE_INODE_CREATE,
8887 N_("Resize @i (re)creation failed: %m."),
8890 /* invalid inode->i_extra_isize */
8892 N_("@i %i has a extra size (%IS) which is @n\n"),
8893 PROMPT_FIX, PR_PREEN_OK },
8895 /* invalid ea entry->e_name_len */
8896 { PR_1_ATTR_NAME_LEN,
8897 N_("@a in @i %i has a namelen (%N) which is @n\n"),
8898 PROMPT_CLEAR, PR_PREEN_OK },
8900 /* invalid ea entry->e_value_size */
8901 { PR_1_ATTR_VALUE_SIZE,
8902 N_("@a in @i %i has a value size (%N) which is @n\n"),
8903 PROMPT_CLEAR, PR_PREEN_OK },
8905 /* invalid ea entry->e_value_offs */
8906 { PR_1_ATTR_VALUE_OFFSET,
8907 N_("@a in @i %i has a value offset (%N) which is @n\n"),
8908 PROMPT_CLEAR, PR_PREEN_OK },
8910 /* invalid ea entry->e_value_block */
8911 { PR_1_ATTR_VALUE_BLOCK,
8912 N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"),
8913 PROMPT_CLEAR, PR_PREEN_OK },
8915 /* invalid ea entry->e_hash */
8917 N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"),
8918 PROMPT_CLEAR, PR_PREEN_OK },
8920 /* Pass 1b errors */
8922 /* Pass 1B: Rescan for duplicate/bad blocks */
8923 { PR_1B_PASS_HEADER,
8924 N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n"
8925 "Pass 1B: Rescanning for @m @bs\n"),
8928 /* Duplicate/bad block(s) header */
8929 { PR_1B_DUP_BLOCK_HEADER,
8930 N_("@m @b(s) in @i %i:"),
8933 /* Duplicate/bad block(s) in inode */
8936 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
8938 /* Duplicate/bad block(s) end */
8939 { PR_1B_DUP_BLOCK_END,
8941 PROMPT_NONE, PR_PREEN_NOHDR },
8943 /* Error while scanning inodes */
8944 { PR_1B_ISCAN_ERROR,
8945 N_("Error while scanning inodes (%i): %m\n"),
8946 PROMPT_NONE, PR_FATAL },
8948 /* Error allocating inode bitmap */
8949 { PR_1B_ALLOCATE_IBITMAP_ERROR,
8950 N_("@A @i @B (@i_dup_map): %m\n"),
8951 PROMPT_NONE, PR_FATAL },
8953 /* Error while iterating over blocks */
8954 { PR_1B_BLOCK_ITERATE,
8955 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
8958 /* Error adjusting EA refcount */
8959 { PR_1B_ADJ_EA_REFCOUNT,
8960 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
8964 /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */
8965 { PR_1C_PASS_HEADER,
8966 N_("Pass 1C: Scanning directories for @is with @m @bs.\n"),
8970 /* Pass 1D: Reconciling multiply-claimed blocks */
8971 { PR_1D_PASS_HEADER,
8972 N_("Pass 1D: Reconciling @m @bs\n"),
8975 /* File has duplicate blocks */
8977 N_("File %Q (@i #%i, mod time %IM) \n"
8978 " has %B @m @b(s), shared with %N file(s):\n"),
8981 /* List of files sharing duplicate blocks */
8982 { PR_1D_DUP_FILE_LIST,
8983 N_("\t%Q (@i #%i, mod time %IM)\n"),
8986 /* File sharing blocks with filesystem metadata */
8987 { PR_1D_SHARE_METADATA,
8988 N_("\t<@f metadata>\n"),
8991 /* Report of how many duplicate/bad inodes */
8992 { PR_1D_NUM_DUP_INODES,
8993 N_("(There are %N @is containing @m @bs.)\n\n"),
8996 /* Duplicated blocks already reassigned or cloned. */
8997 { PR_1D_DUP_BLOCKS_DEALT,
8998 N_("@m @bs already reassigned or cloned.\n\n"),
9001 /* Clone duplicate/bad blocks? */
9002 { PR_1D_CLONE_QUESTION,
9003 "", PROMPT_CLONE, PR_NO_OK },
9006 { PR_1D_DELETE_QUESTION,
9007 "", PROMPT_DELETE, 0 },
9009 /* Couldn't clone file (error) */
9010 { PR_1D_CLONE_ERROR,
9011 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
9015 /* Pass 2: Checking directory structure */
9017 N_("Pass 2: Checking @d structure\n"),
9020 /* Bad inode number for '.' */
9021 { PR_2_BAD_INODE_DOT,
9022 N_("@n @i number for '.' in @d @i %i.\n"),
9025 /* Directory entry has bad inode number */
9027 N_("@E has @n @i #: %Di.\n"),
9030 /* Directory entry has deleted or unused inode */
9031 { PR_2_UNUSED_INODE,
9032 N_("@E has @D/unused @i %Di. "),
9033 PROMPT_CLEAR, PR_PREEN_OK },
9035 /* Directry entry is link to '.' */
9037 N_("@E @L to '.' "),
9040 /* Directory entry points to inode now located in a bad block */
9042 N_("@E points to @i (%Di) located in a bad @b.\n"),
9045 /* Directory entry contains a link to a directory */
9047 N_("@E @L to @d %P (%Di).\n"),
9050 /* Directory entry contains a link to the root directry */
9052 N_("@E @L to the @r.\n"),
9055 /* Directory entry has illegal characters in its name */
9057 N_("@E has illegal characters in its name.\n"),
9060 /* Missing '.' in directory inode */
9062 N_("Missing '.' in @d @i %i.\n"),
9065 /* Missing '..' in directory inode */
9066 { PR_2_MISSING_DOT_DOT,
9067 N_("Missing '..' in @d @i %i.\n"),
9070 /* First entry in directory inode doesn't contain '.' */
9072 N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"),
9075 /* Second entry in directory inode doesn't contain '..' */
9076 { PR_2_2ND_NOT_DOT_DOT,
9077 N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"),
9080 /* i_faddr should be zero */
9082 N_("i_faddr @F %IF, @s zero.\n"),
9085 /* i_file_acl should be zero */
9086 { PR_2_FILE_ACL_ZERO,
9087 N_("i_file_acl @F %If, @s zero.\n"),
9090 /* i_dir_acl should be zero */
9091 { PR_2_DIR_ACL_ZERO,
9092 N_("i_dir_acl @F %Id, @s zero.\n"),
9095 /* i_frag should be zero */
9097 N_("i_frag @F %N, @s zero.\n"),
9100 /* i_fsize should be zero */
9102 N_("i_fsize @F %N, @s zero.\n"),
9105 /* inode has bad mode */
9107 N_("@i %i (%Q) has @n mode (%Im).\n"),
9110 /* directory corrupted */
9111 { PR_2_DIR_CORRUPTED,
9112 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
9113 PROMPT_SALVAGE, 0 },
9115 /* filename too long */
9116 { PR_2_FILENAME_LONG,
9117 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
9118 PROMPT_TRUNCATE, 0 },
9120 /* Directory inode has a missing block (hole) */
9121 { PR_2_DIRECTORY_HOLE,
9122 N_("@d @i %i has an unallocated @b #%B. "),
9123 PROMPT_ALLOCATE, 0 },
9125 /* '.' is not NULL terminated */
9126 { PR_2_DOT_NULL_TERM,
9127 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
9130 /* '..' is not NULL terminated */
9131 { PR_2_DOT_DOT_NULL_TERM,
9132 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
9135 /* Illegal character device inode */
9136 { PR_2_BAD_CHAR_DEV,
9137 N_("@i %i (%Q) is an @I character @v.\n"),
9140 /* Illegal block device inode */
9141 { PR_2_BAD_BLOCK_DEV,
9142 N_("@i %i (%Q) is an @I @b @v.\n"),
9145 /* Duplicate '.' entry */
9147 N_("@E is duplicate '.' @e.\n"),
9150 /* Duplicate '..' entry */
9152 N_("@E is duplicate '..' @e.\n"),
9155 /* Internal error: couldn't find dir_info */
9157 N_("Internal error: couldn't find dir_info for %i.\n"),
9158 PROMPT_NONE, PR_FATAL },
9160 /* Final rec_len is wrong */
9161 { PR_2_FINAL_RECLEN,
9162 N_("@E has rec_len of %Dr, @s %N.\n"),
9165 /* Error allocating icount structure */
9166 { PR_2_ALLOCATE_ICOUNT,
9167 N_("@A icount structure: %m\n"),
9168 PROMPT_NONE, PR_FATAL },
9170 /* Error iterating over directory blocks */
9171 { PR_2_DBLIST_ITERATE,
9172 N_("Error iterating over @d @bs: %m\n"),
9173 PROMPT_NONE, PR_FATAL },
9175 /* Error reading directory block */
9176 { PR_2_READ_DIRBLOCK,
9177 N_("Error reading @d @b %b (@i %i): %m\n"),
9178 PROMPT_CONTINUE, 0 },
9180 /* Error writing directory block */
9181 { PR_2_WRITE_DIRBLOCK,
9182 N_("Error writing @d @b %b (@i %i): %m\n"),
9183 PROMPT_CONTINUE, 0 },
9185 /* Error allocating new directory block */
9186 { PR_2_ALLOC_DIRBOCK,
9187 N_("@A new @d @b for @i %i (%s): %m\n"),
9190 /* Error deallocating inode */
9191 { PR_2_DEALLOC_INODE,
9192 N_("Error deallocating @i %i: %m\n"),
9193 PROMPT_NONE, PR_FATAL },
9195 /* Directory entry for '.' is big. Split? */
9197 N_("@d @e for '.' is big. "),
9198 PROMPT_SPLIT, PR_NO_OK },
9200 /* Illegal FIFO inode */
9202 N_("@i %i (%Q) is an @I FIFO.\n"),
9205 /* Illegal socket inode */
9207 N_("@i %i (%Q) is an @I socket.\n"),
9210 /* Directory filetype not set */
9211 { PR_2_SET_FILETYPE,
9212 N_("Setting filetype for @E to %N.\n"),
9213 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
9215 /* Directory filetype incorrect */
9216 { PR_2_BAD_FILETYPE,
9217 N_("@E has an incorrect filetype (was %Dt, @s %N).\n"),
9220 /* Directory filetype set on filesystem */
9221 { PR_2_CLEAR_FILETYPE,
9222 N_("@E has filetype set.\n"),
9223 PROMPT_CLEAR, PR_PREEN_OK },
9225 /* Directory filename is null */
9227 N_("@E has a @z name.\n"),
9230 /* Invalid symlink */
9231 { PR_2_INVALID_SYMLINK,
9232 N_("Symlink %Q (@i #%i) is @n.\n"),
9235 /* i_file_acl (extended attribute block) is bad */
9236 { PR_2_FILE_ACL_BAD,
9237 N_("@a @b @F @n (%If).\n"),
9240 /* Filesystem contains large files, but has no such flag in sb */
9241 { PR_2_FEATURE_LARGE_FILES,
9242 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
9245 /* Node in HTREE directory not referenced */
9246 { PR_2_HTREE_NOTREF,
9247 N_("@p @h %d: node (%B) not referenced\n"),
9250 /* Node in HTREE directory referenced twice */
9251 { PR_2_HTREE_DUPREF,
9252 N_("@p @h %d: node (%B) referenced twice\n"),
9255 /* Node in HTREE directory has bad min hash */
9256 { PR_2_HTREE_MIN_HASH,
9257 N_("@p @h %d: node (%B) has bad min hash\n"),
9260 /* Node in HTREE directory has bad max hash */
9261 { PR_2_HTREE_MAX_HASH,
9262 N_("@p @h %d: node (%B) has bad max hash\n"),
9265 /* Clear invalid HTREE directory */
9267 N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 },
9269 /* Bad block in htree interior node */
9270 { PR_2_HTREE_BADBLK,
9271 N_("@p @h %d (%q): bad @b number %b.\n"),
9272 PROMPT_CLEAR_HTREE, 0 },
9274 /* Error adjusting EA refcount */
9275 { PR_2_ADJ_EA_REFCOUNT,
9276 N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"),
9277 PROMPT_NONE, PR_FATAL },
9279 /* Invalid HTREE root node */
9280 { PR_2_HTREE_BAD_ROOT,
9281 N_("@p @h %d: root node is @n\n"),
9282 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9284 /* Invalid HTREE limit */
9285 { PR_2_HTREE_BAD_LIMIT,
9286 N_("@p @h %d: node (%B) has @n limit (%N)\n"),
9287 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9289 /* Invalid HTREE count */
9290 { PR_2_HTREE_BAD_COUNT,
9291 N_("@p @h %d: node (%B) has @n count (%N)\n"),
9292 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9294 /* HTREE interior node has out-of-order hashes in table */
9295 { PR_2_HTREE_HASH_ORDER,
9296 N_("@p @h %d: node (%B) has an unordered hash table\n"),
9297 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
9299 /* Node in HTREE directory has invalid depth */
9300 { PR_2_HTREE_BAD_DEPTH,
9301 N_("@p @h %d: node (%B) has @n depth\n"),
9304 /* Duplicate directory entry found */
9305 { PR_2_DUPLICATE_DIRENT,
9306 N_("Duplicate @E found. "),
9309 /* Non-unique filename found */
9310 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
9311 N_("@E has a non-unique filename.\nRename to %s"),
9314 /* Duplicate directory entry found */
9315 { PR_2_REPORT_DUP_DIRENT,
9316 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
9321 /* Pass 3: Checking directory connectivity */
9323 N_("Pass 3: Checking @d connectivity\n"),
9326 /* Root inode not allocated */
9327 { PR_3_NO_ROOT_INODE,
9328 N_("@r not allocated. "),
9329 PROMPT_ALLOCATE, 0 },
9331 /* No room in lost+found */
9332 { PR_3_EXPAND_LF_DIR,
9333 N_("No room in @l @d. "),
9336 /* Unconnected directory inode */
9337 { PR_3_UNCONNECTED_DIR,
9338 N_("Unconnected @d @i %i (%p)\n"),
9339 PROMPT_CONNECT, 0 },
9341 /* /lost+found not found */
9343 N_("/@l not found. "),
9344 PROMPT_CREATE, PR_PREEN_OK },
9346 /* .. entry is incorrect */
9348 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
9351 /* Bad or non-existent /lost+found. Cannot reconnect */
9353 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
9356 /* Could not expand /lost+found */
9357 { PR_3_CANT_EXPAND_LPF,
9358 N_("Could not expand /@l: %m\n"),
9361 /* Could not reconnect inode */
9362 { PR_3_CANT_RECONNECT,
9363 N_("Could not reconnect %i: %m\n"),
9366 /* Error while trying to find /lost+found */
9367 { PR_3_ERR_FIND_LPF,
9368 N_("Error while trying to find /@l: %m\n"),
9371 /* Error in ext2fs_new_block while creating /lost+found */
9372 { PR_3_ERR_LPF_NEW_BLOCK,
9373 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
9376 /* Error in ext2fs_new_inode while creating /lost+found */
9377 { PR_3_ERR_LPF_NEW_INODE,
9378 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
9381 /* Error in ext2fs_new_dir_block while creating /lost+found */
9382 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
9383 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
9386 /* Error while writing directory block for /lost+found */
9387 { PR_3_ERR_LPF_WRITE_BLOCK,
9388 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
9391 /* Error while adjusting inode count */
9392 { PR_3_ADJUST_INODE,
9393 N_("Error while adjusting @i count on @i %i\n"),
9396 /* Couldn't fix parent directory -- error */
9397 { PR_3_FIX_PARENT_ERR,
9398 N_("Couldn't fix parent of @i %i: %m\n\n"),
9401 /* Couldn't fix parent directory -- couldn't find it */
9402 { PR_3_FIX_PARENT_NOFIND,
9403 N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"),
9406 /* Error allocating inode bitmap */
9407 { PR_3_ALLOCATE_IBITMAP_ERROR,
9408 N_("@A @i @B (%N): %m\n"),
9409 PROMPT_NONE, PR_FATAL },
9411 /* Error creating root directory */
9412 { PR_3_CREATE_ROOT_ERROR,
9413 N_("Error creating root @d (%s): %m\n"),
9414 PROMPT_NONE, PR_FATAL },
9416 /* Error creating lost and found directory */
9417 { PR_3_CREATE_LPF_ERROR,
9418 N_("Error creating /@l @d (%s): %m\n"),
9419 PROMPT_NONE, PR_FATAL },
9421 /* Root inode is not directory; aborting */
9422 { PR_3_ROOT_NOT_DIR_ABORT,
9423 N_("@r is not a @d; aborting.\n"),
9424 PROMPT_NONE, PR_FATAL },
9426 /* Cannot proceed without a root inode. */
9427 { PR_3_NO_ROOT_INODE_ABORT,
9428 N_("Cannot proceed without a @r.\n"),
9429 PROMPT_NONE, PR_FATAL },
9431 /* Internal error: couldn't find dir_info */
9433 N_("Internal error: couldn't find dir_info for %i.\n"),
9434 PROMPT_NONE, PR_FATAL },
9436 /* Lost+found not a directory */
9438 N_("/@l is not a @d (ino=%i)\n"),
9441 /* Pass 3A Directory Optimization */
9443 /* Pass 3A: Optimizing directories */
9444 { PR_3A_PASS_HEADER,
9445 N_("Pass 3A: Optimizing directories\n"),
9446 PROMPT_NONE, PR_PREEN_NOMSG },
9448 /* Error iterating over directories */
9449 { PR_3A_OPTIMIZE_ITER,
9450 N_("Failed to create dirs_to_hash iterator: %m"),
9453 /* Error rehash directory */
9454 { PR_3A_OPTIMIZE_DIR_ERR,
9455 N_("Failed to optimize directory %q (%d): %m"),
9458 /* Rehashing dir header */
9459 { PR_3A_OPTIMIZE_DIR_HEADER,
9460 N_("Optimizing directories: "),
9461 PROMPT_NONE, PR_MSG_ONLY },
9463 /* Rehashing directory %d */
9464 { PR_3A_OPTIMIZE_DIR,
9466 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
9468 /* Rehashing dir end */
9469 { PR_3A_OPTIMIZE_DIR_END,
9471 PROMPT_NONE, PR_PREEN_NOHDR },
9475 /* Pass 4: Checking reference counts */
9477 N_("Pass 4: Checking reference counts\n"),
9480 /* Unattached zero-length inode */
9481 { PR_4_ZERO_LEN_INODE,
9482 N_("@u @z @i %i. "),
9483 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
9485 /* Unattached inode */
9486 { PR_4_UNATTACHED_INODE,
9488 PROMPT_CONNECT, 0 },
9490 /* Inode ref count wrong */
9491 { PR_4_BAD_REF_COUNT,
9492 N_("@i %i ref count is %Il, @s %N. "),
9493 PROMPT_FIX, PR_PREEN_OK },
9495 { PR_4_INCONSISTENT_COUNT,
9496 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
9497 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
9498 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
9499 "They @s the same!\n"),
9504 /* Pass 5: Checking group summary information */
9506 N_("Pass 5: Checking @g summary information\n"),
9509 /* Padding at end of inode bitmap is not set. */
9510 { PR_5_INODE_BMAP_PADDING,
9511 N_("Padding at end of @i @B is not set. "),
9512 PROMPT_FIX, PR_PREEN_OK },
9514 /* Padding at end of block bitmap is not set. */
9515 { PR_5_BLOCK_BMAP_PADDING,
9516 N_("Padding at end of @b @B is not set. "),
9517 PROMPT_FIX, PR_PREEN_OK },
9519 /* Block bitmap differences header */
9520 { PR_5_BLOCK_BITMAP_HEADER,
9521 N_("@b @B differences: "),
9522 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
9524 /* Block not used, but marked in bitmap */
9525 { PR_5_BLOCK_UNUSED,
9527 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9529 /* Block used, but not marked used in bitmap */
9532 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9534 /* Block bitmap differences end */
9535 { PR_5_BLOCK_BITMAP_END,
9537 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9539 /* Inode bitmap differences header */
9540 { PR_5_INODE_BITMAP_HEADER,
9541 N_("@i @B differences: "),
9542 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
9544 /* Inode not used, but marked in bitmap */
9545 { PR_5_INODE_UNUSED,
9547 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9549 /* Inode used, but not marked used in bitmap */
9552 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9554 /* Inode bitmap differences end */
9555 { PR_5_INODE_BITMAP_END,
9557 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9559 /* Free inodes count for group wrong */
9560 { PR_5_FREE_INODE_COUNT_GROUP,
9561 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
9562 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9564 /* Directories count for group wrong */
9565 { PR_5_FREE_DIR_COUNT_GROUP,
9566 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
9567 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9569 /* Free inodes count wrong */
9570 { PR_5_FREE_INODE_COUNT,
9571 N_("Free @is count wrong (%i, counted=%j).\n"),
9572 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9574 /* Free blocks count for group wrong */
9575 { PR_5_FREE_BLOCK_COUNT_GROUP,
9576 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
9577 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9579 /* Free blocks count wrong */
9580 { PR_5_FREE_BLOCK_COUNT,
9581 N_("Free @bs count wrong (%b, counted=%c).\n"),
9582 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
9584 /* Programming error: bitmap endpoints don't match */
9585 { PR_5_BMAP_ENDPOINTS,
9586 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
9587 "match calculated @B endpoints (%i, %j)\n"),
9588 PROMPT_NONE, PR_FATAL },
9590 /* Internal error: fudging end of bitmap */
9591 { PR_5_FUDGE_BITMAP_ERROR,
9592 N_("Internal error: fudging end of bitmap (%N)\n"),
9593 PROMPT_NONE, PR_FATAL },
9595 /* Error copying in replacement inode bitmap */
9596 { PR_5_COPY_IBITMAP_ERROR,
9597 N_("Error copying in replacement @i @B: %m\n"),
9598 PROMPT_NONE, PR_FATAL },
9600 /* Error copying in replacement block bitmap */
9601 { PR_5_COPY_BBITMAP_ERROR,
9602 N_("Error copying in replacement @b @B: %m\n"),
9603 PROMPT_NONE, PR_FATAL },
9605 /* Block range not used, but marked in bitmap */
9606 { PR_5_BLOCK_RANGE_UNUSED,
9608 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9610 /* Block range used, but not marked used in bitmap */
9611 { PR_5_BLOCK_RANGE_USED,
9613 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9615 /* Inode range not used, but marked in bitmap */
9616 { PR_5_INODE_RANGE_UNUSED,
9618 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9620 /* Inode range used, but not marked used in bitmap */
9621 { PR_5_INODE_RANGE_USED,
9623 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
9629 * This is the latch flags register. It allows several problems to be
9630 * "latched" together. This means that the user has to answer but one
9631 * question for the set of problems, and all of the associated
9632 * problems will be either fixed or not fixed.
9634 static struct latch_descr pr_latch_info[] = {
9635 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
9636 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
9637 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
9638 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
9639 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
9640 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
9641 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
9642 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
9643 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
9647 static const struct e2fsck_problem *find_problem(problem_t code)
9651 for (i=0; problem_table[i].e2p_code; i++) {
9652 if (problem_table[i].e2p_code == code)
9653 return &problem_table[i];
9658 static struct latch_descr *find_latch(int code)
9662 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
9663 if (pr_latch_info[i].latch_code == code)
9664 return &pr_latch_info[i];
9669 int end_problem_latch(e2fsck_t ctx, int mask)
9671 struct latch_descr *ldesc;
9672 struct problem_context pctx;
9675 ldesc = find_latch(mask);
9676 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
9677 clear_problem_context(&pctx);
9678 answer = fix_problem(ctx, ldesc->end_message, &pctx);
9680 ldesc->flags &= ~(PRL_VARIABLE);
9684 int set_latch_flags(int mask, int setflags, int clearflags)
9686 struct latch_descr *ldesc;
9688 ldesc = find_latch(mask);
9691 ldesc->flags |= setflags;
9692 ldesc->flags &= ~clearflags;
9696 void clear_problem_context(struct problem_context *ctx)
9698 memset(ctx, 0, sizeof(struct problem_context));
9703 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9705 ext2_filsys fs = ctx->fs;
9706 const struct e2fsck_problem *ptr;
9707 struct latch_descr *ldesc = 0;
9708 const char *message;
9709 int def_yn, answer, ans;
9710 int print_answer = 0;
9713 ptr = find_problem(code);
9715 printf(_("Unhandled error code (0x%x)!\n"), code);
9719 if ((ptr->flags & PR_NO_DEFAULT) ||
9720 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
9721 (ctx->options & E2F_OPT_NO))
9725 * Do special latch processing. This is where we ask the
9726 * latch question, if it exists
9728 if (ptr->flags & PR_LATCH_MASK) {
9729 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
9730 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
9731 ans = fix_problem(ctx, ldesc->question, pctx);
9733 ldesc->flags |= PRL_YES;
9735 ldesc->flags |= PRL_NO;
9736 ldesc->flags |= PRL_LATCHED;
9738 if (ldesc->flags & PRL_SUPPRESS)
9741 if ((ptr->flags & PR_PREEN_NOMSG) &&
9742 (ctx->options & E2F_OPT_PREEN))
9744 if ((ptr->flags & PR_NO_NOMSG) &&
9745 (ctx->options & E2F_OPT_NO))
9748 message = ptr->e2p_description;
9749 if ((ctx->options & E2F_OPT_PREEN) &&
9750 !(ptr->flags & PR_PREEN_NOHDR)) {
9751 printf("%s: ", ctx->device_name ?
9752 ctx->device_name : ctx->filesystem_name);
9755 print_e2fsck_message(ctx, _(message), pctx, 1);
9757 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
9760 if (ptr->flags & PR_FATAL)
9761 bb_error_msg_and_die(0);
9763 if (ptr->prompt == PROMPT_NONE) {
9764 if (ptr->flags & PR_NOCOLLATE)
9769 if (ctx->options & E2F_OPT_PREEN) {
9771 if (!(ptr->flags & PR_PREEN_NOMSG))
9773 } else if ((ptr->flags & PR_LATCH_MASK) &&
9774 (ldesc->flags & (PRL_YES | PRL_NO))) {
9777 if (ldesc->flags & PRL_YES)
9782 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
9783 if (!answer && !(ptr->flags & PR_NO_OK))
9784 ext2fs_unmark_valid(fs);
9787 printf("%s.\n", answer ?
9788 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9792 if ((ptr->prompt == PROMPT_ABORT) && answer)
9793 bb_error_msg_and_die(0);
9795 if (ptr->flags & PR_AFTER_CODE)
9796 answer = fix_problem(ctx, ptr->second_code, pctx);
9802 * linux/fs/recovery.c
9804 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
9808 * Maintain information about the progress of the recovery job, so that
9809 * the different passes can carry information between them.
9811 struct recovery_info
9813 tid_t start_transaction;
9814 tid_t end_transaction;
9821 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
9822 static int do_one_pass(journal_t *journal,
9823 struct recovery_info *info, enum passtype pass);
9824 static int scan_revoke_records(journal_t *, struct buffer_head *,
9825 tid_t, struct recovery_info *);
9828 * Read a block from the journal
9831 static int jread(struct buffer_head **bhp, journal_t *journal,
9832 unsigned int offset)
9835 unsigned long blocknr;
9836 struct buffer_head *bh;
9840 err = journal_bmap(journal, offset, &blocknr);
9843 printf ("JBD: bad block at offset %u\n", offset);
9847 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
9851 if (!buffer_uptodate(bh)) {
9852 /* If this is a brand new buffer, start readahead.
9853 Otherwise, we assume we are already reading it. */
9854 if (!buffer_req(bh))
9855 do_readahead(journal, offset);
9859 if (!buffer_uptodate(bh)) {
9860 printf ("JBD: Failed to read block at offset %u\n", offset);
9871 * Count the number of in-use tags in a journal descriptor block.
9874 static int count_tags(struct buffer_head *bh, int size)
9877 journal_block_tag_t * tag;
9880 tagp = &bh->b_data[sizeof(journal_header_t)];
9882 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
9883 tag = (journal_block_tag_t *) tagp;
9886 tagp += sizeof(journal_block_tag_t);
9887 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
9890 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
9898 /* Make sure we wrap around the log correctly! */
9899 #define wrap(journal, var) \
9901 if (var >= (journal)->j_last) \
9902 var -= ((journal)->j_last - (journal)->j_first); \
9906 * int journal_recover(journal_t *journal) - recovers a on-disk journal
9907 * @journal: the journal to recover
9909 * The primary function for recovering the log contents when mounting a
9912 * Recovery is done in three passes. In the first pass, we look for the
9913 * end of the log. In the second, we assemble the list of revoke
9914 * blocks. In the third and final pass, we replay any un-revoked blocks
9917 int journal_recover(journal_t *journal)
9920 journal_superblock_t * sb;
9922 struct recovery_info info;
9924 memset(&info, 0, sizeof(info));
9925 sb = journal->j_superblock;
9928 * The journal superblock's s_start field (the current log head)
9929 * is always zero if, and only if, the journal was cleanly
9934 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
9938 err = do_one_pass(journal, &info, PASS_SCAN);
9940 err = do_one_pass(journal, &info, PASS_REVOKE);
9942 err = do_one_pass(journal, &info, PASS_REPLAY);
9944 /* Restart the log at the next transaction ID, thus invalidating
9945 * any existing commit records in the log. */
9946 journal->j_transaction_sequence = ++info.end_transaction;
9948 journal_clear_revoke(journal);
9949 sync_blockdev(journal->j_fs_dev);
9953 static int do_one_pass(journal_t *journal,
9954 struct recovery_info *info, enum passtype pass)
9956 unsigned int first_commit_ID, next_commit_ID;
9957 unsigned long next_log_block;
9958 int err, success = 0;
9959 journal_superblock_t * sb;
9960 journal_header_t * tmp;
9961 struct buffer_head * bh;
9962 unsigned int sequence;
9965 /* Precompute the maximum metadata descriptors in a descriptor block */
9966 int MAX_BLOCKS_PER_DESC;
9967 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
9968 / sizeof(journal_block_tag_t));
9971 * First thing is to establish what we expect to find in the log
9972 * (in terms of transaction IDs), and where (in terms of log
9973 * block offsets): query the superblock.
9976 sb = journal->j_superblock;
9977 next_commit_ID = ntohl(sb->s_sequence);
9978 next_log_block = ntohl(sb->s_start);
9980 first_commit_ID = next_commit_ID;
9981 if (pass == PASS_SCAN)
9982 info->start_transaction = first_commit_ID;
9985 * Now we walk through the log, transaction by transaction,
9986 * making sure that each transaction has a commit block in the
9987 * expected place. Each complete transaction gets replayed back
9988 * into the main filesystem.
9994 journal_block_tag_t * tag;
9995 struct buffer_head * obh;
9996 struct buffer_head * nbh;
9998 /* If we already know where to stop the log traversal,
9999 * check right now that we haven't gone past the end of
10002 if (pass != PASS_SCAN)
10003 if (tid_geq(next_commit_ID, info->end_transaction))
10006 /* Skip over each chunk of the transaction looking
10007 * either the next descriptor block or the final commit
10010 err = jread(&bh, journal, next_log_block);
10015 wrap(journal, next_log_block);
10017 /* What kind of buffer is it?
10019 * If it is a descriptor block, check that it has the
10020 * expected sequence number. Otherwise, we're all done
10023 tmp = (journal_header_t *)bh->b_data;
10025 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
10030 blocktype = ntohl(tmp->h_blocktype);
10031 sequence = ntohl(tmp->h_sequence);
10033 if (sequence != next_commit_ID) {
10038 /* OK, we have a valid descriptor block which matches
10039 * all of the sequence number checks. What are we going
10040 * to do with it? That depends on the pass... */
10042 switch(blocktype) {
10043 case JFS_DESCRIPTOR_BLOCK:
10044 /* If it is a valid descriptor block, replay it
10045 * in pass REPLAY; otherwise, just skip over the
10046 * blocks it describes. */
10047 if (pass != PASS_REPLAY) {
10049 count_tags(bh, journal->j_blocksize);
10050 wrap(journal, next_log_block);
10055 /* A descriptor block: we can now write all of
10056 * the data blocks. Yay, useful work is finally
10057 * getting done here! */
10059 tagp = &bh->b_data[sizeof(journal_header_t)];
10060 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
10061 <= journal->j_blocksize) {
10062 unsigned long io_block;
10064 tag = (journal_block_tag_t *) tagp;
10065 flags = ntohl(tag->t_flags);
10067 io_block = next_log_block++;
10068 wrap(journal, next_log_block);
10069 err = jread(&obh, journal, io_block);
10071 /* Recover what we can, but
10072 * report failure at the end. */
10074 printf ("JBD: IO error %d recovering "
10075 "block %ld in log\n",
10078 unsigned long blocknr;
10080 blocknr = ntohl(tag->t_blocknr);
10082 /* If the block has been
10083 * revoked, then we're all done
10085 if (journal_test_revoke
10089 ++info->nr_revoke_hits;
10093 /* Find a buffer for the new
10094 * data being restored */
10095 nbh = getblk(journal->j_fs_dev,
10097 journal->j_blocksize);
10099 printf ("JBD: Out of memory "
10100 "during recovery.\n");
10108 memcpy(nbh->b_data, obh->b_data,
10109 journal->j_blocksize);
10110 if (flags & JFS_FLAG_ESCAPE) {
10111 *((unsigned int *)bh->b_data) =
10112 htonl(JFS_MAGIC_NUMBER);
10115 mark_buffer_uptodate(nbh, 1);
10116 mark_buffer_dirty(nbh);
10117 ++info->nr_replays;
10118 /* ll_rw_block(WRITE, 1, &nbh); */
10119 unlock_buffer(nbh);
10125 tagp += sizeof(journal_block_tag_t);
10126 if (!(flags & JFS_FLAG_SAME_UUID))
10129 if (flags & JFS_FLAG_LAST_TAG)
10136 case JFS_COMMIT_BLOCK:
10137 /* Found an expected commit block: not much to
10138 * do other than move on to the next sequence
10144 case JFS_REVOKE_BLOCK:
10145 /* If we aren't in the REVOKE pass, then we can
10146 * just skip over this block. */
10147 if (pass != PASS_REVOKE) {
10152 err = scan_revoke_records(journal, bh,
10153 next_commit_ID, info);
10166 * We broke out of the log scan loop: either we came to the
10167 * known end of the log or we found an unexpected block in the
10168 * log. If the latter happened, then we know that the "current"
10169 * transaction marks the end of the valid log.
10172 if (pass == PASS_SCAN)
10173 info->end_transaction = next_commit_ID;
10175 /* It's really bad news if different passes end up at
10176 * different places (but possible due to IO errors). */
10177 if (info->end_transaction != next_commit_ID) {
10178 printf ("JBD: recovery pass %d ended at "
10179 "transaction %u, expected %u\n",
10180 pass, next_commit_ID, info->end_transaction);
10193 /* Scan a revoke record, marking all blocks mentioned as revoked. */
10195 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
10196 tid_t sequence, struct recovery_info *info)
10198 journal_revoke_header_t *header;
10201 header = (journal_revoke_header_t *) bh->b_data;
10202 offset = sizeof(journal_revoke_header_t);
10203 max = ntohl(header->r_count);
10205 while (offset < max) {
10206 unsigned long blocknr;
10209 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
10211 err = journal_set_revoke(journal, blocknr, sequence);
10214 ++info->nr_revokes;
10221 * rehash.c --- rebuild hash tree directories
10223 * This algorithm is designed for simplicity of implementation and to
10224 * pack the directory as much as possible. It however requires twice
10225 * as much memory as the size of the directory. The maximum size
10226 * directory supported using a 4k blocksize is roughly a gigabyte, and
10227 * so there may very well be problems with machines that don't have
10228 * virtual memory, and obscenely large directories.
10230 * An alternate algorithm which is much more disk intensive could be
10231 * written, and probably will need to be written in the future. The
10232 * design goals of such an algorithm are: (a) use (roughly) constant
10233 * amounts of memory, no matter how large the directory, (b) the
10234 * directory must be safe at all times, even if e2fsck is interrupted
10235 * in the middle, (c) we must use minimal amounts of extra disk
10236 * blocks. This pretty much requires an incremental approach, where
10237 * we are reading from one part of the directory, and inserting into
10238 * the front half. So the algorithm will have to keep track of a
10239 * moving block boundary between the new tree and the old tree, and
10240 * files will need to be moved from the old directory and inserted
10241 * into the new tree. If the new directory requires space which isn't
10242 * yet available, blocks from the beginning part of the old directory
10243 * may need to be moved to the end of the directory to make room for
10246 * --------------------------------------------------------
10247 * | new tree | | old tree |
10248 * --------------------------------------------------------
10250 * tail new head old
10252 * This is going to be a pain in the tuckus to implement, and will
10253 * require a lot more disk accesses. So I'm going to skip it for now;
10254 * it's only really going to be an issue for really, really big
10255 * filesystems (when we reach the level of tens of millions of files
10256 * in a single directory). It will probably be easier to simply
10257 * require that e2fsck use VM first.
10260 struct fill_dir_struct {
10262 struct ext2_inode *inode;
10265 struct hash_entry *harray;
10266 int max_array, num_array;
10272 struct hash_entry {
10273 ext2_dirhash_t hash;
10274 ext2_dirhash_t minor_hash;
10275 struct ext2_dir_entry *dir;
10282 ext2_dirhash_t *hashes;
10285 static int fill_dir_block(ext2_filsys fs,
10287 e2_blkcnt_t blockcnt,
10288 blk_t ref_block FSCK_ATTR((unused)),
10289 int ref_offset FSCK_ATTR((unused)),
10292 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
10293 struct hash_entry *new_array, *ent;
10294 struct ext2_dir_entry *dirent;
10296 unsigned int offset, dir_offset;
10301 offset = blockcnt * fs->blocksize;
10302 if (offset + fs->blocksize > fd->inode->i_size) {
10303 fd->err = EXT2_ET_DIR_CORRUPTED;
10304 return BLOCK_ABORT;
10306 dir = (fd->buf+offset);
10307 if (HOLE_BLKADDR(*block_nr)) {
10308 memset(dir, 0, fs->blocksize);
10309 dirent = (struct ext2_dir_entry *) dir;
10310 dirent->rec_len = fs->blocksize;
10312 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
10314 return BLOCK_ABORT;
10316 /* While the directory block is "hot", index it. */
10318 while (dir_offset < fs->blocksize) {
10319 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
10320 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
10321 (dirent->rec_len < 8) ||
10322 ((dirent->rec_len % 4) != 0) ||
10323 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
10324 fd->err = EXT2_ET_DIR_CORRUPTED;
10325 return BLOCK_ABORT;
10327 dir_offset += dirent->rec_len;
10328 if (dirent->inode == 0)
10330 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
10331 (dirent->name[0] == '.'))
10333 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
10334 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
10335 fd->parent = dirent->inode;
10338 if (fd->num_array >= fd->max_array) {
10339 new_array = realloc(fd->harray,
10340 sizeof(struct hash_entry) * (fd->max_array+500));
10343 return BLOCK_ABORT;
10345 fd->harray = new_array;
10346 fd->max_array += 500;
10348 ent = fd->harray + fd->num_array++;
10350 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
10352 ent->hash = ent->minor_hash = 0;
10354 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
10356 dirent->name_len & 0xFF,
10357 fs->super->s_hash_seed,
10358 &ent->hash, &ent->minor_hash);
10360 return BLOCK_ABORT;
10367 /* Used for sorting the hash entry */
10368 static int name_cmp(const void *a, const void *b)
10370 const struct hash_entry *he_a = (const struct hash_entry *) a;
10371 const struct hash_entry *he_b = (const struct hash_entry *) b;
10375 min_len = he_a->dir->name_len;
10376 if (min_len > he_b->dir->name_len)
10377 min_len = he_b->dir->name_len;
10379 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
10381 if (he_a->dir->name_len > he_b->dir->name_len)
10383 else if (he_a->dir->name_len < he_b->dir->name_len)
10386 ret = he_b->dir->inode - he_a->dir->inode;
10391 /* Used for sorting the hash entry */
10392 static int hash_cmp(const void *a, const void *b)
10394 const struct hash_entry *he_a = (const struct hash_entry *) a;
10395 const struct hash_entry *he_b = (const struct hash_entry *) b;
10398 if (he_a->hash > he_b->hash)
10400 else if (he_a->hash < he_b->hash)
10403 if (he_a->minor_hash > he_b->minor_hash)
10405 else if (he_a->minor_hash < he_b->minor_hash)
10408 ret = name_cmp(a, b);
10413 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
10419 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
10422 outdir->buf = new_mem;
10423 new_mem = realloc(outdir->hashes,
10424 blocks * sizeof(ext2_dirhash_t));
10427 outdir->hashes = new_mem;
10429 outdir->buf = malloc(blocks * fs->blocksize);
10430 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
10433 outdir->max = blocks;
10437 static void free_out_dir(struct out_dir *outdir)
10440 free(outdir->hashes);
10445 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
10450 if (outdir->num >= outdir->max) {
10451 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
10455 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
10456 memset(*ret, 0, fs->blocksize);
10461 * This function is used to make a unique filename. We do this by
10462 * appending ~0, and then incrementing the number. However, we cannot
10463 * expand the length of the filename beyond the padding available in
10464 * the directory entry.
10466 static void mutate_name(char *str, __u16 *len)
10469 __u16 l = *len & 0xFF, h = *len & 0xff00;
10472 * First check to see if it looks the name has been mutated
10475 for (i = l-1; i > 0; i--) {
10476 if (!isdigit(str[i]))
10479 if ((i == l-1) || (str[i] != '~')) {
10480 if (((l-1) & 3) < 2)
10489 for (i = l-1; i >= 0; i--) {
10490 if (isdigit(str[i])) {
10502 else if (str[0] == 'Z') {
10507 } else if (i > 0) {
10520 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
10522 struct fill_dir_struct *fd)
10524 struct problem_context pctx;
10525 struct hash_entry *ent, *prev;
10528 char new_name[256];
10531 clear_problem_context(&pctx);
10534 for (i=1; i < fd->num_array; i++) {
10535 ent = fd->harray + i;
10537 if (!ent->dir->inode ||
10538 ((ent->dir->name_len & 0xFF) !=
10539 (prev->dir->name_len & 0xFF)) ||
10540 (strncmp(ent->dir->name, prev->dir->name,
10541 ent->dir->name_len & 0xFF)))
10543 pctx.dirent = ent->dir;
10544 if ((ent->dir->inode == prev->dir->inode) &&
10545 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
10546 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
10547 ent->dir->inode = 0;
10551 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
10552 new_len = ent->dir->name_len;
10553 mutate_name(new_name, &new_len);
10554 for (j=0; j < fd->num_array; j++) {
10556 ((ent->dir->name_len & 0xFF) !=
10557 (fd->harray[j].dir->name_len & 0xFF)) ||
10558 (strncmp(new_name, fd->harray[j].dir->name,
10561 mutate_name(new_name, &new_len);
10565 new_name[new_len & 0xFF] = 0;
10566 pctx.str = new_name;
10567 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
10568 memcpy(ent->dir->name, new_name, new_len & 0xFF);
10569 ent->dir->name_len = new_len;
10570 ext2fs_dirhash(fs->super->s_def_hash_version,
10572 ent->dir->name_len & 0xFF,
10573 fs->super->s_hash_seed,
10574 &ent->hash, &ent->minor_hash);
10582 static errcode_t copy_dir_entries(ext2_filsys fs,
10583 struct fill_dir_struct *fd,
10584 struct out_dir *outdir)
10588 struct hash_entry *ent;
10589 struct ext2_dir_entry *dirent;
10590 int i, rec_len, left;
10591 ext2_dirhash_t prev_hash;
10595 retval = alloc_size_dir(fs, outdir,
10596 (fd->dir_size / fs->blocksize) + 2);
10599 outdir->num = fd->compress ? 0 : 1;
10601 outdir->hashes[0] = 0;
10603 if ((retval = get_next_block(fs, outdir, &block_start)))
10605 dirent = (struct ext2_dir_entry *) block_start;
10606 left = fs->blocksize;
10607 for (i=0; i < fd->num_array; i++) {
10608 ent = fd->harray + i;
10609 if (ent->dir->inode == 0)
10611 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
10612 if (rec_len > left) {
10614 dirent->rec_len += left;
10615 if ((retval = get_next_block(fs, outdir,
10620 left = fs->blocksize - offset;
10621 dirent = (struct ext2_dir_entry *) (block_start + offset);
10623 if (ent->hash == prev_hash)
10624 outdir->hashes[outdir->num-1] = ent->hash | 1;
10626 outdir->hashes[outdir->num-1] = ent->hash;
10628 dirent->inode = ent->dir->inode;
10629 dirent->name_len = ent->dir->name_len;
10630 dirent->rec_len = rec_len;
10631 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
10635 dirent->rec_len += left;
10639 prev_hash = ent->hash;
10642 dirent->rec_len += left;
10648 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
10649 ext2_ino_t ino, ext2_ino_t parent)
10651 struct ext2_dir_entry *dir;
10652 struct ext2_dx_root_info *root;
10653 struct ext2_dx_countlimit *limits;
10656 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
10657 filetype = EXT2_FT_DIR << 8;
10659 memset(buf, 0, fs->blocksize);
10660 dir = (struct ext2_dir_entry *) buf;
10662 dir->name[0] = '.';
10663 dir->name_len = 1 | filetype;
10665 dir = (struct ext2_dir_entry *) (buf + 12);
10666 dir->inode = parent;
10667 dir->name[0] = '.';
10668 dir->name[1] = '.';
10669 dir->name_len = 2 | filetype;
10670 dir->rec_len = fs->blocksize - 12;
10672 root = (struct ext2_dx_root_info *) (buf+24);
10673 root->reserved_zero = 0;
10674 root->hash_version = fs->super->s_def_hash_version;
10675 root->info_length = 8;
10676 root->indirect_levels = 0;
10677 root->unused_flags = 0;
10679 limits = (struct ext2_dx_countlimit *) (buf+32);
10680 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
10687 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
10689 struct ext2_dir_entry *dir;
10690 struct ext2_dx_countlimit *limits;
10692 memset(buf, 0, fs->blocksize);
10693 dir = (struct ext2_dir_entry *) buf;
10695 dir->rec_len = fs->blocksize;
10697 limits = (struct ext2_dx_countlimit *) (buf+8);
10698 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
10701 return (struct ext2_dx_entry *) limits;
10705 * This function takes the leaf nodes which have been written in
10706 * outdir, and populates the root node and any necessary interior nodes.
10708 static errcode_t calculate_tree(ext2_filsys fs,
10709 struct out_dir *outdir,
10713 struct ext2_dx_root_info *root_info;
10714 struct ext2_dx_entry *root, *dx_ent = 0;
10715 struct ext2_dx_countlimit *root_limit, *limit;
10717 char * block_start;
10718 int i, c1, c2, nblks;
10719 int limit_offset, root_offset;
10721 root_info = set_root_node(fs, outdir->buf, ino, parent);
10722 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
10723 root_info->info_length;
10724 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10725 c1 = root_limit->limit;
10726 nblks = outdir->num;
10728 /* Write out the pointer blocks */
10729 if (nblks-1 <= c1) {
10730 /* Just write out the root block, and we're done */
10731 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
10732 for (i=1; i < nblks; i++) {
10733 root->block = ext2fs_cpu_to_le32(i);
10736 ext2fs_cpu_to_le32(outdir->hashes[i]);
10743 root_info->indirect_levels = 1;
10744 for (i=1; i < nblks; i++) {
10749 limit->limit = limit->count =
10750 ext2fs_cpu_to_le16(limit->limit);
10751 root = (struct ext2_dx_entry *)
10752 (outdir->buf + root_offset);
10753 root->block = ext2fs_cpu_to_le32(outdir->num);
10756 ext2fs_cpu_to_le32(outdir->hashes[i]);
10757 if ((retval = get_next_block(fs, outdir,
10760 dx_ent = set_int_node(fs, block_start);
10761 limit = (struct ext2_dx_countlimit *) dx_ent;
10763 root_offset += sizeof(struct ext2_dx_entry);
10766 dx_ent->block = ext2fs_cpu_to_le32(i);
10767 if (c2 != limit->limit)
10769 ext2fs_cpu_to_le32(outdir->hashes[i]);
10773 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
10774 limit->limit = ext2fs_cpu_to_le16(limit->limit);
10776 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
10777 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
10778 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
10783 struct write_dir_struct {
10784 struct out_dir *outdir;
10791 * Helper function which writes out a directory block.
10793 static int write_dir_block(ext2_filsys fs,
10795 e2_blkcnt_t blockcnt,
10796 blk_t ref_block FSCK_ATTR((unused)),
10797 int ref_offset FSCK_ATTR((unused)),
10800 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
10804 if (*block_nr == 0)
10806 if (blockcnt >= wd->outdir->num) {
10807 e2fsck_read_bitmaps(wd->ctx);
10809 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
10810 ext2fs_block_alloc_stats(fs, blk, -1);
10813 return BLOCK_CHANGED;
10818 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
10819 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
10821 return BLOCK_ABORT;
10825 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
10826 struct out_dir *outdir,
10827 ext2_ino_t ino, int compress)
10829 struct write_dir_struct wd;
10831 struct ext2_inode inode;
10833 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
10837 wd.outdir = outdir;
10842 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10843 write_dir_block, &wd);
10849 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10851 inode.i_flags &= ~EXT2_INDEX_FL;
10853 inode.i_flags |= EXT2_INDEX_FL;
10854 inode.i_size = outdir->num * fs->blocksize;
10855 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
10856 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
10861 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
10863 ext2_filsys fs = ctx->fs;
10865 struct ext2_inode inode;
10867 struct fill_dir_struct fd;
10868 struct out_dir outdir;
10870 outdir.max = outdir.num = 0;
10873 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
10877 dir_buf = malloc(inode.i_size);
10881 fd.max_array = inode.i_size / 32;
10883 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
10893 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
10894 (inode.i_size / fs->blocksize) < 2)
10898 /* Read in the entire directory into memory */
10899 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
10900 fill_dir_block, &fd);
10906 /* Sort the list */
10909 qsort(fd.harray+2, fd.num_array-2,
10910 sizeof(struct hash_entry), name_cmp);
10912 qsort(fd.harray, fd.num_array,
10913 sizeof(struct hash_entry), hash_cmp);
10916 * Look for duplicates
10918 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
10921 if (ctx->options & E2F_OPT_NO) {
10927 * Copy the directory entries. In a htree directory these
10928 * will become the leaf nodes.
10930 retval = copy_dir_entries(fs, &fd, &outdir);
10934 free(dir_buf); dir_buf = 0;
10936 if (!fd.compress) {
10937 /* Calculate the interior nodes */
10938 retval = calculate_tree(fs, &outdir, ino, fd.parent);
10943 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
10949 free_out_dir(&outdir);
10953 void e2fsck_rehash_directories(e2fsck_t ctx)
10955 struct problem_context pctx;
10956 struct dir_info *dir;
10957 ext2_u32_iterate iter;
10960 int i, cur, max, all_dirs, dir_index, first = 1;
10962 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
10964 if (!ctx->dirs_to_hash && !all_dirs)
10967 e2fsck_get_lost_and_found(ctx, 0);
10969 clear_problem_context(&pctx);
10971 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
10975 max = e2fsck_get_num_dirinfo(ctx);
10977 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
10980 pctx.errcode = retval;
10981 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
10984 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
10988 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
10992 if (!ext2fs_u32_list_iterate(iter, &ino))
10995 if (ino == ctx->lost_and_found)
10999 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
11002 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
11003 if (pctx.errcode) {
11004 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11005 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
11007 if (ctx->progress && !ctx->progress_fd)
11008 e2fsck_simple_progress(ctx, "Rebuilding directory",
11009 100.0 * (float) (++cur) / (float) max, ino);
11011 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
11013 ext2fs_u32_list_iterate_end(iter);
11015 ext2fs_u32_list_free(ctx->dirs_to_hash);
11016 ctx->dirs_to_hash = 0;
11020 * linux/fs/revoke.c
11022 * Journal revoke routines for the generic filesystem journaling code;
11023 * part of the ext2fs journaling system.
11025 * Revoke is the mechanism used to prevent old log records for deleted
11026 * metadata from being replayed on top of newer data using the same
11027 * blocks. The revoke mechanism is used in two separate places:
11029 * + Commit: during commit we write the entire list of the current
11030 * transaction's revoked blocks to the journal
11032 * + Recovery: during recovery we record the transaction ID of all
11033 * revoked blocks. If there are multiple revoke records in the log
11034 * for a single block, only the last one counts, and if there is a log
11035 * entry for a block beyond the last revoke, then that log entry still
11038 * We can get interactions between revokes and new log data within a
11039 * single transaction:
11041 * Block is revoked and then journaled:
11042 * The desired end result is the journaling of the new block, so we
11043 * cancel the revoke before the transaction commits.
11045 * Block is journaled and then revoked:
11046 * The revoke must take precedence over the write of the block, so we
11047 * need either to cancel the journal entry or to write the revoke
11048 * later in the log than the log block. In this case, we choose the
11049 * latter: journaling a block cancels any revoke record for that block
11050 * in the current transaction, so any revoke for that block in the
11051 * transaction must have happened after the block was journaled and so
11052 * the revoke must take precedence.
11054 * Block is revoked and then written as data:
11055 * The data write is allowed to succeed, but the revoke is _not_
11056 * cancelled. We still need to prevent old log records from
11057 * overwriting the new data. We don't even need to clear the revoke
11060 * Revoke information on buffers is a tri-state value:
11062 * RevokeValid clear: no cached revoke status, need to look it up
11063 * RevokeValid set, Revoked clear:
11064 * buffer has not been revoked, and cancel_revoke
11066 * RevokeValid set, Revoked set:
11067 * buffer has been revoked.
11070 static kmem_cache_t *revoke_record_cache;
11071 static kmem_cache_t *revoke_table_cache;
11073 /* Each revoke record represents one single revoked block. During
11074 journal replay, this involves recording the transaction ID of the
11075 last transaction to revoke this block. */
11077 struct jbd_revoke_record_s
11079 struct list_head hash;
11080 tid_t sequence; /* Used for recovery only */
11081 unsigned long blocknr;
11085 /* The revoke table is just a simple hash table of revoke records. */
11086 struct jbd_revoke_table_s
11088 /* It is conceivable that we might want a larger hash table
11089 * for recovery. Must be a power of two. */
11092 struct list_head *hash_table;
11096 /* Utility functions to maintain the revoke table */
11098 /* Borrowed from buffer.c: this is a tried and tested block hash function */
11099 static inline int hash(journal_t *journal, unsigned long block)
11101 struct jbd_revoke_table_s *table = journal->j_revoke;
11102 int hash_shift = table->hash_shift;
11104 return ((block << (hash_shift - 6)) ^
11106 (block << (hash_shift - 12))) & (table->hash_size - 1);
11109 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
11112 struct list_head *hash_list;
11113 struct jbd_revoke_record_s *record;
11115 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
11119 record->sequence = seq;
11120 record->blocknr = blocknr;
11121 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11122 list_add(&record->hash, hash_list);
11129 /* Find a revoke record in the journal's hash table. */
11131 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
11132 unsigned long blocknr)
11134 struct list_head *hash_list;
11135 struct jbd_revoke_record_s *record;
11137 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
11139 record = (struct jbd_revoke_record_s *) hash_list->next;
11140 while (&(record->hash) != hash_list) {
11141 if (record->blocknr == blocknr)
11143 record = (struct jbd_revoke_record_s *) record->hash.next;
11148 int journal_init_revoke_caches(void)
11150 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
11151 if (revoke_record_cache == 0)
11154 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
11155 if (revoke_table_cache == 0) {
11156 do_cache_destroy(revoke_record_cache);
11157 revoke_record_cache = NULL;
11163 void journal_destroy_revoke_caches(void)
11165 do_cache_destroy(revoke_record_cache);
11166 revoke_record_cache = 0;
11167 do_cache_destroy(revoke_table_cache);
11168 revoke_table_cache = 0;
11171 /* Initialise the revoke table for a given journal to a given size. */
11173 int journal_init_revoke(journal_t *journal, int hash_size)
11177 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
11178 if (!journal->j_revoke)
11181 /* Check that the hash_size is a power of two */
11182 journal->j_revoke->hash_size = hash_size;
11186 while((tmp >>= 1UL) != 0UL)
11188 journal->j_revoke->hash_shift = shift;
11190 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
11191 if (!journal->j_revoke->hash_table) {
11192 free(journal->j_revoke);
11193 journal->j_revoke = NULL;
11197 for (tmp = 0; tmp < hash_size; tmp++)
11198 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
11203 /* Destoy a journal's revoke table. The table must already be empty! */
11205 void journal_destroy_revoke(journal_t *journal)
11207 struct jbd_revoke_table_s *table;
11208 struct list_head *hash_list;
11211 table = journal->j_revoke;
11215 for (i=0; i<table->hash_size; i++) {
11216 hash_list = &table->hash_table[i];
11219 free(table->hash_table);
11221 journal->j_revoke = NULL;
11225 * Revoke support for recovery.
11227 * Recovery needs to be able to:
11229 * record all revoke records, including the tid of the latest instance
11230 * of each revoke in the journal
11232 * check whether a given block in a given transaction should be replayed
11233 * (ie. has not been revoked by a revoke record in that or a subsequent
11236 * empty the revoke table after recovery.
11240 * First, setting revoke records. We create a new revoke record for
11241 * every block ever revoked in the log as we scan it for recovery, and
11242 * we update the existing records if we find multiple revokes for a
11246 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
11249 struct jbd_revoke_record_s *record;
11251 record = find_revoke_record(journal, blocknr);
11253 /* If we have multiple occurences, only record the
11254 * latest sequence number in the hashed record */
11255 if (tid_gt(sequence, record->sequence))
11256 record->sequence = sequence;
11259 return insert_revoke_hash(journal, blocknr, sequence);
11263 * Test revoke records. For a given block referenced in the log, has
11264 * that block been revoked? A revoke record with a given transaction
11265 * sequence number revokes all blocks in that transaction and earlier
11266 * ones, but later transactions still need replayed.
11269 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
11272 struct jbd_revoke_record_s *record;
11274 record = find_revoke_record(journal, blocknr);
11277 if (tid_gt(sequence, record->sequence))
11283 * Finally, once recovery is over, we need to clear the revoke table so
11284 * that it can be reused by the running filesystem.
11287 void journal_clear_revoke(journal_t *journal)
11290 struct list_head *hash_list;
11291 struct jbd_revoke_record_s *record;
11292 struct jbd_revoke_table_s *revoke_var;
11294 revoke_var = journal->j_revoke;
11296 for (i = 0; i < revoke_var->hash_size; i++) {
11297 hash_list = &revoke_var->hash_table[i];
11298 while (!list_empty(hash_list)) {
11299 record = (struct jbd_revoke_record_s*) hash_list->next;
11300 list_del(&record->hash);
11307 * e2fsck.c - superblock checks
11310 #define MIN_CHECK 1
11311 #define MAX_CHECK 2
11313 static void check_super_value(e2fsck_t ctx, const char *descr,
11314 unsigned long value, int flags,
11315 unsigned long min_val, unsigned long max_val)
11317 struct problem_context pctx;
11319 if (((flags & MIN_CHECK) && (value < min_val)) ||
11320 ((flags & MAX_CHECK) && (value > max_val))) {
11321 clear_problem_context(&pctx);
11324 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11325 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11330 * This routine may get stubbed out in special compilations of the
11333 #ifndef EXT2_SPECIAL_DEVICE_SIZE
11334 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
11336 return (ext2fs_get_device_size(ctx->filesystem_name,
11337 EXT2_BLOCK_SIZE(ctx->fs->super),
11338 &ctx->num_blocks));
11343 * helper function to release an inode
11345 struct process_block_struct {
11348 struct problem_context *pctx;
11350 int truncate_offset;
11351 e2_blkcnt_t truncate_block;
11352 int truncated_blocks;
11357 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11358 e2_blkcnt_t blockcnt,
11359 blk_t ref_blk FSCK_ATTR((unused)),
11360 int ref_offset FSCK_ATTR((unused)),
11363 struct process_block_struct *pb;
11365 struct problem_context *pctx;
11366 blk_t blk = *block_nr;
11369 pb = (struct process_block_struct *) priv_data;
11374 pctx->blkcount = blockcnt;
11376 if (HOLE_BLKADDR(blk))
11379 if ((blk < fs->super->s_first_data_block) ||
11380 (blk >= fs->super->s_blocks_count)) {
11381 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11384 return BLOCK_ABORT;
11387 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
11388 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
11393 * If we are deleting an orphan, then we leave the fields alone.
11394 * If we are truncating an orphan, then update the inode fields
11395 * and clean up any partial block data.
11397 if (pb->truncating) {
11399 * We only remove indirect blocks if they are
11400 * completely empty.
11402 if (blockcnt < 0) {
11406 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11411 limit = fs->blocksize >> 2;
11412 for (i = 0, bp = (blk_t *) pb->buf;
11413 i < limit; i++, bp++)
11418 * We don't remove direct blocks until we've reached
11419 * the truncation block.
11421 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
11424 * If part of the last block needs truncating, we do
11427 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
11428 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
11432 memset(pb->buf + pb->truncate_offset, 0,
11433 fs->blocksize - pb->truncate_offset);
11434 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
11439 pb->truncated_blocks++;
11441 retval |= BLOCK_CHANGED;
11444 ext2fs_block_alloc_stats(fs, blk, -1);
11449 * This function releases an inode. Returns 1 if an inconsistency was
11450 * found. If the inode has a link count, then it is being truncated and
11453 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
11454 struct ext2_inode *inode, char *block_buf,
11455 struct problem_context *pctx)
11457 struct process_block_struct pb;
11458 ext2_filsys fs = ctx->fs;
11462 if (!ext2fs_inode_has_valid_blocks(inode))
11465 pb.buf = block_buf + 3 * ctx->fs->blocksize;
11470 if (inode->i_links_count) {
11472 pb.truncate_block = (e2_blkcnt_t)
11473 ((((long long)inode->i_size_high << 32) +
11474 inode->i_size + fs->blocksize - 1) /
11476 pb.truncate_offset = inode->i_size % fs->blocksize;
11479 pb.truncate_block = 0;
11480 pb.truncate_offset = 0;
11482 pb.truncated_blocks = 0;
11483 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
11484 block_buf, release_inode_block, &pb);
11486 bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"),
11493 /* Refresh the inode since ext2fs_block_iterate may have changed it */
11494 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
11496 if (pb.truncated_blocks)
11497 inode->i_blocks -= pb.truncated_blocks *
11498 (fs->blocksize / 512);
11500 if (inode->i_file_acl) {
11501 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
11502 block_buf, -1, &count);
11503 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
11508 bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"),
11513 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
11514 inode->i_file_acl = 0;
11520 * This function releases all of the orphan inodes. It returns 1 if
11521 * it hit some error, and 0 on success.
11523 static int release_orphan_inodes(e2fsck_t ctx)
11525 ext2_filsys fs = ctx->fs;
11526 ext2_ino_t ino, next_ino;
11527 struct ext2_inode inode;
11528 struct problem_context pctx;
11531 if ((ino = fs->super->s_last_orphan) == 0)
11535 * Win or lose, we won't be using the head of the orphan inode
11538 fs->super->s_last_orphan = 0;
11539 ext2fs_mark_super_dirty(fs);
11542 * If the filesystem contains errors, don't run the orphan
11543 * list, since the orphan list can't be trusted; and we're
11544 * going to be running a full e2fsck run anyway...
11546 if (fs->super->s_state & EXT2_ERROR_FS)
11549 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
11550 (ino > fs->super->s_inodes_count)) {
11551 clear_problem_context(&pctx);
11553 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
11557 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
11558 "block iterate buffer");
11559 e2fsck_read_bitmaps(ctx);
11562 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
11563 clear_problem_context(&pctx);
11565 pctx.inode = &inode;
11566 pctx.str = inode.i_links_count ? _("Truncating") :
11569 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
11571 next_ino = inode.i_dtime;
11573 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
11574 (next_ino > fs->super->s_inodes_count))) {
11575 pctx.ino = next_ino;
11576 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
11580 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
11583 if (!inode.i_links_count) {
11584 ext2fs_inode_alloc_stats2(fs, ino, -1,
11585 LINUX_S_ISDIR(inode.i_mode));
11586 inode.i_dtime = time(0);
11590 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
11593 ext2fs_free_mem(&block_buf);
11596 ext2fs_free_mem(&block_buf);
11601 * Check the resize inode to make sure it is sane. We check both for
11602 * the case where on-line resizing is not enabled (in which case the
11603 * resize inode should be cleared) as well as the case where on-line
11604 * resizing is enabled.
11606 static void check_resize_inode(e2fsck_t ctx)
11608 ext2_filsys fs = ctx->fs;
11609 struct ext2_inode inode;
11610 struct problem_context pctx;
11611 int i, j, gdt_off, ind_off;
11612 blk_t blk, pblk, expect;
11613 __u32 *dind_buf = 0, *ind_buf;
11616 clear_problem_context(&pctx);
11619 * If the resize inode feature isn't set, then
11620 * s_reserved_gdt_blocks must be zero.
11622 if (!(fs->super->s_feature_compat &
11623 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11624 if (fs->super->s_reserved_gdt_blocks) {
11625 pctx.num = fs->super->s_reserved_gdt_blocks;
11626 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
11628 fs->super->s_reserved_gdt_blocks = 0;
11629 ext2fs_mark_super_dirty(fs);
11634 /* Read the resize inode */
11635 pctx.ino = EXT2_RESIZE_INO;
11636 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
11638 if (fs->super->s_feature_compat &
11639 EXT2_FEATURE_COMPAT_RESIZE_INODE)
11640 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11645 * If the resize inode feature isn't set, check to make sure
11646 * the resize inode is cleared; then we're done.
11648 if (!(fs->super->s_feature_compat &
11649 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
11650 for (i=0; i < EXT2_N_BLOCKS; i++) {
11651 if (inode.i_block[i])
11654 if ((i < EXT2_N_BLOCKS) &&
11655 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
11656 memset(&inode, 0, sizeof(inode));
11657 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11664 * The resize inode feature is enabled; check to make sure the
11665 * only block in use is the double indirect block
11667 blk = inode.i_block[EXT2_DIND_BLOCK];
11668 for (i=0; i < EXT2_N_BLOCKS; i++) {
11669 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
11672 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
11673 !(inode.i_mode & LINUX_S_IFREG) ||
11674 (blk < fs->super->s_first_data_block ||
11675 blk >= fs->super->s_blocks_count)) {
11676 resize_inode_invalid:
11677 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11678 memset(&inode, 0, sizeof(inode));
11679 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
11681 ctx->flags |= E2F_FLAG_RESIZE_INODE;
11683 if (!(ctx->options & E2F_OPT_READONLY)) {
11684 fs->super->s_state &= ~EXT2_VALID_FS;
11685 ext2fs_mark_super_dirty(fs);
11689 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
11690 "resize dind buffer");
11691 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
11693 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
11695 goto resize_inode_invalid;
11697 gdt_off = fs->desc_blocks;
11698 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
11699 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
11700 i++, gdt_off++, pblk++) {
11701 gdt_off %= fs->blocksize/4;
11702 if (dind_buf[gdt_off] != pblk)
11703 goto resize_inode_invalid;
11704 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
11706 goto resize_inode_invalid;
11708 for (j = 1; j < fs->group_desc_count; j++) {
11709 if (!ext2fs_bg_has_super(fs, j))
11711 expect = pblk + (j * fs->super->s_blocks_per_group);
11712 if (ind_buf[ind_off] != expect)
11713 goto resize_inode_invalid;
11719 ext2fs_free_mem(&dind_buf);
11723 static void check_super_block(e2fsck_t ctx)
11725 ext2_filsys fs = ctx->fs;
11726 blk_t first_block, last_block;
11727 struct ext2_super_block *sb = fs->super;
11728 struct ext2_group_desc *gd;
11729 blk_t blocks_per_group = fs->super->s_blocks_per_group;
11731 int inodes_per_block;
11736 struct problem_context pctx;
11737 __u32 free_blocks = 0, free_inodes = 0;
11739 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
11740 ipg_max = inodes_per_block * (blocks_per_group - 4);
11741 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
11742 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
11743 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
11744 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
11745 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
11747 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11748 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
11749 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
11750 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
11751 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
11752 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
11754 clear_problem_context(&pctx);
11757 * Verify the super block constants...
11759 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
11761 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
11763 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
11764 MAX_CHECK, 0, sb->s_blocks_count);
11765 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
11766 MIN_CHECK | MAX_CHECK, 0,
11767 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
11768 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
11769 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
11770 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
11771 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
11773 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
11774 MIN_CHECK | MAX_CHECK, 8, bpg_max);
11775 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
11776 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
11777 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
11778 MAX_CHECK, 0, sb->s_blocks_count / 2);
11779 check_super_value(ctx, "reserved_gdt_blocks",
11780 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
11782 inode_size = EXT2_INODE_SIZE(sb);
11783 check_super_value(ctx, "inode_size",
11784 inode_size, MIN_CHECK | MAX_CHECK,
11785 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
11786 if (inode_size & (inode_size - 1)) {
11787 pctx.num = inode_size;
11788 pctx.str = "inode_size";
11789 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
11790 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
11794 if (!ctx->num_blocks) {
11795 pctx.errcode = e2fsck_get_device_size(ctx);
11796 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
11797 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
11798 ctx->flags |= E2F_FLAG_ABORT;
11801 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
11802 (ctx->num_blocks < sb->s_blocks_count)) {
11803 pctx.blk = sb->s_blocks_count;
11804 pctx.blk2 = ctx->num_blocks;
11805 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
11806 ctx->flags |= E2F_FLAG_ABORT;
11812 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
11813 pctx.blk = EXT2_BLOCK_SIZE(sb);
11814 pctx.blk2 = EXT2_FRAG_SIZE(sb);
11815 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
11816 ctx->flags |= E2F_FLAG_ABORT;
11820 should_be = sb->s_frags_per_group >>
11821 (sb->s_log_block_size - sb->s_log_frag_size);
11822 if (sb->s_blocks_per_group != should_be) {
11823 pctx.blk = sb->s_blocks_per_group;
11824 pctx.blk2 = should_be;
11825 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
11826 ctx->flags |= E2F_FLAG_ABORT;
11830 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
11831 if (sb->s_first_data_block != should_be) {
11832 pctx.blk = sb->s_first_data_block;
11833 pctx.blk2 = should_be;
11834 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
11835 ctx->flags |= E2F_FLAG_ABORT;
11839 should_be = sb->s_inodes_per_group * fs->group_desc_count;
11840 if (sb->s_inodes_count != should_be) {
11841 pctx.ino = sb->s_inodes_count;
11842 pctx.ino2 = should_be;
11843 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
11844 sb->s_inodes_count = should_be;
11845 ext2fs_mark_super_dirty(fs);
11850 * Verify the group descriptors....
11852 first_block = sb->s_first_data_block;
11853 last_block = first_block + blocks_per_group;
11855 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
11858 if (i == fs->group_desc_count - 1)
11859 last_block = sb->s_blocks_count;
11860 if ((gd->bg_block_bitmap < first_block) ||
11861 (gd->bg_block_bitmap >= last_block)) {
11862 pctx.blk = gd->bg_block_bitmap;
11863 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
11864 gd->bg_block_bitmap = 0;
11866 if (gd->bg_block_bitmap == 0) {
11867 ctx->invalid_block_bitmap_flag[i]++;
11868 ctx->invalid_bitmaps++;
11870 if ((gd->bg_inode_bitmap < first_block) ||
11871 (gd->bg_inode_bitmap >= last_block)) {
11872 pctx.blk = gd->bg_inode_bitmap;
11873 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
11874 gd->bg_inode_bitmap = 0;
11876 if (gd->bg_inode_bitmap == 0) {
11877 ctx->invalid_inode_bitmap_flag[i]++;
11878 ctx->invalid_bitmaps++;
11880 if ((gd->bg_inode_table < first_block) ||
11881 ((gd->bg_inode_table +
11882 fs->inode_blocks_per_group - 1) >= last_block)) {
11883 pctx.blk = gd->bg_inode_table;
11884 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
11885 gd->bg_inode_table = 0;
11887 if (gd->bg_inode_table == 0) {
11888 ctx->invalid_inode_table_flag[i]++;
11889 ctx->invalid_bitmaps++;
11891 free_blocks += gd->bg_free_blocks_count;
11892 free_inodes += gd->bg_free_inodes_count;
11893 first_block += sb->s_blocks_per_group;
11894 last_block += sb->s_blocks_per_group;
11896 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
11897 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11898 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11899 ext2fs_unmark_valid(fs);
11904 * Update the global counts from the block group counts. This
11905 * is needed for an experimental patch which eliminates
11906 * locking the entire filesystem when allocating blocks or
11907 * inodes; if the filesystem is not unmounted cleanly, the
11908 * global counts may not be accurate.
11910 if ((free_blocks != sb->s_free_blocks_count) ||
11911 (free_inodes != sb->s_free_inodes_count)) {
11912 if (ctx->options & E2F_OPT_READONLY)
11913 ext2fs_unmark_valid(fs);
11915 sb->s_free_blocks_count = free_blocks;
11916 sb->s_free_inodes_count = free_inodes;
11917 ext2fs_mark_super_dirty(fs);
11921 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
11922 (sb->s_free_inodes_count > sb->s_inodes_count))
11923 ext2fs_unmark_valid(fs);
11927 * If we have invalid bitmaps, set the error state of the
11930 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
11931 sb->s_state &= ~EXT2_VALID_FS;
11932 ext2fs_mark_super_dirty(fs);
11935 clear_problem_context(&pctx);
11938 * If the UUID field isn't assigned, assign it.
11940 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
11941 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
11942 uuid_generate(sb->s_uuid);
11943 ext2fs_mark_super_dirty(fs);
11944 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
11948 /* FIXME - HURD support?
11949 * For the Hurd, check to see if the filetype option is set,
11950 * since it doesn't support it.
11952 if (!(ctx->options & E2F_OPT_READONLY) &&
11953 fs->super->s_creator_os == EXT2_OS_HURD &&
11954 (fs->super->s_feature_incompat &
11955 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
11956 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
11957 fs->super->s_feature_incompat &=
11958 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11959 ext2fs_mark_super_dirty(fs);
11965 * If we have any of the compatibility flags set, we need to have a
11966 * revision 1 filesystem. Most kernels will not check the flags on
11967 * a rev 0 filesystem and we may have corruption issues because of
11968 * the incompatible changes to the filesystem.
11970 if (!(ctx->options & E2F_OPT_READONLY) &&
11971 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
11972 (fs->super->s_feature_compat ||
11973 fs->super->s_feature_ro_compat ||
11974 fs->super->s_feature_incompat) &&
11975 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
11976 ext2fs_update_dynamic_rev(fs);
11977 ext2fs_mark_super_dirty(fs);
11980 check_resize_inode(ctx);
11983 * Clean up any orphan inodes, if present.
11985 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
11986 fs->super->s_state &= ~EXT2_VALID_FS;
11987 ext2fs_mark_super_dirty(fs);
11991 * Move the ext3 journal file, if necessary.
11993 e2fsck_move_ext3_journal(ctx);
11998 * swapfs.c --- byte-swap an ext2 filesystem
12001 #ifdef ENABLE_SWAPFS
12003 struct swap_block_struct {
12008 struct ext2_inode *inode;
12012 * This is a helper function for block_iterate. We mark all of the
12013 * indirect and direct blocks as changed, so that block_iterate will
12016 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
12021 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
12023 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
12024 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
12026 sb->errcode = retval;
12027 return BLOCK_ABORT;
12029 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
12031 sb->errcode = retval;
12032 return BLOCK_ABORT;
12035 if (blockcnt >= 0) {
12036 if (blockcnt < EXT2_NDIR_BLOCKS)
12038 return BLOCK_CHANGED;
12040 if (blockcnt == BLOCK_COUNT_IND) {
12041 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
12043 return BLOCK_CHANGED;
12045 if (blockcnt == BLOCK_COUNT_DIND) {
12046 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
12048 return BLOCK_CHANGED;
12050 if (blockcnt == BLOCK_COUNT_TIND) {
12051 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
12053 return BLOCK_CHANGED;
12055 return BLOCK_CHANGED;
12059 * This function is responsible for byte-swapping all of the indirect,
12060 * block pointers. It is also responsible for byte-swapping directories.
12062 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
12063 struct ext2_inode *inode)
12066 struct swap_block_struct sb;
12070 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
12073 if (LINUX_S_ISDIR(inode->i_mode))
12076 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
12079 bb_error_msg(_("while calling ext2fs_block_iterate"));
12080 ctx->flags |= E2F_FLAG_ABORT;
12084 bb_error_msg(_("while calling iterator function"));
12085 ctx->flags |= E2F_FLAG_ABORT;
12090 static void swap_inodes(e2fsck_t ctx)
12092 ext2_filsys fs = ctx->fs;
12095 ext2_ino_t ino = 1;
12096 char *buf, *block_buf;
12098 struct ext2_inode * inode;
12100 e2fsck_use_inode_shortcuts(ctx, 1);
12102 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
12105 bb_error_msg(_("while allocating inode buffer"));
12106 ctx->flags |= E2F_FLAG_ABORT;
12109 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
12110 "block interate buffer");
12111 for (group = 0; group < fs->group_desc_count; group++) {
12112 retval = io_channel_read_blk(fs->io,
12113 fs->group_desc[group].bg_inode_table,
12114 fs->inode_blocks_per_group, buf);
12116 bb_error_msg(_("while reading inode table (group %d)"),
12118 ctx->flags |= E2F_FLAG_ABORT;
12121 inode = (struct ext2_inode *) buf;
12122 for (i=0; i < fs->super->s_inodes_per_group;
12123 i++, ino++, inode++) {
12124 ctx->stashed_ino = ino;
12125 ctx->stashed_inode = inode;
12127 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
12128 ext2fs_swap_inode(fs, inode, inode, 0);
12131 * Skip deleted files.
12133 if (inode->i_links_count == 0)
12136 if (LINUX_S_ISDIR(inode->i_mode) ||
12137 ((inode->i_block[EXT2_IND_BLOCK] ||
12138 inode->i_block[EXT2_DIND_BLOCK] ||
12139 inode->i_block[EXT2_TIND_BLOCK]) &&
12140 ext2fs_inode_has_valid_blocks(inode)))
12141 swap_inode_blocks(ctx, ino, block_buf, inode);
12143 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12146 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12147 ext2fs_swap_inode(fs, inode, inode, 1);
12149 retval = io_channel_write_blk(fs->io,
12150 fs->group_desc[group].bg_inode_table,
12151 fs->inode_blocks_per_group, buf);
12153 bb_error_msg(_("while writing inode table (group %d)"),
12155 ctx->flags |= E2F_FLAG_ABORT;
12159 ext2fs_free_mem(&buf);
12160 ext2fs_free_mem(&block_buf);
12161 e2fsck_use_inode_shortcuts(ctx, 0);
12162 ext2fs_flush_icache(fs);
12165 #if defined(__powerpc__) && BB_BIG_ENDIAN
12167 * On the PowerPC, the big-endian variant of the ext2 filesystem
12168 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
12169 * of each word. Thus a bitmap with only bit 0 set would be, as
12170 * a string of bytes, 00 00 00 01 00 ...
12171 * To cope with this, we byte-reverse each word of a bitmap if
12172 * we have a big-endian filesystem, that is, if we are *not*
12173 * byte-swapping other word-sized numbers.
12175 #define EXT2_BIG_ENDIAN_BITMAPS
12178 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12179 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
12181 __u32 *p = (__u32 *) bmap->bitmap;
12182 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
12184 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
12185 *p = ext2fs_swab32(*p);
12190 #ifdef ENABLE_SWAPFS
12191 static void swap_filesys(e2fsck_t ctx)
12193 ext2_filsys fs = ctx->fs;
12194 if (!(ctx->options & E2F_OPT_PREEN))
12195 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
12199 if (fs->super->s_mnt_count) {
12200 fprintf(stderr, _("%s: the filesystem must be freshly "
12201 "checked using fsck\n"
12202 "and not mounted before trying to "
12203 "byte-swap it.\n"), ctx->device_name);
12204 ctx->flags |= E2F_FLAG_ABORT;
12207 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
12208 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
12209 EXT2_FLAG_SWAP_BYTES_WRITE);
12210 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
12212 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
12213 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
12216 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
12218 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
12219 fs->flags |= EXT2_FLAG_SWAP_BYTES;
12220 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
12221 EXT2_FLAG_SWAP_BYTES_WRITE);
12223 #ifdef EXT2_BIG_ENDIAN_BITMAPS
12224 e2fsck_read_bitmaps(ctx);
12225 ext2fs_swap_bitmap(fs->inode_map);
12226 ext2fs_swap_bitmap(fs->block_map);
12227 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
12229 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
12231 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
12233 #endif /* ENABLE_SWAPFS */
12238 * util.c --- miscellaneous utilities
12242 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
12243 const char *description)
12248 ret = malloc(size);
12250 sprintf(buf, "Can't allocate %s\n", description);
12251 bb_error_msg_and_die(buf);
12253 memset(ret, 0, size);
12257 static char *string_copy(const char *str, int len)
12265 ret = malloc(len+1);
12267 strncpy(ret, str, len);
12273 #ifndef HAVE_CONIO_H
12274 static int read_a_char(void)
12281 if (e2fsck_global_ctx &&
12282 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12285 r = read(0, &c, 1);
12295 static int ask_yn(const char * string, int def)
12298 const char *defstr;
12299 static const char short_yes[] = "yY";
12300 static const char short_no[] = "nN";
12302 #ifdef HAVE_TERMIOS_H
12303 struct termios termios, tmp;
12305 tcgetattr (0, &termios);
12307 tmp.c_lflag &= ~(ICANON | ECHO);
12308 tmp.c_cc[VMIN] = 1;
12309 tmp.c_cc[VTIME] = 0;
12310 tcsetattr (0, TCSANOW, &tmp);
12319 printf("%s%s? ", string, defstr);
12322 if ((c = read_a_char()) == EOF)
12325 #ifdef HAVE_TERMIOS_H
12326 tcsetattr (0, TCSANOW, &termios);
12328 if (e2fsck_global_ctx &&
12329 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
12331 longjmp(e2fsck_global_ctx->abort_loc, 1);
12333 puts(_("cancelled!\n"));
12336 if (strchr(short_yes, (char) c)) {
12340 else if (strchr(short_no, (char) c)) {
12344 else if ((c == ' ' || c == '\n') && (def != -1))
12351 #ifdef HAVE_TERMIOS_H
12352 tcsetattr (0, TCSANOW, &termios);
12357 int ask (e2fsck_t ctx, const char * string, int def)
12359 if (ctx->options & E2F_OPT_NO) {
12360 printf (_("%s? no\n\n"), string);
12363 if (ctx->options & E2F_OPT_YES) {
12364 printf (_("%s? yes\n\n"), string);
12367 if (ctx->options & E2F_OPT_PREEN) {
12368 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
12371 return ask_yn(string, def);
12374 void e2fsck_read_bitmaps(e2fsck_t ctx)
12376 ext2_filsys fs = ctx->fs;
12379 if (ctx->invalid_bitmaps) {
12380 bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
12382 bb_error_msg_and_die(0);
12385 ehandler_operation(_("reading inode and block bitmaps"));
12386 retval = ext2fs_read_bitmaps(fs);
12387 ehandler_operation(0);
12389 bb_error_msg(_("while retrying to read bitmaps for %s"),
12391 bb_error_msg_and_die(0);
12395 static void e2fsck_write_bitmaps(e2fsck_t ctx)
12397 ext2_filsys fs = ctx->fs;
12400 if (ext2fs_test_bb_dirty(fs)) {
12401 ehandler_operation(_("writing block bitmaps"));
12402 retval = ext2fs_write_block_bitmap(fs);
12403 ehandler_operation(0);
12405 bb_error_msg(_("while retrying to write block bitmaps for %s"),
12407 bb_error_msg_and_die(0);
12411 if (ext2fs_test_ib_dirty(fs)) {
12412 ehandler_operation(_("writing inode bitmaps"));
12413 retval = ext2fs_write_inode_bitmap(fs);
12414 ehandler_operation(0);
12416 bb_error_msg(_("while retrying to write inode bitmaps for %s"),
12418 bb_error_msg_and_die(0);
12423 void preenhalt(e2fsck_t ctx)
12425 ext2_filsys fs = ctx->fs;
12427 if (!(ctx->options & E2F_OPT_PREEN))
12429 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
12430 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
12433 fs->super->s_state |= EXT2_ERROR_FS;
12434 ext2fs_mark_super_dirty(fs);
12437 exit(EXIT_UNCORRECTED);
12440 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
12441 struct ext2_inode * inode, const char *proc)
12445 retval = ext2fs_read_inode(ctx->fs, ino, inode);
12447 bb_error_msg(_("while reading inode %ld in %s"), ino, proc);
12448 bb_error_msg_and_die(0);
12452 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
12453 struct ext2_inode * inode, int bufsize,
12458 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
12460 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12461 bb_error_msg_and_die(0);
12465 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
12466 struct ext2_inode * inode, const char *proc)
12470 retval = ext2fs_write_inode(ctx->fs, ino, inode);
12472 bb_error_msg(_("while writing inode %ld in %s"), ino, proc);
12473 bb_error_msg_and_die(0);
12477 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
12478 io_manager manager)
12480 struct ext2_super_block *sb;
12481 io_channel io = NULL;
12484 blk_t superblock, ret_sb = 8193;
12486 if (fs && fs->super) {
12487 ret_sb = (fs->super->s_blocks_per_group +
12488 fs->super->s_first_data_block);
12490 ctx->superblock = ret_sb;
12491 ctx->blocksize = fs->blocksize;
12497 if (ctx->blocksize) {
12498 ret_sb = ctx->blocksize * 8;
12499 if (ctx->blocksize == 1024)
12501 ctx->superblock = ret_sb;
12504 ctx->superblock = ret_sb;
12505 ctx->blocksize = 1024;
12508 if (!name || !manager)
12511 if (manager->open(name, 0, &io) != 0)
12514 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
12516 sb = (struct ext2_super_block *) buf;
12518 for (blocksize = EXT2_MIN_BLOCK_SIZE;
12519 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
12520 superblock = blocksize*8;
12521 if (blocksize == 1024)
12523 io_channel_set_blksize(io, blocksize);
12524 if (io_channel_read_blk(io, superblock,
12525 -SUPERBLOCK_SIZE, buf))
12528 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
12529 ext2fs_swap_super(sb);
12531 if (sb->s_magic == EXT2_SUPER_MAGIC) {
12532 ret_sb = superblock;
12534 ctx->superblock = superblock;
12535 ctx->blocksize = blocksize;
12543 io_channel_close(io);
12544 ext2fs_free_mem(&buf);
12550 * This function runs through the e2fsck passes and calls them all,
12551 * returning restart, abort, or cancel as necessary...
12553 typedef void (*pass_t)(e2fsck_t ctx);
12555 static const pass_t e2fsck_passes[] = {
12556 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
12559 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
12561 static int e2fsck_run(e2fsck_t ctx)
12564 pass_t e2fsck_pass;
12566 if (setjmp(ctx->abort_loc)) {
12567 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12568 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12570 ctx->flags |= E2F_FLAG_SETJMP_OK;
12572 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
12573 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12577 (void) (ctx->progress)(ctx, 0, 0, 0);
12579 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
12581 if (ctx->flags & E2F_FLAG_RUN_RETURN)
12582 return (ctx->flags & E2F_FLAG_RUN_RETURN);
12588 * unix.c - The unix-specific code for e2fsck
12592 /* Command line options */
12594 #ifdef ENABLE_SWAPFS
12595 static int normalize_swapfs;
12597 static int cflag; /* check disk */
12598 static int show_version_only;
12599 static int verbose;
12601 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
12603 static void show_stats(e2fsck_t ctx)
12605 ext2_filsys fs = ctx->fs;
12606 int inodes, inodes_used, blocks, blocks_used;
12608 int num_files, num_links;
12611 dir_links = 2 * ctx->fs_directory_count - 1;
12612 num_files = ctx->fs_total_count - dir_links;
12613 num_links = ctx->fs_links_count - dir_links;
12614 inodes = fs->super->s_inodes_count;
12615 inodes_used = (fs->super->s_inodes_count -
12616 fs->super->s_free_inodes_count);
12617 blocks = fs->super->s_blocks_count;
12618 blocks_used = (fs->super->s_blocks_count -
12619 fs->super->s_free_blocks_count);
12621 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
12622 frag_percent = (frag_percent + 5) / 10;
12625 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
12626 ctx->device_name, inodes_used, inodes,
12627 frag_percent / 10, frag_percent % 10,
12628 blocks_used, blocks);
12631 printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
12632 100 * inodes_used / inodes);
12633 printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
12634 P_E2("", "s", ctx->fs_fragmented),
12635 frag_percent / 10, frag_percent % 10);
12636 printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
12637 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
12638 printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
12639 (int) ((long long) 100 * blocks_used / blocks));
12640 printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
12641 printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
12642 printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
12643 printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
12644 printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
12645 printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
12646 printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
12647 printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
12648 printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
12649 printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
12650 printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
12653 static void check_mount(e2fsck_t ctx)
12658 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
12659 &ctx->mount_flags);
12661 bb_error_msg(_("while determining whether %s is mounted."),
12662 ctx->filesystem_name);
12667 * If the filesystem isn't mounted, or it's the root filesystem
12668 * and it's mounted read-only, then everything's fine.
12670 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
12671 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
12672 (ctx->mount_flags & EXT2_MF_READONLY)))
12675 if (ctx->options & E2F_OPT_READONLY) {
12676 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
12680 printf(_("%s is mounted. "), ctx->filesystem_name);
12681 if (!ctx->interactive)
12682 bb_error_msg_and_die(_("Cannot continue, aborting.\n\n"));
12683 printf(_("\n\n\007\007\007\007WARNING!!! "
12684 "Running e2fsck on a mounted filesystem may cause\n"
12685 "SEVERE filesystem damage.\007\007\007\n\n"));
12686 cont = ask_yn(_("Do you really want to continue"), -1);
12688 printf (_("check aborted.\n"));
12694 static int is_on_batt(void)
12698 char tmp[80], tmp2[80], fname[80];
12699 unsigned int acflag;
12702 f = fopen("/proc/apm", "r");
12704 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
12707 return (acflag != 1);
12709 d = opendir("/proc/acpi/ac_adapter");
12711 while ((de=readdir(d)) != NULL) {
12712 if (!strncmp(".", de->d_name, 1))
12714 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
12716 f = fopen(fname, "r");
12719 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
12722 if (strncmp(tmp, "off-line", 8) == 0) {
12733 * This routine checks to see if a filesystem can be skipped; if so,
12734 * it will exit with EXIT_OK. Under some conditions it will print a
12735 * message explaining why a check is being forced.
12737 static void check_if_skip(e2fsck_t ctx)
12739 ext2_filsys fs = ctx->fs;
12740 const char *reason = NULL;
12741 unsigned int reason_arg = 0;
12743 int batt = is_on_batt();
12744 time_t now = time(0);
12746 if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs)
12749 if ((fs->super->s_state & EXT2_ERROR_FS) ||
12750 !ext2fs_test_valid(fs))
12751 reason = _(" contains a file system with errors");
12752 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
12753 reason = _(" was not cleanly unmounted");
12754 else if ((fs->super->s_max_mnt_count > 0) &&
12755 (fs->super->s_mnt_count >=
12756 (unsigned) fs->super->s_max_mnt_count)) {
12757 reason = _(" has been mounted %u times without being checked");
12758 reason_arg = fs->super->s_mnt_count;
12759 if (batt && (fs->super->s_mnt_count <
12760 (unsigned) fs->super->s_max_mnt_count*2))
12762 } else if (fs->super->s_checkinterval &&
12763 ((now - fs->super->s_lastcheck) >=
12764 fs->super->s_checkinterval)) {
12765 reason = _(" has gone %u days without being checked");
12766 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
12767 if (batt && ((now - fs->super->s_lastcheck) <
12768 fs->super->s_checkinterval*2))
12772 fputs(ctx->device_name, stdout);
12773 printf(reason, reason_arg);
12774 fputs(_(", check forced.\n"), stdout);
12777 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
12778 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
12779 fs->super->s_inodes_count,
12780 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
12781 fs->super->s_blocks_count);
12782 next_check = 100000;
12783 if (fs->super->s_max_mnt_count > 0) {
12784 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
12785 if (next_check <= 0)
12788 if (fs->super->s_checkinterval &&
12789 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
12791 if (next_check <= 5) {
12792 if (next_check == 1)
12793 fputs(_(" (check after next mount)"), stdout);
12795 printf(_(" (check in %ld mounts)"), next_check);
12797 fputc('\n', stdout);
12800 e2fsck_free_context(ctx);
12805 * For completion notice
12807 struct percent_tbl {
12811 static const struct percent_tbl e2fsck_tbl = {
12812 5, { 0, 70, 90, 92, 95, 100 }
12815 static char bar[128], spaces[128];
12817 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
12824 if (pass > tbl->max_pass || max == 0)
12826 percent = ((float) curr) / ((float) max);
12827 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
12828 + tbl->table[pass-1]);
12831 void e2fsck_clear_progbar(e2fsck_t ctx)
12833 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
12836 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
12839 ctx->flags &= ~E2F_FLAG_PROG_BAR;
12842 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
12843 unsigned int dpynum)
12845 static const char spinner[] = "\\|/-";
12852 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
12856 * Calculate the new progress position. If the
12857 * percentage hasn't changed, then we skip out right
12860 fixed_percent = (int) ((10 * percent) + 0.5);
12861 if (ctx->progress_last_percent == fixed_percent)
12863 ctx->progress_last_percent = fixed_percent;
12866 * If we've already updated the spinner once within
12867 * the last 1/8th of a second, no point doing it
12870 gettimeofday(&tv, NULL);
12871 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
12872 if ((tick == ctx->progress_last_time) &&
12873 (fixed_percent != 0) && (fixed_percent != 1000))
12875 ctx->progress_last_time = tick;
12878 * Advance the spinner, and note that the progress bar
12879 * will be on the screen
12881 ctx->progress_pos = (ctx->progress_pos+1) & 3;
12882 ctx->flags |= E2F_FLAG_PROG_BAR;
12884 dpywidth = 66 - strlen(label);
12885 dpywidth = 8 * (dpywidth / 8);
12889 i = ((percent * dpywidth) + 50) / 100;
12890 printf("%s%s: |%s%s", ctx->start_meta, label,
12891 bar + (sizeof(bar) - (i+1)),
12892 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
12893 if (fixed_percent == 1000)
12894 fputc('|', stdout);
12896 fputc(spinner[ctx->progress_pos & 3], stdout);
12897 printf(" %4.1f%% ", percent);
12899 printf("%u\r", dpynum);
12901 fputs(" \r", stdout);
12902 fputs(ctx->stop_meta, stdout);
12904 if (fixed_percent == 1000)
12905 e2fsck_clear_progbar(ctx);
12911 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
12912 unsigned long cur, unsigned long max)
12920 if (ctx->progress_fd) {
12921 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
12922 write(ctx->progress_fd, buf, strlen(buf));
12924 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
12925 e2fsck_simple_progress(ctx, ctx->device_name,
12931 static void reserve_stdio_fds(void)
12936 fd = open(bb_dev_null, O_RDWR);
12940 fprintf(stderr, _("ERROR: Couldn't open "
12941 "/dev/null (%s)\n"),
12949 static void signal_progress_on(int sig FSCK_ATTR((unused)))
12951 e2fsck_t ctx = e2fsck_global_ctx;
12956 ctx->progress = e2fsck_update_progress;
12957 ctx->progress_fd = 0;
12960 static void signal_progress_off(int sig FSCK_ATTR((unused)))
12962 e2fsck_t ctx = e2fsck_global_ctx;
12967 e2fsck_clear_progbar(ctx);
12971 static void signal_cancel(int sig FSCK_ATTR((unused)))
12973 e2fsck_t ctx = e2fsck_global_ctx;
12976 exit(FSCK_CANCELED);
12978 ctx->flags |= E2F_FLAG_CANCEL;
12981 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
12983 char *buf, *token, *next, *p, *arg;
12985 int extended_usage = 0;
12987 buf = string_copy(opts, 0);
12988 for (token = buf; token && *token; token = next) {
12989 p = strchr(token, ',');
12995 arg = strchr(token, '=');
13000 if (strcmp(token, "ea_ver") == 0) {
13005 ea_ver = strtoul(arg, &p, 0);
13007 ((ea_ver != 1) && (ea_ver != 2))) {
13009 _("Invalid EA version.\n"));
13013 ctx->ext_attr_ver = ea_ver;
13015 fprintf(stderr, _("Unknown extended option: %s\n"),
13020 if (extended_usage) {
13021 bb_error_msg_and_die(
13022 "Extended options are separated by commas, "
13023 "and may take an argument which\n"
13024 "is set off by an equals ('=') sign. "
13025 "Valid extended options are:\n"
13026 "\tea_ver=<ea_version (1 or 2)>\n\n");
13031 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
13037 struct sigaction sa;
13038 char *extended_opts = 0;
13040 retval = e2fsck_allocate_context(&ctx);
13046 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
13047 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
13048 if (isatty(0) && isatty(1)) {
13049 ctx->interactive = 1;
13051 ctx->start_meta[0] = '\001';
13052 ctx->stop_meta[0] = '\002';
13054 memset(bar, '=', sizeof(bar)-1);
13055 memset(spaces, ' ', sizeof(spaces)-1);
13056 blkid_get_cache(&ctx->blkid, NULL);
13059 ctx->program_name = *argv;
13061 ctx->program_name = "e2fsck";
13062 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
13065 ctx->progress = e2fsck_update_progress;
13066 ctx->progress_fd = atoi(optarg);
13067 if (!ctx->progress_fd)
13069 /* Validate the file descriptor to avoid disasters */
13070 fd = dup(ctx->progress_fd);
13073 _("Error validating file descriptor %d: %s\n"),
13075 error_message(errno));
13076 bb_error_msg_and_die(_("Invalid completion information file descriptor"));
13081 ctx->options |= E2F_OPT_COMPRESS_DIRS;
13084 extended_opts = optarg;
13088 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
13090 bb_error_msg_and_die(_("Only one the options -p/-a, -n or -y may be specified."));
13092 ctx->options |= E2F_OPT_PREEN;
13095 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
13097 ctx->options |= E2F_OPT_NO;
13100 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
13102 ctx->options |= E2F_OPT_YES;
13105 /* FIXME - This needs to go away in a future path - will change binary */
13106 fprintf(stderr, _("The -t option is not "
13107 "supported on this version of e2fsck.\n"));
13111 ctx->options |= E2F_OPT_WRITECHECK;
13112 ctx->options |= E2F_OPT_CHECKBLOCKS;
13115 /* What we do by default, anyway! */
13118 ctx->use_superblock = atoi(optarg);
13119 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
13122 ctx->blocksize = atoi(optarg);
13125 ctx->inode_buffer_blocks = atoi(optarg);
13128 ctx->journal_name = string_copy(optarg, 0);
13131 ctx->process_inode_size = atoi(optarg);
13134 ctx->options |= E2F_OPT_DEBUG;
13137 ctx->options |= E2F_OPT_FORCE;
13146 show_version_only = 1;
13149 ctx->device_name = optarg;
13151 #ifdef ENABLE_SWAPFS
13153 normalize_swapfs = 1;
13160 fprintf(stderr, _("Byte-swapping filesystems "
13161 "not compiled in this version "
13168 if (show_version_only)
13170 if (optind != argc - 1)
13172 if ((ctx->options & E2F_OPT_NO) &&
13173 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
13174 ctx->options |= E2F_OPT_READONLY;
13175 ctx->io_options = strchr(argv[optind], '?');
13176 if (ctx->io_options)
13177 *ctx->io_options++ = 0;
13178 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
13179 if (!ctx->filesystem_name) {
13180 bb_error_msg(_("Unable to resolve '%s'"), argv[optind]);
13181 bb_error_msg_and_die(0);
13184 parse_extended_opts(ctx, extended_opts);
13187 fd = open(ctx->filesystem_name, O_RDONLY, 0);
13189 bb_error_msg(_("while opening %s for flushing"),
13190 ctx->filesystem_name);
13191 bb_error_msg_and_die(0);
13193 if ((retval = ext2fs_sync_device(fd, 1))) {
13194 bb_error_msg(_("while trying to flush %s"),
13195 ctx->filesystem_name);
13196 bb_error_msg_and_die(0);
13200 #ifdef ENABLE_SWAPFS
13201 if (swapfs && cflag) {
13202 fprintf(stderr, _("Incompatible options not "
13203 "allowed when byte-swapping.\n"));
13208 * Set up signal action
13210 memset(&sa, 0, sizeof(struct sigaction));
13211 sa.sa_handler = signal_cancel;
13212 sigaction(SIGINT, &sa, 0);
13213 sigaction(SIGTERM, &sa, 0);
13215 sa.sa_flags = SA_RESTART;
13217 e2fsck_global_ctx = ctx;
13218 sa.sa_handler = signal_progress_on;
13219 sigaction(SIGUSR1, &sa, 0);
13220 sa.sa_handler = signal_progress_off;
13221 sigaction(SIGUSR2, &sa, 0);
13223 /* Update our PATH to include /sbin if we need to run badblocks */
13225 e2fs_set_sbin_path();
13229 static const char my_ver_string[] = E2FSPROGS_VERSION;
13230 static const char my_ver_date[] = E2FSPROGS_DATE;
13232 int e2fsck_main (int argc, char *argv[])
13235 int exit_value = EXIT_OK;
13236 ext2_filsys fs = 0;
13238 struct ext2_super_block *sb;
13239 const char *lib_ver_date;
13240 int my_ver, lib_ver;
13242 struct problem_context pctx;
13243 int flags, run_result;
13245 clear_problem_context(&pctx);
13247 my_ver = ext2fs_parse_version_string(my_ver_string);
13248 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
13249 if (my_ver > lib_ver) {
13250 fprintf( stderr, _("Error: ext2fs library version "
13251 "out of date!\n"));
13252 show_version_only++;
13255 retval = PRS(argc, argv, &ctx);
13257 bb_error_msg(_("while trying to initialize program"));
13260 reserve_stdio_fds();
13262 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
13263 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
13266 if (show_version_only) {
13267 fprintf(stderr, _("\tUsing %s, %s\n"),
13268 error_message(EXT2_ET_BASE), lib_ver_date);
13274 if (!(ctx->options & E2F_OPT_PREEN) &&
13275 !(ctx->options & E2F_OPT_NO) &&
13276 !(ctx->options & E2F_OPT_YES)) {
13277 if (!ctx->interactive)
13278 bb_error_msg_and_die(_("need terminal for interactive repairs"));
13280 ctx->superblock = ctx->use_superblock;
13282 #ifdef CONFIG_TESTIO_DEBUG
13283 io_ptr = test_io_manager;
13284 test_io_backing_manager = unix_io_manager;
13286 io_ptr = unix_io_manager;
13289 if ((ctx->options & E2F_OPT_READONLY) == 0)
13290 flags |= EXT2_FLAG_RW;
13292 if (ctx->superblock && ctx->blocksize) {
13293 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13294 flags, ctx->superblock, ctx->blocksize,
13296 } else if (ctx->superblock) {
13298 for (blocksize = EXT2_MIN_BLOCK_SIZE;
13299 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
13300 retval = ext2fs_open2(ctx->filesystem_name,
13301 ctx->io_options, flags,
13302 ctx->superblock, blocksize,
13308 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
13309 flags, 0, 0, io_ptr, &fs);
13310 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
13311 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
13312 ((retval == EXT2_ET_BAD_MAGIC) ||
13313 ((retval == 0) && ext2fs_check_desc(fs)))) {
13314 if (!fs || (fs->group_desc_count > 1)) {
13315 printf(_("%s trying backup blocks...\n"),
13316 retval ? _("Couldn't find ext2 superblock,") :
13317 _("Group descriptors look bad..."));
13318 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
13325 bb_error_msg(_("while trying to open %s"),
13326 ctx->filesystem_name);
13327 if (retval == EXT2_ET_REV_TOO_HIGH) {
13328 printf(_("The filesystem revision is apparently "
13329 "too high for this version of e2fsck.\n"
13330 "(Or the filesystem superblock "
13331 "is corrupt)\n\n"));
13332 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13333 } else if (retval == EXT2_ET_SHORT_READ)
13334 printf(_("Could this be a zero-length partition?\n"));
13335 else if ((retval == EPERM) || (retval == EACCES))
13336 printf(_("You must have %s access to the "
13337 "filesystem or be root\n"),
13338 (ctx->options & E2F_OPT_READONLY) ?
13340 else if (retval == ENXIO)
13341 printf(_("Possibly non-existent or swap device?\n"));
13343 else if (retval == EROFS)
13344 printf(_("Disk write-protected; use the -n option "
13345 "to do a read-only\n"
13346 "check of the device.\n"));
13349 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
13350 bb_error_msg_and_die(0);
13353 fs->priv_data = ctx;
13355 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
13356 bb_error_msg(_("while trying to open %s"),
13357 ctx->filesystem_name);
13359 bb_error_msg_and_die(_("Get a newer version of e2fsck!"));
13363 * Set the device name, which is used whenever we print error
13364 * or informational messages to the user.
13366 if (ctx->device_name == 0 &&
13367 (sb->s_volume_name[0] != 0)) {
13368 ctx->device_name = string_copy(sb->s_volume_name,
13369 sizeof(sb->s_volume_name));
13371 if (ctx->device_name == 0)
13372 ctx->device_name = ctx->filesystem_name;
13375 * Make sure the ext3 superblock fields are consistent.
13377 retval = e2fsck_check_ext3_journal(ctx);
13379 bb_error_msg(_("while checking ext3 journal for %s"),
13381 bb_error_msg_and_die(0);
13385 * Check to see if we need to do ext3-style recovery. If so,
13386 * do it, and then restart the fsck.
13388 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
13389 if (ctx->options & E2F_OPT_READONLY) {
13390 printf(_("Warning: skipping journal recovery "
13391 "because doing a read-only filesystem "
13393 io_channel_flush(ctx->fs->io);
13395 if (ctx->flags & E2F_FLAG_RESTARTED) {
13397 * Whoops, we attempted to run the
13398 * journal twice. This should never
13399 * happen, unless the hardware or
13400 * device driver is being bogus.
13402 bb_error_msg(_("unable to set superblock flags on %s\n"), ctx->device_name);
13403 bb_error_msg_and_die(0);
13405 retval = e2fsck_run_ext3_journal(ctx);
13407 bb_error_msg(_("while recovering ext3 journal of %s"),
13409 bb_error_msg_and_die(0);
13411 ext2fs_close(ctx->fs);
13413 ctx->flags |= E2F_FLAG_RESTARTED;
13419 * Check for compatibility with the feature sets. We need to
13420 * be more stringent than ext2fs_open().
13422 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
13423 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
13424 bb_error_msg("(%s)", ctx->device_name);
13427 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
13428 bb_error_msg("(%s)", ctx->device_name);
13431 #ifdef ENABLE_COMPRESSION
13432 /* FIXME - do we support this at all? */
13433 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
13434 bb_error_msg(_("Warning: compression support is experimental.\n"));
13436 #ifndef ENABLE_HTREE
13437 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
13438 bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t"
13439 "but filesystem %s has HTREE directories.\n"),
13446 * If the user specified a specific superblock, presumably the
13447 * master superblock has been trashed. So we mark the
13448 * superblock as dirty, so it can be written out.
13450 if (ctx->superblock &&
13451 !(ctx->options & E2F_OPT_READONLY))
13452 ext2fs_mark_super_dirty(fs);
13455 * We only update the master superblock because (a) paranoia;
13456 * we don't want to corrupt the backup superblocks, and (b) we
13457 * don't need to update the mount count and last checked
13458 * fields in the backup superblock (the kernel doesn't
13459 * update the backup superblocks anyway).
13461 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
13463 ehandler_init(fs->io);
13465 if (ctx->superblock)
13466 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
13467 ext2fs_mark_valid(fs);
13468 check_super_block(ctx);
13469 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13470 bb_error_msg_and_die(0);
13471 check_if_skip(ctx);
13472 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13473 bb_error_msg_and_die(0);
13474 #ifdef ENABLE_SWAPFS
13476 #ifdef WORDS_BIGENDIAN
13477 #define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES
13479 #define NATIVE_FLAG 0
13483 if (normalize_swapfs) {
13484 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) {
13485 fprintf(stderr, _("%s: Filesystem byte order "
13486 "already normalized.\n"), ctx->device_name);
13487 bb_error_msg_and_die(0);
13492 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
13493 bb_error_msg_and_die(0);
13498 * Mark the system as valid, 'til proven otherwise
13500 ext2fs_mark_valid(fs);
13502 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
13504 bb_error_msg(_("while reading bad blocks inode"));
13506 printf(_("This doesn't bode well,"
13507 " but we'll try to go on...\n"));
13510 run_result = e2fsck_run(ctx);
13511 e2fsck_clear_progbar(ctx);
13512 if (run_result == E2F_FLAG_RESTART) {
13513 printf(_("Restarting e2fsck from the beginning...\n"));
13514 retval = e2fsck_reset_context(ctx);
13516 bb_error_msg(_("while resetting context"));
13517 bb_error_msg_and_die(0);
13522 if (run_result & E2F_FLAG_CANCEL) {
13523 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
13524 ctx->device_name : ctx->filesystem_name);
13525 exit_value |= FSCK_CANCELED;
13527 if (run_result & E2F_FLAG_ABORT)
13528 bb_error_msg_and_die(_("aborted"));
13531 if (ext2fs_test_changed(fs)) {
13532 exit_value |= EXIT_NONDESTRUCT;
13533 if (!(ctx->options & E2F_OPT_PREEN))
13534 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
13536 if (ctx->mount_flags & EXT2_MF_ISROOT) {
13537 printf(_("%s: ***** REBOOT LINUX *****\n"),
13539 exit_value |= EXIT_DESTRUCT;
13542 if (!ext2fs_test_valid(fs)) {
13543 printf(_("\n%s: ********** WARNING: Filesystem still has "
13544 "errors **********\n\n"), ctx->device_name);
13545 exit_value |= EXIT_UNCORRECTED;
13546 exit_value &= ~EXIT_NONDESTRUCT;
13548 if (exit_value & FSCK_CANCELED)
13549 exit_value &= ~EXIT_NONDESTRUCT;
13552 if (!(ctx->options & E2F_OPT_READONLY)) {
13553 if (ext2fs_test_valid(fs)) {
13554 if (!(sb->s_state & EXT2_VALID_FS))
13555 exit_value |= EXIT_NONDESTRUCT;
13556 sb->s_state = EXT2_VALID_FS;
13558 sb->s_state &= ~EXT2_VALID_FS;
13559 sb->s_mnt_count = 0;
13560 sb->s_lastcheck = time(NULL);
13561 ext2fs_mark_super_dirty(fs);
13565 e2fsck_write_bitmaps(ctx);
13569 free(ctx->filesystem_name);
13570 free(ctx->journal_name);
13571 e2fsck_free_context(ctx);