4 * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
6 * redistributed under the terms of the GNU Public License.
9 * Dictionary Abstract Data Type
10 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
11 * Free Software License:
12 * All rights are reserved by the author, with the following exceptions:
13 * Permission is granted to freely reproduce and distribute this software,
14 * possibly in exchange for a fee, provided that this copyright notice appears
15 * intact. Permission is also granted to adapt this software to produce
16 * derivative works, as long as the modified versions carry this copyright
17 * notice and additional notices stating that the work has been modified.
18 * This source code may be translated into executable form and incorporated
19 * into proprietary software; there is no requirement for such software to
20 * contain a copyright notice related to this source.
22 * linux/fs/recovery and linux/fs/revoke
23 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
25 * Copyright 1999-2000 Red Hat Software --- All Rights Reserved
27 * This file is part of the Linux kernel and is made available under
28 * the terms of the GNU General Public License, version 2, or at your
29 * option, any later version, incorporated herein by reference.
31 * Journal recovery routines for the generic filesystem journaling code;
32 * part of the ext2fs journaling system.
36 #define _GNU_SOURCE 1 /* get strnlen() */
38 #include <sys/types.h>
56 #include <sys/resource.h>
57 #include <sys/param.h>
58 #include <sys/mount.h>
59 #include <sys/ioctl.h>
67 #include "ext2fs/ext2_fs.h"
68 #include "ext2fs/ext2fs.h"
69 #include "blkid/blkid.h"
70 #include "ext2fs/ext2_ext_attr.h"
71 #include "uuid/uuid.h"
74 #define _INLINE_ __inline__
75 #define EXT2FS_ATTR(x) __attribute__(x)
78 #define EXT2FS_ATTR(x)
82 * The last ext2fs revision level that this version of e2fsck is able to
85 #define E2FSCK_CURRENT_REV 1
88 * The directory information structure; stores directory information
89 * collected in earlier passes, to avoid disk i/o in fetching the
90 * directory information.
93 ext2_ino_t ino; /* Inode number */
94 ext2_ino_t dotdot; /* Parent according to '..' */
95 ext2_ino_t parent; /* Parent according to treewalk */
100 * The indexed directory information structure; stores information for
101 * directories which contain a hash tree index.
104 ext2_ino_t ino; /* Inode number */
105 int numblocks; /* number of blocks */
107 short depth; /* depth of tree */
108 struct dx_dirblock_info *dx_block; /* Array of size numblocks */
111 #define DX_DIRBLOCK_ROOT 1
112 #define DX_DIRBLOCK_LEAF 2
113 #define DX_DIRBLOCK_NODE 3
114 #define DX_DIRBLOCK_CORRUPT 4
115 #define DX_DIRBLOCK_CLEARED 8
117 struct dx_dirblock_info {
122 ext2_dirhash_t min_hash;
123 ext2_dirhash_t max_hash;
124 ext2_dirhash_t node_min_hash;
125 ext2_dirhash_t node_max_hash;
128 #define DX_FLAG_REFERENCED 1
129 #define DX_FLAG_DUP_REF 2
130 #define DX_FLAG_FIRST 4
131 #define DX_FLAG_LAST 8
133 #ifdef RESOURCE_TRACK
135 * This structure is used for keeping track of how much resources have
136 * been used for a particular pass of e2fsck.
138 struct resource_track {
139 struct timeval time_start;
140 struct timeval user_start;
141 struct timeval system_start;
149 #define E2F_OPT_READONLY 0x0001
150 #define E2F_OPT_PREEN 0x0002
151 #define E2F_OPT_YES 0x0004
152 #define E2F_OPT_NO 0x0008
153 #define E2F_OPT_TIME 0x0010
154 #define E2F_OPT_TIME2 0x0020
155 #define E2F_OPT_CHECKBLOCKS 0x0040
156 #define E2F_OPT_DEBUG 0x0080
157 #define E2F_OPT_FORCE 0x0100
158 #define E2F_OPT_WRITECHECK 0x0200
159 #define E2F_OPT_COMPRESS_DIRS 0x0400
164 #define E2F_FLAG_ABORT 0x0001 /* Abort signaled */
165 #define E2F_FLAG_CANCEL 0x0002 /* Cancel signaled */
166 #define E2F_FLAG_SIGNAL_MASK 0x0003
167 #define E2F_FLAG_RESTART 0x0004 /* Restart signaled */
169 #define E2F_FLAG_SETJMP_OK 0x0010 /* Setjmp valid for abort */
171 #define E2F_FLAG_PROG_BAR 0x0020 /* Progress bar on screen */
172 #define E2F_FLAG_PROG_SUPPRESS 0x0040 /* Progress suspended */
173 #define E2F_FLAG_JOURNAL_INODE 0x0080 /* Create a new ext3 journal inode */
174 #define E2F_FLAG_SB_SPECIFIED 0x0100 /* The superblock was explicitly
175 * specified by the user */
176 #define E2F_FLAG_RESTARTED 0x0200 /* E2fsck has been restarted */
177 #define E2F_FLAG_RESIZE_INODE 0x0400 /* Request to recreate resize inode */
180 * Defines for indicating the e2fsck pass number
187 #define E2F_PASS_1B 6
191 * This is the global e2fsck structure.
193 typedef struct e2fsck_struct *e2fsck_t;
196 * Define the extended attribute refcount structure
198 typedef struct ea_refcount *ext2_refcount_t;
200 struct e2fsck_struct {
202 const char *program_name;
203 char *filesystem_name;
206 int flags; /* E2fsck internal flags */
208 blk_t use_superblock; /* sb requested by user */
209 blk_t superblock; /* sb used to open fs */
210 int blocksize; /* blocksize */
211 blk_t num_blocks; /* Total number of blocks */
213 blkid_cache blkid; /* blkid cache */
217 unsigned long abort_code;
219 int (*progress)(e2fsck_t ctx, int pass, unsigned long cur,
222 ext2fs_inode_bitmap inode_used_map; /* Inodes which are in use */
223 ext2fs_inode_bitmap inode_bad_map; /* Inodes which are bad somehow */
224 ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */
225 ext2fs_inode_bitmap inode_bb_map; /* Inodes which are in bad blocks */
226 ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */
227 ext2fs_inode_bitmap inode_reg_map; /* Inodes which are regular files*/
229 ext2fs_block_bitmap block_found_map; /* Blocks which are in use */
230 ext2fs_block_bitmap block_dup_map; /* Blks referenced more than once */
231 ext2fs_block_bitmap block_ea_map; /* Blocks which are used by EA's */
236 ext2_icount_t inode_count;
237 ext2_icount_t inode_link_info;
239 ext2_refcount_t refcount;
240 ext2_refcount_t refcount_extra;
243 * Array of flags indicating whether an inode bitmap, block
244 * bitmap, or inode table is invalid
246 int *invalid_inode_bitmap_flag;
247 int *invalid_block_bitmap_flag;
248 int *invalid_inode_table_flag;
249 int invalid_bitmaps; /* There are invalid bitmaps/itable */
257 * For pass1_check_directory and pass1_get_blocks
259 ext2_ino_t stashed_ino;
260 struct ext2_inode *stashed_inode;
263 * Location of the lost and found directory
265 ext2_ino_t lost_and_found;
266 int bad_lost_and_found;
269 * Directory information
273 struct dir_info *dir_info;
276 * Indexed directory information
278 int dx_dir_info_count;
279 int dx_dir_info_size;
280 struct dx_dir_info *dx_dir_info;
283 * Directories to hash
285 ext2_u32_list dirs_to_hash;
290 int process_inode_size;
291 int inode_buffer_blocks;
294 * ext3 journal support
296 io_channel journal_io;
299 #ifdef RESOURCE_TRACK
301 * For timing purposes
303 struct resource_track global_rtrack;
307 * How we display the progress update (for unix)
311 int progress_last_percent;
312 unsigned int progress_last_time;
313 int interactive; /* Are we connected directly to a tty? */
314 char start_meta[2], stop_meta[2];
317 int fs_directory_count;
318 int fs_regular_count;
319 int fs_blockdev_count;
320 int fs_chardev_count;
322 int fs_symlinks_count;
323 int fs_fast_symlinks_count;
326 int fs_badblocks_count;
327 int fs_sockets_count;
333 int fs_ext_attr_inodes;
334 int fs_ext_attr_blocks;
339 * For the use of callers of the e2fsck functions; not used by
340 * e2fsck functions themselves.
345 /* Used by the region allocation code */
346 typedef __u32 region_addr_t;
347 typedef struct region_struct *region_t;
350 * Procedure declarations
353 static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf);
356 static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool);
359 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
360 ext2_ino_t ino, char *buf);
363 static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode);
364 static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
365 int num, int gauranteed_size);
366 static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix);
367 static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino,
371 static void e2fsck_rehash_directories(e2fsck_t ctx);
374 static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
375 const char *description);
376 static int ask(e2fsck_t ctx, const char * string, int def);
377 static void e2fsck_read_bitmaps(e2fsck_t ctx);
378 static void preenhalt(e2fsck_t ctx);
379 #ifdef RESOURCE_TRACK
380 static void print_resource_track(const char *desc,
381 struct resource_track *track);
382 static void init_resource_track(struct resource_track *track);
384 static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
385 struct ext2_inode * inode, const char * proc);
386 static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
387 struct ext2_inode * inode, const char * proc);
389 static void mtrace_print(char *mesg);
391 static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs,
392 const char *name, io_manager manager);
395 static void e2fsck_clear_progbar(e2fsck_t ctx);
396 static int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
397 float percent, unsigned int dpynum);
399 * problem.h --- e2fsck problem error codes
402 typedef __u32 problem_t;
404 struct problem_context {
406 ext2_ino_t ino, ino2, dir;
407 struct ext2_inode *inode;
408 struct ext2_dir_entry *dirent;
410 e2_blkcnt_t blkcount;
417 * We define a set of "latch groups"; these are problems which are
418 * handled as a set. The user answers once for a particular latch
421 #define PR_LATCH_MASK 0x0ff0 /* Latch mask */
422 #define PR_LATCH_BLOCK 0x0010 /* Latch for illegal blocks (pass 1) */
423 #define PR_LATCH_BBLOCK 0x0020 /* Latch for bad block inode blocks (pass 1) */
424 #define PR_LATCH_IBITMAP 0x0030 /* Latch for pass 5 inode bitmap proc. */
425 #define PR_LATCH_BBITMAP 0x0040 /* Latch for pass 5 inode bitmap proc. */
426 #define PR_LATCH_RELOC 0x0050 /* Latch for superblock relocate hint */
427 #define PR_LATCH_DBLOCK 0x0060 /* Latch for pass 1b dup block headers */
428 #define PR_LATCH_LOW_DTIME 0x0070 /* Latch for pass1 orphaned list refugees */
429 #define PR_LATCH_TOOBIG 0x0080 /* Latch for file to big errors */
430 #define PR_LATCH_OPTIMIZE_DIR 0x0090 /* Latch for optimize directories */
432 #define PR_LATCH(x) ((((x) & PR_LATCH_MASK) >> 4) - 1)
435 * Latch group descriptor flags
437 #define PRL_YES 0x0001 /* Answer yes */
438 #define PRL_NO 0x0002 /* Answer no */
439 #define PRL_LATCHED 0x0004 /* The latch group is latched */
440 #define PRL_SUPPRESS 0x0008 /* Suppress all latch group questions */
442 #define PRL_VARIABLE 0x000f /* All the flags that need to be reset */
448 /* Block bitmap not in group */
449 #define PR_0_BB_NOT_GROUP 0x000001
451 /* Inode bitmap not in group */
452 #define PR_0_IB_NOT_GROUP 0x000002
454 /* Inode table not in group */
455 #define PR_0_ITABLE_NOT_GROUP 0x000003
457 /* Superblock corrupt */
458 #define PR_0_SB_CORRUPT 0x000004
460 /* Filesystem size is wrong */
461 #define PR_0_FS_SIZE_WRONG 0x000005
463 /* Fragments not supported */
464 #define PR_0_NO_FRAGMENTS 0x000006
466 /* Bad blocks_per_group */
467 #define PR_0_BLOCKS_PER_GROUP 0x000007
469 /* Bad first_data_block */
470 #define PR_0_FIRST_DATA_BLOCK 0x000008
472 /* Adding UUID to filesystem */
473 #define PR_0_ADD_UUID 0x000009
476 #define PR_0_RELOCATE_HINT 0x00000A
478 /* Miscellaneous superblock corruption */
479 #define PR_0_MISC_CORRUPT_SUPER 0x00000B
481 /* Error determing physical device size of filesystem */
482 #define PR_0_GETSIZE_ERROR 0x00000C
484 /* Inode count in the superblock incorrect */
485 #define PR_0_INODE_COUNT_WRONG 0x00000D
487 /* The Hurd does not support the filetype feature */
488 #define PR_0_HURD_CLEAR_FILETYPE 0x00000E
490 /* Journal inode is invalid */
491 #define PR_0_JOURNAL_BAD_INODE 0x00000F
493 /* The external journal has multiple filesystems (which we can't handle yet) */
494 #define PR_0_JOURNAL_UNSUPP_MULTIFS 0x000010
496 /* Can't find external journal */
497 #define PR_0_CANT_FIND_JOURNAL 0x000011
499 /* External journal has bad superblock */
500 #define PR_0_EXT_JOURNAL_BAD_SUPER 0x000012
502 /* Superblock has a bad journal UUID */
503 #define PR_0_JOURNAL_BAD_UUID 0x000013
505 /* Journal has an unknown superblock type */
506 #define PR_0_JOURNAL_UNSUPP_SUPER 0x000014
508 /* Journal superblock is corrupt */
509 #define PR_0_JOURNAL_BAD_SUPER 0x000015
511 /* Journal superblock is corrupt */
512 #define PR_0_JOURNAL_HAS_JOURNAL 0x000016
514 /* Superblock has recovery flag set but no journal */
515 #define PR_0_JOURNAL_RECOVER_SET 0x000017
517 /* Journal has data, but recovery flag is clear */
518 #define PR_0_JOURNAL_RECOVERY_CLEAR 0x000018
520 /* Ask if we should clear the journal */
521 #define PR_0_JOURNAL_RESET_JOURNAL 0x000019
523 /* Filesystem revision is 0, but feature flags are set */
524 #define PR_0_FS_REV_LEVEL 0x00001A
526 /* Clearing orphan inode */
527 #define PR_0_ORPHAN_CLEAR_INODE 0x000020
529 /* Illegal block found in orphaned inode */
530 #define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000021
532 /* Already cleared block found in orphaned inode */
533 #define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000022
535 /* Illegal orphan inode in superblock */
536 #define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000023
538 /* Illegal inode in orphaned inode list */
539 #define PR_0_ORPHAN_ILLEGAL_INODE 0x000024
541 /* Journal has unsupported read-only feature - abort */
542 #define PR_0_JOURNAL_UNSUPP_ROCOMPAT 0x000025
544 /* Journal has unsupported incompatible feature - abort */
545 #define PR_0_JOURNAL_UNSUPP_INCOMPAT 0x000026
547 /* Journal has unsupported version number */
548 #define PR_0_JOURNAL_UNSUPP_VERSION 0x000027
550 /* Moving journal to hidden file */
551 #define PR_0_MOVE_JOURNAL 0x000028
553 /* Error moving journal */
554 #define PR_0_ERR_MOVE_JOURNAL 0x000029
556 /* Clearing V2 journal superblock */
557 #define PR_0_CLEAR_V2_JOURNAL 0x00002A
559 /* Run journal anyway */
560 #define PR_0_JOURNAL_RUN 0x00002B
562 /* Run journal anyway by default */
563 #define PR_0_JOURNAL_RUN_DEFAULT 0x00002C
565 /* Backup journal inode blocks */
566 #define PR_0_BACKUP_JNL 0x00002D
568 /* Reserved blocks w/o resize_inode */
569 #define PR_0_NONZERO_RESERVED_GDT_BLOCKS 0x00002E
571 /* Resize_inode not enabled, but resize inode is non-zero */
572 #define PR_0_CLEAR_RESIZE_INODE 0x00002F
574 /* Resize inode invalid */
575 #define PR_0_RESIZE_INODE_INVALID 0x000030
581 /* Pass 1: Checking inodes, blocks, and sizes */
582 #define PR_1_PASS_HEADER 0x010000
584 /* Root directory is not an inode */
585 #define PR_1_ROOT_NO_DIR 0x010001
587 /* Root directory has dtime set */
588 #define PR_1_ROOT_DTIME 0x010002
590 /* Reserved inode has bad mode */
591 #define PR_1_RESERVED_BAD_MODE 0x010003
593 /* Deleted inode has zero dtime */
594 #define PR_1_ZERO_DTIME 0x010004
596 /* Inode in use, but dtime set */
597 #define PR_1_SET_DTIME 0x010005
599 /* Zero-length directory */
600 #define PR_1_ZERO_LENGTH_DIR 0x010006
602 /* Block bitmap conflicts with some other fs block */
603 #define PR_1_BB_CONFLICT 0x010007
605 /* Inode bitmap conflicts with some other fs block */
606 #define PR_1_IB_CONFLICT 0x010008
608 /* Inode table conflicts with some other fs block */
609 #define PR_1_ITABLE_CONFLICT 0x010009
611 /* Block bitmap is on a bad block */
612 #define PR_1_BB_BAD_BLOCK 0x01000A
614 /* Inode bitmap is on a bad block */
615 #define PR_1_IB_BAD_BLOCK 0x01000B
617 /* Inode has incorrect i_size */
618 #define PR_1_BAD_I_SIZE 0x01000C
620 /* Inode has incorrect i_blocks */
621 #define PR_1_BAD_I_BLOCKS 0x01000D
623 /* Illegal block number in inode */
624 #define PR_1_ILLEGAL_BLOCK_NUM 0x01000E
626 /* Block number overlaps fs metadata */
627 #define PR_1_BLOCK_OVERLAPS_METADATA 0x01000F
629 /* Inode has illegal blocks (latch question) */
630 #define PR_1_INODE_BLOCK_LATCH 0x010010
632 /* Too many bad blocks in inode */
633 #define PR_1_TOO_MANY_BAD_BLOCKS 0x010011
635 /* Illegal block number in bad block inode */
636 #define PR_1_BB_ILLEGAL_BLOCK_NUM 0x010012
638 /* Bad block inode has illegal blocks (latch question) */
639 #define PR_1_INODE_BBLOCK_LATCH 0x010013
641 /* Duplicate or bad blocks in use! */
642 #define PR_1_DUP_BLOCKS_PREENSTOP 0x010014
644 /* Bad block used as bad block indirect block */
645 #define PR_1_BBINODE_BAD_METABLOCK 0x010015
647 /* Inconsistency can't be fixed prompt */
648 #define PR_1_BBINODE_BAD_METABLOCK_PROMPT 0x010016
650 /* Bad primary block */
651 #define PR_1_BAD_PRIMARY_BLOCK 0x010017
653 /* Bad primary block prompt */
654 #define PR_1_BAD_PRIMARY_BLOCK_PROMPT 0x010018
656 /* Bad primary superblock */
657 #define PR_1_BAD_PRIMARY_SUPERBLOCK 0x010019
659 /* Bad primary block group descriptors */
660 #define PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR 0x01001A
662 /* Bad superblock in group */
663 #define PR_1_BAD_SUPERBLOCK 0x01001B
665 /* Bad block group descriptors in group */
666 #define PR_1_BAD_GROUP_DESCRIPTORS 0x01001C
668 /* Block claimed for no reason */
669 #define PR_1_PROGERR_CLAIMED_BLOCK 0x01001D
671 /* Error allocating blocks for relocating metadata */
672 #define PR_1_RELOC_BLOCK_ALLOCATE 0x01001E
674 /* Error allocating block buffer during relocation process */
675 #define PR_1_RELOC_MEMORY_ALLOCATE 0x01001F
677 /* Relocating metadata group information from X to Y */
678 #define PR_1_RELOC_FROM_TO 0x010020
680 /* Relocating metatdata group information to X */
681 #define PR_1_RELOC_TO 0x010021
683 /* Block read error during relocation process */
684 #define PR_1_RELOC_READ_ERR 0x010022
686 /* Block write error during relocation process */
687 #define PR_1_RELOC_WRITE_ERR 0x010023
689 /* Error allocating inode bitmap */
690 #define PR_1_ALLOCATE_IBITMAP_ERROR 0x010024
692 /* Error allocating block bitmap */
693 #define PR_1_ALLOCATE_BBITMAP_ERROR 0x010025
695 /* Error allocating icount structure */
696 #define PR_1_ALLOCATE_ICOUNT 0x010026
698 /* Error allocating dbcount */
699 #define PR_1_ALLOCATE_DBCOUNT 0x010027
701 /* Error while scanning inodes */
702 #define PR_1_ISCAN_ERROR 0x010028
704 /* Error while iterating over blocks */
705 #define PR_1_BLOCK_ITERATE 0x010029
707 /* Error while storing inode count information */
708 #define PR_1_ICOUNT_STORE 0x01002A
710 /* Error while storing directory block information */
711 #define PR_1_ADD_DBLOCK 0x01002B
713 /* Error while reading inode (for clearing) */
714 #define PR_1_READ_INODE 0x01002C
716 /* Suppress messages prompt */
717 #define PR_1_SUPPRESS_MESSAGES 0x01002D
719 /* Imagic flag set on an inode when filesystem doesn't support it */
720 #define PR_1_SET_IMAGIC 0x01002F
722 /* Immutable flag set on a device or socket inode */
723 #define PR_1_SET_IMMUTABLE 0x010030
725 /* Compression flag set on a non-compressed filesystem */
726 #define PR_1_COMPR_SET 0x010031
728 /* Non-zero size on on device, fifo or socket inode */
729 #define PR_1_SET_NONZSIZE 0x010032
731 /* Filesystem revision is 0, but feature flags are set */
732 #define PR_1_FS_REV_LEVEL 0x010033
734 /* Journal inode not in use, needs clearing */
735 #define PR_1_JOURNAL_INODE_NOT_CLEAR 0x010034
737 /* Journal inode has wrong mode */
738 #define PR_1_JOURNAL_BAD_MODE 0x010035
740 /* Inode that was part of orphan linked list */
741 #define PR_1_LOW_DTIME 0x010036
743 /* Latch question which asks how to deal with low dtime inodes */
744 #define PR_1_ORPHAN_LIST_REFUGEES 0x010037
746 /* Error allocating refcount structure */
747 #define PR_1_ALLOCATE_REFCOUNT 0x010038
749 /* Error reading Extended Attribute block */
750 #define PR_1_READ_EA_BLOCK 0x010039
752 /* Invalid Extended Attribute block */
753 #define PR_1_BAD_EA_BLOCK 0x01003A
755 /* Error reading Extended Attribute block while fixing refcount -- abort */
756 #define PR_1_EXTATTR_READ_ABORT 0x01003B
758 /* Extended attribute reference count incorrect */
759 #define PR_1_EXTATTR_REFCOUNT 0x01003C
761 /* Error writing Extended Attribute block while fixing refcount */
762 #define PR_1_EXTATTR_WRITE 0x01003D
764 /* Multiple EA blocks not supported */
765 #define PR_1_EA_MULTI_BLOCK 0x01003E
767 /* Error allocating EA region allocation structure */
768 #define PR_1_EA_ALLOC_REGION 0x01003F
770 /* Error EA allocation collision */
771 #define PR_1_EA_ALLOC_COLLISION 0x010040
773 /* Bad extended attribute name */
774 #define PR_1_EA_BAD_NAME 0x010041
776 /* Bad extended attribute value */
777 #define PR_1_EA_BAD_VALUE 0x010042
779 /* Inode too big (latch question) */
780 #define PR_1_INODE_TOOBIG 0x010043
782 /* Directory too big */
783 #define PR_1_TOOBIG_DIR 0x010044
785 /* Regular file too big */
786 #define PR_1_TOOBIG_REG 0x010045
788 /* Symlink too big */
789 #define PR_1_TOOBIG_SYMLINK 0x010046
791 /* INDEX_FL flag set on a non-HTREE filesystem */
792 #define PR_1_HTREE_SET 0x010047
794 /* INDEX_FL flag set on a non-directory */
795 #define PR_1_HTREE_NODIR 0x010048
797 /* Invalid root node in HTREE directory */
798 #define PR_1_HTREE_BADROOT 0x010049
800 /* Unsupported hash version in HTREE directory */
801 #define PR_1_HTREE_HASHV 0x01004A
803 /* Incompatible flag in HTREE root node */
804 #define PR_1_HTREE_INCOMPAT 0x01004B
807 #define PR_1_HTREE_DEPTH 0x01004C
809 /* Bad block has indirect block that conflicts with filesystem block */
810 #define PR_1_BB_FS_BLOCK 0x01004D
812 /* Resize inode failed */
813 #define PR_1_RESIZE_INODE_CREATE 0x01004E
815 /* inode->i_size is too long */
816 #define PR_1_EXTRA_ISIZE 0x01004F
818 /* attribute name is too long */
819 #define PR_1_ATTR_NAME_LEN 0x010050
821 /* wrong EA value offset */
822 #define PR_1_ATTR_VALUE_OFFSET 0x010051
824 /* wrong EA blocknumber */
825 #define PR_1_ATTR_VALUE_BLOCK 0x010052
827 /* wrong EA value size */
828 #define PR_1_ATTR_VALUE_SIZE 0x010053
830 /* wrong EA hash value */
831 #define PR_1_ATTR_HASH 0x010054
837 /* Pass 1B: Rescan for duplicate/bad blocks */
838 #define PR_1B_PASS_HEADER 0x011000
840 /* Duplicate/bad block(s) header */
841 #define PR_1B_DUP_BLOCK_HEADER 0x011001
843 /* Duplicate/bad block(s) in inode */
844 #define PR_1B_DUP_BLOCK 0x011002
846 /* Duplicate/bad block(s) end */
847 #define PR_1B_DUP_BLOCK_END 0x011003
849 /* Error while scanning inodes */
850 #define PR_1B_ISCAN_ERROR 0x011004
852 /* Error allocating inode bitmap */
853 #define PR_1B_ALLOCATE_IBITMAP_ERROR 0x011005
855 /* Error while iterating over blocks */
856 #define PR_1B_BLOCK_ITERATE 0x0110006
858 /* Error adjusting EA refcount */
859 #define PR_1B_ADJ_EA_REFCOUNT 0x0110007
862 /* Pass 1C: Scan directories for inodes with dup blocks. */
863 #define PR_1C_PASS_HEADER 0x012000
866 /* Pass 1D: Reconciling duplicate blocks */
867 #define PR_1D_PASS_HEADER 0x013000
869 /* File has duplicate blocks */
870 #define PR_1D_DUP_FILE 0x013001
872 /* List of files sharing duplicate blocks */
873 #define PR_1D_DUP_FILE_LIST 0x013002
875 /* File sharing blocks with filesystem metadata */
876 #define PR_1D_SHARE_METADATA 0x013003
878 /* Report of how many duplicate/bad inodes */
879 #define PR_1D_NUM_DUP_INODES 0x013004
881 /* Duplicated blocks already reassigned or cloned. */
882 #define PR_1D_DUP_BLOCKS_DEALT 0x013005
884 /* Clone duplicate/bad blocks? */
885 #define PR_1D_CLONE_QUESTION 0x013006
888 #define PR_1D_DELETE_QUESTION 0x013007
890 /* Couldn't clone file (error) */
891 #define PR_1D_CLONE_ERROR 0x013008
897 /* Pass 2: Checking directory structure */
898 #define PR_2_PASS_HEADER 0x020000
900 /* Bad inode number for '.' */
901 #define PR_2_BAD_INODE_DOT 0x020001
903 /* Directory entry has bad inode number */
904 #define PR_2_BAD_INO 0x020002
906 /* Directory entry has deleted or unused inode */
907 #define PR_2_UNUSED_INODE 0x020003
909 /* Directry entry is link to '.' */
910 #define PR_2_LINK_DOT 0x020004
912 /* Directory entry points to inode now located in a bad block */
913 #define PR_2_BB_INODE 0x020005
915 /* Directory entry contains a link to a directory */
916 #define PR_2_LINK_DIR 0x020006
918 /* Directory entry contains a link to the root directry */
919 #define PR_2_LINK_ROOT 0x020007
921 /* Directory entry has illegal characters in its name */
922 #define PR_2_BAD_NAME 0x020008
924 /* Missing '.' in directory inode */
925 #define PR_2_MISSING_DOT 0x020009
927 /* Missing '..' in directory inode */
928 #define PR_2_MISSING_DOT_DOT 0x02000A
930 /* First entry in directory inode doesn't contain '.' */
931 #define PR_2_1ST_NOT_DOT 0x02000B
933 /* Second entry in directory inode doesn't contain '..' */
934 #define PR_2_2ND_NOT_DOT_DOT 0x02000C
936 /* i_faddr should be zero */
937 #define PR_2_FADDR_ZERO 0x02000D
939 /* i_file_acl should be zero */
940 #define PR_2_FILE_ACL_ZERO 0x02000E
942 /* i_dir_acl should be zero */
943 #define PR_2_DIR_ACL_ZERO 0x02000F
945 /* i_frag should be zero */
946 #define PR_2_FRAG_ZERO 0x020010
948 /* i_fsize should be zero */
949 #define PR_2_FSIZE_ZERO 0x020011
951 /* inode has bad mode */
952 #define PR_2_BAD_MODE 0x020012
954 /* directory corrupted */
955 #define PR_2_DIR_CORRUPTED 0x020013
957 /* filename too long */
958 #define PR_2_FILENAME_LONG 0x020014
960 /* Directory inode has a missing block (hole) */
961 #define PR_2_DIRECTORY_HOLE 0x020015
963 /* '.' is not NULL terminated */
964 #define PR_2_DOT_NULL_TERM 0x020016
966 /* '..' is not NULL terminated */
967 #define PR_2_DOT_DOT_NULL_TERM 0x020017
969 /* Illegal character device in inode */
970 #define PR_2_BAD_CHAR_DEV 0x020018
972 /* Illegal block device in inode */
973 #define PR_2_BAD_BLOCK_DEV 0x020019
975 /* Duplicate '.' entry */
976 #define PR_2_DUP_DOT 0x02001A
978 /* Duplicate '..' entry */
979 #define PR_2_DUP_DOT_DOT 0x02001B
981 /* Internal error: couldn't find dir_info */
982 #define PR_2_NO_DIRINFO 0x02001C
984 /* Final rec_len is wrong */
985 #define PR_2_FINAL_RECLEN 0x02001D
987 /* Error allocating icount structure */
988 #define PR_2_ALLOCATE_ICOUNT 0x02001E
990 /* Error iterating over directory blocks */
991 #define PR_2_DBLIST_ITERATE 0x02001F
993 /* Error reading directory block */
994 #define PR_2_READ_DIRBLOCK 0x020020
996 /* Error writing directory block */
997 #define PR_2_WRITE_DIRBLOCK 0x020021
999 /* Error allocating new directory block */
1000 #define PR_2_ALLOC_DIRBOCK 0x020022
1002 /* Error deallocating inode */
1003 #define PR_2_DEALLOC_INODE 0x020023
1005 /* Directory entry for '.' is big. Split? */
1006 #define PR_2_SPLIT_DOT 0x020024
1009 #define PR_2_BAD_FIFO 0x020025
1011 /* Illegal socket */
1012 #define PR_2_BAD_SOCKET 0x020026
1014 /* Directory filetype not set */
1015 #define PR_2_SET_FILETYPE 0x020027
1017 /* Directory filetype incorrect */
1018 #define PR_2_BAD_FILETYPE 0x020028
1020 /* Directory filetype set when it shouldn't be */
1021 #define PR_2_CLEAR_FILETYPE 0x020029
1023 /* Directory filename can't be zero-length */
1024 #define PR_2_NULL_NAME 0x020030
1026 /* Invalid symlink */
1027 #define PR_2_INVALID_SYMLINK 0x020031
1029 /* i_file_acl (extended attribute) is bad */
1030 #define PR_2_FILE_ACL_BAD 0x020032
1032 /* Filesystem contains large files, but has no such flag in sb */
1033 #define PR_2_FEATURE_LARGE_FILES 0x020033
1035 /* Node in HTREE directory not referenced */
1036 #define PR_2_HTREE_NOTREF 0x020034
1038 /* Node in HTREE directory referenced twice */
1039 #define PR_2_HTREE_DUPREF 0x020035
1041 /* Node in HTREE directory has bad min hash */
1042 #define PR_2_HTREE_MIN_HASH 0x020036
1044 /* Node in HTREE directory has bad max hash */
1045 #define PR_2_HTREE_MAX_HASH 0x020037
1047 /* Clear invalid HTREE directory */
1048 #define PR_2_HTREE_CLEAR 0x020038
1050 /* Clear the htree flag forcibly */
1051 /* #define PR_2_HTREE_FCLR 0x020039 */
1053 /* Bad block in htree interior node */
1054 #define PR_2_HTREE_BADBLK 0x02003A
1056 /* Error adjusting EA refcount */
1057 #define PR_2_ADJ_EA_REFCOUNT 0x02003B
1059 /* Invalid HTREE root node */
1060 #define PR_2_HTREE_BAD_ROOT 0x02003C
1062 /* Invalid HTREE limit */
1063 #define PR_2_HTREE_BAD_LIMIT 0x02003D
1065 /* Invalid HTREE count */
1066 #define PR_2_HTREE_BAD_COUNT 0x02003E
1068 /* HTREE interior node has out-of-order hashes in table */
1069 #define PR_2_HTREE_HASH_ORDER 0x02003F
1071 /* Node in HTREE directory has bad depth */
1072 #define PR_2_HTREE_BAD_DEPTH 0x020040
1074 /* Duplicate directory entry found */
1075 #define PR_2_DUPLICATE_DIRENT 0x020041
1077 /* Non-unique filename found */
1078 #define PR_2_NON_UNIQUE_FILE 0x020042
1080 /* Duplicate directory entry found */
1081 #define PR_2_REPORT_DUP_DIRENT 0x020043
1087 /* Pass 3: Checking directory connectivity */
1088 #define PR_3_PASS_HEADER 0x030000
1090 /* Root inode not allocated */
1091 #define PR_3_NO_ROOT_INODE 0x030001
1093 /* No room in lost+found */
1094 #define PR_3_EXPAND_LF_DIR 0x030002
1096 /* Unconnected directory inode */
1097 #define PR_3_UNCONNECTED_DIR 0x030003
1099 /* /lost+found not found */
1100 #define PR_3_NO_LF_DIR 0x030004
1102 /* .. entry is incorrect */
1103 #define PR_3_BAD_DOT_DOT 0x030005
1105 /* Bad or non-existent /lost+found. Cannot reconnect */
1106 #define PR_3_NO_LPF 0x030006
1108 /* Could not expand /lost+found */
1109 #define PR_3_CANT_EXPAND_LPF 0x030007
1111 /* Could not reconnect inode */
1112 #define PR_3_CANT_RECONNECT 0x030008
1114 /* Error while trying to find /lost+found */
1115 #define PR_3_ERR_FIND_LPF 0x030009
1117 /* Error in ext2fs_new_block while creating /lost+found */
1118 #define PR_3_ERR_LPF_NEW_BLOCK 0x03000A
1120 /* Error in ext2fs_new_inode while creating /lost+found */
1121 #define PR_3_ERR_LPF_NEW_INODE 0x03000B
1123 /* Error in ext2fs_new_dir_block while creating /lost+found */
1124 #define PR_3_ERR_LPF_NEW_DIR_BLOCK 0x03000C
1126 /* Error while writing directory block for /lost+found */
1127 #define PR_3_ERR_LPF_WRITE_BLOCK 0x03000D
1129 /* Error while adjusting inode count */
1130 #define PR_3_ADJUST_INODE 0x03000E
1132 /* Couldn't fix parent directory -- error */
1133 #define PR_3_FIX_PARENT_ERR 0x03000F
1135 /* Couldn't fix parent directory -- couldn't find it */
1136 #define PR_3_FIX_PARENT_NOFIND 0x030010
1138 /* Error allocating inode bitmap */
1139 #define PR_3_ALLOCATE_IBITMAP_ERROR 0x030011
1141 /* Error creating root directory */
1142 #define PR_3_CREATE_ROOT_ERROR 0x030012
1144 /* Error creating lost and found directory */
1145 #define PR_3_CREATE_LPF_ERROR 0x030013
1147 /* Root inode is not directory; aborting */
1148 #define PR_3_ROOT_NOT_DIR_ABORT 0x030014
1150 /* Cannot proceed without a root inode. */
1151 #define PR_3_NO_ROOT_INODE_ABORT 0x030015
1153 /* Internal error: couldn't find dir_info */
1154 #define PR_3_NO_DIRINFO 0x030016
1156 /* Lost+found is not a directory */
1157 #define PR_3_LPF_NOTDIR 0x030017
1160 * Pass 3a --- rehashing diretories
1162 /* Pass 3a: Reindexing directories */
1163 #define PR_3A_PASS_HEADER 0x031000
1165 /* Error iterating over directories */
1166 #define PR_3A_OPTIMIZE_ITER 0x031001
1168 /* Error rehash directory */
1169 #define PR_3A_OPTIMIZE_DIR_ERR 0x031002
1171 /* Rehashing dir header */
1172 #define PR_3A_OPTIMIZE_DIR_HEADER 0x031003
1174 /* Rehashing directory %d */
1175 #define PR_3A_OPTIMIZE_DIR 0x031004
1177 /* Rehashing dir end */
1178 #define PR_3A_OPTIMIZE_DIR_END 0x031005
1184 /* Pass 4: Checking reference counts */
1185 #define PR_4_PASS_HEADER 0x040000
1187 /* Unattached zero-length inode */
1188 #define PR_4_ZERO_LEN_INODE 0x040001
1190 /* Unattached inode */
1191 #define PR_4_UNATTACHED_INODE 0x040002
1193 /* Inode ref count wrong */
1194 #define PR_4_BAD_REF_COUNT 0x040003
1196 /* Inconsistent inode count information cached */
1197 #define PR_4_INCONSISTENT_COUNT 0x040004
1203 /* Pass 5: Checking group summary information */
1204 #define PR_5_PASS_HEADER 0x050000
1206 /* Padding at end of inode bitmap is not set. */
1207 #define PR_5_INODE_BMAP_PADDING 0x050001
1209 /* Padding at end of block bitmap is not set. */
1210 #define PR_5_BLOCK_BMAP_PADDING 0x050002
1212 /* Block bitmap differences header */
1213 #define PR_5_BLOCK_BITMAP_HEADER 0x050003
1215 /* Block not used, but marked in bitmap */
1216 #define PR_5_BLOCK_UNUSED 0x050004
1218 /* Block used, but not marked used in bitmap */
1219 #define PR_5_BLOCK_USED 0x050005
1221 /* Block bitmap differences end */
1222 #define PR_5_BLOCK_BITMAP_END 0x050006
1224 /* Inode bitmap differences header */
1225 #define PR_5_INODE_BITMAP_HEADER 0x050007
1227 /* Inode not used, but marked in bitmap */
1228 #define PR_5_INODE_UNUSED 0x050008
1230 /* Inode used, but not marked used in bitmap */
1231 #define PR_5_INODE_USED 0x050009
1233 /* Inode bitmap differences end */
1234 #define PR_5_INODE_BITMAP_END 0x05000A
1236 /* Free inodes count for group wrong */
1237 #define PR_5_FREE_INODE_COUNT_GROUP 0x05000B
1239 /* Directories count for group wrong */
1240 #define PR_5_FREE_DIR_COUNT_GROUP 0x05000C
1242 /* Free inodes count wrong */
1243 #define PR_5_FREE_INODE_COUNT 0x05000D
1245 /* Free blocks count for group wrong */
1246 #define PR_5_FREE_BLOCK_COUNT_GROUP 0x05000E
1248 /* Free blocks count wrong */
1249 #define PR_5_FREE_BLOCK_COUNT 0x05000F
1251 /* Programming error: bitmap endpoints don't match */
1252 #define PR_5_BMAP_ENDPOINTS 0x050010
1254 /* Internal error: fudging end of bitmap */
1255 #define PR_5_FUDGE_BITMAP_ERROR 0x050011
1257 /* Error copying in replacement inode bitmap */
1258 #define PR_5_COPY_IBITMAP_ERROR 0x050012
1260 /* Error copying in replacement block bitmap */
1261 #define PR_5_COPY_BBITMAP_ERROR 0x050013
1263 /* Block range not used, but marked in bitmap */
1264 #define PR_5_BLOCK_RANGE_UNUSED 0x050014
1266 /* Block range used, but not marked used in bitmap */
1267 #define PR_5_BLOCK_RANGE_USED 0x050015
1269 /* Inode range not used, but marked in bitmap */
1270 #define PR_5_INODE_RANGE_UNUSED 0x050016
1272 /* Inode rangeused, but not marked used in bitmap */
1273 #define PR_5_INODE_RANGE_USED 0x050017
1276 * Function declarations
1278 static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx);
1279 static int end_problem_latch(e2fsck_t ctx, int mask);
1280 static int set_latch_flags(int mask, int setflags, int clearflags);
1281 static void clear_problem_context(struct problem_context *ctx);
1284 * Dictionary Abstract Data Type
1285 * Copyright (C) 1997 Kaz Kylheku <kaz@ashi.footprints.net>
1287 * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz
1295 * Blurb for inclusion into C++ translation units
1298 typedef unsigned long dictcount_t;
1299 #define DICTCOUNT_T_MAX ULONG_MAX
1302 * The dictionary is implemented as a red-black tree
1305 typedef enum { dnode_red, dnode_black } dnode_color_t;
1307 typedef struct dnode_t {
1308 struct dnode_t *dict_left;
1309 struct dnode_t *dict_right;
1310 struct dnode_t *dict_parent;
1311 dnode_color_t dict_color;
1312 const void *dict_key;
1316 typedef int (*dict_comp_t)(const void *, const void *);
1317 typedef void (*dnode_free_t)(dnode_t *);
1319 typedef struct dict_t {
1320 dnode_t dict_nilnode;
1321 dictcount_t dict_nodecount;
1322 dictcount_t dict_maxcount;
1323 dict_comp_t dict_compare;
1324 dnode_free_t dict_freenode;
1328 typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *);
1330 typedef struct dict_load_t {
1331 dict_t *dict_dictptr;
1332 dnode_t dict_nilnode;
1335 #define dict_count(D) ((D)->dict_nodecount)
1336 #define dnode_get(N) ((N)->dict_data)
1337 #define dnode_getkey(N) ((N)->dict_key)
1342 * Compatibility header file for e2fsck which should be included
1343 * instead of linux/jfs.h
1345 * Copyright (C) 2000 Stephen C. Tweedie
1349 * Pull in the definition of the e2fsck context structure
1353 struct buffer_head {
1367 struct ext2_inode i_ext2;
1376 #define K_DEV_JOURNAL 2
1378 typedef struct kdev_s *kdev_t;
1380 #define lock_buffer(bh) do {} while(0)
1381 #define unlock_buffer(bh) do {} while(0)
1382 #define buffer_req(bh) 1
1383 #define do_readahead(journal, start) do {} while(0)
1385 static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */
1391 #define kmem_cache_alloc(cache,flags) malloc((cache)->object_length)
1394 * We use the standard libext2fs portability tricks for inline
1398 static _INLINE_ kmem_cache_t * do_cache_create(int len)
1400 kmem_cache_t *new_cache;
1402 new_cache = malloc(sizeof(*new_cache));
1404 new_cache->object_length = len;
1408 static _INLINE_ void do_cache_destroy(kmem_cache_t *cache)
1414 * Now pull in the real linux/jfs.h definitions.
1416 #include "ext2fs/kernel-jbd.h"
1419 * badblocks.c --- replace/append bad blocks to the bad block inode
1422 static int check_bb_inode_blocks(ext2_filsys fs, blk_t *block_nr, int blockcnt,
1426 static void invalid_block(ext2_filsys fs FSCK_ATTR((unused)), blk_t blk)
1428 printf(_("Bad block %u out of range; ignored.\n"), blk);
1432 static void read_bad_blocks_file(e2fsck_t ctx, const char *bad_blocks_file,
1433 int replace_bad_blocks)
1435 ext2_filsys fs = ctx->fs;
1437 badblocks_list bb_list = 0;
1441 e2fsck_read_bitmaps(ctx);
1444 * Make sure the bad block inode is sane. If there are any
1445 * illegal blocks, clear them.
1447 retval = ext2fs_block_iterate(fs, EXT2_BAD_INO, 0, 0,
1448 check_bb_inode_blocks, 0);
1450 com_err("ext2fs_block_iterate", retval,
1451 _("while sanity checking the bad blocks inode"));
1456 * If we're appending to the bad blocks inode, read in the
1457 * current bad blocks.
1459 if (!replace_bad_blocks) {
1460 retval = ext2fs_read_bb_inode(fs, &bb_list);
1462 com_err("ext2fs_read_bb_inode", retval,
1463 _("while reading the bad blocks inode"));
1469 * Now read in the bad blocks from the file; if
1470 * bad_blocks_file is null, then try to run the badblocks
1473 if (bad_blocks_file) {
1474 f = fopen(bad_blocks_file, "r");
1476 com_err("read_bad_blocks_file", errno,
1477 _("while trying to open %s"), bad_blocks_file);
1481 sprintf(buf, "badblocks -b %d %s%s%s %d", fs->blocksize,
1482 (ctx->options & E2F_OPT_PREEN) ? "" : "-s ",
1483 (ctx->options & E2F_OPT_WRITECHECK) ? "-n " : "",
1484 fs->device_name, fs->super->s_blocks_count);
1485 f = popen(buf, "r");
1487 com_err("read_bad_blocks_file", errno,
1488 _("while trying popen '%s'"), buf);
1492 retval = ext2fs_read_bb_FILE(fs, f, &bb_list, invalid_block);
1493 if (bad_blocks_file)
1498 com_err("ext2fs_read_bb_FILE", retval,
1499 _("while reading in list of bad blocks from file"));
1504 * Finally, update the bad blocks from the bad_block_map
1506 retval = ext2fs_update_bb_inode(fs, bb_list);
1508 com_err("ext2fs_update_bb_inode", retval,
1509 _("while updating bad block inode"));
1513 ext2fs_badblocks_list_free(bb_list);
1517 ctx->flags |= E2F_FLAG_ABORT;
1522 static int check_bb_inode_blocks(ext2_filsys fs,
1524 int blockcnt FSCK_ATTR((unused)),
1525 void *priv_data FSCK_ATTR((unused)))
1531 * If the block number is outrageous, clear it and ignore it.
1533 if (*block_nr >= fs->super->s_blocks_count ||
1534 *block_nr < fs->super->s_first_data_block) {
1535 printf(_("Warning illegal block %u found in bad block inode. Cleared.\n"), *block_nr);
1537 return BLOCK_CHANGED;
1544 * Dictionary Abstract Data Type
1549 * These macros provide short convenient names for structure members,
1550 * which are embellished with dict_ prefixes so that they are
1551 * properly confined to the documented namespace. It's legal for a
1552 * program which uses dict to define, for instance, a macro called ``parent''.
1553 * Such a macro would interfere with the dnode_t struct definition.
1554 * In general, highly portable and reusable C modules which expose their
1555 * structures need to confine structure member names to well-defined spaces.
1556 * The resulting identifiers aren't necessarily convenient to use, nor
1557 * readable, in the implementation, however!
1560 #define left dict_left
1561 #define right dict_right
1562 #define parent dict_parent
1563 #define color dict_color
1564 #define key dict_key
1565 #define data dict_data
1567 #define nilnode dict_nilnode
1568 #define maxcount dict_maxcount
1569 #define compare dict_compare
1570 #define dupes dict_dupes
1572 #define dict_root(D) ((D)->nilnode.left)
1573 #define dict_nil(D) (&(D)->nilnode)
1574 #define DICT_DEPTH_MAX 64
1576 static void dnode_free(dnode_t *node);
1579 * Perform a ``left rotation'' adjustment on the tree. The given node P and
1580 * its right child C are rearranged so that the P instead becomes the left
1581 * child of C. The left subtree of C is inherited as the new right subtree
1582 * for P. The ordering of the keys within the tree is thus preserved.
1585 static void rotate_left(dnode_t *upper)
1587 dnode_t *lower, *lowleft, *upparent;
1589 lower = upper->right;
1590 upper->right = lowleft = lower->left;
1591 lowleft->parent = upper;
1593 lower->parent = upparent = upper->parent;
1595 /* don't need to check for root node here because root->parent is
1596 the sentinel nil node, and root->parent->left points back to root */
1598 if (upper == upparent->left) {
1599 upparent->left = lower;
1601 assert (upper == upparent->right);
1602 upparent->right = lower;
1605 lower->left = upper;
1606 upper->parent = lower;
1610 * This operation is the ``mirror'' image of rotate_left. It is
1611 * the same procedure, but with left and right interchanged.
1614 static void rotate_right(dnode_t *upper)
1616 dnode_t *lower, *lowright, *upparent;
1618 lower = upper->left;
1619 upper->left = lowright = lower->right;
1620 lowright->parent = upper;
1622 lower->parent = upparent = upper->parent;
1624 if (upper == upparent->right) {
1625 upparent->right = lower;
1627 assert (upper == upparent->left);
1628 upparent->left = lower;
1631 lower->right = upper;
1632 upper->parent = lower;
1636 * Do a postorder traversal of the tree rooted at the specified
1637 * node and free everything under it. Used by dict_free().
1640 static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil)
1644 free_nodes(dict, node->left, nil);
1645 free_nodes(dict, node->right, nil);
1646 dict->dict_freenode(node);
1650 * Verify that the tree contains the given node. This is done by
1651 * traversing all of the nodes and comparing their pointers to the
1652 * given pointer. Returns 1 if the node is found, otherwise
1653 * returns zero. It is intended for debugging purposes.
1656 static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node)
1660 || verify_dict_has_node(nil, root->left, node)
1661 || verify_dict_has_node(nil, root->right, node);
1668 * Select a different set of node allocator routines.
1671 static void dict_set_allocator(dict_t *dict, dnode_free_t fr)
1673 assert (dict_count(dict) == 0);
1674 dict->dict_freenode = fr;
1678 * Free all the nodes in the dictionary by using the dictionary's
1679 * installed free routine. The dictionary is emptied.
1682 static void dict_free_nodes(dict_t *dict)
1684 dnode_t *nil = dict_nil(dict), *root = dict_root(dict);
1685 free_nodes(dict, root, nil);
1686 dict->dict_nodecount = 0;
1687 dict->nilnode.left = &dict->nilnode;
1688 dict->nilnode.right = &dict->nilnode;
1692 * Initialize a user-supplied dictionary object.
1695 static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp)
1697 dict->compare = comp;
1698 dict->dict_freenode = dnode_free;
1699 dict->dict_nodecount = 0;
1700 dict->maxcount = maxcount;
1701 dict->nilnode.left = &dict->nilnode;
1702 dict->nilnode.right = &dict->nilnode;
1703 dict->nilnode.parent = &dict->nilnode;
1704 dict->nilnode.color = dnode_black;
1710 * Locate a node in the dictionary having the given key.
1711 * If the node is not found, a null a pointer is returned (rather than
1712 * a pointer that dictionary's nil sentinel node), otherwise a pointer to the
1713 * located node is returned.
1716 static dnode_t *dict_lookup(dict_t *dict, const void *key)
1718 dnode_t *root = dict_root(dict);
1719 dnode_t *nil = dict_nil(dict);
1723 /* simple binary search adapted for trees that contain duplicate keys */
1725 while (root != nil) {
1726 result = dict->compare(key, root->key);
1729 else if (result > 0)
1732 if (!dict->dupes) { /* no duplicates, return match */
1734 } else { /* could be dupes, find leftmost one */
1738 while (root != nil && dict->compare(key, root->key))
1740 } while (root != nil);
1750 * Insert a node into the dictionary. The node should have been
1751 * initialized with a data field. All other fields are ignored.
1752 * The behavior is undefined if the user attempts to insert into
1753 * a dictionary that is already full (for which the dict_isfull()
1754 * function returns true).
1757 static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
1759 dnode_t *where = dict_root(dict), *nil = dict_nil(dict);
1760 dnode_t *parent = nil, *uncle, *grandpa;
1765 /* basic binary tree insert */
1767 while (where != nil) {
1769 result = dict->compare(key, where->key);
1770 /* trap attempts at duplicate key insertion unless it's explicitly allowed */
1771 assert (dict->dupes || result != 0);
1773 where = where->left;
1775 where = where->right;
1778 assert (where == nil);
1781 parent->left = node;
1783 parent->right = node;
1785 node->parent = parent;
1789 dict->dict_nodecount++;
1791 /* red black adjustments */
1793 node->color = dnode_red;
1795 while (parent->color == dnode_red) {
1796 grandpa = parent->parent;
1797 if (parent == grandpa->left) {
1798 uncle = grandpa->right;
1799 if (uncle->color == dnode_red) { /* red parent, red uncle */
1800 parent->color = dnode_black;
1801 uncle->color = dnode_black;
1802 grandpa->color = dnode_red;
1804 parent = grandpa->parent;
1805 } else { /* red parent, black uncle */
1806 if (node == parent->right) {
1807 rotate_left(parent);
1809 assert (grandpa == parent->parent);
1810 /* rotation between parent and child preserves grandpa */
1812 parent->color = dnode_black;
1813 grandpa->color = dnode_red;
1814 rotate_right(grandpa);
1817 } else { /* symmetric cases: parent == parent->parent->right */
1818 uncle = grandpa->left;
1819 if (uncle->color == dnode_red) {
1820 parent->color = dnode_black;
1821 uncle->color = dnode_black;
1822 grandpa->color = dnode_red;
1824 parent = grandpa->parent;
1826 if (node == parent->left) {
1827 rotate_right(parent);
1829 assert (grandpa == parent->parent);
1831 parent->color = dnode_black;
1832 grandpa->color = dnode_red;
1833 rotate_left(grandpa);
1839 dict_root(dict)->color = dnode_black;
1844 * Allocate a node using the dictionary's allocator routine, give it
1848 static dnode_t *dnode_init(dnode_t *dnode, void *data)
1851 dnode->parent = NULL;
1853 dnode->right = NULL;
1857 static int dict_alloc_insert(dict_t *dict, const void *key, void *data)
1859 dnode_t *node = malloc(sizeof(dnode_t));
1862 dnode_init(node, data);
1863 dict_insert(dict, node, key);
1870 * Return the node with the lowest (leftmost) key. If the dictionary is empty
1871 * (that is, dict_isempty(dict) returns 1) a null pointer is returned.
1874 static dnode_t *dict_first(dict_t *dict)
1876 dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left;
1879 while ((left = root->left) != nil)
1882 return (root == nil) ? NULL : root;
1886 * Return the given node's successor node---the node which has the
1887 * next key in the the left to right ordering. If the node has
1888 * no successor, a null pointer is returned rather than a pointer to
1892 static dnode_t *dict_next(dict_t *dict, dnode_t *curr)
1894 dnode_t *nil = dict_nil(dict), *parent, *left;
1896 if (curr->right != nil) {
1898 while ((left = curr->left) != nil)
1903 parent = curr->parent;
1905 while (parent != nil && curr == parent->right) {
1907 parent = curr->parent;
1910 return (parent == nil) ? NULL : parent;
1914 static void dnode_free(dnode_t *node)
1934 * dirinfo.c --- maintains the directory information table for e2fsck.
1938 * This subroutine is called during pass1 to create a directory info
1939 * entry. During pass1, the passed-in parent is 0; it will get filled
1942 static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent)
1944 struct dir_info *dir;
1946 ext2_ino_t num_dirs;
1948 unsigned long old_size;
1951 printf("add_dir_info for inode %lu...\n", ino);
1953 if (!ctx->dir_info) {
1954 ctx->dir_info_count = 0;
1955 retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs);
1957 num_dirs = 1024; /* Guess */
1958 ctx->dir_info_size = num_dirs + 10;
1959 ctx->dir_info = (struct dir_info *)
1960 e2fsck_allocate_memory(ctx, ctx->dir_info_size
1961 * sizeof (struct dir_info),
1965 if (ctx->dir_info_count >= ctx->dir_info_size) {
1966 old_size = ctx->dir_info_size * sizeof(struct dir_info);
1967 ctx->dir_info_size += 10;
1968 retval = ext2fs_resize_mem(old_size, ctx->dir_info_size *
1969 sizeof(struct dir_info),
1972 ctx->dir_info_size -= 10;
1978 * Normally, add_dir_info is called with each inode in
1979 * sequential order; but once in a while (like when pass 3
1980 * needs to recreate the root directory or lost+found
1981 * directory) it is called out of order. In those cases, we
1982 * need to move the dir_info entries down to make room, since
1983 * the dir_info array needs to be sorted by inode number for
1984 * get_dir_info()'s sake.
1986 if (ctx->dir_info_count &&
1987 ctx->dir_info[ctx->dir_info_count-1].ino >= ino) {
1988 for (i = ctx->dir_info_count-1; i > 0; i--)
1989 if (ctx->dir_info[i-1].ino < ino)
1991 dir = &ctx->dir_info[i];
1992 if (dir->ino != ino)
1993 for (j = ctx->dir_info_count++; j > i; j--)
1994 ctx->dir_info[j] = ctx->dir_info[j-1];
1996 dir = &ctx->dir_info[ctx->dir_info_count++];
1999 dir->dotdot = parent;
2000 dir->parent = parent;
2004 * get_dir_info() --- given an inode number, try to find the directory
2005 * information entry for it.
2007 static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino)
2012 high = ctx->dir_info_count-1;
2015 if (ino == ctx->dir_info[low].ino)
2016 return &ctx->dir_info[low];
2017 if (ino == ctx->dir_info[high].ino)
2018 return &ctx->dir_info[high];
2020 while (low < high) {
2022 if (mid == low || mid == high)
2024 if (ino == ctx->dir_info[mid].ino)
2025 return &ctx->dir_info[mid];
2026 if (ino < ctx->dir_info[mid].ino)
2035 * Free the dir_info structure when it isn't needed any more.
2037 static void e2fsck_free_dir_info(e2fsck_t ctx)
2039 if (ctx->dir_info) {
2040 ext2fs_free_mem(&ctx->dir_info);
2043 ctx->dir_info_size = 0;
2044 ctx->dir_info_count = 0;
2048 * Return the count of number of directories in the dir_info structure
2050 static inline int e2fsck_get_num_dirinfo(e2fsck_t ctx)
2052 return ctx->dir_info_count;
2056 * A simple interator function
2058 static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control)
2060 if (*control >= ctx->dir_info_count)
2063 return(ctx->dir_info + (*control)++);
2067 * dirinfo.c --- maintains the directory information table for e2fsck.
2074 * This subroutine is called during pass1 to create a directory info
2075 * entry. During pass1, the passed-in parent is 0; it will get filled
2078 static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
2080 struct dx_dir_info *dir;
2083 unsigned long old_size;
2086 printf("add_dx_dir_info for inode %lu...\n", ino);
2088 if (!ctx->dx_dir_info) {
2089 ctx->dx_dir_info_count = 0;
2090 ctx->dx_dir_info_size = 100; /* Guess */
2091 ctx->dx_dir_info = (struct dx_dir_info *)
2092 e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size
2093 * sizeof (struct dx_dir_info),
2097 if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) {
2098 old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info);
2099 ctx->dx_dir_info_size += 10;
2100 retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size *
2101 sizeof(struct dx_dir_info),
2104 ctx->dx_dir_info_size -= 10;
2110 * Normally, add_dx_dir_info is called with each inode in
2111 * sequential order; but once in a while (like when pass 3
2112 * needs to recreate the root directory or lost+found
2113 * directory) it is called out of order. In those cases, we
2114 * need to move the dx_dir_info entries down to make room, since
2115 * the dx_dir_info array needs to be sorted by inode number for
2116 * get_dx_dir_info()'s sake.
2118 if (ctx->dx_dir_info_count &&
2119 ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) {
2120 for (i = ctx->dx_dir_info_count-1; i > 0; i--)
2121 if (ctx->dx_dir_info[i-1].ino < ino)
2123 dir = &ctx->dx_dir_info[i];
2124 if (dir->ino != ino)
2125 for (j = ctx->dx_dir_info_count++; j > i; j--)
2126 ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1];
2128 dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++];
2131 dir->numblocks = num_blocks;
2132 dir->hashversion = 0;
2133 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
2134 * sizeof (struct dx_dirblock_info),
2135 "dx_block info array");
2140 * get_dx_dir_info() --- given an inode number, try to find the directory
2141 * information entry for it.
2143 static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino)
2148 high = ctx->dx_dir_info_count-1;
2149 if (!ctx->dx_dir_info)
2151 if (ino == ctx->dx_dir_info[low].ino)
2152 return &ctx->dx_dir_info[low];
2153 if (ino == ctx->dx_dir_info[high].ino)
2154 return &ctx->dx_dir_info[high];
2156 while (low < high) {
2158 if (mid == low || mid == high)
2160 if (ino == ctx->dx_dir_info[mid].ino)
2161 return &ctx->dx_dir_info[mid];
2162 if (ino < ctx->dx_dir_info[mid].ino)
2171 * Free the dx_dir_info structure when it isn't needed any more.
2173 static void e2fsck_free_dx_dir_info(e2fsck_t ctx)
2176 struct dx_dir_info *dir;
2178 if (ctx->dx_dir_info) {
2179 dir = ctx->dx_dir_info;
2180 for (i=0; i < ctx->dx_dir_info_count; i++) {
2181 if (dir->dx_block) {
2182 ext2fs_free_mem(&dir->dx_block);
2186 ext2fs_free_mem(&ctx->dx_dir_info);
2187 ctx->dx_dir_info = 0;
2189 ctx->dx_dir_info_size = 0;
2190 ctx->dx_dir_info_count = 0;
2194 * A simple interator function
2196 static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control)
2198 if (*control >= ctx->dx_dir_info_count)
2201 return(ctx->dx_dir_info + (*control)++);
2204 #endif /* ENABLE_HTREE */
2206 * e2fsck.c - a consistency checker for the new extended file system.
2211 * This function allocates an e2fsck context
2213 static errcode_t e2fsck_allocate_context(e2fsck_t *ret)
2218 retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context);
2222 memset(context, 0, sizeof(struct e2fsck_struct));
2224 context->process_inode_size = 256;
2225 context->ext_attr_ver = 2;
2231 struct ea_refcount_el {
2236 struct ea_refcount {
2240 struct ea_refcount_el *list;
2243 static void ea_refcount_free(ext2_refcount_t refcount)
2249 ext2fs_free_mem(&refcount->list);
2250 ext2fs_free_mem(&refcount);
2254 * This function resets an e2fsck context; it is called when e2fsck
2255 * needs to be restarted.
2257 static errcode_t e2fsck_reset_context(e2fsck_t ctx)
2260 ctx->lost_and_found = 0;
2261 ctx->bad_lost_and_found = 0;
2262 if (ctx->inode_used_map) {
2263 ext2fs_free_inode_bitmap(ctx->inode_used_map);
2264 ctx->inode_used_map = 0;
2266 if (ctx->inode_dir_map) {
2267 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
2268 ctx->inode_dir_map = 0;
2270 if (ctx->inode_reg_map) {
2271 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
2272 ctx->inode_reg_map = 0;
2274 if (ctx->block_found_map) {
2275 ext2fs_free_block_bitmap(ctx->block_found_map);
2276 ctx->block_found_map = 0;
2278 if (ctx->inode_link_info) {
2279 ext2fs_free_icount(ctx->inode_link_info);
2280 ctx->inode_link_info = 0;
2282 if (ctx->journal_io) {
2283 if (ctx->fs && ctx->fs->io != ctx->journal_io)
2284 io_channel_close(ctx->journal_io);
2285 ctx->journal_io = 0;
2287 if (ctx->fs && ctx->fs->dblist) {
2288 ext2fs_free_dblist(ctx->fs->dblist);
2289 ctx->fs->dblist = 0;
2291 e2fsck_free_dir_info(ctx);
2293 e2fsck_free_dx_dir_info(ctx);
2295 if (ctx->refcount) {
2296 ea_refcount_free(ctx->refcount);
2299 if (ctx->refcount_extra) {
2300 ea_refcount_free(ctx->refcount_extra);
2301 ctx->refcount_extra = 0;
2303 if (ctx->block_dup_map) {
2304 ext2fs_free_block_bitmap(ctx->block_dup_map);
2305 ctx->block_dup_map = 0;
2307 if (ctx->block_ea_map) {
2308 ext2fs_free_block_bitmap(ctx->block_ea_map);
2309 ctx->block_ea_map = 0;
2311 if (ctx->inode_bb_map) {
2312 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
2313 ctx->inode_bb_map = 0;
2315 if (ctx->inode_bad_map) {
2316 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
2317 ctx->inode_bad_map = 0;
2319 if (ctx->inode_imagic_map) {
2320 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
2321 ctx->inode_imagic_map = 0;
2323 if (ctx->dirs_to_hash) {
2324 ext2fs_u32_list_free(ctx->dirs_to_hash);
2325 ctx->dirs_to_hash = 0;
2329 * Clear the array of invalid meta-data flags
2331 if (ctx->invalid_inode_bitmap_flag) {
2332 ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag);
2333 ctx->invalid_inode_bitmap_flag = 0;
2335 if (ctx->invalid_block_bitmap_flag) {
2336 ext2fs_free_mem(&ctx->invalid_block_bitmap_flag);
2337 ctx->invalid_block_bitmap_flag = 0;
2339 if (ctx->invalid_inode_table_flag) {
2340 ext2fs_free_mem(&ctx->invalid_inode_table_flag);
2341 ctx->invalid_inode_table_flag = 0;
2344 /* Clear statistic counters */
2345 ctx->fs_directory_count = 0;
2346 ctx->fs_regular_count = 0;
2347 ctx->fs_blockdev_count = 0;
2348 ctx->fs_chardev_count = 0;
2349 ctx->fs_links_count = 0;
2350 ctx->fs_symlinks_count = 0;
2351 ctx->fs_fast_symlinks_count = 0;
2352 ctx->fs_fifo_count = 0;
2353 ctx->fs_total_count = 0;
2354 ctx->fs_badblocks_count = 0;
2355 ctx->fs_sockets_count = 0;
2356 ctx->fs_ind_count = 0;
2357 ctx->fs_dind_count = 0;
2358 ctx->fs_tind_count = 0;
2359 ctx->fs_fragmented = 0;
2360 ctx->large_files = 0;
2362 /* Reset the superblock to the user's requested value */
2363 ctx->superblock = ctx->use_superblock;
2368 static void e2fsck_free_context(e2fsck_t ctx)
2373 e2fsck_reset_context(ctx);
2375 blkid_put_cache(ctx->blkid);
2377 ext2fs_free_mem(&ctx);
2385 * The strategy we use for keeping track of EA refcounts is as
2386 * follows. We keep a sorted array of first EA blocks and its
2387 * reference counts. Once the refcount has dropped to zero, it is
2388 * removed from the array to save memory space. Once the EA block is
2389 * checked, its bit is set in the block_ea_map bitmap.
2393 static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret)
2395 ext2_refcount_t refcount;
2399 retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount);
2402 memset(refcount, 0, sizeof(struct ea_refcount));
2406 refcount->size = size;
2407 bytes = (size_t) (size * sizeof(struct ea_refcount_el));
2409 printf("Refcount allocated %d entries, %d bytes.\n",
2410 refcount->size, bytes);
2412 retval = ext2fs_get_mem(bytes, &refcount->list);
2415 memset(refcount->list, 0, bytes);
2417 refcount->count = 0;
2418 refcount->cursor = 0;
2424 ea_refcount_free(refcount);
2429 * collapse_refcount() --- go through the refcount array, and get rid
2430 * of any count == zero entries
2432 static void refcount_collapse(ext2_refcount_t refcount)
2435 struct ea_refcount_el *list;
2437 list = refcount->list;
2438 for (i = 0, j = 0; i < refcount->count; i++) {
2439 if (list[i].ea_count) {
2445 #if defined(DEBUG) || defined(TEST_PROGRAM)
2446 printf("Refcount_collapse: size was %d, now %d\n",
2447 refcount->count, j);
2449 refcount->count = j;
2454 * insert_refcount_el() --- Insert a new entry into the sorted list at a
2455 * specified position.
2457 static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount,
2460 struct ea_refcount_el *el;
2465 if (refcount->count >= refcount->size) {
2466 new_size = refcount->size + 100;
2468 printf("Reallocating refcount %d entries...\n", new_size);
2470 retval = ext2fs_resize_mem((size_t) refcount->size *
2471 sizeof(struct ea_refcount_el),
2473 sizeof(struct ea_refcount_el),
2477 refcount->size = new_size;
2479 num = (int) refcount->count - pos;
2481 return 0; /* should never happen */
2483 memmove(&refcount->list[pos+1], &refcount->list[pos],
2484 sizeof(struct ea_refcount_el) * num);
2487 el = &refcount->list[pos];
2495 * get_refcount_el() --- given an block number, try to find refcount
2496 * information in the sorted list. If the create flag is set,
2497 * and we can't find an entry, create one in the sorted list.
2499 static struct ea_refcount_el *get_refcount_el(ext2_refcount_t refcount,
2500 blk_t blk, int create)
2504 blk_t lowval, highval;
2506 if (!refcount || !refcount->list)
2510 high = (int) refcount->count-1;
2511 if (create && ((refcount->count == 0) ||
2512 (blk > refcount->list[high].ea_blk))) {
2513 if (refcount->count >= refcount->size)
2514 refcount_collapse(refcount);
2516 return insert_refcount_el(refcount, blk,
2517 (unsigned) refcount->count);
2519 if (refcount->count == 0)
2522 if (refcount->cursor >= refcount->count)
2523 refcount->cursor = 0;
2524 if (blk == refcount->list[refcount->cursor].ea_blk)
2525 return &refcount->list[refcount->cursor++];
2527 printf("Non-cursor get_refcount_el: %u\n", blk);
2529 while (low <= high) {
2536 /* Interpolate for efficiency */
2537 lowval = refcount->list[low].ea_blk;
2538 highval = refcount->list[high].ea_blk;
2542 else if (blk > highval)
2545 range = ((float) (blk - lowval)) /
2547 mid = low + ((int) (range * (high-low)));
2550 if (blk == refcount->list[mid].ea_blk) {
2551 refcount->cursor = mid+1;
2552 return &refcount->list[mid];
2554 if (blk < refcount->list[mid].ea_blk)
2560 * If we need to create a new entry, it should be right at
2561 * low (where high will be left at low-1).
2564 if (refcount->count >= refcount->size) {
2565 refcount_collapse(refcount);
2566 if (refcount->count < refcount->size)
2569 return insert_refcount_el(refcount, blk, low);
2575 ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret)
2577 struct ea_refcount_el *el;
2579 el = get_refcount_el(refcount, blk, 1);
2581 return EXT2_ET_NO_MEMORY;
2585 *ret = el->ea_count;
2590 ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret)
2592 struct ea_refcount_el *el;
2594 el = get_refcount_el(refcount, blk, 0);
2595 if (!el || el->ea_count == 0)
2596 return EXT2_ET_INVALID_ARGUMENT;
2601 *ret = el->ea_count;
2606 ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count)
2608 struct ea_refcount_el *el;
2611 * Get the refcount element
2613 el = get_refcount_el(refcount, blk, count ? 1 : 0);
2615 return count ? EXT2_ET_NO_MEMORY : 0;
2616 el->ea_count = count;
2620 static inline void ea_refcount_intr_begin(ext2_refcount_t refcount)
2622 refcount->cursor = 0;
2626 static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret)
2628 struct ea_refcount_el *list;
2631 if (refcount->cursor >= refcount->count)
2633 list = refcount->list;
2634 if (list[refcount->cursor].ea_count) {
2636 *ret = list[refcount->cursor].ea_count;
2637 return list[refcount->cursor++].ea_blk;
2645 * ehandler.c --- handle bad block errors which come up during the
2646 * course of an e2fsck session.
2650 static const char *operation;
2653 e2fsck_handle_read_error(io_channel channel, unsigned long block, int count,
2654 void *data, size_t size FSCK_ATTR((unused)),
2655 int actual FSCK_ATTR((unused)), errcode_t error)
2659 ext2_filsys fs = (ext2_filsys) channel->app_data;
2662 ctx = (e2fsck_t) fs->priv_data;
2665 * If more than one block was read, try reading each block
2666 * separately. We could use the actual bytes read to figure
2667 * out where to start, but we don't bother.
2671 for (i=0; i < count; i++, p += channel->block_size, block++) {
2672 error = io_channel_read_blk(channel, block,
2680 printf(_("Error reading block %lu (%s) while %s. "), block,
2681 error_message(error), operation);
2683 printf(_("Error reading block %lu (%s). "), block,
2684 error_message(error));
2686 if (ask(ctx, _("Ignore error"), 1)) {
2687 if (ask(ctx, _("Force rewrite"), 1))
2688 io_channel_write_blk(channel, block, 1, data);
2696 e2fsck_handle_write_error(io_channel channel, unsigned long block, int count,
2697 const void *data, size_t size FSCK_ATTR((unused)),
2698 int actual FSCK_ATTR((unused)), errcode_t error)
2702 ext2_filsys fs = (ext2_filsys) channel->app_data;
2705 ctx = (e2fsck_t) fs->priv_data;
2708 * If more than one block was written, try writing each block
2709 * separately. We could use the actual bytes read to figure
2710 * out where to start, but we don't bother.
2713 p = (const char *) data;
2714 for (i=0; i < count; i++, p += channel->block_size, block++) {
2715 error = io_channel_write_blk(channel, block,
2724 printf(_("Error writing block %lu (%s) while %s. "), block,
2725 error_message(error), operation);
2727 printf(_("Error writing block %lu (%s). "), block,
2728 error_message(error));
2730 if (ask(ctx, _("Ignore error"), 1))
2736 static inline const char *ehandler_operation(const char *op)
2738 const char *ret = operation;
2744 static void ehandler_init(io_channel channel)
2746 channel->read_error = e2fsck_handle_read_error;
2747 channel->write_error = e2fsck_handle_write_error;
2751 * journal.c --- code for handling the "ext3" journal
2753 * Copyright (C) 2000 Andreas Dilger
2754 * Copyright (C) 2000 Theodore Ts'o
2756 * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie
2757 * Copyright (C) 1999 Red Hat Software
2759 * This file may be redistributed under the terms of the
2760 * GNU General Public License version 2 or at your discretion
2761 * any later version.
2764 #define MNT_FL (MS_MGC_VAL | MS_RDONLY)
2767 #ifdef __CONFIG_JBD_DEBUG__E2FS /* Enabled by configure --enable-jfs-debug */
2768 static int bh_count = 0;
2772 * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths.
2773 * This creates a larger static binary, and a smaller binary using
2774 * shared libraries. It's also probably slightly less CPU-efficient,
2775 * which is why it's not on by default. But, it's a good way of
2776 * testing the functions in inode_io.c and fileio.c.
2780 /* Kernel compatibility functions for handling the journal. These allow us
2781 * to use the recovery.c file virtually unchanged from the kernel, so we
2782 * don't have to do much to keep kernel and user recovery in sync.
2784 static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys)
2790 struct inode *inode = journal->j_inode;
2799 retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino,
2800 &inode->i_ext2, NULL, 0, block, &pblk);
2806 static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize)
2808 struct buffer_head *bh;
2810 bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer");
2814 jfs_debug(4, "getblk for block %lu (%d bytes)(total %d)\n",
2815 (unsigned long) blocknr, blocksize, ++bh_count);
2817 bh->b_ctx = kdev->k_ctx;
2818 if (kdev->k_dev == K_DEV_FS)
2819 bh->b_io = kdev->k_ctx->fs->io;
2821 bh->b_io = kdev->k_ctx->journal_io;
2822 bh->b_size = blocksize;
2823 bh->b_blocknr = blocknr;
2828 static void sync_blockdev(kdev_t kdev)
2832 if (kdev->k_dev == K_DEV_FS)
2833 io = kdev->k_ctx->fs->io;
2835 io = kdev->k_ctx->journal_io;
2837 io_channel_flush(io);
2840 static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[])
2843 struct buffer_head *bh;
2845 for (; nr > 0; --nr) {
2847 if (rw == READ && !bh->b_uptodate) {
2848 jfs_debug(3, "reading block %lu/%p\n",
2849 (unsigned long) bh->b_blocknr, (void *) bh);
2850 retval = io_channel_read_blk(bh->b_io,
2854 com_err(bh->b_ctx->device_name, retval,
2855 "while reading block %lu\n",
2856 (unsigned long) bh->b_blocknr);
2861 } else if (rw == WRITE && bh->b_dirty) {
2862 jfs_debug(3, "writing block %lu/%p\n",
2863 (unsigned long) bh->b_blocknr, (void *) bh);
2864 retval = io_channel_write_blk(bh->b_io,
2868 com_err(bh->b_ctx->device_name, retval,
2869 "while writing block %lu\n",
2870 (unsigned long) bh->b_blocknr);
2877 jfs_debug(3, "no-op %s for block %lu\n",
2878 rw == READ ? "read" : "write",
2879 (unsigned long) bh->b_blocknr);
2884 static inline void mark_buffer_dirty(struct buffer_head *bh)
2889 static inline void mark_buffer_clean(struct buffer_head * bh)
2894 static void brelse(struct buffer_head *bh)
2897 ll_rw_block(WRITE, 1, &bh);
2898 jfs_debug(3, "freeing block %lu/%p (total %d)\n",
2899 (unsigned long) bh->b_blocknr, (void *) bh, --bh_count);
2900 ext2fs_free_mem(&bh);
2903 static inline int buffer_uptodate(struct buffer_head *bh)
2905 return bh->b_uptodate;
2908 static inline void mark_buffer_uptodate(struct buffer_head *bh, int val)
2910 bh->b_uptodate = val;
2913 static void wait_on_buffer(struct buffer_head *bh)
2915 if (!bh->b_uptodate)
2916 ll_rw_block(READ, 1, &bh);
2920 static void e2fsck_clear_recover(e2fsck_t ctx, int error)
2922 ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER;
2924 /* if we had an error doing journal recovery, we need a full fsck */
2926 ctx->fs->super->s_state &= ~EXT2_VALID_FS;
2927 ext2fs_mark_super_dirty(ctx->fs);
2930 static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal)
2932 struct ext2_super_block *sb = ctx->fs->super;
2933 struct ext2_super_block jsuper;
2934 struct problem_context pctx;
2935 struct buffer_head *bh;
2936 struct inode *j_inode = NULL;
2937 struct kdev_s *dev_fs = NULL, *dev_journal;
2938 const char *journal_name = 0;
2939 journal_t *journal = NULL;
2940 errcode_t retval = 0;
2941 io_manager io_ptr = 0;
2942 unsigned long start = 0;
2944 int ext_journal = 0;
2945 int tried_backup_jnl = 0;
2948 clear_problem_context(&pctx);
2950 journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal");
2952 return EXT2_ET_NO_MEMORY;
2955 dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev");
2957 retval = EXT2_ET_NO_MEMORY;
2960 dev_journal = dev_fs+1;
2962 dev_fs->k_ctx = dev_journal->k_ctx = ctx;
2963 dev_fs->k_dev = K_DEV_FS;
2964 dev_journal->k_dev = K_DEV_JOURNAL;
2966 journal->j_dev = dev_journal;
2967 journal->j_fs_dev = dev_fs;
2968 journal->j_inode = NULL;
2969 journal->j_blocksize = ctx->fs->blocksize;
2971 if (uuid_is_null(sb->s_journal_uuid)) {
2972 if (!sb->s_journal_inum)
2973 return EXT2_ET_BAD_INODE_NUM;
2974 j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode),
2977 retval = EXT2_ET_NO_MEMORY;
2981 j_inode->i_ctx = ctx;
2982 j_inode->i_ino = sb->s_journal_inum;
2984 if ((retval = ext2fs_read_inode(ctx->fs,
2986 &j_inode->i_ext2))) {
2988 if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS ||
2991 memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode));
2992 memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks,
2994 j_inode->i_ext2.i_size = sb->s_jnl_blocks[16];
2995 j_inode->i_ext2.i_links_count = 1;
2996 j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600;
2999 if (!j_inode->i_ext2.i_links_count ||
3000 !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) {
3001 retval = EXT2_ET_NO_JOURNAL;
3002 goto try_backup_journal;
3004 if (j_inode->i_ext2.i_size / journal->j_blocksize <
3005 JFS_MIN_JOURNAL_BLOCKS) {
3006 retval = EXT2_ET_JOURNAL_TOO_SMALL;
3007 goto try_backup_journal;
3009 for (i=0; i < EXT2_N_BLOCKS; i++) {
3010 blk = j_inode->i_ext2.i_block[i];
3012 if (i < EXT2_NDIR_BLOCKS) {
3013 retval = EXT2_ET_JOURNAL_TOO_SMALL;
3014 goto try_backup_journal;
3018 if (blk < sb->s_first_data_block ||
3019 blk >= sb->s_blocks_count) {
3020 retval = EXT2_ET_BAD_BLOCK_NUM;
3021 goto try_backup_journal;
3024 journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize;
3027 retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum,
3033 io_ptr = inode_io_manager;
3035 journal->j_inode = j_inode;
3036 ctx->journal_io = ctx->fs->io;
3037 if ((retval = journal_bmap(journal, 0, &start)) != 0)
3042 if (!ctx->journal_name) {
3045 uuid_unparse(sb->s_journal_uuid, uuid);
3046 ctx->journal_name = blkid_get_devname(ctx->blkid,
3048 if (!ctx->journal_name)
3049 ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev);
3051 journal_name = ctx->journal_name;
3053 if (!journal_name) {
3054 fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx);
3055 return EXT2_ET_LOAD_EXT_JOURNAL;
3058 jfs_debug(1, "Using journal file %s\n", journal_name);
3059 io_ptr = unix_io_manager;
3063 test_io_backing_manager = io_ptr;
3064 io_ptr = test_io_manager;
3066 #ifndef USE_INODE_IO
3069 retval = io_ptr->open(journal_name, IO_FLAG_RW,
3074 io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize);
3077 if (ctx->fs->blocksize == 1024)
3079 bh = getblk(dev_journal, start, ctx->fs->blocksize);
3081 retval = EXT2_ET_NO_MEMORY;
3084 ll_rw_block(READ, 1, &bh);
3085 if ((retval = bh->b_err) != 0)
3087 memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024,
3090 #ifdef EXT2FS_ENABLE_SWAPFS
3091 if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
3092 ext2fs_swap_super(&jsuper);
3094 if (jsuper.s_magic != EXT2_SUPER_MAGIC ||
3095 !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
3096 fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx);
3097 retval = EXT2_ET_LOAD_EXT_JOURNAL;
3100 /* Make sure the journal UUID is correct */
3101 if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid,
3102 sizeof(jsuper.s_uuid))) {
3103 fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx);
3104 retval = EXT2_ET_LOAD_EXT_JOURNAL;
3108 journal->j_maxlen = jsuper.s_blocks_count;
3112 if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) {
3113 retval = EXT2_ET_NO_MEMORY;
3117 journal->j_sb_buffer = bh;
3118 journal->j_superblock = (journal_superblock_t *)bh->b_data;
3122 ext2fs_free_mem(&j_inode);
3125 *ret_journal = journal;
3130 ext2fs_free_mem(&dev_fs);
3132 ext2fs_free_mem(&j_inode);
3134 ext2fs_free_mem(&journal);
3139 static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
3140 struct problem_context *pctx)
3142 struct ext2_super_block *sb = ctx->fs->super;
3143 int recover = ctx->fs->super->s_feature_incompat &
3144 EXT3_FEATURE_INCOMPAT_RECOVER;
3145 int has_journal = ctx->fs->super->s_feature_compat &
3146 EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3148 if (has_journal || sb->s_journal_inum) {
3149 /* The journal inode is bogus, remove and force full fsck */
3150 pctx->ino = sb->s_journal_inum;
3151 if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) {
3152 if (has_journal && sb->s_journal_inum)
3153 printf("*** ext3 journal has been deleted - "
3154 "filesystem is now ext2 only ***\n\n");
3155 sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3156 sb->s_journal_inum = 0;
3157 ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */
3158 e2fsck_clear_recover(ctx, 1);
3161 return EXT2_ET_BAD_INODE_NUM;
3162 } else if (recover) {
3163 if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) {
3164 e2fsck_clear_recover(ctx, 1);
3167 return EXT2_ET_UNSUPP_FEATURE;
3172 #define V1_SB_SIZE 0x0024
3173 static void clear_v2_journal_fields(journal_t *journal)
3175 e2fsck_t ctx = journal->j_dev->k_ctx;
3176 struct problem_context pctx;
3178 clear_problem_context(&pctx);
3180 if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx))
3183 memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0,
3184 ctx->fs->blocksize-V1_SB_SIZE);
3185 mark_buffer_dirty(journal->j_sb_buffer);
3189 static errcode_t e2fsck_journal_load(journal_t *journal)
3191 e2fsck_t ctx = journal->j_dev->k_ctx;
3192 journal_superblock_t *jsb;
3193 struct buffer_head *jbh = journal->j_sb_buffer;
3194 struct problem_context pctx;
3196 clear_problem_context(&pctx);
3198 ll_rw_block(READ, 1, &jbh);
3200 com_err(ctx->device_name, jbh->b_err,
3201 _("reading journal superblock\n"));
3205 jsb = journal->j_superblock;
3206 /* If we don't even have JFS_MAGIC, we probably have a wrong inode */
3207 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER))
3208 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
3210 switch (ntohl(jsb->s_header.h_blocktype)) {
3211 case JFS_SUPERBLOCK_V1:
3212 journal->j_format_version = 1;
3213 if (jsb->s_feature_compat ||
3214 jsb->s_feature_incompat ||
3215 jsb->s_feature_ro_compat ||
3217 clear_v2_journal_fields(journal);
3220 case JFS_SUPERBLOCK_V2:
3221 journal->j_format_version = 2;
3222 if (ntohl(jsb->s_nr_users) > 1 &&
3223 uuid_is_null(ctx->fs->super->s_journal_uuid))
3224 clear_v2_journal_fields(journal);
3225 if (ntohl(jsb->s_nr_users) > 1) {
3226 fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx);
3227 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
3232 * These should never appear in a journal super block, so if
3233 * they do, the journal is badly corrupted.
3235 case JFS_DESCRIPTOR_BLOCK:
3236 case JFS_COMMIT_BLOCK:
3237 case JFS_REVOKE_BLOCK:
3238 return EXT2_ET_CORRUPT_SUPERBLOCK;
3240 /* If we don't understand the superblock major type, but there
3241 * is a magic number, then it is likely to be a new format we
3242 * just don't understand, so leave it alone. */
3244 return EXT2_ET_JOURNAL_UNSUPP_VERSION;
3247 if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES))
3248 return EXT2_ET_UNSUPP_FEATURE;
3250 if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES))
3251 return EXT2_ET_RO_UNSUPP_FEATURE;
3253 /* We have now checked whether we know enough about the journal
3254 * format to be able to proceed safely, so any other checks that
3255 * fail we should attempt to recover from. */
3256 if (jsb->s_blocksize != htonl(journal->j_blocksize)) {
3257 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
3258 _("%s: no valid journal superblock found\n"),
3260 return EXT2_ET_CORRUPT_SUPERBLOCK;
3263 if (ntohl(jsb->s_maxlen) < journal->j_maxlen)
3264 journal->j_maxlen = ntohl(jsb->s_maxlen);
3265 else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) {
3266 com_err(ctx->program_name, EXT2_ET_CORRUPT_SUPERBLOCK,
3267 _("%s: journal too short\n"),
3269 return EXT2_ET_CORRUPT_SUPERBLOCK;
3272 journal->j_tail_sequence = ntohl(jsb->s_sequence);
3273 journal->j_transaction_sequence = journal->j_tail_sequence;
3274 journal->j_tail = ntohl(jsb->s_start);
3275 journal->j_first = ntohl(jsb->s_first);
3276 journal->j_last = ntohl(jsb->s_maxlen);
3281 static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb,
3292 /* Leave a valid existing V1 superblock signature alone.
3293 * Anything unrecognisable we overwrite with a new V2
3296 if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) ||
3297 jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) {
3298 jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
3299 jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
3302 /* Zero out everything else beyond the superblock header */
3304 p = ((char *) jsb) + sizeof(journal_header_t);
3305 memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t));
3307 jsb->s_blocksize = htonl(ctx->fs->blocksize);
3308 jsb->s_maxlen = htonl(journal->j_maxlen);
3309 jsb->s_first = htonl(1);
3311 /* Initialize the journal sequence number so that there is "no"
3312 * chance we will find old "valid" transactions in the journal.
3313 * This avoids the need to zero the whole journal (slow to do,
3314 * and risky when we are just recovering the filesystem).
3316 uuid_generate(u.uuid);
3317 for (i = 0; i < 4; i ++)
3318 new_seq ^= u.val[i];
3319 jsb->s_sequence = htonl(new_seq);
3321 mark_buffer_dirty(journal->j_sb_buffer);
3322 ll_rw_block(WRITE, 1, &journal->j_sb_buffer);
3325 static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx,
3327 struct problem_context *pctx)
3329 struct ext2_super_block *sb = ctx->fs->super;
3330 int recover = ctx->fs->super->s_feature_incompat &
3331 EXT3_FEATURE_INCOMPAT_RECOVER;
3333 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) {
3334 if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) {
3335 e2fsck_journal_reset_super(ctx, journal->j_superblock,
3337 journal->j_transaction_sequence = 1;
3338 e2fsck_clear_recover(ctx, recover);
3341 return EXT2_ET_CORRUPT_SUPERBLOCK;
3342 } else if (e2fsck_journal_fix_bad_inode(ctx, pctx))
3343 return EXT2_ET_CORRUPT_SUPERBLOCK;
3348 static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal,
3349 int reset, int drop)
3351 journal_superblock_t *jsb;
3354 mark_buffer_clean(journal->j_sb_buffer);
3355 else if (!(ctx->options & E2F_OPT_READONLY)) {
3356 jsb = journal->j_superblock;
3357 jsb->s_sequence = htonl(journal->j_transaction_sequence);
3359 jsb->s_start = 0; /* this marks the journal as empty */
3360 mark_buffer_dirty(journal->j_sb_buffer);
3362 brelse(journal->j_sb_buffer);
3364 if (ctx->journal_io) {
3365 if (ctx->fs && ctx->fs->io != ctx->journal_io)
3366 io_channel_close(ctx->journal_io);
3367 ctx->journal_io = 0;
3370 #ifndef USE_INODE_IO
3371 if (journal->j_inode)
3372 ext2fs_free_mem(&journal->j_inode);
3374 if (journal->j_fs_dev)
3375 ext2fs_free_mem(&journal->j_fs_dev);
3376 ext2fs_free_mem(&journal);
3380 * This function makes sure that the superblock fields regarding the
3381 * journal are consistent.
3383 static int e2fsck_check_ext3_journal(e2fsck_t ctx)
3385 struct ext2_super_block *sb = ctx->fs->super;
3387 int recover = ctx->fs->super->s_feature_incompat &
3388 EXT3_FEATURE_INCOMPAT_RECOVER;
3389 struct problem_context pctx;
3391 int reset = 0, force_fsck = 0;
3394 /* If we don't have any journal features, don't do anything more */
3395 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
3396 !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 &&
3397 uuid_is_null(sb->s_journal_uuid))
3400 clear_problem_context(&pctx);
3401 pctx.num = sb->s_journal_inum;
3403 retval = e2fsck_get_journal(ctx, &journal);
3405 if ((retval == EXT2_ET_BAD_INODE_NUM) ||
3406 (retval == EXT2_ET_BAD_BLOCK_NUM) ||
3407 (retval == EXT2_ET_JOURNAL_TOO_SMALL) ||
3408 (retval == EXT2_ET_NO_JOURNAL))
3409 return e2fsck_journal_fix_bad_inode(ctx, &pctx);
3413 retval = e2fsck_journal_load(journal);
3415 if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) ||
3416 ((retval == EXT2_ET_UNSUPP_FEATURE) &&
3417 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT,
3419 ((retval == EXT2_ET_RO_UNSUPP_FEATURE) &&
3420 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT,
3422 ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) &&
3423 (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx))))
3424 retval = e2fsck_journal_fix_corrupt_super(ctx, journal,
3426 e2fsck_journal_release(ctx, journal, 0, 1);
3431 * We want to make the flags consistent here. We will not leave with
3432 * needs_recovery set but has_journal clear. We can't get in a loop
3433 * with -y, -n, or -p, only if a user isn't making up their mind.
3436 if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) {
3437 recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER;
3439 if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) {
3441 !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx))
3442 goto no_has_journal;
3444 * Need a full fsck if we are releasing a
3445 * journal stored on a reserved inode.
3447 force_fsck = recover ||
3448 (sb->s_journal_inum < EXT2_FIRST_INODE(sb));
3449 /* Clear all of the journal fields */
3450 sb->s_journal_inum = 0;
3451 sb->s_journal_dev = 0;
3452 memset(sb->s_journal_uuid, 0,
3453 sizeof(sb->s_journal_uuid));
3454 e2fsck_clear_recover(ctx, force_fsck);
3455 } else if (!(ctx->options & E2F_OPT_READONLY)) {
3456 sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
3457 ext2fs_mark_super_dirty(ctx->fs);
3461 if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL &&
3462 !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) &&
3463 journal->j_superblock->s_start != 0) {
3464 /* Print status information */
3465 fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx);
3466 if (ctx->superblock)
3467 problem = PR_0_JOURNAL_RUN_DEFAULT;
3469 problem = PR_0_JOURNAL_RUN;
3470 if (fix_problem(ctx, problem, &pctx)) {
3471 ctx->options |= E2F_OPT_FORCE;
3472 sb->s_feature_incompat |=
3473 EXT3_FEATURE_INCOMPAT_RECOVER;
3474 ext2fs_mark_super_dirty(ctx->fs);
3475 } else if (fix_problem(ctx,
3476 PR_0_JOURNAL_RESET_JOURNAL, &pctx)) {
3478 sb->s_state &= ~EXT2_VALID_FS;
3479 ext2fs_mark_super_dirty(ctx->fs);
3482 * If the user answers no to the above question, we
3483 * ignore the fact that journal apparently has data;
3484 * accidentally replaying over valid data would be far
3485 * worse than skipping a questionable recovery.
3487 * XXX should we abort with a fatal error here? What
3488 * will the ext3 kernel code do if a filesystem with
3489 * !NEEDS_RECOVERY but with a non-zero
3490 * journal->j_superblock->s_start is mounted?
3494 e2fsck_journal_release(ctx, journal, reset, 0);
3498 static errcode_t recover_ext3_journal(e2fsck_t ctx)
3503 journal_init_revoke_caches();
3504 retval = e2fsck_get_journal(ctx, &journal);
3508 retval = e2fsck_journal_load(journal);
3512 retval = journal_init_revoke(journal, 1024);
3516 retval = -journal_recover(journal);
3520 if (journal->j_superblock->s_errno) {
3521 ctx->fs->super->s_state |= EXT2_ERROR_FS;
3522 ext2fs_mark_super_dirty(ctx->fs);
3523 journal->j_superblock->s_errno = 0;
3524 mark_buffer_dirty(journal->j_sb_buffer);
3528 journal_destroy_revoke(journal);
3529 journal_destroy_revoke_caches();
3530 e2fsck_journal_release(ctx, journal, 1, 0);
3534 static int e2fsck_run_ext3_journal(e2fsck_t ctx)
3536 io_manager io_ptr = ctx->fs->io->manager;
3537 int blocksize = ctx->fs->blocksize;
3538 errcode_t retval, recover_retval;
3540 printf(_("%s: recovering journal\n"), ctx->device_name);
3541 if (ctx->options & E2F_OPT_READONLY) {
3542 printf(_("%s: won't do journal recovery while read-only\n"),
3544 return EXT2_ET_FILE_RO;
3547 if (ctx->fs->flags & EXT2_FLAG_DIRTY)
3548 ext2fs_flush(ctx->fs); /* Force out any modifications */
3550 recover_retval = recover_ext3_journal(ctx);
3553 * Reload the filesystem context to get up-to-date data from disk
3554 * because journal recovery will change the filesystem under us.
3556 ext2fs_close(ctx->fs);
3557 retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW,
3558 ctx->superblock, blocksize, io_ptr,
3562 com_err(ctx->program_name, retval,
3563 _("while trying to re-open %s"),
3565 fatal_error(ctx, 0);
3567 ctx->fs->priv_data = ctx;
3569 /* Set the superblock flags */
3570 e2fsck_clear_recover(ctx, recover_retval);
3571 return recover_retval;
3575 * This function will move the journal inode from a visible file in
3576 * the filesystem directory hierarchy to the reserved inode if necessary.
3578 static const char * const journal_names[] = {
3579 ".journal", "journal", ".journal.dat", "journal.dat", 0 };
3581 static void e2fsck_move_ext3_journal(e2fsck_t ctx)
3583 struct ext2_super_block *sb = ctx->fs->super;
3584 struct problem_context pctx;
3585 struct ext2_inode inode;
3586 ext2_filsys fs = ctx->fs;
3589 const char * const * cpp;
3590 int group, mount_flags;
3592 clear_problem_context(&pctx);
3595 * If the filesystem is opened read-only, or there is no
3596 * journal, then do nothing.
3598 if ((ctx->options & E2F_OPT_READONLY) ||
3599 (sb->s_journal_inum == 0) ||
3600 !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL))
3604 * Read in the journal inode
3606 if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0)
3610 * If it's necessary to backup the journal inode, do so.
3612 if ((sb->s_jnl_backup_type == 0) ||
3613 ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) &&
3614 memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) {
3615 if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) {
3616 memcpy(sb->s_jnl_blocks, inode.i_block,
3618 sb->s_jnl_blocks[16] = inode.i_size;
3619 sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
3620 ext2fs_mark_super_dirty(fs);
3621 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3626 * If the journal is already the hidden inode, then do nothing
3628 if (sb->s_journal_inum == EXT2_JOURNAL_INO)
3632 * The journal inode had better have only one link and not be readable.
3634 if (inode.i_links_count != 1)
3638 * If the filesystem is mounted, or we can't tell whether
3639 * or not it's mounted, do nothing.
3641 retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags);
3642 if (retval || (mount_flags & EXT2_MF_MOUNTED))
3646 * If we can't find the name of the journal inode, then do
3649 for (cpp = journal_names; *cpp; cpp++) {
3650 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp,
3651 strlen(*cpp), 0, &ino);
3652 if ((retval == 0) && (ino == sb->s_journal_inum))
3658 /* We need the inode bitmap to be loaded */
3659 retval = ext2fs_read_bitmaps(fs);
3664 if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx))
3668 * OK, we've done all the checks, let's actually move the
3669 * journal inode. Errors at this point mean we need to force
3670 * an ext2 filesystem check.
3672 if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0)
3674 if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0)
3676 sb->s_journal_inum = EXT2_JOURNAL_INO;
3677 ext2fs_mark_super_dirty(fs);
3678 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
3679 inode.i_links_count = 0;
3680 inode.i_dtime = time(0);
3681 if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0)
3684 group = ext2fs_group_of_ino(fs, ino);
3685 ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
3686 ext2fs_mark_ib_dirty(fs);
3687 fs->group_desc[group].bg_free_inodes_count++;
3688 fs->super->s_free_inodes_count++;
3692 pctx.errcode = retval;
3693 fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx);
3694 fs->super->s_state &= ~EXT2_VALID_FS;
3695 ext2fs_mark_super_dirty(fs);
3700 * message.c --- print e2fsck messages (with compression)
3702 * print_e2fsck_message() prints a message to the user, using
3703 * compression techniques and expansions of abbreviations.
3705 * The following % expansions are supported:
3707 * %b <blk> block number
3708 * %B <blkcount> integer
3709 * %c <blk2> block number
3710 * %Di <dirent>->ino inode number
3711 * %Dn <dirent>->name string
3712 * %Dr <dirent>->rec_len
3713 * %Dl <dirent>->name_len
3714 * %Dt <dirent>->filetype
3715 * %d <dir> inode number
3716 * %g <group> integer
3717 * %i <ino> inode number
3718 * %Is <inode> -> i_size
3719 * %IS <inode> -> i_extra_isize
3720 * %Ib <inode> -> i_blocks
3721 * %Il <inode> -> i_links_count
3722 * %Im <inode> -> i_mode
3723 * %IM <inode> -> i_mtime
3724 * %IF <inode> -> i_faddr
3725 * %If <inode> -> i_file_acl
3726 * %Id <inode> -> i_dir_acl
3727 * %Iu <inode> -> i_uid
3728 * %Ig <inode> -> i_gid
3729 * %j <ino2> inode number
3730 * %m <com_err error message>
3732 * %p ext2fs_get_pathname of directory <ino>
3733 * %P ext2fs_get_pathname of <dirent>->ino with <ino2> as
3734 * the containing directory. (If dirent is NULL
3735 * then return the pathname of directory <ino2>)
3736 * %q ext2fs_get_pathname of directory <dir>
3737 * %Q ext2fs_get_pathname of directory <ino> with <dir> as
3738 * the containing directory.
3739 * %s <str> miscellaneous string
3740 * %S backup superblock
3741 * %X <num> hexadecimal format
3743 * The following '@' expansions are supported:
3745 * @a extended attribute
3746 * @A error allocating
3750 * @C conflicts with some other fs block
3754 * @E Entry '%Dn' in %p (%i)
3756 * @F for @i %i (%Q) is
3758 * @h HTREE directory inode
3776 * This structure defines the abbreviations used by the text strings
3777 * below. The first character in the string is the index letter. An
3778 * abbreviation of the form '@<i>' is expanded by looking up the index
3779 * letter <i> in the table below.
3781 static const char * const abbrevs[] = {
3782 N_("aextended attribute"),
3783 N_("Aerror allocating"),
3787 N_("Cconflicts with some other fs @b"),
3794 N_("E@e '%Dn' in %p (%i)"),
3796 N_("Ffor @i %i (%Q) is"),
3814 * Give more user friendly names to the "special" inodes.
3816 #define num_special_inodes 11
3817 static const char * const special_inode_name[] =
3819 N_("<The NULL inode>"), /* 0 */
3820 N_("<The bad blocks inode>"), /* 1 */
3822 N_("<The ACL index inode>"), /* 3 */
3823 N_("<The ACL data inode>"), /* 4 */
3824 N_("<The boot loader inode>"), /* 5 */
3825 N_("<The undelete directory inode>"), /* 6 */
3826 N_("<The group descriptor inode>"), /* 7 */
3827 N_("<The journal inode>"), /* 8 */
3828 N_("<Reserved inode 9>"), /* 9 */
3829 N_("<Reserved inode 10>"), /* 10 */
3833 * This function does "safe" printing. It will convert non-printable
3834 * ASCII characters using '^' and M- notation.
3836 static void safe_print(const char *cp, int len)
3846 fputs("M-", stdout);
3849 if ((ch < 32) || (ch == 0x7f)) {
3851 ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */
3859 * This function prints a pathname, using the ext2fs_get_pathname
3862 static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino)
3867 if (!dir && (ino < num_special_inodes)) {
3868 fputs(_(special_inode_name[ino]), stdout);
3872 retval = ext2fs_get_pathname(fs, dir, ino, &path);
3874 fputs("???", stdout);
3876 safe_print(path, -1);
3877 ext2fs_free_mem(&path);
3881 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
3882 struct problem_context *pctx, int first);
3884 * This function handles the '@' expansion. We allow recursive
3885 * expansion; an @ expression can contain further '@' and '%'
3888 static void expand_at_expression(e2fsck_t ctx, char ch,
3889 struct problem_context *pctx,
3892 const char * const *cpp;
3895 /* Search for the abbreviation */
3896 for (cpp = abbrevs; *cpp; cpp++) {
3902 if (*first && islower(*str)) {
3904 fputc(toupper(*str++), stdout);
3906 print_e2fsck_message(ctx, str, pctx, *first);
3912 * This function expands '%IX' expressions
3914 static void expand_inode_expression(char ch,
3915 struct problem_context *ctx)
3917 struct ext2_inode *inode;
3918 struct ext2_inode_large *large_inode;
3923 if (!ctx || !ctx->inode)
3927 large_inode = (struct ext2_inode_large *) inode;
3931 if (LINUX_S_ISDIR(inode->i_mode))
3932 printf("%u", inode->i_size);
3934 #ifdef EXT2_NO_64_TYPE
3935 if (inode->i_size_high)
3936 printf("0x%x%08x", inode->i_size_high,
3939 printf("%u", inode->i_size);
3941 printf("%llu", (inode->i_size |
3942 ((__u64) inode->i_size_high << 32)));
3947 printf("%u", large_inode->i_extra_isize);
3950 printf("%u", inode->i_blocks);
3953 printf("%d", inode->i_links_count);
3956 printf("0%o", inode->i_mode);
3959 /* The diet libc doesn't respect the TZ environemnt variable */
3961 time_str = getenv("TZ");
3964 do_gmt = !strcmp(time_str, "GMT");
3967 time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
3968 printf("%.24s", time_str);
3971 printf("%u", inode->i_faddr);
3974 printf("%u", inode->i_file_acl);
3977 printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
3978 inode->i_dir_acl : 0));
3981 printf("%d", (inode->i_uid |
3982 (inode->osd2.linux2.l_i_uid_high << 16)));
3985 printf("%d", (inode->i_gid |
3986 (inode->osd2.linux2.l_i_gid_high << 16)));
3990 printf("%%I%c", ch);
3996 * This function expands '%dX' expressions
3998 static _INLINE_ void expand_dirent_expression(char ch,
3999 struct problem_context *ctx)
4001 struct ext2_dir_entry *dirent;
4004 if (!ctx || !ctx->dirent)
4007 dirent = ctx->dirent;
4011 printf("%u", dirent->inode);
4014 len = dirent->name_len & 0xFF;
4015 if (len > EXT2_NAME_LEN)
4016 len = EXT2_NAME_LEN;
4017 if (len > dirent->rec_len)
4018 len = dirent->rec_len;
4019 safe_print(dirent->name, len);
4022 printf("%u", dirent->rec_len);
4025 printf("%u", dirent->name_len & 0xFF);
4028 printf("%u", dirent->name_len >> 8);
4032 printf("%%D%c", ch);
4037 static _INLINE_ void expand_percent_expression(ext2_filsys fs, char ch,
4038 struct problem_context *ctx)
4048 printf("%u", ctx->blk);
4051 #ifdef EXT2_NO_64_TYPE
4052 printf("%d", ctx->blkcount);
4054 printf("%lld", ctx->blkcount);
4058 printf("%u", ctx->blk2);
4061 printf("%u", ctx->dir);
4064 printf("%d", ctx->group);
4067 printf("%u", ctx->ino);
4070 printf("%u", ctx->ino2);
4073 printf("%s", error_message(ctx->errcode));
4076 #ifdef EXT2_NO_64_TYPE
4077 printf("%u", ctx->num);
4079 printf("%llu", ctx->num);
4083 print_pathname(fs, ctx->ino, 0);
4086 print_pathname(fs, ctx->ino2,
4087 ctx->dirent ? ctx->dirent->inode : 0);
4090 print_pathname(fs, ctx->dir, 0);
4093 print_pathname(fs, ctx->dir, ctx->ino);
4096 printf("%d", get_backup_sb(NULL, fs, NULL, NULL));
4099 printf("%s", ctx->str ? ctx->str : "NULL");
4102 #ifdef EXT2_NO_64_TYPE
4103 printf("0x%x", ctx->num);
4105 printf("0x%llx", ctx->num);
4116 static void print_e2fsck_message(e2fsck_t ctx, const char *msg,
4117 struct problem_context *pctx, int first)
4119 ext2_filsys fs = ctx->fs;
4123 e2fsck_clear_progbar(ctx);
4124 for (cp = msg; *cp; cp++) {
4127 expand_at_expression(ctx, *cp, pctx, &first);
4128 } else if (cp[0] == '%' && cp[1] == 'I') {
4130 expand_inode_expression(*cp, pctx);
4131 } else if (cp[0] == '%' && cp[1] == 'D') {
4133 expand_dirent_expression(*cp, pctx);
4134 } else if ((cp[0] == '%')) {
4136 expand_percent_expression(fs, *cp, pctx);
4138 for (i=0; cp[i]; i++)
4139 if ((cp[i] == '@') || cp[i] == '%')
4141 printf("%.*s", i, cp);
4150 * region.c --- code which manages allocations within a region.
4154 region_addr_t start;
4156 struct region_el *next;
4159 struct region_struct {
4162 struct region_el *allocated;
4165 static region_t region_create(region_addr_t min, region_addr_t max)
4169 region = malloc(sizeof(struct region_struct));
4172 memset(region, 0, sizeof(struct region_struct));
4178 static void region_free(region_t region)
4180 struct region_el *r, *next;
4182 for (r = region->allocated; r; r = next) {
4186 memset(region, 0, sizeof(struct region_struct));
4190 static int region_allocate(region_t region, region_addr_t start, int n)
4192 struct region_el *r, *new_region, *prev, *next;
4196 if ((start < region->min) || (end > region->max))
4202 * Search through the linked list. If we find that it
4203 * conflicts witih something that's already allocated, return
4204 * 1; if we can find an existing region which we can grow, do
4205 * so. Otherwise, stop when we find the appropriate place
4206 * insert a new region element into the linked list.
4208 for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) {
4209 if (((start >= r->start) && (start < r->end)) ||
4210 ((end > r->start) && (end <= r->end)) ||
4211 ((start <= r->start) && (end >= r->end)))
4213 if (end == r->start) {
4217 if (start == r->end) {
4218 if ((next = r->next)) {
4219 if (end > next->start)
4221 if (end == next->start) {
4223 r->next = next->next;
4231 if (start < r->start)
4235 * Insert a new region element structure into the linked list
4237 new_region = malloc(sizeof(struct region_el));
4240 new_region->start = start;
4241 new_region->end = start + n;
4242 new_region->next = r;
4244 prev->next = new_region;
4246 region->allocated = new_region;
4251 * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table
4253 * Pass 1 of e2fsck iterates over all the inodes in the filesystems,
4254 * and applies the following tests to each inode:
4256 * - The mode field of the inode must be legal.
4257 * - The size and block count fields of the inode are correct.
4258 * - A data block must not be used by another inode
4260 * Pass 1 also gathers the collects the following information:
4262 * - A bitmap of which inodes are in use. (inode_used_map)
4263 * - A bitmap of which inodes are directories. (inode_dir_map)
4264 * - A bitmap of which inodes are regular files. (inode_reg_map)
4265 * - A bitmap of which inodes have bad fields. (inode_bad_map)
4266 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
4267 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
4268 * - A bitmap of which blocks are in use. (block_found_map)
4269 * - A bitmap of which blocks are in use by two inodes (block_dup_map)
4270 * - The data blocks of the directory inodes. (dir_map)
4272 * Pass 1 is designed to stash away enough information so that the
4273 * other passes should not need to read in the inode information
4274 * during the normal course of a filesystem check. (Althogh if an
4275 * inconsistency is detected, other passes may need to read in an
4278 * Note that pass 1B will be invoked if there are any duplicate blocks
4283 static int process_block(ext2_filsys fs, blk_t *blocknr,
4284 e2_blkcnt_t blockcnt, blk_t ref_blk,
4285 int ref_offset, void *priv_data);
4286 static int process_bad_block(ext2_filsys fs, blk_t *block_nr,
4287 e2_blkcnt_t blockcnt, blk_t ref_blk,
4288 int ref_offset, void *priv_data);
4289 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
4291 static void mark_table_blocks(e2fsck_t ctx);
4292 static void alloc_bb_map(e2fsck_t ctx);
4293 static void alloc_imagic_map(e2fsck_t ctx);
4294 static void mark_inode_bad(e2fsck_t ctx, ino_t ino);
4295 static void handle_fs_bad_blocks(e2fsck_t ctx);
4296 static void process_inodes(e2fsck_t ctx, char *block_buf);
4297 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b);
4298 static errcode_t scan_callback(ext2_filsys fs, ext2_inode_scan scan,
4299 dgrp_t group, void * priv_data);
4300 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
4301 char *block_buf, int adjust_sign);
4302 /* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */
4304 static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
4305 struct ext2_inode * inode, int bufsize,
4308 struct process_block_struct_1 {
4310 unsigned is_dir:1, is_reg:1, clear:1, suppress:1,
4311 fragmented:1, compressed:1, bbcheck:1;
4314 e2_blkcnt_t last_block;
4315 int num_illegal_blocks;
4316 blk_t previous_block;
4317 struct ext2_inode *inode;
4318 struct problem_context *pctx;
4319 ext2fs_block_bitmap fs_meta_blocks;
4323 struct process_inode_block {
4325 struct ext2_inode inode;
4328 struct scan_callback_struct {
4334 * For the inodes to process list.
4336 static struct process_inode_block *inodes_to_process;
4337 static int process_inode_count;
4339 static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE -
4340 EXT2_MIN_BLOCK_LOG_SIZE + 1];
4343 * Free all memory allocated by pass1 in preparation for restarting
4346 static void unwind_pass1(void)
4348 ext2fs_free_mem(&inodes_to_process);
4349 inodes_to_process = 0;
4353 * Check to make sure a device inode is real. Returns 1 if the device
4354 * checks out, 0 if not.
4356 * Note: this routine is now also used to check FIFO's and Sockets,
4357 * since they have the same requirement; the i_block fields should be
4361 e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode)
4366 * If i_blocks is non-zero, or the index flag is set, then
4367 * this is a bogus device/fifo/socket
4369 if ((ext2fs_inode_data_blocks(fs, inode) != 0) ||
4370 (inode->i_flags & EXT2_INDEX_FL))
4374 * We should be able to do the test below all the time, but
4375 * because the kernel doesn't forcibly clear the device
4376 * inode's additional i_block fields, there are some rare
4377 * occasions when a legitimate device inode will have non-zero
4378 * additional i_block fields. So for now, we only complain
4379 * when the immutable flag is set, which should never happen
4380 * for devices. (And that's when the problem is caused, since
4381 * you can't set or clear immutable flags for devices.) Once
4382 * the kernel has been fixed we can change this...
4384 if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) {
4385 for (i=4; i < EXT2_N_BLOCKS; i++)
4386 if (inode->i_block[i])
4393 * Check to make sure a symlink inode is real. Returns 1 if the symlink
4394 * checks out, 0 if not.
4397 e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf)
4403 if ((inode->i_size_high || inode->i_size == 0) ||
4404 (inode->i_flags & EXT2_INDEX_FL))
4407 blocks = ext2fs_inode_data_blocks(fs, inode);
4409 if ((inode->i_size >= fs->blocksize) ||
4410 (blocks != fs->blocksize >> 9) ||
4411 (inode->i_block[0] < fs->super->s_first_data_block) ||
4412 (inode->i_block[0] >= fs->super->s_blocks_count))
4415 for (i = 1; i < EXT2_N_BLOCKS; i++)
4416 if (inode->i_block[i])
4419 if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf))
4422 len = strnlen(buf, fs->blocksize);
4423 if (len == fs->blocksize)
4426 if (inode->i_size >= sizeof(inode->i_block))
4429 len = strnlen((char *)inode->i_block, sizeof(inode->i_block));
4430 if (len == sizeof(inode->i_block))
4433 if (len != inode->i_size)
4439 * If the immutable (or append-only) flag is set on the inode, offer
4442 #define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)
4443 static void check_immutable(e2fsck_t ctx, struct problem_context *pctx)
4445 if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS))
4448 if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx))
4451 pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS;
4452 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4456 * If device, fifo or socket, check size is zero -- if not offer to
4459 static void check_size(e2fsck_t ctx, struct problem_context *pctx)
4461 struct ext2_inode *inode = pctx->inode;
4463 if ((inode->i_size == 0) && (inode->i_size_high == 0))
4466 if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx))
4470 inode->i_size_high = 0;
4471 e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1");
4474 static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx)
4476 struct ext2_super_block *sb = ctx->fs->super;
4477 struct ext2_inode_large *inode;
4478 struct ext2_ext_attr_entry *entry;
4480 int storage_size, remain, offs;
4483 inode = (struct ext2_inode_large *) pctx->inode;
4484 storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
4485 inode->i_extra_isize;
4486 start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4487 inode->i_extra_isize + sizeof(__u32);
4488 end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super);
4489 entry = (struct ext2_ext_attr_entry *) start;
4491 /* scan all entry's headers first */
4493 /* take finish entry 0UL into account */
4494 remain = storage_size - sizeof(__u32);
4497 while (!EXT2_EXT_IS_LAST_ENTRY(entry)) {
4499 /* header eats this space */
4500 remain -= sizeof(struct ext2_ext_attr_entry);
4502 /* is attribute name valid? */
4503 if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) {
4504 pctx->num = entry->e_name_len;
4505 problem = PR_1_ATTR_NAME_LEN;
4509 /* attribute len eats this space */
4510 remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len);
4512 /* check value size */
4513 if (entry->e_value_size == 0 || entry->e_value_size > remain) {
4514 pctx->num = entry->e_value_size;
4515 problem = PR_1_ATTR_VALUE_SIZE;
4519 /* check value placement */
4520 if (entry->e_value_offs +
4521 EXT2_XATTR_SIZE(entry->e_value_size) != offs) {
4522 printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs);
4523 pctx->num = entry->e_value_offs;
4524 problem = PR_1_ATTR_VALUE_OFFSET;
4528 /* e_value_block must be 0 in inode's ea */
4529 if (entry->e_value_block != 0) {
4530 pctx->num = entry->e_value_block;
4531 problem = PR_1_ATTR_VALUE_BLOCK;
4535 /* e_hash must be 0 in inode's ea */
4536 if (entry->e_hash != 0) {
4537 pctx->num = entry->e_hash;
4538 problem = PR_1_ATTR_HASH;
4542 remain -= entry->e_value_size;
4543 offs -= EXT2_XATTR_SIZE(entry->e_value_size);
4545 entry = EXT2_EXT_ATTR_NEXT(entry);
4549 * it seems like a corruption. it's very unlikely we could repair
4550 * EA(s) in automatic fashion -bzzz
4553 problem = PR_1_ATTR_HASH;
4555 if (problem == 0 || !fix_problem(ctx, problem, pctx))
4558 /* simple remove all possible EA(s) */
4559 *((__u32 *)start) = 0UL;
4560 e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode,
4561 EXT2_INODE_SIZE(sb), "pass1");
4564 static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx)
4566 struct ext2_super_block *sb = ctx->fs->super;
4567 struct ext2_inode_large *inode;
4571 inode = (struct ext2_inode_large *) pctx->inode;
4572 if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) {
4573 /* this isn't large inode. so, nothing to check */
4578 printf("inode #%u, i_extra_size %d\n", pctx->ino,
4579 inode->i_extra_isize);
4581 /* i_extra_isize must cover i_extra_isize + i_pad1 at least */
4582 min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1);
4583 max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE;
4585 * For now we will allow i_extra_isize to be 0, but really
4586 * implementations should never allow i_extra_isize to be 0
4588 if (inode->i_extra_isize &&
4589 (inode->i_extra_isize < min || inode->i_extra_isize > max)) {
4590 if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx))
4592 inode->i_extra_isize = min;
4593 e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode,
4594 EXT2_INODE_SIZE(sb), "pass1");
4598 eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
4599 inode->i_extra_isize);
4600 if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
4601 /* it seems inode has an extended attribute(s) in body */
4602 check_ea_in_inode(ctx, pctx);
4606 static void e2fsck_pass1(e2fsck_t ctx)
4610 ext2_filsys fs = ctx->fs;
4612 struct ext2_inode *inode;
4613 ext2_inode_scan scan;
4615 #ifdef RESOURCE_TRACK
4616 struct resource_track rtrack;
4618 unsigned char frag, fsize;
4619 struct problem_context pctx;
4620 struct scan_callback_struct scan_struct;
4621 struct ext2_super_block *sb = ctx->fs->super;
4623 int busted_fs_time = 0;
4626 #ifdef RESOURCE_TRACK
4627 init_resource_track(&rtrack);
4629 clear_problem_context(&pctx);
4631 if (!(ctx->options & E2F_OPT_PREEN))
4632 fix_problem(ctx, PR_1_PASS_HEADER, &pctx);
4634 if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
4635 !(ctx->options & E2F_OPT_NO)) {
4636 if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50))
4637 ctx->dirs_to_hash = 0;
4641 mtrace_print("Pass 1");
4644 #define EXT2_BPP(bits) (1ULL << ((bits) - 2))
4646 for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) {
4647 max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i);
4648 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i);
4649 max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i);
4650 max_sizes = (max_sizes * (1UL << i)) - 1;
4651 ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes;
4655 imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES);
4658 * Allocate bitmaps structures
4660 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"),
4661 &ctx->inode_used_map);
4664 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4665 ctx->flags |= E2F_FLAG_ABORT;
4668 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4669 _("directory inode map"), &ctx->inode_dir_map);
4672 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4673 ctx->flags |= E2F_FLAG_ABORT;
4676 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
4677 _("regular file inode map"), &ctx->inode_reg_map);
4680 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
4681 ctx->flags |= E2F_FLAG_ABORT;
4684 pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"),
4685 &ctx->block_found_map);
4688 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4689 ctx->flags |= E2F_FLAG_ABORT;
4692 pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0,
4693 &ctx->inode_link_info);
4695 fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx);
4696 ctx->flags |= E2F_FLAG_ABORT;
4699 inode_size = EXT2_INODE_SIZE(fs->super);
4700 inode = (struct ext2_inode *)
4701 e2fsck_allocate_memory(ctx, inode_size, "scratch inode");
4703 inodes_to_process = (struct process_inode_block *)
4704 e2fsck_allocate_memory(ctx,
4705 (ctx->process_inode_size *
4706 sizeof(struct process_inode_block)),
4707 "array of inodes to process");
4708 process_inode_count = 0;
4710 pctx.errcode = ext2fs_init_dblist(fs, 0);
4712 fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
4713 ctx->flags |= E2F_FLAG_ABORT;
4718 * If the last orphan field is set, clear it, since the pass1
4719 * processing will automatically find and clear the orphans.
4720 * In the future, we may want to try using the last_orphan
4721 * linked list ourselves, but for now, we clear it so that the
4722 * ext3 mount code won't get confused.
4724 if (!(ctx->options & E2F_OPT_READONLY)) {
4725 if (fs->super->s_last_orphan) {
4726 fs->super->s_last_orphan = 0;
4727 ext2fs_mark_super_dirty(fs);
4731 mark_table_blocks(ctx);
4732 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
4733 "block interate buffer");
4734 e2fsck_use_inode_shortcuts(ctx, 1);
4735 ehandler_operation(_("doing inode scan"));
4736 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
4739 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4740 ctx->flags |= E2F_FLAG_ABORT;
4743 ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
4744 ctx->stashed_inode = inode;
4745 scan_struct.ctx = ctx;
4746 scan_struct.block_buf = block_buf;
4747 ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
4749 if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
4751 if (fs->super->s_wtime < fs->super->s_inodes_count)
4755 pctx.errcode = ext2fs_get_next_inode_full(scan, &ino,
4757 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
4759 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) {
4760 if (!ctx->inode_bb_map)
4762 ext2fs_mark_inode_bitmap(ctx->inode_bb_map, ino);
4763 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4767 fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
4768 ctx->flags |= E2F_FLAG_ABORT;
4775 ctx->stashed_ino = ino;
4776 if (inode->i_links_count) {
4777 pctx.errcode = ext2fs_icount_store(ctx->inode_link_info,
4778 ino, inode->i_links_count);
4780 pctx.num = inode->i_links_count;
4781 fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
4782 ctx->flags |= E2F_FLAG_ABORT;
4786 if (ino == EXT2_BAD_INO) {
4787 struct process_block_struct_1 pb;
4789 pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map,
4790 &pb.fs_meta_blocks);
4793 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
4794 ctx->flags |= E2F_FLAG_ABORT;
4797 pb.ino = EXT2_BAD_INO;
4798 pb.num_blocks = pb.last_block = 0;
4799 pb.num_illegal_blocks = 0;
4800 pb.suppress = 0; pb.clear = 0; pb.is_dir = 0;
4801 pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0;
4805 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0,
4806 block_buf, process_bad_block, &pb);
4807 ext2fs_free_block_bitmap(pb.fs_meta_blocks);
4809 fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
4810 ctx->flags |= E2F_FLAG_ABORT;
4814 if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
4815 ctx->flags |= E2F_FLAG_ABORT;
4818 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4819 clear_problem_context(&pctx);
4821 } else if (ino == EXT2_ROOT_INO) {
4823 * Make sure the root inode is a directory; if
4824 * not, offer to clear it. It will be
4825 * regnerated in pass #3.
4827 if (!LINUX_S_ISDIR(inode->i_mode)) {
4828 if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) {
4829 inode->i_dtime = time(0);
4830 inode->i_links_count = 0;
4831 ext2fs_icount_store(ctx->inode_link_info,
4833 e2fsck_write_inode(ctx, ino, inode,
4839 * If dtime is set, offer to clear it. mke2fs
4840 * version 0.2b created filesystems with the
4841 * dtime field set for the root and lost+found
4842 * directories. We won't worry about
4843 * /lost+found, since that can be regenerated
4844 * easily. But we will fix the root directory
4845 * as a special case.
4847 if (inode->i_dtime && inode->i_links_count) {
4848 if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) {
4850 e2fsck_write_inode(ctx, ino, inode,
4854 } else if (ino == EXT2_JOURNAL_INO) {
4855 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4856 if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) {
4857 if (!LINUX_S_ISREG(inode->i_mode) &&
4858 fix_problem(ctx, PR_1_JOURNAL_BAD_MODE,
4860 inode->i_mode = LINUX_S_IFREG;
4861 e2fsck_write_inode(ctx, ino, inode,
4864 check_blocks(ctx, &pctx, block_buf);
4867 if ((inode->i_links_count || inode->i_blocks ||
4868 inode->i_blocks || inode->i_block[0]) &&
4869 fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR,
4871 memset(inode, 0, inode_size);
4872 ext2fs_icount_store(ctx->inode_link_info,
4874 e2fsck_write_inode_full(ctx, ino, inode,
4875 inode_size, "pass1");
4877 } else if (ino < EXT2_FIRST_INODE(fs->super)) {
4880 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4881 if (ino == EXT2_BOOT_LOADER_INO) {
4882 if (LINUX_S_ISDIR(inode->i_mode))
4883 problem = PR_1_RESERVED_BAD_MODE;
4884 } else if (ino == EXT2_RESIZE_INO) {
4885 if (inode->i_mode &&
4886 !LINUX_S_ISREG(inode->i_mode))
4887 problem = PR_1_RESERVED_BAD_MODE;
4889 if (inode->i_mode != 0)
4890 problem = PR_1_RESERVED_BAD_MODE;
4893 if (fix_problem(ctx, problem, &pctx)) {
4895 e2fsck_write_inode(ctx, ino, inode,
4899 check_blocks(ctx, &pctx, block_buf);
4903 * Check for inodes who might have been part of the
4904 * orphaned list linked list. They should have gotten
4905 * dealt with by now, unless the list had somehow been
4908 * FIXME: In the future, inodes which are still in use
4909 * (and which are therefore) pending truncation should
4910 * be handled specially. Right now we just clear the
4911 * dtime field, and the normal e2fsck handling of
4912 * inodes where i_size and the inode blocks are
4913 * inconsistent is to fix i_size, instead of releasing
4914 * the extra blocks. This won't catch the inodes that
4915 * was at the end of the orphan list, but it's better
4916 * than nothing. The right answer is that there
4917 * shouldn't be any bugs in the orphan list handling. :-)
4919 if (inode->i_dtime && !busted_fs_time &&
4920 inode->i_dtime < ctx->fs->super->s_inodes_count) {
4921 if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) {
4922 inode->i_dtime = inode->i_links_count ?
4924 e2fsck_write_inode(ctx, ino, inode,
4930 * This code assumes that deleted inodes have
4931 * i_links_count set to 0.
4933 if (!inode->i_links_count) {
4934 if (!inode->i_dtime && inode->i_mode) {
4935 if (fix_problem(ctx,
4936 PR_1_ZERO_DTIME, &pctx)) {
4937 inode->i_dtime = time(0);
4938 e2fsck_write_inode(ctx, ino, inode,
4945 * n.b. 0.3c ext2fs code didn't clear i_links_count for
4946 * deleted files. Oops.
4948 * Since all new ext2 implementations get this right,
4949 * we now assume that the case of non-zero
4950 * i_links_count and non-zero dtime means that we
4951 * should keep the file, not delete it.
4954 if (inode->i_dtime) {
4955 if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) {
4957 e2fsck_write_inode(ctx, ino, inode, "pass1");
4961 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
4962 switch (fs->super->s_creator_os) {
4964 frag = inode->osd2.linux2.l_i_frag;
4965 fsize = inode->osd2.linux2.l_i_fsize;
4968 frag = inode->osd2.hurd2.h_i_frag;
4969 fsize = inode->osd2.hurd2.h_i_fsize;
4972 frag = inode->osd2.masix2.m_i_frag;
4973 fsize = inode->osd2.masix2.m_i_fsize;
4979 if (inode->i_faddr || frag || fsize ||
4980 (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
4981 mark_inode_bad(ctx, ino);
4982 if (inode->i_flags & EXT2_IMAGIC_FL) {
4984 if (!ctx->inode_imagic_map)
4985 alloc_imagic_map(ctx);
4986 ext2fs_mark_inode_bitmap(ctx->inode_imagic_map,
4989 if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) {
4990 inode->i_flags &= ~EXT2_IMAGIC_FL;
4991 e2fsck_write_inode(ctx, ino,
4997 check_inode_extra_space(ctx, &pctx);
4999 if (LINUX_S_ISDIR(inode->i_mode)) {
5000 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
5001 e2fsck_add_dir_info(ctx, ino, 0);
5002 ctx->fs_directory_count++;
5003 } else if (LINUX_S_ISREG (inode->i_mode)) {
5004 ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino);
5005 ctx->fs_regular_count++;
5006 } else if (LINUX_S_ISCHR (inode->i_mode) &&
5007 e2fsck_pass1_check_device_inode(fs, inode)) {
5008 check_immutable(ctx, &pctx);
5009 check_size(ctx, &pctx);
5010 ctx->fs_chardev_count++;
5011 } else if (LINUX_S_ISBLK (inode->i_mode) &&
5012 e2fsck_pass1_check_device_inode(fs, inode)) {
5013 check_immutable(ctx, &pctx);
5014 check_size(ctx, &pctx);
5015 ctx->fs_blockdev_count++;
5016 } else if (LINUX_S_ISLNK (inode->i_mode) &&
5017 e2fsck_pass1_check_symlink(fs, inode, block_buf)) {
5018 check_immutable(ctx, &pctx);
5019 ctx->fs_symlinks_count++;
5020 if (ext2fs_inode_data_blocks(fs, inode) == 0) {
5021 ctx->fs_fast_symlinks_count++;
5022 check_blocks(ctx, &pctx, block_buf);
5026 else if (LINUX_S_ISFIFO (inode->i_mode) &&
5027 e2fsck_pass1_check_device_inode(fs, inode)) {
5028 check_immutable(ctx, &pctx);
5029 check_size(ctx, &pctx);
5030 ctx->fs_fifo_count++;
5031 } else if ((LINUX_S_ISSOCK (inode->i_mode)) &&
5032 e2fsck_pass1_check_device_inode(fs, inode)) {
5033 check_immutable(ctx, &pctx);
5034 check_size(ctx, &pctx);
5035 ctx->fs_sockets_count++;
5037 mark_inode_bad(ctx, ino);
5038 if (inode->i_block[EXT2_IND_BLOCK])
5039 ctx->fs_ind_count++;
5040 if (inode->i_block[EXT2_DIND_BLOCK])
5041 ctx->fs_dind_count++;
5042 if (inode->i_block[EXT2_TIND_BLOCK])
5043 ctx->fs_tind_count++;
5044 if (inode->i_block[EXT2_IND_BLOCK] ||
5045 inode->i_block[EXT2_DIND_BLOCK] ||
5046 inode->i_block[EXT2_TIND_BLOCK] ||
5047 inode->i_file_acl) {
5048 inodes_to_process[process_inode_count].ino = ino;
5049 inodes_to_process[process_inode_count].inode = *inode;
5050 process_inode_count++;
5052 check_blocks(ctx, &pctx, block_buf);
5054 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5057 if (process_inode_count >= ctx->process_inode_size) {
5058 process_inodes(ctx, block_buf);
5060 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5064 process_inodes(ctx, block_buf);
5065 ext2fs_close_inode_scan(scan);
5066 ehandler_operation(0);
5069 * If any extended attribute blocks' reference counts need to
5070 * be adjusted, either up (ctx->refcount_extra), or down
5071 * (ctx->refcount), then fix them.
5073 if (ctx->refcount) {
5074 adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1);
5075 ea_refcount_free(ctx->refcount);
5078 if (ctx->refcount_extra) {
5079 adjust_extattr_refcount(ctx, ctx->refcount_extra,
5081 ea_refcount_free(ctx->refcount_extra);
5082 ctx->refcount_extra = 0;
5085 if (ctx->invalid_bitmaps)
5086 handle_fs_bad_blocks(ctx);
5088 /* We don't need the block_ea_map any more */
5089 if (ctx->block_ea_map) {
5090 ext2fs_free_block_bitmap(ctx->block_ea_map);
5091 ctx->block_ea_map = 0;
5094 if (ctx->flags & E2F_FLAG_RESIZE_INODE) {
5095 ext2fs_block_bitmap save_bmap;
5097 save_bmap = fs->block_map;
5098 fs->block_map = ctx->block_found_map;
5099 clear_problem_context(&pctx);
5100 pctx.errcode = ext2fs_create_resize_inode(fs);
5102 fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx);
5103 /* Should never get here */
5104 ctx->flags |= E2F_FLAG_ABORT;
5107 fs->block_map = save_bmap;
5108 ctx->flags &= ~E2F_FLAG_RESIZE_INODE;
5111 if (ctx->flags & E2F_FLAG_RESTART) {
5113 * Only the master copy of the superblock and block
5114 * group descriptors are going to be written during a
5115 * restart, so set the superblock to be used to be the
5116 * master superblock.
5118 ctx->use_superblock = 0;
5123 if (ctx->block_dup_map) {
5124 if (ctx->options & E2F_OPT_PREEN) {
5125 clear_problem_context(&pctx);
5126 fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx);
5128 e2fsck_pass1_dupblocks(ctx, block_buf);
5130 ext2fs_free_mem(&inodes_to_process);
5132 e2fsck_use_inode_shortcuts(ctx, 0);
5134 ext2fs_free_mem(&block_buf);
5135 ext2fs_free_mem(&inode);
5137 #ifdef RESOURCE_TRACK
5138 if (ctx->options & E2F_OPT_TIME2) {
5139 e2fsck_clear_progbar(ctx);
5140 print_resource_track(_("Pass 1"), &rtrack);
5146 * When the inode_scan routines call this callback at the end of the
5147 * glock group, call process_inodes.
5149 static errcode_t scan_callback(ext2_filsys fs,
5150 ext2_inode_scan scan FSCK_ATTR((unused)),
5151 dgrp_t group, void * priv_data)
5153 struct scan_callback_struct *scan_struct;
5156 scan_struct = (struct scan_callback_struct *) priv_data;
5157 ctx = scan_struct->ctx;
5159 process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf);
5162 if ((ctx->progress)(ctx, 1, group+1,
5163 ctx->fs->group_desc_count))
5164 return EXT2_ET_CANCEL_REQUESTED;
5170 * Process the inodes in the "inodes to process" list.
5172 static void process_inodes(e2fsck_t ctx, char *block_buf)
5175 struct ext2_inode *old_stashed_inode;
5176 ext2_ino_t old_stashed_ino;
5177 const char *old_operation;
5179 struct problem_context pctx;
5182 printf("begin process_inodes: ");
5184 if (process_inode_count == 0)
5186 old_operation = ehandler_operation(0);
5187 old_stashed_inode = ctx->stashed_inode;
5188 old_stashed_ino = ctx->stashed_ino;
5189 qsort(inodes_to_process, process_inode_count,
5190 sizeof(struct process_inode_block), process_inode_cmp);
5191 clear_problem_context(&pctx);
5192 for (i=0; i < process_inode_count; i++) {
5193 pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode;
5194 pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino;
5197 printf("%u ", pctx.ino);
5199 sprintf(buf, _("reading indirect blocks of inode %u"),
5201 ehandler_operation(buf);
5202 check_blocks(ctx, &pctx, block_buf);
5203 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5206 ctx->stashed_inode = old_stashed_inode;
5207 ctx->stashed_ino = old_stashed_ino;
5208 process_inode_count = 0;
5210 printf("end process inodes\n");
5212 ehandler_operation(old_operation);
5215 static EXT2_QSORT_TYPE process_inode_cmp(const void *a, const void *b)
5217 const struct process_inode_block *ib_a =
5218 (const struct process_inode_block *) a;
5219 const struct process_inode_block *ib_b =
5220 (const struct process_inode_block *) b;
5223 ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] -
5224 ib_b->inode.i_block[EXT2_IND_BLOCK]);
5226 ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl;
5231 * Mark an inode as being bad in some what
5233 static void mark_inode_bad(e2fsck_t ctx, ino_t ino)
5235 struct problem_context pctx;
5237 if (!ctx->inode_bad_map) {
5238 clear_problem_context(&pctx);
5240 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5241 _("bad inode map"), &ctx->inode_bad_map);
5244 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5245 /* Should never get here */
5246 ctx->flags |= E2F_FLAG_ABORT;
5250 ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino);
5255 * This procedure will allocate the inode "bb" (badblock) map table
5257 static void alloc_bb_map(e2fsck_t ctx)
5259 struct problem_context pctx;
5261 clear_problem_context(&pctx);
5262 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5263 _("inode in bad block map"),
5264 &ctx->inode_bb_map);
5267 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5268 /* Should never get here */
5269 ctx->flags |= E2F_FLAG_ABORT;
5275 * This procedure will allocate the inode imagic table
5277 static void alloc_imagic_map(e2fsck_t ctx)
5279 struct problem_context pctx;
5281 clear_problem_context(&pctx);
5282 pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs,
5283 _("imagic inode map"),
5284 &ctx->inode_imagic_map);
5287 fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx);
5288 /* Should never get here */
5289 ctx->flags |= E2F_FLAG_ABORT;
5295 * Marks a block as in use, setting the dup_map if it's been set
5296 * already. Called by process_block and process_bad_block.
5298 * WARNING: Assumes checks have already been done to make sure block
5299 * is valid. This is true in both process_block and process_bad_block.
5301 static _INLINE_ void mark_block_used(e2fsck_t ctx, blk_t block)
5303 struct problem_context pctx;
5305 clear_problem_context(&pctx);
5307 if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) {
5308 if (!ctx->block_dup_map) {
5309 pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs,
5310 _("multiply claimed block map"),
5311 &ctx->block_dup_map);
5314 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR,
5316 /* Should never get here */
5317 ctx->flags |= E2F_FLAG_ABORT;
5321 ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block);
5323 ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block);
5328 * Adjust the extended attribute block's reference counts at the end
5329 * of pass 1, either by subtracting out references for EA blocks that
5330 * are still referenced in ctx->refcount, or by adding references for
5331 * EA blocks that had extra references as accounted for in
5332 * ctx->refcount_extra.
5334 static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount,
5335 char *block_buf, int adjust_sign)
5337 struct ext2_ext_attr_header *header;
5338 struct problem_context pctx;
5339 ext2_filsys fs = ctx->fs;
5344 clear_problem_context(&pctx);
5346 ea_refcount_intr_begin(refcount);
5348 if ((blk = ea_refcount_intr_next(refcount, &count)) == 0)
5351 pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
5353 fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx);
5356 header = (struct ext2_ext_attr_header *) block_buf;
5357 pctx.blkcount = header->h_refcount;
5358 should_be = header->h_refcount + adjust_sign * count;
5359 pctx.num = should_be;
5360 if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) {
5361 header->h_refcount = should_be;
5362 pctx.errcode = ext2fs_write_ext_attr(fs, blk,
5365 fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx);
5373 * Handle processing the extended attribute blocks
5375 static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx,
5378 ext2_filsys fs = ctx->fs;
5379 ext2_ino_t ino = pctx->ino;
5380 struct ext2_inode *inode = pctx->inode;
5383 struct ext2_ext_attr_header *header;
5384 struct ext2_ext_attr_entry *entry;
5388 blk = inode->i_file_acl;
5393 * If the Extended attribute flag isn't set, then a non-zero
5394 * file acl means that the inode is corrupted.
5396 * Or if the extended attribute block is an invalid block,
5397 * then the inode is also corrupted.
5399 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) ||
5400 (blk < fs->super->s_first_data_block) ||
5401 (blk >= fs->super->s_blocks_count)) {
5402 mark_inode_bad(ctx, ino);
5406 /* If ea bitmap hasn't been allocated, create it */
5407 if (!ctx->block_ea_map) {
5408 pctx->errcode = ext2fs_allocate_block_bitmap(fs,
5409 _("ext attr block map"),
5410 &ctx->block_ea_map);
5411 if (pctx->errcode) {
5413 fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx);
5414 ctx->flags |= E2F_FLAG_ABORT;
5419 /* Create the EA refcount structure if necessary */
5420 if (!ctx->refcount) {
5421 pctx->errcode = ea_refcount_create(0, &ctx->refcount);
5422 if (pctx->errcode) {
5424 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5425 ctx->flags |= E2F_FLAG_ABORT;
5431 /* Debugging text */
5432 printf("Inode %u has EA block %u\n", ino, blk);
5435 /* Have we seen this EA block before? */
5436 if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) {
5437 if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0)
5439 /* Ooops, this EA was referenced more than it stated */
5440 if (!ctx->refcount_extra) {
5441 pctx->errcode = ea_refcount_create(0,
5442 &ctx->refcount_extra);
5443 if (pctx->errcode) {
5445 fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx);
5446 ctx->flags |= E2F_FLAG_ABORT;
5450 ea_refcount_increment(ctx->refcount_extra, blk, 0);
5455 * OK, we haven't seen this EA block yet. So we need to
5459 pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf);
5460 if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx))
5462 header = (struct ext2_ext_attr_header *) block_buf;
5463 pctx->blk = inode->i_file_acl;
5464 if (((ctx->ext_attr_ver == 1) &&
5465 (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) ||
5466 ((ctx->ext_attr_ver == 2) &&
5467 (header->h_magic != EXT2_EXT_ATTR_MAGIC))) {
5468 if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx))
5472 if (header->h_blocks != 1) {
5473 if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx))
5477 region = region_create(0, fs->blocksize);
5479 fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx);
5480 ctx->flags |= E2F_FLAG_ABORT;
5483 if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) {
5484 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5488 entry = (struct ext2_ext_attr_entry *)(header+1);
5489 end = block_buf + fs->blocksize;
5490 while ((char *)entry < end && *(__u32 *)entry) {
5491 if (region_allocate(region, (char *)entry - (char *)header,
5492 EXT2_EXT_ATTR_LEN(entry->e_name_len))) {
5493 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5496 if ((ctx->ext_attr_ver == 1 &&
5497 (entry->e_name_len == 0 || entry->e_name_index != 0)) ||
5498 (ctx->ext_attr_ver == 2 &&
5499 entry->e_name_index == 0)) {
5500 if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx))
5503 if (entry->e_value_block != 0) {
5504 if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx))
5507 if (entry->e_value_size &&
5508 region_allocate(region, entry->e_value_offs,
5509 EXT2_EXT_ATTR_SIZE(entry->e_value_size))) {
5510 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5513 entry = EXT2_EXT_ATTR_NEXT(entry);
5515 if (region_allocate(region, (char *)entry - (char *)header, 4)) {
5516 if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx))
5519 region_free(region);
5521 count = header->h_refcount - 1;
5523 ea_refcount_store(ctx->refcount, blk, count);
5524 mark_block_used(ctx, blk);
5525 ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk);
5530 inode->i_file_acl = 0;
5531 e2fsck_write_inode(ctx, ino, inode, "check_ext_attr");
5535 /* Returns 1 if bad htree, 0 if OK */
5536 static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
5537 ext2_ino_t ino FSCK_ATTR((unused)),
5538 struct ext2_inode *inode,
5541 struct ext2_dx_root_info *root;
5542 ext2_filsys fs = ctx->fs;
5546 if ((!LINUX_S_ISDIR(inode->i_mode) &&
5547 fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) ||
5548 (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) &&
5549 fix_problem(ctx, PR_1_HTREE_SET, pctx)))
5552 blk = inode->i_block[0];
5554 (blk < fs->super->s_first_data_block) ||
5555 (blk >= fs->super->s_blocks_count)) &&
5556 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5559 retval = io_channel_read_blk(fs->io, blk, 1, block_buf);
5560 if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5563 /* XXX should check that beginning matches a directory */
5564 root = (struct ext2_dx_root_info *) (block_buf + 24);
5566 if ((root->reserved_zero || root->info_length < 8) &&
5567 fix_problem(ctx, PR_1_HTREE_BADROOT, pctx))
5570 pctx->num = root->hash_version;
5571 if ((root->hash_version != EXT2_HASH_LEGACY) &&
5572 (root->hash_version != EXT2_HASH_HALF_MD4) &&
5573 (root->hash_version != EXT2_HASH_TEA) &&
5574 fix_problem(ctx, PR_1_HTREE_HASHV, pctx))
5577 if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) &&
5578 fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx))
5581 pctx->num = root->indirect_levels;
5582 if ((root->indirect_levels > 1) &&
5583 fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
5590 * This subroutine is called on each inode to account for all of the
5591 * blocks used by that inode.
5593 static void check_blocks(e2fsck_t ctx, struct problem_context *pctx,
5596 ext2_filsys fs = ctx->fs;
5597 struct process_block_struct_1 pb;
5598 ext2_ino_t ino = pctx->ino;
5599 struct ext2_inode *inode = pctx->inode;
5601 int dirty_inode = 0;
5607 pb.num_illegal_blocks = 0;
5608 pb.suppress = 0; pb.clear = 0;
5611 pb.previous_block = 0;
5612 pb.is_dir = LINUX_S_ISDIR(inode->i_mode);
5613 pb.is_reg = LINUX_S_ISREG(inode->i_mode);
5614 pb.max_blocks = 1 << (31 - fs->super->s_log_block_size);
5621 if (inode->i_flags & EXT2_COMPRBLK_FL) {
5622 if (fs->super->s_feature_incompat &
5623 EXT2_FEATURE_INCOMPAT_COMPRESSION)
5626 if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) {
5627 inode->i_flags &= ~EXT2_COMPRBLK_FL;
5633 if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf))
5636 if (ext2fs_inode_has_valid_blocks(inode))
5637 pctx->errcode = ext2fs_block_iterate2(fs, ino,
5638 pb.is_dir ? BLOCK_FLAG_HOLE : 0,
5639 block_buf, process_block, &pb);
5640 end_problem_latch(ctx, PR_LATCH_BLOCK);
5641 end_problem_latch(ctx, PR_LATCH_TOOBIG);
5642 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
5645 fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx);
5647 if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group)
5648 ctx->fs_fragmented++;
5651 inode->i_links_count = 0;
5652 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5653 inode->i_dtime = time(0);
5655 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5656 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5657 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5659 * The inode was probably partially accounted for
5660 * before processing was aborted, so we need to
5661 * restart the pass 1 scan.
5663 ctx->flags |= E2F_FLAG_RESTART;
5667 if (inode->i_flags & EXT2_INDEX_FL) {
5668 if (handle_htree(ctx, pctx, ino, inode, block_buf)) {
5669 inode->i_flags &= ~EXT2_INDEX_FL;
5673 e2fsck_add_dx_dir(ctx, ino, pb.last_block+1);
5677 if (ctx->dirs_to_hash && pb.is_dir &&
5678 !(inode->i_flags & EXT2_INDEX_FL) &&
5679 ((inode->i_size / fs->blocksize) >= 3))
5680 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
5682 if (!pb.num_blocks && pb.is_dir) {
5683 if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) {
5684 inode->i_links_count = 0;
5685 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
5686 inode->i_dtime = time(0);
5688 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
5689 ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino);
5690 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
5691 ctx->fs_directory_count--;
5696 pb.num_blocks *= (fs->blocksize / 512);
5698 printf("inode %u, i_size = %lu, last_block = %lld, i_blocks=%lu, num_blocks = %lu\n",
5699 ino, inode->i_size, pb.last_block, inode->i_blocks,
5703 int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super);
5704 if (nblock > (pb.last_block + 1))
5706 else if (nblock < (pb.last_block + 1)) {
5707 if (((pb.last_block + 1) - nblock) >
5708 fs->super->s_prealloc_dir_blocks)
5712 size = EXT2_I_SIZE(inode);
5713 if ((pb.last_block >= 0) &&
5714 (size < (__u64) pb.last_block * fs->blocksize))
5716 else if (size > ext2_max_sizes[fs->super->s_log_block_size])
5719 /* i_size for symlinks is checked elsewhere */
5720 if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) {
5721 pctx->num = (pb.last_block+1) * fs->blocksize;
5722 if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) {
5723 inode->i_size = pctx->num;
5724 if (!LINUX_S_ISDIR(inode->i_mode))
5725 inode->i_size_high = pctx->num >> 32;
5730 if (LINUX_S_ISREG(inode->i_mode) &&
5731 (inode->i_size_high || inode->i_size & 0x80000000UL))
5733 if (pb.num_blocks != inode->i_blocks) {
5734 pctx->num = pb.num_blocks;
5735 if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) {
5736 inode->i_blocks = pb.num_blocks;
5743 e2fsck_write_inode(ctx, ino, inode, "check_blocks");
5748 * Helper function called by process block when an illegal block is
5749 * found. It returns a description about why the block is illegal
5751 static char *describe_illegal_block(ext2_filsys fs, blk_t block)
5755 static char problem[80];
5757 super = fs->super->s_first_data_block;
5758 strcpy(problem, "PROGRAMMING ERROR: Unknown reason for illegal block");
5759 if (block < super) {
5760 sprintf(problem, "< FIRSTBLOCK (%u)", super);
5762 } else if (block >= fs->super->s_blocks_count) {
5763 sprintf(problem, "> BLOCKS (%u)", fs->super->s_blocks_count);
5766 for (i = 0; i < fs->group_desc_count; i++) {
5767 if (block == super) {
5768 sprintf(problem, "is the superblock in group %d", i);
5771 if (block > super &&
5772 block <= (super + fs->desc_blocks)) {
5773 sprintf(problem, "is in the group descriptors "
5777 if (block == fs->group_desc[i].bg_block_bitmap) {
5778 sprintf(problem, "is the block bitmap of group %d", i);
5781 if (block == fs->group_desc[i].bg_inode_bitmap) {
5782 sprintf(problem, "is the inode bitmap of group %d", i);
5785 if (block >= fs->group_desc[i].bg_inode_table &&
5786 (block < fs->group_desc[i].bg_inode_table
5787 + fs->inode_blocks_per_group)) {
5788 sprintf(problem, "is in the inode table of group %d",
5792 super += fs->super->s_blocks_per_group;
5799 * This is a helper function for check_blocks().
5801 static int process_block(ext2_filsys fs,
5803 e2_blkcnt_t blockcnt,
5804 blk_t ref_block FSCK_ATTR((unused)),
5805 int ref_offset FSCK_ATTR((unused)),
5808 struct process_block_struct_1 *p;
5809 struct problem_context *pctx;
5810 blk_t blk = *block_nr;
5815 p = (struct process_block_struct_1 *) priv_data;
5819 if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) {
5820 /* todo: Check that the comprblk_fl is high, that the
5821 blkaddr pattern looks right (all non-holes up to
5822 first EXT2FS_COMPRESSED_BLKADDR, then all
5823 EXT2FS_COMPRESSED_BLKADDR up to end of cluster),
5824 that the feature_incompat bit is high, and that the
5825 inode is a regular file. If we're doing a "full
5826 check" (a concept introduced to e2fsck by e2compr,
5827 meaning that we look at data blocks as well as
5828 metadata) then call some library routine that
5829 checks the compressed data. I'll have to think
5830 about this, because one particularly important
5831 problem to be able to fix is to recalculate the
5832 cluster size if necessary. I think that perhaps
5833 we'd better do most/all e2compr-specific checks
5834 separately, after the non-e2compr checks. If not
5835 doing a full check, it may be useful to test that
5836 the personality is linux; e.g. if it isn't then
5837 perhaps this really is just an illegal block. */
5842 if (p->is_dir == 0) {
5844 * Should never happen, since only directories
5845 * get called with BLOCK_FLAG_HOLE
5848 printf("process_block() called with blk == 0, "
5849 "blockcnt=%d, inode %lu???\n",
5856 if (blockcnt * fs->blocksize < p->inode->i_size) {
5858 printf("Missing block (#%d) in directory inode %lu!\n",
5867 printf("Process_block, inode %lu, block %u, #%d\n", p->ino, blk,
5872 * Simplistic fragmentation check. We merely require that the
5873 * file be contiguous. (Which can never be true for really
5874 * big files that are greater than a block group.)
5876 if (!HOLE_BLKADDR(p->previous_block)) {
5877 if (p->previous_block+1 != blk)
5880 p->previous_block = blk;
5882 if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size)))
5883 problem = PR_1_TOOBIG_DIR;
5884 if (p->is_reg && p->num_blocks+1 >= p->max_blocks)
5885 problem = PR_1_TOOBIG_REG;
5886 if (!p->is_dir && !p->is_reg && blockcnt > 0)
5887 problem = PR_1_TOOBIG_SYMLINK;
5889 if (blk < fs->super->s_first_data_block ||
5890 blk >= fs->super->s_blocks_count)
5891 problem = PR_1_ILLEGAL_BLOCK_NUM;
5894 p->num_illegal_blocks++;
5895 if (!p->suppress && (p->num_illegal_blocks % 12) == 0) {
5896 if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) {
5900 if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) {
5902 set_latch_flags(PR_LATCH_BLOCK,
5907 pctx->blkcount = blockcnt;
5908 if (fix_problem(ctx, problem, pctx)) {
5909 blk = *block_nr = 0;
5910 ret_code = BLOCK_CHANGED;
5916 if (p->ino == EXT2_RESIZE_INO) {
5918 * The resize inode has already be sanity checked
5919 * during pass #0 (the superblock checks). All we
5920 * have to do is mark the double indirect block as
5921 * being in use; all of the other blocks are handled
5922 * by mark_table_blocks()).
5924 if (blockcnt == BLOCK_COUNT_DIND)
5925 mark_block_used(ctx, blk);
5927 mark_block_used(ctx, blk);
5930 p->last_block = blockcnt;
5932 if (p->is_dir && (blockcnt >= 0)) {
5933 pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino,
5935 if (pctx->errcode) {
5937 pctx->num = blockcnt;
5938 fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
5939 /* Should never get here */
5940 ctx->flags |= E2F_FLAG_ABORT;
5947 static int process_bad_block(ext2_filsys fs,
5949 e2_blkcnt_t blockcnt,
5950 blk_t ref_block FSCK_ATTR((unused)),
5951 int ref_offset FSCK_ATTR((unused)),
5954 struct process_block_struct_1 *p;
5955 blk_t blk = *block_nr;
5958 struct problem_context *pctx;
5962 * Note: This function processes blocks for the bad blocks
5963 * inode, which is never compressed. So we don't use HOLE_BLKADDR().
5969 p = (struct process_block_struct_1 *) priv_data;
5973 pctx->ino = EXT2_BAD_INO;
5975 pctx->blkcount = blockcnt;
5977 if ((blk < fs->super->s_first_data_block) ||
5978 (blk >= fs->super->s_blocks_count)) {
5979 if (fix_problem(ctx, PR_1_BB_ILLEGAL_BLOCK_NUM, pctx)) {
5981 return BLOCK_CHANGED;
5987 if (ext2fs_test_block_bitmap(p->fs_meta_blocks, blk)) {
5989 if (fix_problem(ctx, PR_1_BB_FS_BLOCK, pctx)) {
5991 return BLOCK_CHANGED;
5993 } else if (ext2fs_test_block_bitmap(ctx->block_found_map,
5996 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK,
5999 return BLOCK_CHANGED;
6001 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6004 mark_block_used(ctx, blk);
6008 printf ("DEBUG: Marking %u as bad.\n", blk);
6010 ctx->fs_badblocks_count++;
6012 * If the block is not used, then mark it as used and return.
6013 * If it is already marked as found, this must mean that
6014 * there's an overlap between the filesystem table blocks
6015 * (bitmaps and inode table) and the bad block list.
6017 if (!ext2fs_test_block_bitmap(ctx->block_found_map, blk)) {
6018 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
6022 * Try to find the where the filesystem block was used...
6024 first_block = fs->super->s_first_data_block;
6026 for (i = 0; i < fs->group_desc_count; i++ ) {
6029 if (!ext2fs_bg_has_super(fs, i))
6031 if (blk == first_block) {
6033 if (fix_problem(ctx,
6034 PR_1_BAD_PRIMARY_SUPERBLOCK,
6037 return BLOCK_CHANGED;
6041 fix_problem(ctx, PR_1_BAD_SUPERBLOCK, pctx);
6044 if ((blk > first_block) &&
6045 (blk <= first_block + fs->desc_blocks)) {
6047 pctx->blk = *block_nr;
6048 if (fix_problem(ctx,
6049 PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, pctx)) {
6051 return BLOCK_CHANGED;
6055 fix_problem(ctx, PR_1_BAD_GROUP_DESCRIPTORS, pctx);
6059 if (blk == fs->group_desc[i].bg_block_bitmap) {
6060 if (fix_problem(ctx, PR_1_BB_BAD_BLOCK, pctx)) {
6061 ctx->invalid_block_bitmap_flag[i]++;
6062 ctx->invalid_bitmaps++;
6066 if (blk == fs->group_desc[i].bg_inode_bitmap) {
6067 if (fix_problem(ctx, PR_1_IB_BAD_BLOCK, pctx)) {
6068 ctx->invalid_inode_bitmap_flag[i]++;
6069 ctx->invalid_bitmaps++;
6073 if ((blk >= fs->group_desc[i].bg_inode_table) &&
6074 (blk < (fs->group_desc[i].bg_inode_table +
6075 fs->inode_blocks_per_group))) {
6077 * If there are bad blocks in the inode table,
6078 * the inode scan code will try to do
6079 * something reasonable automatically.
6083 first_block += fs->super->s_blocks_per_group;
6086 * If we've gotten to this point, then the only
6087 * possibility is that the bad block inode meta data
6088 * is using a bad block.
6090 if ((blk == p->inode->i_block[EXT2_IND_BLOCK]) ||
6091 (blk == p->inode->i_block[EXT2_DIND_BLOCK]) ||
6092 (blk == p->inode->i_block[EXT2_TIND_BLOCK])) {
6094 if (fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK, pctx)) {
6096 return BLOCK_CHANGED;
6098 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
6105 /* Warn user that the block wasn't claimed */
6106 fix_problem(ctx, PR_1_PROGERR_CLAIMED_BLOCK, pctx);
6111 static void new_table_block(e2fsck_t ctx, blk_t first_block, int group,
6112 const char *name, int num, blk_t *new_block)
6114 ext2_filsys fs = ctx->fs;
6115 blk_t old_block = *new_block;
6118 struct problem_context pctx;
6120 clear_problem_context(&pctx);
6123 pctx.blk = old_block;
6126 pctx.errcode = ext2fs_get_free_blocks(fs, first_block,
6127 first_block + fs->super->s_blocks_per_group,
6128 num, ctx->block_found_map, new_block);
6131 fix_problem(ctx, PR_1_RELOC_BLOCK_ALLOCATE, &pctx);
6132 ext2fs_unmark_valid(fs);
6135 pctx.errcode = ext2fs_get_mem(fs->blocksize, &buf);
6137 fix_problem(ctx, PR_1_RELOC_MEMORY_ALLOCATE, &pctx);
6138 ext2fs_unmark_valid(fs);
6141 ext2fs_mark_super_dirty(fs);
6142 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
6143 pctx.blk2 = *new_block;
6144 fix_problem(ctx, (old_block ? PR_1_RELOC_FROM_TO :
6145 PR_1_RELOC_TO), &pctx);
6147 for (i = 0; i < num; i++) {
6149 ext2fs_mark_block_bitmap(ctx->block_found_map, (*new_block)+i);
6151 pctx.errcode = io_channel_read_blk(fs->io,
6152 old_block + i, 1, buf);
6154 fix_problem(ctx, PR_1_RELOC_READ_ERR, &pctx);
6156 memset(buf, 0, fs->blocksize);
6158 pctx.blk = (*new_block) + i;
6159 pctx.errcode = io_channel_write_blk(fs->io, pctx.blk,
6162 fix_problem(ctx, PR_1_RELOC_WRITE_ERR, &pctx);
6164 ext2fs_free_mem(&buf);
6168 * This routine gets called at the end of pass 1 if bad blocks are
6169 * detected in the superblock, group descriptors, inode_bitmaps, or
6170 * block bitmaps. At this point, all of the blocks have been mapped
6171 * out, so we can try to allocate new block(s) to replace the bad
6174 static void handle_fs_bad_blocks(e2fsck_t ctx)
6176 ext2_filsys fs = ctx->fs;
6178 int first_block = fs->super->s_first_data_block;
6180 for (i = 0; i < fs->group_desc_count; i++) {
6181 if (ctx->invalid_block_bitmap_flag[i]) {
6182 new_table_block(ctx, first_block, i, _("block bitmap"),
6183 1, &fs->group_desc[i].bg_block_bitmap);
6185 if (ctx->invalid_inode_bitmap_flag[i]) {
6186 new_table_block(ctx, first_block, i, _("inode bitmap"),
6187 1, &fs->group_desc[i].bg_inode_bitmap);
6189 if (ctx->invalid_inode_table_flag[i]) {
6190 new_table_block(ctx, first_block, i, _("inode table"),
6191 fs->inode_blocks_per_group,
6192 &fs->group_desc[i].bg_inode_table);
6193 ctx->flags |= E2F_FLAG_RESTART;
6195 first_block += fs->super->s_blocks_per_group;
6197 ctx->invalid_bitmaps = 0;
6201 * This routine marks all blocks which are used by the superblock,
6202 * group descriptors, inode bitmaps, and block bitmaps.
6204 static void mark_table_blocks(e2fsck_t ctx)
6206 ext2_filsys fs = ctx->fs;
6210 struct problem_context pctx;
6212 clear_problem_context(&pctx);
6214 block = fs->super->s_first_data_block;
6215 for (i = 0; i < fs->group_desc_count; i++) {
6218 ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map);
6221 * Mark the blocks used for the inode table
6223 if (fs->group_desc[i].bg_inode_table) {
6224 for (j = 0, b = fs->group_desc[i].bg_inode_table;
6225 j < fs->inode_blocks_per_group;
6227 if (ext2fs_test_block_bitmap(ctx->block_found_map,
6230 if (fix_problem(ctx,
6231 PR_1_ITABLE_CONFLICT, &pctx)) {
6232 ctx->invalid_inode_table_flag[i]++;
6233 ctx->invalid_bitmaps++;
6236 ext2fs_mark_block_bitmap(ctx->block_found_map,
6243 * Mark block used for the block bitmap
6245 if (fs->group_desc[i].bg_block_bitmap) {
6246 if (ext2fs_test_block_bitmap(ctx->block_found_map,
6247 fs->group_desc[i].bg_block_bitmap)) {
6248 pctx.blk = fs->group_desc[i].bg_block_bitmap;
6249 if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) {
6250 ctx->invalid_block_bitmap_flag[i]++;
6251 ctx->invalid_bitmaps++;
6254 ext2fs_mark_block_bitmap(ctx->block_found_map,
6255 fs->group_desc[i].bg_block_bitmap);
6260 * Mark block used for the inode bitmap
6262 if (fs->group_desc[i].bg_inode_bitmap) {
6263 if (ext2fs_test_block_bitmap(ctx->block_found_map,
6264 fs->group_desc[i].bg_inode_bitmap)) {
6265 pctx.blk = fs->group_desc[i].bg_inode_bitmap;
6266 if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) {
6267 ctx->invalid_inode_bitmap_flag[i]++;
6268 ctx->invalid_bitmaps++;
6271 ext2fs_mark_block_bitmap(ctx->block_found_map,
6272 fs->group_desc[i].bg_inode_bitmap);
6275 block += fs->super->s_blocks_per_group;
6280 * Thes subroutines short circuits ext2fs_get_blocks and
6281 * ext2fs_check_directory; we use them since we already have the inode
6282 * structure, so there's no point in letting the ext2fs library read
6285 static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino,
6288 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6291 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6292 return EXT2_ET_CALLBACK_NOTHANDLED;
6294 for (i=0; i < EXT2_N_BLOCKS; i++)
6295 blocks[i] = ctx->stashed_inode->i_block[i];
6299 static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino,
6300 struct ext2_inode *inode)
6302 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6304 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6305 return EXT2_ET_CALLBACK_NOTHANDLED;
6306 *inode = *ctx->stashed_inode;
6310 static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino,
6311 struct ext2_inode *inode)
6313 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6315 if ((ino == ctx->stashed_ino) && ctx->stashed_inode)
6316 *ctx->stashed_inode = *inode;
6317 return EXT2_ET_CALLBACK_NOTHANDLED;
6320 static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino)
6322 e2fsck_t ctx = (e2fsck_t) fs->priv_data;
6324 if ((ino != ctx->stashed_ino) || !ctx->stashed_inode)
6325 return EXT2_ET_CALLBACK_NOTHANDLED;
6327 if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode))
6328 return EXT2_ET_NO_DIRECTORY;
6332 void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool)
6334 ext2_filsys fs = ctx->fs;
6337 fs->get_blocks = pass1_get_blocks;
6338 fs->check_directory = pass1_check_directory;
6339 fs->read_inode = pass1_read_inode;
6340 fs->write_inode = pass1_write_inode;
6341 ctx->stashed_ino = 0;
6344 fs->check_directory = 0;
6346 fs->write_inode = 0;
6351 * pass1b.c --- Pass #1b of e2fsck
6353 * This file contains pass1B, pass1C, and pass1D of e2fsck. They are
6354 * only invoked if pass 1 discovered blocks which are in use by more
6357 * Pass1B scans the data blocks of all the inodes again, generating a
6358 * complete list of duplicate blocks and which inodes have claimed
6361 * Pass1C does a tree-traversal of the filesystem, to determine the
6362 * parent directories of these inodes. This step is necessary so that
6363 * e2fsck can print out the pathnames of affected inodes.
6365 * Pass1D is a reconciliation pass. For each inode with duplicate
6366 * blocks, the user is prompted if s/he would like to clone the file
6367 * (so that the file gets a fresh copy of the duplicated blocks) or
6368 * simply to delete the file.
6373 /* Needed for architectures where sizeof(int) != sizeof(void *) */
6374 #define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val))
6375 #define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr))
6377 /* Define an extension to the ext2 library's block count information */
6378 #define BLOCK_COUNT_EXTATTR (-5)
6382 struct block_el *next;
6387 struct inode_el *next;
6392 struct inode_el *inode_list;
6396 * This structure stores information about a particular inode which
6397 * is sharing blocks with other inodes. This information is collected
6398 * to display to the user, so that the user knows what files he or she
6399 * is dealing with, when trying to decide how to resolve the conflict
6400 * of multiply-claimed blocks.
6405 struct ext2_inode inode;
6406 struct block_el *block_list;
6409 static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr,
6410 e2_blkcnt_t blockcnt, blk_t ref_blk,
6411 int ref_offset, void *priv_data);
6412 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
6413 struct dup_inode *dp, char *block_buf);
6414 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
6415 struct dup_inode *dp, char* block_buf);
6416 static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk);
6418 static void pass1b(e2fsck_t ctx, char *block_buf);
6419 static void pass1c(e2fsck_t ctx, char *block_buf);
6420 static void pass1d(e2fsck_t ctx, char *block_buf);
6422 static int dup_inode_count = 0;
6424 static dict_t blk_dict, ino_dict;
6426 static ext2fs_inode_bitmap inode_dup_map;
6428 static int dict_int_cmp(const void *a, const void *b)
6439 * Add a duplicate block record
6441 static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk,
6442 struct ext2_inode *inode)
6445 struct dup_block *db;
6446 struct dup_inode *di;
6447 struct block_el *blk_el;
6448 struct inode_el *ino_el;
6450 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
6452 db = (struct dup_block *) dnode_get(n);
6454 db = (struct dup_block *) e2fsck_allocate_memory(ctx,
6455 sizeof(struct dup_block), "duplicate block header");
6458 dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db);
6460 ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx,
6461 sizeof(struct inode_el), "inode element");
6462 ino_el->inode = ino;
6463 ino_el->next = db->inode_list;
6464 db->inode_list = ino_el;
6467 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino));
6469 di = (struct dup_inode *) dnode_get(n);
6471 di = (struct dup_inode *) e2fsck_allocate_memory(ctx,
6472 sizeof(struct dup_inode), "duplicate inode header");
6473 di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0 ;
6474 di->num_dupblocks = 0;
6477 dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di);
6479 blk_el = (struct block_el *) e2fsck_allocate_memory(ctx,
6480 sizeof(struct block_el), "block element");
6481 blk_el->block = blk;
6482 blk_el->next = di->block_list;
6483 di->block_list = blk_el;
6484 di->num_dupblocks++;
6488 * Free a duplicate inode record
6490 static void inode_dnode_free(dnode_t *node)
6492 struct dup_inode *di;
6493 struct block_el *p, *next;
6495 di = (struct dup_inode *) dnode_get(node);
6496 for (p = di->block_list; p; p = next) {
6504 * Free a duplicate block record
6506 static void block_dnode_free(dnode_t *node)
6508 struct dup_block *db;
6509 struct inode_el *p, *next;
6511 db = (struct dup_block *) dnode_get(node);
6512 for (p = db->inode_list; p; p = next) {
6521 * Main procedure for handling duplicate blocks
6523 void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf)
6525 ext2_filsys fs = ctx->fs;
6526 struct problem_context pctx;
6528 clear_problem_context(&pctx);
6530 pctx.errcode = ext2fs_allocate_inode_bitmap(fs,
6531 _("multiply claimed inode map"), &inode_dup_map);
6533 fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx);
6534 ctx->flags |= E2F_FLAG_ABORT;
6538 dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6539 dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp);
6540 dict_set_allocator(&ino_dict, inode_dnode_free);
6541 dict_set_allocator(&blk_dict, block_dnode_free);
6543 pass1b(ctx, block_buf);
6544 pass1c(ctx, block_buf);
6545 pass1d(ctx, block_buf);
6548 * Time to free all of the accumulated data structures that we
6549 * don't need anymore.
6551 dict_free_nodes(&ino_dict);
6552 dict_free_nodes(&blk_dict);
6556 * Scan the inodes looking for inodes that contain duplicate blocks.
6558 struct process_block_struct_1b {
6562 struct ext2_inode *inode;
6563 struct problem_context *pctx;
6566 static void pass1b(e2fsck_t ctx, char *block_buf)
6568 ext2_filsys fs = ctx->fs;
6570 struct ext2_inode inode;
6571 ext2_inode_scan scan;
6572 struct process_block_struct_1b pb;
6573 struct problem_context pctx;
6575 clear_problem_context(&pctx);
6577 if (!(ctx->options & E2F_OPT_PREEN))
6578 fix_problem(ctx, PR_1B_PASS_HEADER, &pctx);
6579 pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks,
6582 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6583 ctx->flags |= E2F_FLAG_ABORT;
6586 ctx->stashed_inode = &inode;
6589 pctx.str = "pass1b";
6591 pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode);
6592 if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
6595 fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx);
6596 ctx->flags |= E2F_FLAG_ABORT;
6601 pctx.ino = ctx->stashed_ino = ino;
6602 if ((ino != EXT2_BAD_INO) &&
6603 !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))
6610 if (ext2fs_inode_has_valid_blocks(&inode) ||
6611 (ino == EXT2_BAD_INO))
6612 pctx.errcode = ext2fs_block_iterate2(fs, ino,
6613 0, block_buf, process_pass1b_block, &pb);
6614 if (inode.i_file_acl)
6615 process_pass1b_block(fs, &inode.i_file_acl,
6616 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
6617 if (pb.dup_blocks) {
6618 end_problem_latch(ctx, PR_LATCH_DBLOCK);
6619 if (ino >= EXT2_FIRST_INODE(fs->super) ||
6620 ino == EXT2_ROOT_INO)
6624 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6626 ext2fs_close_inode_scan(scan);
6627 e2fsck_use_inode_shortcuts(ctx, 0);
6630 static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)),
6632 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6633 blk_t ref_blk FSCK_ATTR((unused)),
6634 int ref_offset FSCK_ATTR((unused)),
6637 struct process_block_struct_1b *p;
6640 if (HOLE_BLKADDR(*block_nr))
6642 p = (struct process_block_struct_1b *) priv_data;
6645 if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr))
6648 /* OK, this is a duplicate block */
6649 if (p->ino != EXT2_BAD_INO) {
6650 p->pctx->blk = *block_nr;
6651 fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx);
6654 ext2fs_mark_inode_bitmap(inode_dup_map, p->ino);
6656 add_dupe(ctx, p->ino, *block_nr, p->inode);
6662 * Pass 1c: Scan directories for inodes with duplicate blocks. This
6663 * is used so that we can print pathnames when prompting the user for
6666 struct search_dir_struct {
6668 ext2_ino_t first_inode;
6669 ext2_ino_t max_inode;
6672 static int search_dirent_proc(ext2_ino_t dir, int entry,
6673 struct ext2_dir_entry *dirent,
6674 int offset FSCK_ATTR((unused)),
6675 int blocksize FSCK_ATTR((unused)),
6676 char *buf FSCK_ATTR((unused)),
6679 struct search_dir_struct *sd;
6680 struct dup_inode *p;
6683 sd = (struct search_dir_struct *) priv_data;
6685 if (dirent->inode > sd->max_inode)
6686 /* Should abort this inode, but not everything */
6689 if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) ||
6690 !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode))
6693 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode));
6696 p = (struct dup_inode *) dnode_get(n);
6700 return(sd->count ? 0 : DIRENT_ABORT);
6704 static void pass1c(e2fsck_t ctx, char *block_buf)
6706 ext2_filsys fs = ctx->fs;
6707 struct search_dir_struct sd;
6708 struct problem_context pctx;
6710 clear_problem_context(&pctx);
6712 if (!(ctx->options & E2F_OPT_PREEN))
6713 fix_problem(ctx, PR_1C_PASS_HEADER, &pctx);
6716 * Search through all directories to translate inodes to names
6717 * (by searching for the containing directory for that inode.)
6719 sd.count = dup_inode_count;
6720 sd.first_inode = EXT2_FIRST_INODE(fs->super);
6721 sd.max_inode = fs->super->s_inodes_count;
6722 ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf,
6723 search_dirent_proc, &sd);
6726 static void pass1d(e2fsck_t ctx, char *block_buf)
6728 ext2_filsys fs = ctx->fs;
6729 struct dup_inode *p, *t;
6730 struct dup_block *q;
6731 ext2_ino_t *shared, ino;
6736 struct problem_context pctx;
6741 clear_problem_context(&pctx);
6743 if (!(ctx->options & E2F_OPT_PREEN))
6744 fix_problem(ctx, PR_1D_PASS_HEADER, &pctx);
6745 e2fsck_read_bitmaps(ctx);
6747 pctx.num = dup_inode_count; /* dict_count(&ino_dict); */
6748 fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx);
6749 shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx,
6750 sizeof(ext2_ino_t) * dict_count(&ino_dict),
6751 "Shared inode list");
6752 for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) {
6753 p = (struct dup_inode *) dnode_get(n);
6756 ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n));
6757 if (ino == EXT2_BAD_INO)
6761 * Find all of the inodes which share blocks with this
6762 * one. First we find all of the duplicate blocks
6763 * belonging to this inode, and then search each block
6764 * get the list of inodes, and merge them together.
6766 for (s = p->block_list; s; s = s->next) {
6767 m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block));
6769 continue; /* Should never happen... */
6770 q = (struct dup_block *) dnode_get(m);
6773 if (check_if_fs_block(ctx, s->block)) {
6779 * Add all inodes used by this block to the
6780 * shared[] --- which is a unique list, so
6781 * if an inode is already in shared[], don't
6784 for (r = q->inode_list; r; r = r->next) {
6785 if (r->inode == ino)
6787 for (i = 0; i < shared_len; i++)
6788 if (shared[i] == r->inode)
6790 if (i == shared_len) {
6791 shared[shared_len++] = r->inode;
6797 * Report the inode that we are working on
6799 pctx.inode = &p->inode;
6802 pctx.blkcount = p->num_dupblocks;
6803 pctx.num = meta_data ? shared_len+1 : shared_len;
6804 fix_problem(ctx, PR_1D_DUP_FILE, &pctx);
6809 fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx);
6811 for (i = 0; i < shared_len; i++) {
6812 m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i]));
6814 continue; /* should never happen */
6815 t = (struct dup_inode *) dnode_get(m);
6817 * Report the inode that we are sharing with
6819 pctx.inode = &t->inode;
6820 pctx.ino = shared[i];
6822 fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx);
6825 fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx);
6828 if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) {
6829 pctx.errcode = clone_file(ctx, ino, p, block_buf);
6831 fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx);
6835 if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx))
6836 delete_file(ctx, ino, p, block_buf);
6838 ext2fs_unmark_valid(fs);
6840 ext2fs_free_mem(&shared);
6844 * Drop the refcount on the dup_block structure, and clear the entry
6845 * in the block_dup_map if appropriate.
6847 static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p)
6850 if (p->num_bad <= 0 ||
6851 (p->num_bad == 1 && !check_if_fs_block(ctx, block)))
6852 ext2fs_unmark_block_bitmap(ctx->block_dup_map, block);
6855 static int delete_file_block(ext2_filsys fs,
6857 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
6858 blk_t ref_block FSCK_ATTR((unused)),
6859 int ref_offset FSCK_ATTR((unused)),
6862 struct process_block_struct_1b *pb;
6863 struct dup_block *p;
6867 pb = (struct process_block_struct_1b *) priv_data;
6870 if (HOLE_BLKADDR(*block_nr))
6873 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
6874 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
6876 p = (struct dup_block *) dnode_get(n);
6877 decrement_badcount(ctx, *block_nr, p);
6879 com_err("delete_file_block", 0,
6880 _("internal error; can't find dup_blk for %d\n"),
6883 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
6884 ext2fs_block_alloc_stats(fs, *block_nr, -1);
6890 static void delete_file(e2fsck_t ctx, ext2_ino_t ino,
6891 struct dup_inode *dp, char* block_buf)
6893 ext2_filsys fs = ctx->fs;
6894 struct process_block_struct_1b pb;
6895 struct ext2_inode inode;
6896 struct problem_context pctx;
6899 clear_problem_context(&pctx);
6900 pctx.ino = pb.ino = ino;
6901 pb.dup_blocks = dp->num_dupblocks;
6903 pctx.str = "delete_file";
6905 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
6906 if (ext2fs_inode_has_valid_blocks(&inode))
6907 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
6908 delete_file_block, &pb);
6910 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
6911 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
6912 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
6913 if (ctx->inode_bad_map)
6914 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
6915 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
6917 /* Inode may have changed by block_iterate, so reread it */
6918 e2fsck_read_inode(ctx, ino, &inode, "delete_file");
6919 inode.i_links_count = 0;
6920 inode.i_dtime = time(0);
6921 if (inode.i_file_acl &&
6922 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
6924 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
6925 block_buf, -1, &count);
6926 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
6931 pctx.blk = inode.i_file_acl;
6932 fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx);
6935 * If the count is zero, then arrange to have the
6936 * block deleted. If the block is in the block_dup_map,
6937 * also call delete_file_block since it will take care
6938 * of keeping the accounting straight.
6941 ext2fs_test_block_bitmap(ctx->block_dup_map,
6943 delete_file_block(fs, &inode.i_file_acl,
6944 BLOCK_COUNT_EXTATTR, 0, 0, &pb);
6946 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
6949 struct clone_struct {
6956 static int clone_file_block(ext2_filsys fs,
6958 e2_blkcnt_t blockcnt,
6959 blk_t ref_block FSCK_ATTR((unused)),
6960 int ref_offset FSCK_ATTR((unused)),
6963 struct dup_block *p;
6966 struct clone_struct *cs = (struct clone_struct *) priv_data;
6972 if (HOLE_BLKADDR(*block_nr))
6975 if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) {
6976 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr));
6978 p = (struct dup_block *) dnode_get(n);
6979 retval = ext2fs_new_block(fs, 0, ctx->block_found_map,
6982 cs->errcode = retval;
6985 if (cs->dir && (blockcnt >= 0)) {
6986 retval = ext2fs_set_dir_block(fs->dblist,
6987 cs->dir, new_block, blockcnt);
6989 cs->errcode = retval;
6994 printf("Cloning block %u to %u\n", *block_nr,
6997 retval = io_channel_read_blk(fs->io, *block_nr, 1,
7000 cs->errcode = retval;
7003 retval = io_channel_write_blk(fs->io, new_block, 1,
7006 cs->errcode = retval;
7009 decrement_badcount(ctx, *block_nr, p);
7010 *block_nr = new_block;
7011 ext2fs_mark_block_bitmap(ctx->block_found_map,
7013 ext2fs_mark_block_bitmap(fs->block_map, new_block);
7014 return BLOCK_CHANGED;
7016 com_err("clone_file_block", 0,
7017 _("internal error; can't find dup_blk for %d\n"),
7023 static int clone_file(e2fsck_t ctx, ext2_ino_t ino,
7024 struct dup_inode *dp, char* block_buf)
7026 ext2_filsys fs = ctx->fs;
7028 struct clone_struct cs;
7029 struct problem_context pctx;
7032 struct inode_el *ino_el;
7033 struct dup_block *db;
7034 struct dup_inode *di;
7036 clear_problem_context(&pctx);
7040 retval = ext2fs_get_mem(fs->blocksize, &cs.buf);
7044 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino))
7048 pctx.str = "clone_file";
7049 if (ext2fs_inode_has_valid_blocks(&dp->inode))
7050 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
7051 clone_file_block, &cs);
7052 ext2fs_mark_bb_dirty(fs);
7054 fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx);
7055 retval = pctx.errcode;
7059 com_err("clone_file", cs.errcode,
7060 _("returned from clone_file_block"));
7061 retval = cs.errcode;
7064 /* The inode may have changed on disk, so we have to re-read it */
7065 e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA");
7066 blk = dp->inode.i_file_acl;
7067 if (blk && (clone_file_block(fs, &dp->inode.i_file_acl,
7068 BLOCK_COUNT_EXTATTR, 0, 0, &cs) ==
7070 e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA");
7072 * If we cloned the EA block, find all other inodes
7073 * which refered to that EA block, and modify
7074 * them to point to the new EA block.
7076 n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk));
7077 db = (struct dup_block *) dnode_get(n);
7078 for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) {
7079 if (ino_el->inode == ino)
7081 n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode));
7082 di = (struct dup_inode *) dnode_get(n);
7083 if (di->inode.i_file_acl == blk) {
7084 di->inode.i_file_acl = dp->inode.i_file_acl;
7085 e2fsck_write_inode(ctx, ino_el->inode,
7086 &di->inode, "clone file EA");
7087 decrement_badcount(ctx, blk, db);
7093 ext2fs_free_mem(&cs.buf);
7098 * This routine returns 1 if a block overlaps with one of the superblocks,
7099 * group descriptors, inode bitmaps, or block bitmaps.
7101 static int check_if_fs_block(e2fsck_t ctx, blk_t test_block)
7103 ext2_filsys fs = ctx->fs;
7107 block = fs->super->s_first_data_block;
7108 for (i = 0; i < fs->group_desc_count; i++) {
7110 /* Check superblocks/block group descriptros */
7111 if (ext2fs_bg_has_super(fs, i)) {
7112 if (test_block >= block &&
7113 (test_block <= block + fs->desc_blocks))
7117 /* Check the inode table */
7118 if ((fs->group_desc[i].bg_inode_table) &&
7119 (test_block >= fs->group_desc[i].bg_inode_table) &&
7120 (test_block < (fs->group_desc[i].bg_inode_table +
7121 fs->inode_blocks_per_group)))
7124 /* Check the bitmap blocks */
7125 if ((test_block == fs->group_desc[i].bg_block_bitmap) ||
7126 (test_block == fs->group_desc[i].bg_inode_bitmap))
7129 block += fs->super->s_blocks_per_group;
7134 * pass2.c --- check directory structure
7136 * Pass 2 of e2fsck iterates through all active directory inodes, and
7137 * applies to following tests to each directory entry in the directory
7138 * blocks in the inodes:
7140 * - The length of the directory entry (rec_len) should be at
7141 * least 8 bytes, and no more than the remaining space
7142 * left in the directory block.
7143 * - The length of the name in the directory entry (name_len)
7144 * should be less than (rec_len - 8).
7145 * - The inode number in the directory entry should be within
7147 * - The inode number should refer to a in-use inode.
7148 * - The first entry should be '.', and its inode should be
7149 * the inode of the directory.
7150 * - The second entry should be '..'.
7152 * To minimize disk seek time, the directory blocks are processed in
7153 * sorted order of block numbers.
7155 * Pass 2 also collects the following information:
7156 * - The inode numbers of the subdirectories for each directory.
7158 * Pass 2 relies on the following information from previous passes:
7159 * - The directory information collected in pass 1.
7160 * - The inode_used_map bitmap
7161 * - The inode_bad_map bitmap
7162 * - The inode_dir_map bitmap
7164 * Pass 2 frees the following data structures
7165 * - The inode_bad_map bitmap
7166 * - The inode_reg_map bitmap
7169 /* #define DX_DEBUG */
7172 * Keeps track of how many times an inode is referenced.
7174 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf);
7175 static int check_dir_block(ext2_filsys fs,
7176 struct ext2_db_entry *dir_blocks_info,
7178 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info,
7179 struct problem_context *pctx);
7180 static int update_dir_block(ext2_filsys fs,
7182 e2_blkcnt_t blockcnt,
7186 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino);
7187 static int htree_depth(struct dx_dir_info *dx_dir,
7188 struct dx_dirblock_info *dx_db);
7189 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b);
7191 struct check_dir_struct {
7193 struct problem_context pctx;
7198 static void e2fsck_pass2(e2fsck_t ctx)
7200 struct ext2_super_block *sb = ctx->fs->super;
7201 struct problem_context pctx;
7202 ext2_filsys fs = ctx->fs;
7204 #ifdef RESOURCE_TRACK
7205 struct resource_track rtrack;
7207 struct dir_info *dir;
7208 struct check_dir_struct cd;
7209 struct dx_dir_info *dx_dir;
7210 struct dx_dirblock_info *dx_db, *dx_parent;
7216 #ifdef RESOURCE_TRACK
7217 init_resource_track(&rtrack);
7220 clear_problem_context(&cd.pctx);
7223 mtrace_print("Pass 2");
7226 if (!(ctx->options & E2F_OPT_PREEN))
7227 fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx);
7229 cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT,
7230 0, ctx->inode_link_info,
7232 if (cd.pctx.errcode) {
7233 fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx);
7234 ctx->flags |= E2F_FLAG_ABORT;
7237 buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize,
7238 "directory scan buffer");
7241 * Set up the parent pointer for the root directory, if
7242 * present. (If the root directory is not present, we will
7243 * create it in pass 3.)
7245 dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO);
7247 dir->parent = EXT2_ROOT_INO;
7252 cd.max = ext2fs_dblist_count(fs->dblist);
7255 (void) (ctx->progress)(ctx, 2, 0, cd.max);
7257 if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX)
7258 ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp);
7260 cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block,
7262 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7264 if (cd.pctx.errcode) {
7265 fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx);
7266 ctx->flags |= E2F_FLAG_ABORT;
7271 for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) {
7272 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7274 if (dx_dir->numblocks == 0)
7276 clear_problem_context(&pctx);
7278 pctx.dir = dx_dir->ino;
7279 dx_db = dx_dir->dx_block;
7280 if (dx_db->flags & DX_FLAG_REFERENCED)
7281 dx_db->flags |= DX_FLAG_DUP_REF;
7283 dx_db->flags |= DX_FLAG_REFERENCED;
7285 * Find all of the first and last leaf blocks, and
7286 * update their parent's min and max hash values
7288 for (b=0, dx_db = dx_dir->dx_block;
7289 b < dx_dir->numblocks;
7291 if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
7292 !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
7294 dx_parent = &dx_dir->dx_block[dx_db->parent];
7296 * XXX Make sure dx_parent->min_hash > dx_db->min_hash
7298 if (dx_db->flags & DX_FLAG_FIRST)
7299 dx_parent->min_hash = dx_db->min_hash;
7301 * XXX Make sure dx_parent->max_hash < dx_db->max_hash
7303 if (dx_db->flags & DX_FLAG_LAST)
7304 dx_parent->max_hash = dx_db->max_hash;
7307 for (b=0, dx_db = dx_dir->dx_block;
7308 b < dx_dir->numblocks;
7311 pctx.group = dx_db->parent;
7313 if (!(dx_db->flags & DX_FLAG_FIRST) &&
7314 (dx_db->min_hash < dx_db->node_min_hash)) {
7315 pctx.blk = dx_db->min_hash;
7316 pctx.blk2 = dx_db->node_min_hash;
7317 code = PR_2_HTREE_MIN_HASH;
7318 fix_problem(ctx, code, &pctx);
7321 if (dx_db->type == DX_DIRBLOCK_LEAF) {
7322 depth = htree_depth(dx_dir, dx_db);
7323 if (depth != dx_dir->depth) {
7324 code = PR_2_HTREE_BAD_DEPTH;
7325 fix_problem(ctx, code, &pctx);
7330 * This test doesn't apply for the root block
7334 (dx_db->max_hash > dx_db->node_max_hash)) {
7335 pctx.blk = dx_db->max_hash;
7336 pctx.blk2 = dx_db->node_max_hash;
7337 code = PR_2_HTREE_MAX_HASH;
7338 fix_problem(ctx, code, &pctx);
7341 if (!(dx_db->flags & DX_FLAG_REFERENCED)) {
7342 code = PR_2_HTREE_NOTREF;
7343 fix_problem(ctx, code, &pctx);
7345 } else if (dx_db->flags & DX_FLAG_DUP_REF) {
7346 code = PR_2_HTREE_DUPREF;
7347 fix_problem(ctx, code, &pctx);
7353 if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) {
7354 clear_htree(ctx, dx_dir->ino);
7355 dx_dir->numblocks = 0;
7359 ext2fs_free_mem(&buf);
7360 ext2fs_free_dblist(fs->dblist);
7362 if (ctx->inode_bad_map) {
7363 ext2fs_free_inode_bitmap(ctx->inode_bad_map);
7364 ctx->inode_bad_map = 0;
7366 if (ctx->inode_reg_map) {
7367 ext2fs_free_inode_bitmap(ctx->inode_reg_map);
7368 ctx->inode_reg_map = 0;
7371 clear_problem_context(&pctx);
7372 if (ctx->large_files) {
7373 if (!(sb->s_feature_ro_compat &
7374 EXT2_FEATURE_RO_COMPAT_LARGE_FILE) &&
7375 fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) {
7376 sb->s_feature_ro_compat |=
7377 EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
7378 ext2fs_mark_super_dirty(fs);
7380 if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
7381 fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) {
7382 ext2fs_update_dynamic_rev(fs);
7383 ext2fs_mark_super_dirty(fs);
7385 } else if (!ctx->large_files &&
7386 (sb->s_feature_ro_compat &
7387 EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) {
7388 if (fs->flags & EXT2_FLAG_RW) {
7389 sb->s_feature_ro_compat &=
7390 ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
7391 ext2fs_mark_super_dirty(fs);
7395 #ifdef RESOURCE_TRACK
7396 if (ctx->options & E2F_OPT_TIME2) {
7397 e2fsck_clear_progbar(ctx);
7398 print_resource_track(_("Pass 2"), &rtrack);
7403 #define MAX_DEPTH 32000
7404 static int htree_depth(struct dx_dir_info *dx_dir,
7405 struct dx_dirblock_info *dx_db)
7409 while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) {
7410 dx_db = &dx_dir->dx_block[dx_db->parent];
7416 static int dict_de_cmp(const void *a, const void *b)
7418 const struct ext2_dir_entry *de_a, *de_b;
7421 de_a = (const struct ext2_dir_entry *) a;
7422 a_len = de_a->name_len & 0xFF;
7423 de_b = (const struct ext2_dir_entry *) b;
7424 b_len = de_b->name_len & 0xFF;
7427 return (a_len - b_len);
7429 return strncmp(de_a->name, de_b->name, a_len);
7433 * This is special sort function that makes sure that directory blocks
7434 * with a dirblock of zero are sorted to the beginning of the list.
7435 * This guarantees that the root node of the htree directories are
7436 * processed first, so we know what hash version to use.
7438 static EXT2_QSORT_TYPE special_dir_block_cmp(const void *a, const void *b)
7440 const struct ext2_db_entry *db_a =
7441 (const struct ext2_db_entry *) a;
7442 const struct ext2_db_entry *db_b =
7443 (const struct ext2_db_entry *) b;
7445 if (db_a->blockcnt && !db_b->blockcnt)
7448 if (!db_a->blockcnt && db_b->blockcnt)
7451 if (db_a->blk != db_b->blk)
7452 return (int) (db_a->blk - db_b->blk);
7454 if (db_a->ino != db_b->ino)
7455 return (int) (db_a->ino - db_b->ino);
7457 return (int) (db_a->blockcnt - db_b->blockcnt);
7462 * Make sure the first entry in the directory is '.', and that the
7463 * directory entry is sane.
7465 static int check_dot(e2fsck_t ctx,
7466 struct ext2_dir_entry *dirent,
7467 ext2_ino_t ino, struct problem_context *pctx)
7469 struct ext2_dir_entry *nextdir;
7476 problem = PR_2_MISSING_DOT;
7477 else if (((dirent->name_len & 0xFF) != 1) ||
7478 (dirent->name[0] != '.'))
7479 problem = PR_2_1ST_NOT_DOT;
7480 else if (dirent->name[1] != '\0')
7481 problem = PR_2_DOT_NULL_TERM;
7484 if (fix_problem(ctx, problem, pctx)) {
7485 if (dirent->rec_len < 12)
7486 dirent->rec_len = 12;
7487 dirent->inode = ino;
7488 dirent->name_len = 1;
7489 dirent->name[0] = '.';
7490 dirent->name[1] = '\0';
7495 if (dirent->inode != ino) {
7496 if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) {
7497 dirent->inode = ino;
7501 if (dirent->rec_len > 12) {
7502 new_len = dirent->rec_len - 12;
7505 fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) {
7506 nextdir = (struct ext2_dir_entry *)
7507 ((char *) dirent + 12);
7508 dirent->rec_len = 12;
7509 nextdir->rec_len = new_len;
7511 nextdir->name_len = 0;
7520 * Make sure the second entry in the directory is '..', and that the
7521 * directory entry is sane. We do not check the inode number of '..'
7522 * here; this gets done in pass 3.
7524 static int check_dotdot(e2fsck_t ctx,
7525 struct ext2_dir_entry *dirent,
7526 struct dir_info *dir, struct problem_context *pctx)
7531 problem = PR_2_MISSING_DOT_DOT;
7532 else if (((dirent->name_len & 0xFF) != 2) ||
7533 (dirent->name[0] != '.') ||
7534 (dirent->name[1] != '.'))
7535 problem = PR_2_2ND_NOT_DOT_DOT;
7536 else if (dirent->name[2] != '\0')
7537 problem = PR_2_DOT_DOT_NULL_TERM;
7540 if (fix_problem(ctx, problem, pctx)) {
7541 if (dirent->rec_len < 12)
7542 dirent->rec_len = 12;
7544 * Note: we don't have the parent inode just
7545 * yet, so we will fill it in with the root
7546 * inode. This will get fixed in pass 3.
7548 dirent->inode = EXT2_ROOT_INO;
7549 dirent->name_len = 2;
7550 dirent->name[0] = '.';
7551 dirent->name[1] = '.';
7552 dirent->name[2] = '\0';
7557 dir->dotdot = dirent->inode;
7562 * Check to make sure a directory entry doesn't contain any illegal
7565 static int check_name(e2fsck_t ctx,
7566 struct ext2_dir_entry *dirent,
7567 struct problem_context *pctx)
7573 for ( i = 0; i < (dirent->name_len & 0xFF); i++) {
7574 if (dirent->name[i] == '/' || dirent->name[i] == '\0') {
7576 fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx);
7579 dirent->name[i] = '.';
7588 * Check the directory filetype (if present)
7592 * Given a mode, return the ext2 file type
7594 static int ext2_file_type(unsigned int mode)
7596 if (LINUX_S_ISREG(mode))
7597 return EXT2_FT_REG_FILE;
7599 if (LINUX_S_ISDIR(mode))
7602 if (LINUX_S_ISCHR(mode))
7603 return EXT2_FT_CHRDEV;
7605 if (LINUX_S_ISBLK(mode))
7606 return EXT2_FT_BLKDEV;
7608 if (LINUX_S_ISLNK(mode))
7609 return EXT2_FT_SYMLINK;
7611 if (LINUX_S_ISFIFO(mode))
7612 return EXT2_FT_FIFO;
7614 if (LINUX_S_ISSOCK(mode))
7615 return EXT2_FT_SOCK;
7620 static _INLINE_ int check_filetype(e2fsck_t ctx,
7621 struct ext2_dir_entry *dirent,
7622 struct problem_context *pctx)
7624 int filetype = dirent->name_len >> 8;
7625 int should_be = EXT2_FT_UNKNOWN;
7626 struct ext2_inode inode;
7628 if (!(ctx->fs->super->s_feature_incompat &
7629 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
7630 if (filetype == 0 ||
7631 !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx))
7633 dirent->name_len = dirent->name_len & 0xFF;
7637 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) {
7638 should_be = EXT2_FT_DIR;
7639 } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map,
7641 should_be = EXT2_FT_REG_FILE;
7642 } else if (ctx->inode_bad_map &&
7643 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
7647 e2fsck_read_inode(ctx, dirent->inode, &inode,
7649 should_be = ext2_file_type(inode.i_mode);
7651 if (filetype == should_be)
7653 pctx->num = should_be;
7655 if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE,
7659 dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8;
7664 static void parse_int_node(ext2_filsys fs,
7665 struct ext2_db_entry *db,
7666 struct check_dir_struct *cd,
7667 struct dx_dir_info *dx_dir,
7670 struct ext2_dx_root_info *root;
7671 struct ext2_dx_entry *ent;
7672 struct ext2_dx_countlimit *limit;
7673 struct dx_dirblock_info *dx_db;
7674 int i, expect_limit, count;
7676 ext2_dirhash_t min_hash = 0xffffffff;
7677 ext2_dirhash_t max_hash = 0;
7678 ext2_dirhash_t hash = 0, prev_hash;
7680 if (db->blockcnt == 0) {
7681 root = (struct ext2_dx_root_info *) (block_buf + 24);
7684 printf("Root node dump:\n");
7685 printf("\t Reserved zero: %d\n", root->reserved_zero);
7686 printf("\t Hash Version: %d\n", root->hash_version);
7687 printf("\t Info length: %d\n", root->info_length);
7688 printf("\t Indirect levels: %d\n", root->indirect_levels);
7689 printf("\t Flags: %d\n", root->unused_flags);
7692 ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length);
7694 ent = (struct ext2_dx_entry *) (block_buf+8);
7696 limit = (struct ext2_dx_countlimit *) ent;
7699 printf("Number of entries (count): %d\n",
7700 ext2fs_le16_to_cpu(limit->count));
7701 printf("Number of entries (limit): %d\n",
7702 ext2fs_le16_to_cpu(limit->limit));
7705 count = ext2fs_le16_to_cpu(limit->count);
7706 expect_limit = (fs->blocksize - ((char *) ent - block_buf)) /
7707 sizeof(struct ext2_dx_entry);
7708 if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) {
7709 cd->pctx.num = ext2fs_le16_to_cpu(limit->limit);
7710 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx))
7711 goto clear_and_exit;
7713 if (count > expect_limit) {
7714 cd->pctx.num = count;
7715 if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx))
7716 goto clear_and_exit;
7717 count = expect_limit;
7720 for (i=0; i < count; i++) {
7722 hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0;
7724 printf("Entry #%d: Hash 0x%08x, block %d\n", i,
7725 hash, ext2fs_le32_to_cpu(ent[i].block));
7727 blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff;
7728 /* Check to make sure the block is valid */
7729 if (blk > (blk_t) dx_dir->numblocks) {
7731 if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK,
7733 goto clear_and_exit;
7735 if (hash < prev_hash &&
7736 fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx))
7737 goto clear_and_exit;
7738 dx_db = &dx_dir->dx_block[blk];
7739 if (dx_db->flags & DX_FLAG_REFERENCED) {
7740 dx_db->flags |= DX_FLAG_DUP_REF;
7742 dx_db->flags |= DX_FLAG_REFERENCED;
7743 dx_db->parent = db->blockcnt;
7745 if (hash < min_hash)
7747 if (hash > max_hash)
7749 dx_db->node_min_hash = hash;
7751 dx_db->node_max_hash =
7752 ext2fs_le32_to_cpu(ent[i+1].hash) & ~1;
7754 dx_db->node_max_hash = 0xfffffffe;
7755 dx_db->flags |= DX_FLAG_LAST;
7758 dx_db->flags |= DX_FLAG_FIRST;
7761 printf("Blockcnt = %d, min hash 0x%08x, max hash 0x%08x\n",
7762 db->blockcnt, min_hash, max_hash);
7764 dx_db = &dx_dir->dx_block[db->blockcnt];
7765 dx_db->min_hash = min_hash;
7766 dx_db->max_hash = max_hash;
7770 clear_htree(cd->ctx, cd->pctx.ino);
7771 dx_dir->numblocks = 0;
7773 #endif /* ENABLE_HTREE */
7776 * Given a busted directory, try to salvage it somehow.
7779 static void salvage_directory(ext2_filsys fs,
7780 struct ext2_dir_entry *dirent,
7781 struct ext2_dir_entry *prev,
7782 unsigned int *offset)
7784 char *cp = (char *) dirent;
7785 int left = fs->blocksize - *offset - dirent->rec_len;
7786 int name_len = dirent->name_len & 0xFF;
7789 * Special case of directory entry of size 8: copy what's left
7790 * of the directory block up to cover up the invalid hole.
7792 if ((left >= 12) && (dirent->rec_len == 8)) {
7793 memmove(cp, cp+8, left);
7794 memset(cp + left, 0, 8);
7798 * If the directory entry overruns the end of the directory
7799 * block, and the name is small enough to fit, then adjust the
7803 (name_len + 8 <= dirent->rec_len + left) &&
7804 dirent->inode <= fs->super->s_inodes_count &&
7805 strnlen(dirent->name, name_len) == name_len) {
7806 dirent->rec_len += left;
7810 * If the directory entry is a multiple of four, so it is
7811 * valid, let the previous directory entry absorb the invalid
7814 if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) {
7815 prev->rec_len += dirent->rec_len;
7816 *offset += dirent->rec_len;
7820 * Default salvage method --- kill all of the directory
7821 * entries for the rest of the block. We will either try to
7822 * absorb it into the previous directory entry, or create a
7823 * new empty directory entry the rest of the directory block.
7826 prev->rec_len += fs->blocksize - *offset;
7827 *offset = fs->blocksize;
7829 dirent->rec_len = fs->blocksize - *offset;
7830 dirent->name_len = 0;
7835 static int check_dir_block(ext2_filsys fs,
7836 struct ext2_db_entry *db,
7839 struct dir_info *subdir, *dir;
7840 struct dx_dir_info *dx_dir;
7842 struct dx_dirblock_info *dx_db = 0;
7843 #endif /* ENABLE_HTREE */
7844 struct ext2_dir_entry *dirent, *prev;
7845 ext2_dirhash_t hash;
7846 unsigned int offset = 0;
7847 int dir_modified = 0;
7849 blk_t block_nr = db->blk;
7850 ext2_ino_t ino = db->ino;
7852 struct check_dir_struct *cd;
7856 struct ext2_dx_root_info *root;
7857 struct ext2_dx_countlimit *limit;
7858 static dict_t de_dict;
7859 struct problem_context pctx;
7862 cd = (struct check_dir_struct *) priv_data;
7866 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
7867 return DIRENT_ABORT;
7869 if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max))
7870 return DIRENT_ABORT;
7873 * Make sure the inode is still in use (could have been
7874 * deleted in the duplicate/bad blocks pass.
7876 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)))
7880 cd->pctx.blk = block_nr;
7881 cd->pctx.blkcount = db->blockcnt;
7883 cd->pctx.dirent = 0;
7887 if (allocate_dir_block(ctx, db, &cd->pctx))
7897 if (ctx->dirs_to_hash &&
7898 ext2fs_u32_list_test(ctx->dirs_to_hash, ino))
7902 printf("In process_dir_block block %lu, #%d, inode %lu\n", block_nr,
7906 cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf);
7907 if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED)
7908 cd->pctx.errcode = 0; /* We'll handle this ourselves */
7909 if (cd->pctx.errcode) {
7910 if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) {
7911 ctx->flags |= E2F_FLAG_ABORT;
7912 return DIRENT_ABORT;
7914 memset(buf, 0, fs->blocksize);
7917 dx_dir = e2fsck_get_dx_dir_info(ctx, ino);
7918 if (dx_dir && dx_dir->numblocks) {
7919 if (db->blockcnt >= dx_dir->numblocks) {
7920 printf("XXX should never happen!!!\n");
7923 dx_db = &dx_dir->dx_block[db->blockcnt];
7924 dx_db->type = DX_DIRBLOCK_LEAF;
7925 dx_db->phys = block_nr;
7926 dx_db->min_hash = ~0;
7927 dx_db->max_hash = 0;
7929 dirent = (struct ext2_dir_entry *) buf;
7930 limit = (struct ext2_dx_countlimit *) (buf+8);
7931 if (db->blockcnt == 0) {
7932 root = (struct ext2_dx_root_info *) (buf + 24);
7933 dx_db->type = DX_DIRBLOCK_ROOT;
7934 dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
7935 if ((root->reserved_zero ||
7936 root->info_length < 8 ||
7937 root->indirect_levels > 1) &&
7938 fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
7939 clear_htree(ctx, ino);
7940 dx_dir->numblocks = 0;
7943 dx_dir->hashversion = root->hash_version;
7944 dx_dir->depth = root->indirect_levels + 1;
7945 } else if ((dirent->inode == 0) &&
7946 (dirent->rec_len == fs->blocksize) &&
7947 (dirent->name_len == 0) &&
7948 (ext2fs_le16_to_cpu(limit->limit) ==
7949 ((fs->blocksize-8) /
7950 sizeof(struct ext2_dx_entry))))
7951 dx_db->type = DX_DIRBLOCK_NODE;
7953 #endif /* ENABLE_HTREE */
7955 dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp);
7959 dirent = (struct ext2_dir_entry *) (buf + offset);
7960 cd->pctx.dirent = dirent;
7961 cd->pctx.num = offset;
7962 if (((offset + dirent->rec_len) > fs->blocksize) ||
7963 (dirent->rec_len < 12) ||
7964 ((dirent->rec_len % 4) != 0) ||
7965 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
7966 if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) {
7967 salvage_directory(fs, dirent, prev, &offset);
7971 goto abort_free_dict;
7973 if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) {
7974 if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) {
7975 dirent->name_len = EXT2_NAME_LEN;
7980 if (dot_state == 0) {
7981 if (check_dot(ctx, dirent, ino, &cd->pctx))
7983 } else if (dot_state == 1) {
7984 dir = e2fsck_get_dir_info(ctx, ino);
7986 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
7987 goto abort_free_dict;
7989 if (check_dotdot(ctx, dirent, dir, &cd->pctx))
7991 } else if (dirent->inode == ino) {
7992 problem = PR_2_LINK_DOT;
7993 if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) {
8003 * Make sure the inode listed is a legal one.
8005 if (((dirent->inode != EXT2_ROOT_INO) &&
8006 (dirent->inode < EXT2_FIRST_INODE(fs->super))) ||
8007 (dirent->inode > fs->super->s_inodes_count)) {
8008 problem = PR_2_BAD_INO;
8009 } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map,
8012 * If the inode is unused, offer to clear it.
8014 problem = PR_2_UNUSED_INODE;
8015 } else if (ctx->inode_bb_map &&
8016 (ext2fs_test_inode_bitmap(ctx->inode_bb_map,
8019 * If the inode is in a bad block, offer to
8022 problem = PR_2_BB_INODE;
8023 } else if ((dot_state > 1) &&
8024 ((dirent->name_len & 0xFF) == 1) &&
8025 (dirent->name[0] == '.')) {
8027 * If there's a '.' entry in anything other
8028 * than the first directory entry, it's a
8029 * duplicate entry that should be removed.
8031 problem = PR_2_DUP_DOT;
8032 } else if ((dot_state > 1) &&
8033 ((dirent->name_len & 0xFF) == 2) &&
8034 (dirent->name[0] == '.') &&
8035 (dirent->name[1] == '.')) {
8037 * If there's a '..' entry in anything other
8038 * than the second directory entry, it's a
8039 * duplicate entry that should be removed.
8041 problem = PR_2_DUP_DOT_DOT;
8042 } else if ((dot_state > 1) &&
8043 (dirent->inode == EXT2_ROOT_INO)) {
8045 * Don't allow links to the root directory.
8046 * We check this specially to make sure we
8047 * catch this error case even if the root
8048 * directory hasn't been created yet.
8050 problem = PR_2_LINK_ROOT;
8051 } else if ((dot_state > 1) &&
8052 (dirent->name_len & 0xFF) == 0) {
8054 * Don't allow zero-length directory names.
8056 problem = PR_2_NULL_NAME;
8060 if (fix_problem(ctx, problem, &cd->pctx)) {
8065 ext2fs_unmark_valid(fs);
8066 if (problem == PR_2_BAD_INO)
8072 * If the inode was marked as having bad fields in
8073 * pass1, process it and offer to fix/clear it.
8074 * (We wait until now so that we can display the
8075 * pathname to the user.)
8077 if (ctx->inode_bad_map &&
8078 ext2fs_test_inode_bitmap(ctx->inode_bad_map,
8080 if (e2fsck_process_bad_inode(ctx, ino,
8082 buf + fs->blocksize)) {
8087 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8088 return DIRENT_ABORT;
8091 if (check_name(ctx, dirent, &cd->pctx))
8094 if (check_filetype(ctx, dirent, &cd->pctx))
8099 ext2fs_dirhash(dx_dir->hashversion, dirent->name,
8100 (dirent->name_len & 0xFF),
8101 fs->super->s_hash_seed, &hash, 0);
8102 if (hash < dx_db->min_hash)
8103 dx_db->min_hash = hash;
8104 if (hash > dx_db->max_hash)
8105 dx_db->max_hash = hash;
8110 * If this is a directory, then mark its parent in its
8111 * dir_info structure. If the parent field is already
8112 * filled in, then this directory has more than one
8113 * hard link. We assume the first link is correct,
8114 * and ask the user if he/she wants to clear this one.
8116 if ((dot_state > 1) &&
8117 (ext2fs_test_inode_bitmap(ctx->inode_dir_map,
8119 subdir = e2fsck_get_dir_info(ctx, dirent->inode);
8121 cd->pctx.ino = dirent->inode;
8122 fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx);
8123 goto abort_free_dict;
8125 if (subdir->parent) {
8126 cd->pctx.ino2 = subdir->parent;
8127 if (fix_problem(ctx, PR_2_LINK_DIR,
8135 subdir->parent = ino;
8140 } else if (dict_lookup(&de_dict, dirent)) {
8141 clear_problem_context(&pctx);
8143 pctx.dirent = dirent;
8144 fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx);
8145 if (!ctx->dirs_to_hash)
8146 ext2fs_u32_list_create(&ctx->dirs_to_hash, 50);
8147 if (ctx->dirs_to_hash)
8148 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
8151 dict_alloc_insert(&de_dict, dirent, dirent);
8153 ext2fs_icount_increment(ctx->inode_count, dirent->inode,
8156 ctx->fs_links_count++;
8157 ctx->fs_total_count++;
8160 offset += dirent->rec_len;
8162 } while (offset < fs->blocksize);
8169 printf("db_block %d, type %d, min_hash 0x%0x, max_hash 0x%0x\n",
8170 db->blockcnt, dx_db->type,
8171 dx_db->min_hash, dx_db->max_hash);
8173 cd->pctx.dir = cd->pctx.ino;
8174 if ((dx_db->type == DX_DIRBLOCK_ROOT) ||
8175 (dx_db->type == DX_DIRBLOCK_NODE))
8176 parse_int_node(fs, db, cd, dx_dir, buf);
8178 #endif /* ENABLE_HTREE */
8179 if (offset != fs->blocksize) {
8180 cd->pctx.num = dirent->rec_len - fs->blocksize + offset;
8181 if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) {
8182 dirent->rec_len = cd->pctx.num;
8187 cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf);
8188 if (cd->pctx.errcode) {
8189 if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK,
8191 goto abort_free_dict;
8193 ext2fs_mark_changed(fs);
8195 dict_free_nodes(&de_dict);
8198 dict_free_nodes(&de_dict);
8199 ctx->flags |= E2F_FLAG_ABORT;
8200 return DIRENT_ABORT;
8204 * This function is called to deallocate a block, and is an interator
8205 * functioned called by deallocate inode via ext2fs_iterate_block().
8207 static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr,
8208 e2_blkcnt_t blockcnt FSCK_ATTR((unused)),
8209 blk_t ref_block FSCK_ATTR((unused)),
8210 int ref_offset FSCK_ATTR((unused)),
8213 e2fsck_t ctx = (e2fsck_t) priv_data;
8215 if (HOLE_BLKADDR(*block_nr))
8217 if ((*block_nr < fs->super->s_first_data_block) ||
8218 (*block_nr >= fs->super->s_blocks_count))
8220 ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr);
8221 ext2fs_block_alloc_stats(fs, *block_nr, -1);
8226 * This fuction deallocates an inode
8228 static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf)
8230 ext2_filsys fs = ctx->fs;
8231 struct ext2_inode inode;
8232 struct problem_context pctx;
8235 ext2fs_icount_store(ctx->inode_link_info, ino, 0);
8236 e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode");
8237 inode.i_links_count = 0;
8238 inode.i_dtime = time(0);
8239 e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode");
8240 clear_problem_context(&pctx);
8244 * Fix up the bitmaps...
8246 e2fsck_read_bitmaps(ctx);
8247 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino);
8248 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino);
8249 if (ctx->inode_bad_map)
8250 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
8251 ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode));
8253 if (inode.i_file_acl &&
8254 (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
8255 pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl,
8256 block_buf, -1, &count);
8257 if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) {
8262 pctx.blk = inode.i_file_acl;
8263 fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx);
8264 ctx->flags |= E2F_FLAG_ABORT;
8268 ext2fs_unmark_block_bitmap(ctx->block_found_map,
8270 ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1);
8272 inode.i_file_acl = 0;
8275 if (!ext2fs_inode_has_valid_blocks(&inode))
8278 if (LINUX_S_ISREG(inode.i_mode) &&
8279 (inode.i_size_high || inode.i_size & 0x80000000UL))
8282 pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf,
8283 deallocate_inode_block, ctx);
8285 fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx);
8286 ctx->flags |= E2F_FLAG_ABORT;
8292 * This fuction clears the htree flag on an inode
8294 static void clear_htree(e2fsck_t ctx, ext2_ino_t ino)
8296 struct ext2_inode inode;
8298 e2fsck_read_inode(ctx, ino, &inode, "clear_htree");
8299 inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL;
8300 e2fsck_write_inode(ctx, ino, &inode, "clear_htree");
8301 if (ctx->dirs_to_hash)
8302 ext2fs_u32_list_add(ctx->dirs_to_hash, ino);
8306 static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
8307 ext2_ino_t ino, char *buf)
8309 ext2_filsys fs = ctx->fs;
8310 struct ext2_inode inode;
8311 int inode_modified = 0;
8313 unsigned char *frag, *fsize;
8314 struct problem_context pctx;
8317 e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");
8319 clear_problem_context(&pctx);
8322 pctx.inode = &inode;
8324 if (inode.i_file_acl &&
8325 !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
8326 fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
8327 inode.i_file_acl = 0;
8328 #ifdef EXT2FS_ENABLE_SWAPFS
8330 * This is a special kludge to deal with long symlinks
8331 * on big endian systems. i_blocks had already been
8332 * decremented earlier in pass 1, but since i_file_acl
8333 * hadn't yet been cleared, ext2fs_read_inode()
8334 * assumed that the file was short symlink and would
8335 * not have byte swapped i_block[0]. Hence, we have
8336 * to byte-swap it here.
8338 if (LINUX_S_ISLNK(inode.i_mode) &&
8339 (fs->flags & EXT2_FLAG_SWAP_BYTES) &&
8340 (inode.i_blocks == fs->blocksize >> 9))
8341 inode.i_block[0] = ext2fs_swab32(inode.i_block[0]);
8347 if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
8348 !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
8349 !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
8350 !(LINUX_S_ISSOCK(inode.i_mode)))
8351 problem = PR_2_BAD_MODE;
8352 else if (LINUX_S_ISCHR(inode.i_mode)
8353 && !e2fsck_pass1_check_device_inode(fs, &inode))
8354 problem = PR_2_BAD_CHAR_DEV;
8355 else if (LINUX_S_ISBLK(inode.i_mode)
8356 && !e2fsck_pass1_check_device_inode(fs, &inode))
8357 problem = PR_2_BAD_BLOCK_DEV;
8358 else if (LINUX_S_ISFIFO(inode.i_mode)
8359 && !e2fsck_pass1_check_device_inode(fs, &inode))
8360 problem = PR_2_BAD_FIFO;
8361 else if (LINUX_S_ISSOCK(inode.i_mode)
8362 && !e2fsck_pass1_check_device_inode(fs, &inode))
8363 problem = PR_2_BAD_SOCKET;
8364 else if (LINUX_S_ISLNK(inode.i_mode)
8365 && !e2fsck_pass1_check_symlink(fs, &inode, buf)) {
8366 problem = PR_2_INVALID_SYMLINK;
8370 if (fix_problem(ctx, problem, &pctx)) {
8371 deallocate_inode(ctx, ino, 0);
8372 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8380 if (inode.i_faddr) {
8381 if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
8388 switch (fs->super->s_creator_os) {
8390 frag = &inode.osd2.linux2.l_i_frag;
8391 fsize = &inode.osd2.linux2.l_i_fsize;
8394 frag = &inode.osd2.hurd2.h_i_frag;
8395 fsize = &inode.osd2.hurd2.h_i_fsize;
8398 frag = &inode.osd2.masix2.m_i_frag;
8399 fsize = &inode.osd2.masix2.m_i_fsize;
8404 if (frag && *frag) {
8406 if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
8413 if (fsize && *fsize) {
8415 if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
8423 if (inode.i_file_acl &&
8424 ((inode.i_file_acl < fs->super->s_first_data_block) ||
8425 (inode.i_file_acl >= fs->super->s_blocks_count))) {
8426 if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
8427 inode.i_file_acl = 0;
8432 if (inode.i_dir_acl &&
8433 LINUX_S_ISDIR(inode.i_mode)) {
8434 if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
8435 inode.i_dir_acl = 0;
8442 e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
8444 ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino);
8450 * allocate_dir_block --- this function allocates a new directory
8451 * block for a particular inode; this is done if a directory has
8452 * a "hole" in it, or if a directory has a illegal block number
8453 * that was zeroed out and now needs to be replaced.
8455 static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db,
8456 struct problem_context *pctx)
8458 ext2_filsys fs = ctx->fs;
8461 struct ext2_inode inode;
8463 if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0)
8467 * Read the inode and block bitmaps in; we'll be messing with
8470 e2fsck_read_bitmaps(ctx);
8473 * First, find a free block
8475 pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8476 if (pctx->errcode) {
8477 pctx->str = "ext2fs_new_block";
8478 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8481 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8482 ext2fs_mark_block_bitmap(fs->block_map, blk);
8483 ext2fs_mark_bb_dirty(fs);
8486 * Now let's create the actual data block for the inode
8489 pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block);
8491 pctx->errcode = ext2fs_new_dir_block(fs, db->ino,
8492 EXT2_ROOT_INO, &block);
8494 if (pctx->errcode) {
8495 pctx->str = "ext2fs_new_dir_block";
8496 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8500 pctx->errcode = ext2fs_write_dir_block(fs, blk, block);
8501 ext2fs_free_mem(&block);
8502 if (pctx->errcode) {
8503 pctx->str = "ext2fs_write_dir_block";
8504 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8509 * Update the inode block count
8511 e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block");
8512 inode.i_blocks += fs->blocksize / 512;
8513 if (inode.i_size < (db->blockcnt+1) * fs->blocksize)
8514 inode.i_size = (db->blockcnt+1) * fs->blocksize;
8515 e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block");
8518 * Finally, update the block pointers for the inode
8521 pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE,
8522 0, update_dir_block, db);
8523 if (pctx->errcode) {
8524 pctx->str = "ext2fs_block_iterate";
8525 fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx);
8533 * This is a helper function for allocate_dir_block().
8535 static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)),
8537 e2_blkcnt_t blockcnt,
8538 blk_t ref_block FSCK_ATTR((unused)),
8539 int ref_offset FSCK_ATTR((unused)),
8542 struct ext2_db_entry *db;
8544 db = (struct ext2_db_entry *) priv_data;
8545 if (db->blockcnt == (int) blockcnt) {
8546 *block_nr = db->blk;
8547 return BLOCK_CHANGED;
8553 * pass3.c -- pass #3 of e2fsck: Check for directory connectivity
8555 * Pass #3 assures that all directories are connected to the
8556 * filesystem tree, using the following algorithm:
8558 * First, the root directory is checked to make sure it exists; if
8559 * not, e2fsck will offer to create a new one. It is then marked as
8562 * Then, pass3 interates over all directory inodes; for each directory
8563 * it attempts to trace up the filesystem tree, using dirinfo.parent
8564 * until it reaches a directory which has been marked "done". If it
8565 * can not do so, then the directory must be disconnected, and e2fsck
8566 * will offer to reconnect it to /lost+found. While it is chasing
8567 * parent pointers up the filesystem tree, if pass3 sees a directory
8568 * twice, then it has detected a filesystem loop, and it will again
8569 * offer to reconnect the directory to /lost+found in to break the
8572 * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to
8573 * reconnect inodes to /lost+found; this subroutine is also used by
8574 * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which
8575 * is responsible for creating /lost+found if it does not exist.
8577 * Pass 3 frees the following data structures:
8578 * - The dirinfo directory information cache.
8581 static void check_root(e2fsck_t ctx);
8582 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8583 struct problem_context *pctx);
8584 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent);
8586 static ext2fs_inode_bitmap inode_loop_detect;
8587 static ext2fs_inode_bitmap inode_done_map;
8589 static void e2fsck_pass3(e2fsck_t ctx)
8591 ext2_filsys fs = ctx->fs;
8593 #ifdef RESOURCE_TRACK
8594 struct resource_track rtrack;
8596 struct problem_context pctx;
8597 struct dir_info *dir;
8598 unsigned long maxdirs, count;
8600 #ifdef RESOURCE_TRACK
8601 init_resource_track(&rtrack);
8604 clear_problem_context(&pctx);
8607 mtrace_print("Pass 3");
8610 if (!(ctx->options & E2F_OPT_PREEN))
8611 fix_problem(ctx, PR_3_PASS_HEADER, &pctx);
8614 * Allocate some bitmaps to do loop detection.
8616 pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"),
8620 fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx);
8621 ctx->flags |= E2F_FLAG_ABORT;
8624 #ifdef RESOURCE_TRACK
8625 if (ctx->options & E2F_OPT_TIME) {
8626 e2fsck_clear_progbar(ctx);
8627 print_resource_track(_("Peak memory"), &ctx->global_rtrack);
8632 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8635 ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO);
8637 maxdirs = e2fsck_get_num_dirinfo(ctx);
8641 if ((ctx->progress)(ctx, 3, 0, maxdirs))
8644 for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) {
8645 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
8647 if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs))
8649 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino))
8650 if (check_directory(ctx, dir, &pctx))
8655 * Force the creation of /lost+found if not present
8657 if ((ctx->flags & E2F_OPT_READONLY) == 0)
8658 e2fsck_get_lost_and_found(ctx, 1);
8661 * If there are any directories that need to be indexed or
8662 * optimized, do it here.
8664 e2fsck_rehash_directories(ctx);
8667 e2fsck_free_dir_info(ctx);
8668 if (inode_loop_detect) {
8669 ext2fs_free_inode_bitmap(inode_loop_detect);
8670 inode_loop_detect = 0;
8672 if (inode_done_map) {
8673 ext2fs_free_inode_bitmap(inode_done_map);
8677 #ifdef RESOURCE_TRACK
8678 if (ctx->options & E2F_OPT_TIME2) {
8679 e2fsck_clear_progbar(ctx);
8680 print_resource_track(_("Pass 3"), &rtrack);
8686 * This makes sure the root inode is present; if not, we ask if the
8687 * user wants us to create it. Not creating it is a fatal error.
8689 static void check_root(e2fsck_t ctx)
8691 ext2_filsys fs = ctx->fs;
8693 struct ext2_inode inode;
8695 struct problem_context pctx;
8697 clear_problem_context(&pctx);
8699 if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) {
8701 * If the root inode is not a directory, die here. The
8702 * user must have answered 'no' in pass1 when we
8703 * offered to clear it.
8705 if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map,
8707 fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx);
8708 ctx->flags |= E2F_FLAG_ABORT;
8713 if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) {
8714 fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx);
8715 ctx->flags |= E2F_FLAG_ABORT;
8719 e2fsck_read_bitmaps(ctx);
8722 * First, find a free block
8724 pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8726 pctx.str = "ext2fs_new_block";
8727 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8728 ctx->flags |= E2F_FLAG_ABORT;
8731 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8732 ext2fs_mark_block_bitmap(fs->block_map, blk);
8733 ext2fs_mark_bb_dirty(fs);
8736 * Now let's create the actual data block for the inode
8738 pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO,
8741 pctx.str = "ext2fs_new_dir_block";
8742 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8743 ctx->flags |= E2F_FLAG_ABORT;
8747 pctx.errcode = ext2fs_write_dir_block(fs, blk, block);
8749 pctx.str = "ext2fs_write_dir_block";
8750 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8751 ctx->flags |= E2F_FLAG_ABORT;
8754 ext2fs_free_mem(&block);
8757 * Set up the inode structure
8759 memset(&inode, 0, sizeof(inode));
8760 inode.i_mode = 040755;
8761 inode.i_size = fs->blocksize;
8762 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
8763 inode.i_links_count = 2;
8764 inode.i_blocks = fs->blocksize / 512;
8765 inode.i_block[0] = blk;
8768 * Write out the inode.
8770 pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode);
8772 pctx.str = "ext2fs_write_inode";
8773 fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx);
8774 ctx->flags |= E2F_FLAG_ABORT;
8779 * Miscellaneous bookkeeping...
8781 e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO);
8782 ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2);
8783 ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2);
8785 ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO);
8786 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO);
8787 ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO);
8788 ext2fs_mark_ib_dirty(fs);
8792 * This subroutine is responsible for making sure that a particular
8793 * directory is connected to the root; if it isn't we trace it up as
8794 * far as we can go, and then offer to connect the resulting parent to
8795 * the lost+found. We have to do loop detection; if we ever discover
8796 * a loop, we treat that as a disconnected directory and offer to
8797 * reparent it to lost+found.
8799 * However, loop detection is expensive, because for very large
8800 * filesystems, the inode_loop_detect bitmap is huge, and clearing it
8801 * is non-trivial. Loops in filesystems are also a rare error case,
8802 * and we shouldn't optimize for error cases. So we try two passes of
8803 * the algorithm. The first time, we ignore loop detection and merely
8804 * increment a counter; if the counter exceeds some extreme threshold,
8805 * then we try again with the loop detection bitmap enabled.
8807 static int check_directory(e2fsck_t ctx, struct dir_info *dir,
8808 struct problem_context *pctx)
8810 ext2_filsys fs = ctx->fs;
8811 struct dir_info *p = dir;
8812 int loop_pass = 0, parent_count = 0;
8819 * Mark this inode as being "done"; by the time we
8820 * return from this function, the inode we either be
8821 * verified as being connected to the directory tree,
8822 * or we will have offered to reconnect this to
8825 * If it was marked done already, then we've reached a
8826 * parent we've already checked.
8828 if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino))
8832 * If this directory doesn't have a parent, or we've
8833 * seen the parent once already, then offer to
8834 * reparent it to lost+found
8838 (ext2fs_test_inode_bitmap(inode_loop_detect,
8841 if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) {
8842 if (e2fsck_reconnect_file(ctx, pctx->ino))
8843 ext2fs_unmark_valid(fs);
8845 p = e2fsck_get_dir_info(ctx, pctx->ino);
8846 p->parent = ctx->lost_and_found;
8847 fix_dotdot(ctx, p, ctx->lost_and_found);
8852 p = e2fsck_get_dir_info(ctx, p->parent);
8854 fix_problem(ctx, PR_3_NO_DIRINFO, pctx);
8858 ext2fs_mark_inode_bitmap(inode_loop_detect,
8860 } else if (parent_count++ > 2048) {
8862 * If we've run into a path depth that's
8863 * greater than 2048, try again with the inode
8864 * loop bitmap turned on and start from the
8868 if (inode_loop_detect)
8869 ext2fs_clear_inode_bitmap(inode_loop_detect);
8871 pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect);
8872 if (pctx->errcode) {
8875 PR_3_ALLOCATE_IBITMAP_ERROR, pctx);
8876 ctx->flags |= E2F_FLAG_ABORT;
8885 * Make sure that .. and the parent directory are the same;
8886 * offer to fix it if not.
8888 if (dir->parent != dir->dotdot) {
8889 pctx->ino = dir->ino;
8890 pctx->ino2 = dir->dotdot;
8891 pctx->dir = dir->parent;
8892 if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx))
8893 fix_dotdot(ctx, dir, dir->parent);
8899 * This routine gets the lost_and_found inode, making it a directory
8902 ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix)
8904 ext2_filsys fs = ctx->fs;
8908 struct ext2_inode inode;
8910 static const char name[] = "lost+found";
8911 struct problem_context pctx;
8912 struct dir_info *dirinfo;
8914 if (ctx->lost_and_found)
8915 return ctx->lost_and_found;
8917 clear_problem_context(&pctx);
8919 retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name,
8920 sizeof(name)-1, 0, &ino);
8924 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) {
8925 ctx->lost_and_found = ino;
8929 /* Lost+found isn't a directory! */
8933 if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx))
8936 /* OK, unlink the old /lost+found file. */
8937 pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0);
8939 pctx.str = "ext2fs_unlink";
8940 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
8943 dirinfo = e2fsck_get_dir_info(ctx, ino);
8945 dirinfo->parent = 0;
8946 e2fsck_adjust_inode_count(ctx, ino, -1);
8947 } else if (retval != EXT2_ET_FILE_NOT_FOUND) {
8948 pctx.errcode = retval;
8949 fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx);
8951 if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0))
8955 * Read the inode and block bitmaps in; we'll be messing with
8958 e2fsck_read_bitmaps(ctx);
8961 * First, find a free block
8963 retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk);
8965 pctx.errcode = retval;
8966 fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx);
8969 ext2fs_mark_block_bitmap(ctx->block_found_map, blk);
8970 ext2fs_block_alloc_stats(fs, blk, +1);
8973 * Next find a free inode.
8975 retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700,
8976 ctx->inode_used_map, &ino);
8978 pctx.errcode = retval;
8979 fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx);
8982 ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino);
8983 ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino);
8984 ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
8987 * Now let's create the actual data block for the inode
8989 retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block);
8991 pctx.errcode = retval;
8992 fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx);
8996 retval = ext2fs_write_dir_block(fs, blk, block);
8997 ext2fs_free_mem(&block);
8999 pctx.errcode = retval;
9000 fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx);
9005 * Set up the inode structure
9007 memset(&inode, 0, sizeof(inode));
9008 inode.i_mode = 040700;
9009 inode.i_size = fs->blocksize;
9010 inode.i_atime = inode.i_ctime = inode.i_mtime = time(0);
9011 inode.i_links_count = 2;
9012 inode.i_blocks = fs->blocksize / 512;
9013 inode.i_block[0] = blk;
9016 * Next, write out the inode.
9018 pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode);
9020 pctx.str = "ext2fs_write_inode";
9021 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
9025 * Finally, create the directory link
9027 pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR);
9029 pctx.str = "ext2fs_link";
9030 fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx);
9035 * Miscellaneous bookkeeping that needs to be kept straight.
9037 e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO);
9038 e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1);
9039 ext2fs_icount_store(ctx->inode_count, ino, 2);
9040 ext2fs_icount_store(ctx->inode_link_info, ino, 2);
9041 ctx->lost_and_found = ino;
9043 printf("/lost+found created; inode #%lu\n", ino);
9049 * This routine will connect a file to lost+found
9051 int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino)
9053 ext2_filsys fs = ctx->fs;
9056 struct problem_context pctx;
9057 struct ext2_inode inode;
9060 clear_problem_context(&pctx);
9063 if (!ctx->bad_lost_and_found && !ctx->lost_and_found) {
9064 if (e2fsck_get_lost_and_found(ctx, 1) == 0)
9065 ctx->bad_lost_and_found++;
9067 if (ctx->bad_lost_and_found) {
9068 fix_problem(ctx, PR_3_NO_LPF, &pctx);
9072 sprintf(name, "#%u", ino);
9073 if (ext2fs_read_inode(fs, ino, &inode) == 0)
9074 file_type = ext2_file_type(inode.i_mode);
9075 retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type);
9076 if (retval == EXT2_ET_DIR_NO_SPACE) {
9077 if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx))
9079 retval = e2fsck_expand_directory(ctx, ctx->lost_and_found,
9082 pctx.errcode = retval;
9083 fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx);
9086 retval = ext2fs_link(fs, ctx->lost_and_found, name,
9090 pctx.errcode = retval;
9091 fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx);
9094 e2fsck_adjust_inode_count(ctx, ino, 1);
9100 * Utility routine to adjust the inode counts on an inode.
9102 errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj)
9104 ext2_filsys fs = ctx->fs;
9106 struct ext2_inode inode;
9111 retval = ext2fs_read_inode(fs, ino, &inode);
9116 printf("Adjusting link count for inode %lu by %d (from %d)\n", ino, adj,
9117 inode.i_links_count);
9121 ext2fs_icount_increment(ctx->inode_count, ino, 0);
9122 if (inode.i_links_count == (__u16) ~0)
9124 ext2fs_icount_increment(ctx->inode_link_info, ino, 0);
9125 inode.i_links_count++;
9126 } else if (adj == -1) {
9127 ext2fs_icount_decrement(ctx->inode_count, ino, 0);
9128 if (inode.i_links_count == 0)
9130 ext2fs_icount_decrement(ctx->inode_link_info, ino, 0);
9131 inode.i_links_count--;
9134 retval = ext2fs_write_inode(fs, ino, &inode);
9142 * Fix parent --- this routine fixes up the parent of a directory.
9144 struct fix_dotdot_struct {
9151 static int fix_dotdot_proc(struct ext2_dir_entry *dirent,
9152 int offset FSCK_ATTR((unused)),
9153 int blocksize FSCK_ATTR((unused)),
9154 char *buf FSCK_ATTR((unused)),
9157 struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data;
9159 struct problem_context pctx;
9161 if ((dirent->name_len & 0xFF) != 2)
9163 if (strncmp(dirent->name, "..", 2))
9166 clear_problem_context(&pctx);
9168 retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1);
9170 pctx.errcode = retval;
9171 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
9173 retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1);
9175 pctx.errcode = retval;
9176 fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx);
9178 dirent->inode = fp->parent;
9181 return DIRENT_ABORT | DIRENT_CHANGED;
9184 static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent)
9186 ext2_filsys fs = ctx->fs;
9188 struct fix_dotdot_struct fp;
9189 struct problem_context pctx;
9197 printf("Fixing '..' of inode %lu to be %lu...\n", dir->ino, parent);
9200 retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY,
9201 0, fix_dotdot_proc, &fp);
9202 if (retval || !fp.done) {
9203 clear_problem_context(&pctx);
9204 pctx.ino = dir->ino;
9205 pctx.errcode = retval;
9206 fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR :
9207 PR_3_FIX_PARENT_NOFIND, &pctx);
9208 ext2fs_unmark_valid(fs);
9210 dir->dotdot = parent;
9216 * These routines are responsible for expanding a /lost+found if it is
9220 struct expand_dir_struct {
9222 int guaranteed_size;
9229 static int expand_dir_proc(ext2_filsys fs,
9231 e2_blkcnt_t blockcnt,
9232 blk_t ref_block FSCK_ATTR((unused)),
9233 int ref_offset FSCK_ATTR((unused)),
9236 struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
9238 static blk_t last_blk = 0;
9245 if (es->guaranteed_size && blockcnt >= es->guaranteed_size)
9249 es->last_block = blockcnt;
9251 last_blk = *blocknr;
9254 retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map,
9261 retval = ext2fs_new_dir_block(fs, 0, 0, &block);
9267 retval = ext2fs_write_dir_block(fs, new_blk, block);
9269 retval = ext2fs_get_mem(fs->blocksize, &block);
9274 memset(block, 0, fs->blocksize);
9275 retval = io_channel_write_blk(fs->io, new_blk, 1, block);
9281 ext2fs_free_mem(&block);
9283 ext2fs_mark_block_bitmap(ctx->block_found_map, new_blk);
9284 ext2fs_block_alloc_stats(fs, new_blk, +1);
9288 return (BLOCK_CHANGED | BLOCK_ABORT);
9290 return BLOCK_CHANGED;
9293 errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir,
9294 int num, int guaranteed_size)
9296 ext2_filsys fs = ctx->fs;
9298 struct expand_dir_struct es;
9299 struct ext2_inode inode;
9301 if (!(fs->flags & EXT2_FLAG_RW))
9302 return EXT2_ET_RO_FILSYS;
9305 * Read the inode and block bitmaps in; we'll be messing with
9308 e2fsck_read_bitmaps(ctx);
9310 retval = ext2fs_check_directory(fs, dir);
9315 es.guaranteed_size = guaranteed_size;
9321 retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
9322 0, expand_dir_proc, &es);
9328 * Update the size and block count fields in the inode.
9330 retval = ext2fs_read_inode(fs, dir, &inode);
9334 inode.i_size = (es.last_block + 1) * fs->blocksize;
9335 inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
9337 e2fsck_write_inode(ctx, dir, &inode, "expand_directory");
9343 * pass4.c -- pass #4 of e2fsck: Check reference counts
9345 * Pass 4 frees the following data structures:
9346 * - A bitmap of which inodes are in bad blocks. (inode_bb_map)
9347 * - A bitmap of which inodes are imagic inodes. (inode_imagic_map)
9351 * This routine is called when an inode is not connected to the
9354 * This subroutine returns 1 then the caller shouldn't bother with the
9355 * rest of the pass 4 tests.
9357 static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i)
9359 ext2_filsys fs = ctx->fs;
9360 struct ext2_inode inode;
9361 struct problem_context pctx;
9363 e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode");
9364 clear_problem_context(&pctx);
9366 pctx.inode = &inode;
9369 * Offer to delete any zero-length files that does not have
9370 * blocks. If there is an EA block, it might have useful
9371 * information, so we won't prompt to delete it, but let it be
9372 * reconnected to lost+found.
9374 if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) ||
9375 LINUX_S_ISDIR(inode.i_mode))) {
9376 if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) {
9377 ext2fs_icount_store(ctx->inode_link_info, i, 0);
9378 inode.i_links_count = 0;
9379 inode.i_dtime = time(0);
9380 e2fsck_write_inode(ctx, i, &inode,
9381 "disconnect_inode");
9383 * Fix up the bitmaps...
9385 e2fsck_read_bitmaps(ctx);
9386 ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i);
9387 ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i);
9388 ext2fs_inode_alloc_stats2(fs, i, -1,
9389 LINUX_S_ISDIR(inode.i_mode));
9395 * Prompt to reconnect.
9397 if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) {
9398 if (e2fsck_reconnect_file(ctx, i))
9399 ext2fs_unmark_valid(fs);
9402 * If we don't attach the inode, then skip the
9403 * i_links_test since there's no point in trying to
9404 * force i_links_count to zero.
9406 ext2fs_unmark_valid(fs);
9413 static void e2fsck_pass4(e2fsck_t ctx)
9415 ext2_filsys fs = ctx->fs;
9417 struct ext2_inode inode;
9418 #ifdef RESOURCE_TRACK
9419 struct resource_track rtrack;
9421 struct problem_context pctx;
9422 __u16 link_count, link_counted;
9424 int group, maxgroup;
9426 #ifdef RESOURCE_TRACK
9427 init_resource_track(&rtrack);
9431 mtrace_print("Pass 4");
9434 clear_problem_context(&pctx);
9436 if (!(ctx->options & E2F_OPT_PREEN))
9437 fix_problem(ctx, PR_4_PASS_HEADER, &pctx);
9440 maxgroup = fs->group_desc_count;
9442 if ((ctx->progress)(ctx, 4, 0, maxgroup))
9445 for (i=1; i <= fs->super->s_inodes_count; i++) {
9446 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
9448 if ((i % fs->super->s_inodes_per_group) == 0) {
9451 if ((ctx->progress)(ctx, 4, group, maxgroup))
9454 if (i == EXT2_BAD_INO ||
9455 (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super)))
9457 if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) ||
9458 (ctx->inode_imagic_map &&
9459 ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i)) ||
9460 (ctx->inode_bb_map &&
9461 ext2fs_test_inode_bitmap(ctx->inode_bb_map, i)))
9463 ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count);
9464 ext2fs_icount_fetch(ctx->inode_count, i, &link_counted);
9465 if (link_counted == 0) {
9467 buf = e2fsck_allocate_memory(ctx,
9468 fs->blocksize, "bad_inode buffer");
9469 if (e2fsck_process_bad_inode(ctx, 0, i, buf))
9471 if (disconnect_inode(ctx, i))
9473 ext2fs_icount_fetch(ctx->inode_link_info, i,
9475 ext2fs_icount_fetch(ctx->inode_count, i,
9478 if (link_counted != link_count) {
9479 e2fsck_read_inode(ctx, i, &inode, "pass4");
9481 pctx.inode = &inode;
9482 if (link_count != inode.i_links_count) {
9483 pctx.num = link_count;
9485 PR_4_INCONSISTENT_COUNT, &pctx);
9487 pctx.num = link_counted;
9488 if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) {
9489 inode.i_links_count = link_counted;
9490 e2fsck_write_inode(ctx, i, &inode, "pass4");
9494 ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0;
9495 ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0;
9496 ext2fs_free_inode_bitmap(ctx->inode_bb_map);
9497 ctx->inode_bb_map = 0;
9498 ext2fs_free_inode_bitmap(ctx->inode_imagic_map);
9499 ctx->inode_imagic_map = 0;
9501 ext2fs_free_mem(&buf);
9502 #ifdef RESOURCE_TRACK
9503 if (ctx->options & E2F_OPT_TIME2) {
9504 e2fsck_clear_progbar(ctx);
9505 print_resource_track(_("Pass 4"), &rtrack);
9511 * pass5.c --- check block and inode bitmaps against on-disk bitmaps
9514 #define NO_BLK ((blk_t) -1)
9516 static void print_bitmap_problem(e2fsck_t ctx, int problem,
9517 struct problem_context *pctx)
9520 case PR_5_BLOCK_UNUSED:
9521 if (pctx->blk == pctx->blk2)
9524 problem = PR_5_BLOCK_RANGE_UNUSED;
9526 case PR_5_BLOCK_USED:
9527 if (pctx->blk == pctx->blk2)
9530 problem = PR_5_BLOCK_RANGE_USED;
9532 case PR_5_INODE_UNUSED:
9533 if (pctx->ino == pctx->ino2)
9536 problem = PR_5_INODE_RANGE_UNUSED;
9538 case PR_5_INODE_USED:
9539 if (pctx->ino == pctx->ino2)
9542 problem = PR_5_INODE_RANGE_USED;
9545 fix_problem(ctx, problem, pctx);
9546 pctx->blk = pctx->blk2 = NO_BLK;
9547 pctx->ino = pctx->ino2 = 0;
9550 static void check_block_bitmaps(e2fsck_t ctx)
9552 ext2_filsys fs = ctx->fs;
9556 unsigned int blocks = 0;
9557 unsigned int free_blocks = 0;
9560 struct problem_context pctx;
9561 int problem, save_problem, fixit, had_problem;
9564 clear_problem_context(&pctx);
9565 free_array = (int *) e2fsck_allocate_memory(ctx,
9566 fs->group_desc_count * sizeof(int), "free block count array");
9568 if ((fs->super->s_first_data_block <
9569 ext2fs_get_block_bitmap_start(ctx->block_found_map)) ||
9570 (fs->super->s_blocks_count-1 >
9571 ext2fs_get_block_bitmap_end(ctx->block_found_map))) {
9573 pctx.blk = fs->super->s_first_data_block;
9574 pctx.blk2 = fs->super->s_blocks_count -1;
9575 pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map);
9576 pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map);
9577 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9579 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9583 if ((fs->super->s_first_data_block <
9584 ext2fs_get_block_bitmap_start(fs->block_map)) ||
9585 (fs->super->s_blocks_count-1 >
9586 ext2fs_get_block_bitmap_end(fs->block_map))) {
9588 pctx.blk = fs->super->s_first_data_block;
9589 pctx.blk2 = fs->super->s_blocks_count -1;
9590 pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map);
9591 pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map);
9592 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9594 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9601 pctx.blk = pctx.blk2 = NO_BLK;
9602 for (i = fs->super->s_first_data_block;
9603 i < fs->super->s_blocks_count;
9605 actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i);
9606 bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i);
9608 if (actual == bitmap)
9611 if (!actual && bitmap) {
9613 * Block not used, but marked in use in the bitmap.
9615 problem = PR_5_BLOCK_UNUSED;
9618 * Block used, but not marked in use in the bitmap.
9620 problem = PR_5_BLOCK_USED;
9622 if (pctx.blk == NO_BLK) {
9623 pctx.blk = pctx.blk2 = i;
9624 save_problem = problem;
9626 if ((problem == save_problem) &&
9630 print_bitmap_problem(ctx, save_problem, &pctx);
9631 pctx.blk = pctx.blk2 = i;
9632 save_problem = problem;
9635 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
9644 if ((blocks == fs->super->s_blocks_per_group) ||
9645 (i == fs->super->s_blocks_count-1)) {
9646 free_array[group] = group_free;
9651 if ((ctx->progress)(ctx, 5, group,
9652 fs->group_desc_count*2))
9656 if (pctx.blk != NO_BLK)
9657 print_bitmap_problem(ctx, save_problem, &pctx);
9659 fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP);
9662 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
9665 ext2fs_free_block_bitmap(fs->block_map);
9666 retval = ext2fs_copy_bitmap(ctx->block_found_map,
9669 clear_problem_context(&pctx);
9670 fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx);
9671 ctx->flags |= E2F_FLAG_ABORT;
9674 ext2fs_set_bitmap_padding(fs->block_map);
9675 ext2fs_mark_bb_dirty(fs);
9677 /* Redo the counts */
9678 blocks = 0; free_blocks = 0; group_free = 0; group = 0;
9679 memset(free_array, 0, fs->group_desc_count * sizeof(int));
9681 } else if (fixit == 0)
9682 ext2fs_unmark_valid(fs);
9684 for (i = 0; i < fs->group_desc_count; i++) {
9685 if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) {
9687 pctx.blk = fs->group_desc[i].bg_free_blocks_count;
9688 pctx.blk2 = free_array[i];
9690 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP,
9692 fs->group_desc[i].bg_free_blocks_count =
9694 ext2fs_mark_super_dirty(fs);
9696 ext2fs_unmark_valid(fs);
9699 if (free_blocks != fs->super->s_free_blocks_count) {
9701 pctx.blk = fs->super->s_free_blocks_count;
9702 pctx.blk2 = free_blocks;
9704 if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) {
9705 fs->super->s_free_blocks_count = free_blocks;
9706 ext2fs_mark_super_dirty(fs);
9708 ext2fs_unmark_valid(fs);
9710 ext2fs_free_mem(&free_array);
9713 static void check_inode_bitmaps(e2fsck_t ctx)
9715 ext2_filsys fs = ctx->fs;
9717 unsigned int free_inodes = 0;
9721 unsigned int inodes = 0;
9726 struct problem_context pctx;
9727 int problem, save_problem, fixit, had_problem;
9729 clear_problem_context(&pctx);
9730 free_array = (int *) e2fsck_allocate_memory(ctx,
9731 fs->group_desc_count * sizeof(int), "free inode count array");
9733 dir_array = (int *) e2fsck_allocate_memory(ctx,
9734 fs->group_desc_count * sizeof(int), "directory count array");
9736 if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) ||
9737 (fs->super->s_inodes_count >
9738 ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) {
9741 pctx.blk2 = fs->super->s_inodes_count;
9742 pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map);
9743 pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map);
9744 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9746 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9749 if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) ||
9750 (fs->super->s_inodes_count >
9751 ext2fs_get_inode_bitmap_end(fs->inode_map))) {
9754 pctx.blk2 = fs->super->s_inodes_count;
9755 pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map);
9756 pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map);
9757 fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx);
9759 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9766 pctx.ino = pctx.ino2 = 0;
9767 for (i = 1; i <= fs->super->s_inodes_count; i++) {
9768 actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i);
9769 bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i);
9771 if (actual == bitmap)
9774 if (!actual && bitmap) {
9776 * Inode wasn't used, but marked in bitmap
9778 problem = PR_5_INODE_UNUSED;
9779 } else /* if (actual && !bitmap) */ {
9781 * Inode used, but not in bitmap
9783 problem = PR_5_INODE_USED;
9785 if (pctx.ino == 0) {
9786 pctx.ino = pctx.ino2 = i;
9787 save_problem = problem;
9789 if ((problem == save_problem) &&
9793 print_bitmap_problem(ctx, save_problem, &pctx);
9794 pctx.ino = pctx.ino2 = i;
9795 save_problem = problem;
9798 ctx->flags |= E2F_FLAG_PROG_SUPPRESS;
9806 if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i))
9810 if ((inodes == fs->super->s_inodes_per_group) ||
9811 (i == fs->super->s_inodes_count)) {
9812 free_array[group] = group_free;
9813 dir_array[group] = dirs_count;
9819 if ((ctx->progress)(ctx, 5,
9820 group + fs->group_desc_count,
9821 fs->group_desc_count*2))
9826 print_bitmap_problem(ctx, save_problem, &pctx);
9829 fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP);
9832 ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS;
9835 ext2fs_free_inode_bitmap(fs->inode_map);
9836 retval = ext2fs_copy_bitmap(ctx->inode_used_map,
9839 clear_problem_context(&pctx);
9840 fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx);
9841 ctx->flags |= E2F_FLAG_ABORT;
9844 ext2fs_set_bitmap_padding(fs->inode_map);
9845 ext2fs_mark_ib_dirty(fs);
9848 inodes = 0; free_inodes = 0; group_free = 0;
9849 dirs_count = 0; group = 0;
9850 memset(free_array, 0, fs->group_desc_count * sizeof(int));
9851 memset(dir_array, 0, fs->group_desc_count * sizeof(int));
9853 } else if (fixit == 0)
9854 ext2fs_unmark_valid(fs);
9856 for (i = 0; i < fs->group_desc_count; i++) {
9857 if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) {
9859 pctx.ino = fs->group_desc[i].bg_free_inodes_count;
9860 pctx.ino2 = free_array[i];
9861 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP,
9863 fs->group_desc[i].bg_free_inodes_count =
9865 ext2fs_mark_super_dirty(fs);
9867 ext2fs_unmark_valid(fs);
9869 if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) {
9871 pctx.ino = fs->group_desc[i].bg_used_dirs_count;
9872 pctx.ino2 = dir_array[i];
9874 if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP,
9876 fs->group_desc[i].bg_used_dirs_count =
9878 ext2fs_mark_super_dirty(fs);
9880 ext2fs_unmark_valid(fs);
9883 if (free_inodes != fs->super->s_free_inodes_count) {
9885 pctx.ino = fs->super->s_free_inodes_count;
9886 pctx.ino2 = free_inodes;
9888 if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) {
9889 fs->super->s_free_inodes_count = free_inodes;
9890 ext2fs_mark_super_dirty(fs);
9892 ext2fs_unmark_valid(fs);
9894 ext2fs_free_mem(&free_array);
9895 ext2fs_free_mem(&dir_array);
9898 static void check_inode_end(e2fsck_t ctx)
9900 ext2_filsys fs = ctx->fs;
9901 ext2_ino_t end, save_inodes_count, i;
9902 struct problem_context pctx;
9904 clear_problem_context(&pctx);
9906 end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count;
9907 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end,
9908 &save_inodes_count);
9911 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9912 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9915 if (save_inodes_count == end)
9918 for (i = save_inodes_count + 1; i <= end; i++) {
9919 if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) {
9920 if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) {
9921 for (i = save_inodes_count + 1; i <= end; i++)
9922 ext2fs_mark_inode_bitmap(fs->inode_map,
9924 ext2fs_mark_ib_dirty(fs);
9926 ext2fs_unmark_valid(fs);
9931 pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map,
9932 save_inodes_count, 0);
9935 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9936 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9941 static void check_block_end(e2fsck_t ctx)
9943 ext2_filsys fs = ctx->fs;
9944 blk_t end, save_blocks_count, i;
9945 struct problem_context pctx;
9947 clear_problem_context(&pctx);
9949 end = fs->block_map->start +
9950 (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1;
9951 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end,
9952 &save_blocks_count);
9955 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9956 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9959 if (save_blocks_count == end)
9962 for (i = save_blocks_count + 1; i <= end; i++) {
9963 if (!ext2fs_test_block_bitmap(fs->block_map, i)) {
9964 if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) {
9965 for (i = save_blocks_count + 1; i <= end; i++)
9966 ext2fs_mark_block_bitmap(fs->block_map,
9968 ext2fs_mark_bb_dirty(fs);
9970 ext2fs_unmark_valid(fs);
9975 pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map,
9976 save_blocks_count, 0);
9979 fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx);
9980 ctx->flags |= E2F_FLAG_ABORT; /* fatal */
9985 static void e2fsck_pass5(e2fsck_t ctx)
9987 #ifdef RESOURCE_TRACK
9988 struct resource_track rtrack;
9990 struct problem_context pctx;
9993 mtrace_print("Pass 5");
9996 #ifdef RESOURCE_TRACK
9997 init_resource_track(&rtrack);
10000 clear_problem_context(&pctx);
10002 if (!(ctx->options & E2F_OPT_PREEN))
10003 fix_problem(ctx, PR_5_PASS_HEADER, &pctx);
10006 if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2))
10009 e2fsck_read_bitmaps(ctx);
10011 check_block_bitmaps(ctx);
10012 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
10014 check_inode_bitmaps(ctx);
10015 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
10017 check_inode_end(ctx);
10018 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
10020 check_block_end(ctx);
10021 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
10024 ext2fs_free_inode_bitmap(ctx->inode_used_map);
10025 ctx->inode_used_map = 0;
10026 ext2fs_free_inode_bitmap(ctx->inode_dir_map);
10027 ctx->inode_dir_map = 0;
10028 ext2fs_free_block_bitmap(ctx->block_found_map);
10029 ctx->block_found_map = 0;
10031 #ifdef RESOURCE_TRACK
10032 if (ctx->options & E2F_OPT_TIME2) {
10033 e2fsck_clear_progbar(ctx);
10034 print_resource_track(_("Pass 5"), &rtrack);
10040 * problem.c --- report filesystem problems to the user
10043 #define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */
10044 #define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */
10045 #define PR_NO_DEFAULT 0x000004 /* Default to no */
10046 #define PR_MSG_ONLY 0x000008 /* Print message only */
10048 /* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */
10050 #define PR_FATAL 0x001000 /* Fatal error */
10051 #define PR_AFTER_CODE 0x002000 /* After asking the first question, */
10053 #define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */
10054 #define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */
10055 #define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */
10056 #define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */
10057 #define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */
10060 #define PROMPT_NONE 0
10061 #define PROMPT_FIX 1
10062 #define PROMPT_CLEAR 2
10063 #define PROMPT_RELOCATE 3
10064 #define PROMPT_ALLOCATE 4
10065 #define PROMPT_EXPAND 5
10066 #define PROMPT_CONNECT 6
10067 #define PROMPT_CREATE 7
10068 #define PROMPT_SALVAGE 8
10069 #define PROMPT_TRUNCATE 9
10070 #define PROMPT_CLEAR_INODE 10
10071 #define PROMPT_ABORT 11
10072 #define PROMPT_SPLIT 12
10073 #define PROMPT_CONTINUE 13
10074 #define PROMPT_CLONE 14
10075 #define PROMPT_DELETE 15
10076 #define PROMPT_SUPPRESS 16
10077 #define PROMPT_UNLINK 17
10078 #define PROMPT_CLEAR_HTREE 18
10079 #define PROMPT_RECREATE 19
10080 #define PROMPT_NULL 20
10082 struct e2fsck_problem {
10083 problem_t e2p_code;
10084 const char * e2p_description;
10087 problem_t second_code;
10090 struct latch_descr {
10092 problem_t question;
10093 problem_t end_message;
10098 * These are the prompts which are used to ask the user if they want
10099 * to fix a problem.
10101 static const char * const prompt[] = {
10102 N_("(no prompt)"), /* 0 */
10104 N_("Clear"), /* 2 */
10105 N_("Relocate"), /* 3 */
10106 N_("Allocate"), /* 4 */
10107 N_("Expand"), /* 5 */
10108 N_("Connect to /lost+found"), /* 6 */
10109 N_("Create"), /* 7 */
10110 N_("Salvage"), /* 8 */
10111 N_("Truncate"), /* 9 */
10112 N_("Clear inode"), /* 10 */
10113 N_("Abort"), /* 11 */
10114 N_("Split"), /* 12 */
10115 N_("Continue"), /* 13 */
10116 N_("Clone duplicate/bad blocks"), /* 14 */
10117 N_("Delete file"), /* 15 */
10118 N_("Suppress messages"),/* 16 */
10119 N_("Unlink"), /* 17 */
10120 N_("Clear HTree index"),/* 18 */
10121 N_("Recreate"), /* 19 */
10126 * These messages are printed when we are preen mode and we will be
10127 * automatically fixing the problem.
10129 static const char * const preen_msg[] = {
10130 N_("(NONE)"), /* 0 */
10131 N_("FIXED"), /* 1 */
10132 N_("CLEARED"), /* 2 */
10133 N_("RELOCATED"), /* 3 */
10134 N_("ALLOCATED"), /* 4 */
10135 N_("EXPANDED"), /* 5 */
10136 N_("RECONNECTED"), /* 6 */
10137 N_("CREATED"), /* 7 */
10138 N_("SALVAGED"), /* 8 */
10139 N_("TRUNCATED"), /* 9 */
10140 N_("INODE CLEARED"), /* 10 */
10141 N_("ABORTED"), /* 11 */
10142 N_("SPLIT"), /* 12 */
10143 N_("CONTINUING"), /* 13 */
10144 N_("DUPLICATE/BAD BLOCKS CLONED"), /* 14 */
10145 N_("FILE DELETED"), /* 15 */
10146 N_("SUPPRESSED"), /* 16 */
10147 N_("UNLINKED"), /* 17 */
10148 N_("HTREE INDEX CLEARED"),/* 18 */
10149 N_("WILL RECREATE"), /* 19 */
10153 static const struct e2fsck_problem problem_table[] = {
10155 /* Pre-Pass 1 errors */
10157 /* Block bitmap not in group */
10158 { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"),
10159 PROMPT_RELOCATE, PR_LATCH_RELOC },
10161 /* Inode bitmap not in group */
10162 { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"),
10163 PROMPT_RELOCATE, PR_LATCH_RELOC },
10165 /* Inode table not in group */
10166 { PR_0_ITABLE_NOT_GROUP,
10167 N_("@i table for @g %g is not in @g. (@b %b)\n"
10168 "WARNING: SEVERE DATA LOSS POSSIBLE.\n"),
10169 PROMPT_RELOCATE, PR_LATCH_RELOC },
10171 /* Superblock corrupt */
10173 N_("\nThe @S could not be read or does not describe a correct ext2\n"
10174 "@f. If the @v is valid and it really contains an ext2\n"
10175 "@f (and not swap or ufs or something else), then the @S\n"
10176 "is corrupt, and you might try running e2fsck with an alternate @S:\n"
10177 " e2fsck -b %S <@v>\n\n"),
10178 PROMPT_NONE, PR_FATAL },
10180 /* Filesystem size is wrong */
10181 { PR_0_FS_SIZE_WRONG,
10182 N_("The @f size (according to the @S) is %b @bs\n"
10183 "The physical size of the @v is %c @bs\n"
10184 "Either the @S or the partition table is likely to be corrupt!\n"),
10187 /* Fragments not supported */
10188 { PR_0_NO_FRAGMENTS,
10189 N_("@S @b_size = %b, fragsize = %c.\n"
10190 "This version of e2fsck does not support fragment sizes different\n"
10191 "from the @b size.\n"),
10192 PROMPT_NONE, PR_FATAL },
10194 /* Bad blocks_per_group */
10195 { PR_0_BLOCKS_PER_GROUP,
10196 N_("@S @bs_per_group = %b, should have been %c\n"),
10197 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10199 /* Bad first_data_block */
10200 { PR_0_FIRST_DATA_BLOCK,
10201 N_("@S first_data_@b = %b, should have been %c\n"),
10202 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10204 /* Adding UUID to filesystem */
10206 N_("@f did not have a UUID; generating one.\n\n"),
10209 /* Relocate hint */
10210 { PR_0_RELOCATE_HINT,
10211 N_("Note: if there is several inode or block bitmap blocks\n"
10212 "which require relocation, or one part of the inode table\n"
10213 "which must be moved, you may wish to try running e2fsck\n"
10214 "with the '-b %S' option first. The problem may lie only\n"
10215 "with the primary block group descriptor, and the backup\n"
10216 "block group descriptor may be OK.\n\n"),
10217 PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE },
10219 /* Miscellaneous superblock corruption */
10220 { PR_0_MISC_CORRUPT_SUPER,
10221 N_("Corruption found in @S. (%s = %N).\n"),
10222 PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT },
10224 /* Error determing physical device size of filesystem */
10225 { PR_0_GETSIZE_ERROR,
10226 N_("Error determining size of the physical @v: %m\n"),
10227 PROMPT_NONE, PR_FATAL },
10229 /* Inode count in superblock is incorrect */
10230 { PR_0_INODE_COUNT_WRONG,
10231 N_("@i count in @S is %i, should be %j.\n"),
10234 { PR_0_HURD_CLEAR_FILETYPE,
10235 N_("The Hurd does not support the filetype feature.\n"),
10238 /* Journal inode is invalid */
10239 { PR_0_JOURNAL_BAD_INODE,
10240 N_("@S has a bad ext3 @j (@i %i).\n"),
10241 PROMPT_CLEAR, PR_PREEN_OK },
10243 /* The external journal has (unsupported) multiple filesystems */
10244 { PR_0_JOURNAL_UNSUPP_MULTIFS,
10245 N_("External @j has multiple @f users (unsupported).\n"),
10246 PROMPT_NONE, PR_FATAL },
10248 /* Can't find external journal */
10249 { PR_0_CANT_FIND_JOURNAL,
10250 N_("Can't find external @j\n"),
10251 PROMPT_NONE, PR_FATAL },
10253 /* External journal has bad superblock */
10254 { PR_0_EXT_JOURNAL_BAD_SUPER,
10255 N_("External @j has bad @S\n"),
10256 PROMPT_NONE, PR_FATAL },
10258 /* Superblock has a bad journal UUID */
10259 { PR_0_JOURNAL_BAD_UUID,
10260 N_("External @j does not support this @f\n"),
10261 PROMPT_NONE, PR_FATAL },
10263 /* Journal has an unknown superblock type */
10264 { PR_0_JOURNAL_UNSUPP_SUPER,
10265 N_("Ext3 @j @S is unknown type %N (unsupported).\n"
10266 "It is likely that your copy of e2fsck is old and/or doesn't "
10267 "support this @j format.\n"
10268 "It is also possible the @j @S is corrupt.\n"),
10269 PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER },
10271 /* Journal superblock is corrupt */
10272 { PR_0_JOURNAL_BAD_SUPER,
10273 N_("Ext3 @j @S is corrupt.\n"),
10274 PROMPT_FIX, PR_PREEN_OK },
10276 /* Superblock flag should be cleared */
10277 { PR_0_JOURNAL_HAS_JOURNAL,
10278 N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"),
10279 PROMPT_CLEAR, PR_PREEN_OK },
10281 /* Superblock flag is incorrect */
10282 { PR_0_JOURNAL_RECOVER_SET,
10283 N_("@S has ext3 needs_recovery flag set, but no @j.\n"),
10284 PROMPT_CLEAR, PR_PREEN_OK },
10286 /* Journal has data, but recovery flag is clear */
10287 { PR_0_JOURNAL_RECOVERY_CLEAR,
10288 N_("ext3 recovery flag clear, but @j has data.\n"),
10291 /* Ask if we should clear the journal */
10292 { PR_0_JOURNAL_RESET_JOURNAL,
10294 PROMPT_NULL, PR_PREEN_NOMSG },
10296 /* Ask if we should run the journal anyway */
10297 { PR_0_JOURNAL_RUN,
10298 N_("Run @j anyway"),
10301 /* Run the journal by default */
10302 { PR_0_JOURNAL_RUN_DEFAULT,
10303 N_("Recovery flag not set in backup @S, so running @j anyway.\n"),
10306 /* Clearing orphan inode */
10307 { PR_0_ORPHAN_CLEAR_INODE,
10308 N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"),
10311 /* Illegal block found in orphaned inode */
10312 { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM,
10313 N_("@I @b #%B (%b) found in @o @i %i.\n"),
10316 /* Already cleared block found in orphaned inode */
10317 { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK,
10318 N_("Already cleared @b #%B (%b) found in @o @i %i.\n"),
10321 /* Illegal orphan inode in superblock */
10322 { PR_0_ORPHAN_ILLEGAL_HEAD_INODE,
10323 N_("@I @o @i %i in @S.\n"),
10326 /* Illegal inode in orphaned inode list */
10327 { PR_0_ORPHAN_ILLEGAL_INODE,
10328 N_("@I @i %i in @o @i list.\n"),
10331 /* Filesystem revision is 0, but feature flags are set */
10332 { PR_0_FS_REV_LEVEL,
10333 "@f has feature flag(s) set, but is a revision 0 @f. ",
10334 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
10336 /* Journal superblock has an unknown read-only feature flag set */
10337 { PR_0_JOURNAL_UNSUPP_ROCOMPAT,
10338 N_("Ext3 @j @S has an unknown read-only feature flag set.\n"),
10341 /* Journal superblock has an unknown incompatible feature flag set */
10342 { PR_0_JOURNAL_UNSUPP_INCOMPAT,
10343 N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"),
10346 /* Journal has unsupported version number */
10347 { PR_0_JOURNAL_UNSUPP_VERSION,
10348 N_("@j version not supported by this e2fsck.\n"),
10351 /* Moving journal to hidden file */
10352 { PR_0_MOVE_JOURNAL,
10353 N_("Moving @j from /%s to hidden inode.\n\n"),
10356 /* Error moving journal to hidden file */
10357 { PR_0_ERR_MOVE_JOURNAL,
10358 N_("Error moving @j: %m\n\n"),
10361 /* Clearing V2 journal superblock */
10362 { PR_0_CLEAR_V2_JOURNAL,
10363 N_("Found invalid V2 @j @S fields (from V1 journal).\n"
10364 "Clearing fields beyond the V1 @j @S...\n\n"),
10367 /* Backup journal inode blocks */
10369 N_("Backing up @j @i @b information.\n\n"),
10372 /* Reserved blocks w/o resize_inode */
10373 { PR_0_NONZERO_RESERVED_GDT_BLOCKS,
10374 N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n"
10375 "is %N; @s zero. "),
10378 /* Resize_inode not enabled, but resize inode is non-zero */
10379 { PR_0_CLEAR_RESIZE_INODE,
10380 N_("Resize_@i not enabled, but the resize inode is non-zero. "),
10383 /* Resize inode invalid */
10384 { PR_0_RESIZE_INODE_INVALID,
10385 N_("Resize @i not valid. "),
10386 PROMPT_RECREATE, 0 },
10388 /* Pass 1 errors */
10390 /* Pass 1: Checking inodes, blocks, and sizes */
10391 { PR_1_PASS_HEADER,
10392 N_("Pass 1: Checking @is, @bs, and sizes\n"),
10395 /* Root directory is not an inode */
10396 { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "),
10399 /* Root directory has dtime set */
10401 N_("@r has dtime set (probably due to old mke2fs). "),
10402 PROMPT_FIX, PR_PREEN_OK },
10404 /* Reserved inode has bad mode */
10405 { PR_1_RESERVED_BAD_MODE,
10406 N_("Reserved @i %i %Q has bad mode. "),
10407 PROMPT_CLEAR, PR_PREEN_OK },
10409 /* Deleted inode has zero dtime */
10411 N_("@D @i %i has zero dtime. "),
10412 PROMPT_FIX, PR_PREEN_OK },
10414 /* Inode in use, but dtime set */
10416 N_("@i %i is in use, but has dtime set. "),
10417 PROMPT_FIX, PR_PREEN_OK },
10419 /* Zero-length directory */
10420 { PR_1_ZERO_LENGTH_DIR,
10421 N_("@i %i is a @z @d. "),
10422 PROMPT_CLEAR, PR_PREEN_OK },
10424 /* Block bitmap conflicts with some other fs block */
10425 { PR_1_BB_CONFLICT,
10426 N_("@g %g's @b @B at %b @C.\n"),
10427 PROMPT_RELOCATE, 0 },
10429 /* Inode bitmap conflicts with some other fs block */
10430 { PR_1_IB_CONFLICT,
10431 N_("@g %g's @i @B at %b @C.\n"),
10432 PROMPT_RELOCATE, 0 },
10434 /* Inode table conflicts with some other fs block */
10435 { PR_1_ITABLE_CONFLICT,
10436 N_("@g %g's @i table at %b @C.\n"),
10437 PROMPT_RELOCATE, 0 },
10439 /* Block bitmap is on a bad block */
10440 { PR_1_BB_BAD_BLOCK,
10441 N_("@g %g's @b @B (%b) is bad. "),
10442 PROMPT_RELOCATE, 0 },
10444 /* Inode bitmap is on a bad block */
10445 { PR_1_IB_BAD_BLOCK,
10446 N_("@g %g's @i @B (%b) is bad. "),
10447 PROMPT_RELOCATE, 0 },
10449 /* Inode has incorrect i_size */
10451 N_("@i %i, i_size is %Is, @s %N. "),
10452 PROMPT_FIX, PR_PREEN_OK },
10454 /* Inode has incorrect i_blocks */
10455 { PR_1_BAD_I_BLOCKS,
10456 N_("@i %i, i_@bs is %Ib, @s %N. "),
10457 PROMPT_FIX, PR_PREEN_OK },
10459 /* Illegal blocknumber in inode */
10460 { PR_1_ILLEGAL_BLOCK_NUM,
10461 N_("@I @b #%B (%b) in @i %i. "),
10462 PROMPT_CLEAR, PR_LATCH_BLOCK },
10464 /* Block number overlaps fs metadata */
10465 { PR_1_BLOCK_OVERLAPS_METADATA,
10466 N_("@b #%B (%b) overlaps @f metadata in @i %i. "),
10467 PROMPT_CLEAR, PR_LATCH_BLOCK },
10469 /* Inode has illegal blocks (latch question) */
10470 { PR_1_INODE_BLOCK_LATCH,
10471 N_("@i %i has illegal @b(s). "),
10474 /* Too many bad blocks in inode */
10475 { PR_1_TOO_MANY_BAD_BLOCKS,
10476 N_("Too many illegal @bs in @i %i.\n"),
10477 PROMPT_CLEAR_INODE, PR_NO_OK },
10479 /* Illegal block number in bad block inode */
10480 { PR_1_BB_ILLEGAL_BLOCK_NUM,
10481 N_("@I @b #%B (%b) in bad @b @i. "),
10482 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10484 /* Bad block inode has illegal blocks (latch question) */
10485 { PR_1_INODE_BBLOCK_LATCH,
10486 N_("Bad @b @i has illegal @b(s). "),
10489 /* Duplicate or bad blocks in use! */
10490 { PR_1_DUP_BLOCKS_PREENSTOP,
10491 N_("Duplicate or bad @b in use!\n"),
10494 /* Bad block used as bad block indirect block */
10495 { PR_1_BBINODE_BAD_METABLOCK,
10496 N_("Bad @b %b used as bad @b @i indirect @b. "),
10497 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10499 /* Inconsistency can't be fixed prompt */
10500 { PR_1_BBINODE_BAD_METABLOCK_PROMPT,
10501 N_("\nThe bad @b @i has probably been corrupted. You probably\n"
10502 "should stop now and run ""e2fsck -c"" to scan for bad blocks\n"
10504 PROMPT_CONTINUE, PR_PREEN_NOMSG },
10506 /* Bad primary block */
10507 { PR_1_BAD_PRIMARY_BLOCK,
10508 N_("\nIf the @b is really bad, the @f can not be fixed.\n"),
10509 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT },
10511 /* Bad primary block prompt */
10512 { PR_1_BAD_PRIMARY_BLOCK_PROMPT,
10513 N_("You can clear the this @b (and hope for the best) from the\n"
10514 "bad @b list and hope that @b is really OK, but there are no\n"
10515 "guarantees.\n\n"),
10516 PROMPT_CLEAR, PR_PREEN_NOMSG },
10518 /* Bad primary superblock */
10519 { PR_1_BAD_PRIMARY_SUPERBLOCK,
10520 N_("The primary @S (%b) is on the bad @b list.\n"),
10521 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
10523 /* Bad primary block group descriptors */
10524 { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR,
10525 N_("Block %b in the primary @g descriptors "
10526 "is on the bad @b list\n"),
10527 PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK },
10529 /* Bad superblock in group */
10530 { PR_1_BAD_SUPERBLOCK,
10531 N_("Warning: Group %g's @S (%b) is bad.\n"),
10532 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10534 /* Bad block group descriptors in group */
10535 { PR_1_BAD_GROUP_DESCRIPTORS,
10536 N_("Warning: Group %g's copy of the @g descriptors has a bad "
10538 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
10540 /* Block claimed for no reason */
10541 { PR_1_PROGERR_CLAIMED_BLOCK,
10542 N_("Programming error? @b #%b claimed for no reason in "
10543 "process_bad_@b.\n"),
10544 PROMPT_NONE, PR_PREEN_OK },
10546 /* Error allocating blocks for relocating metadata */
10547 { PR_1_RELOC_BLOCK_ALLOCATE,
10548 N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"),
10549 PROMPT_NONE, PR_PREEN_OK },
10551 /* Error allocating block buffer during relocation process */
10552 { PR_1_RELOC_MEMORY_ALLOCATE,
10553 N_("@A @b buffer for relocating %s\n"),
10554 PROMPT_NONE, PR_PREEN_OK },
10556 /* Relocating metadata group information from X to Y */
10557 { PR_1_RELOC_FROM_TO,
10558 N_("Relocating @g %g's %s from %b to %c...\n"),
10559 PROMPT_NONE, PR_PREEN_OK },
10561 /* Relocating metatdata group information to X */
10563 N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */
10564 PROMPT_NONE, PR_PREEN_OK },
10566 /* Block read error during relocation process */
10567 { PR_1_RELOC_READ_ERR,
10568 N_("Warning: could not read @b %b of %s: %m\n"),
10569 PROMPT_NONE, PR_PREEN_OK },
10571 /* Block write error during relocation process */
10572 { PR_1_RELOC_WRITE_ERR,
10573 N_("Warning: could not write @b %b for %s: %m\n"),
10574 PROMPT_NONE, PR_PREEN_OK },
10576 /* Error allocating inode bitmap */
10577 { PR_1_ALLOCATE_IBITMAP_ERROR,
10578 "@A @i @B (%N): %m\n",
10579 PROMPT_NONE, PR_FATAL },
10581 /* Error allocating block bitmap */
10582 { PR_1_ALLOCATE_BBITMAP_ERROR,
10583 "@A @b @B (%N): %m\n",
10584 PROMPT_NONE, PR_FATAL },
10586 /* Error allocating icount structure */
10587 { PR_1_ALLOCATE_ICOUNT,
10588 N_("@A icount link information: %m\n"),
10589 PROMPT_NONE, PR_FATAL },
10591 /* Error allocating dbcount */
10592 { PR_1_ALLOCATE_DBCOUNT,
10593 N_("@A @d @b array: %m\n"),
10594 PROMPT_NONE, PR_FATAL },
10596 /* Error while scanning inodes */
10597 { PR_1_ISCAN_ERROR,
10598 N_("Error while scanning @is (%i): %m\n"),
10599 PROMPT_NONE, PR_FATAL },
10601 /* Error while iterating over blocks */
10602 { PR_1_BLOCK_ITERATE,
10603 N_("Error while iterating over @bs in @i %i: %m\n"),
10604 PROMPT_NONE, PR_FATAL },
10606 /* Error while storing inode count information */
10607 { PR_1_ICOUNT_STORE,
10608 N_("Error storing @i count information (@i=%i, count=%N): %m\n"),
10609 PROMPT_NONE, PR_FATAL },
10611 /* Error while storing directory block information */
10613 N_("Error storing @d @b information "
10614 "(@i=%i, @b=%b, num=%N): %m\n"),
10615 PROMPT_NONE, PR_FATAL },
10617 /* Error while reading inode (for clearing) */
10619 N_("Error reading @i %i: %m\n"),
10620 PROMPT_NONE, PR_FATAL },
10622 /* Suppress messages prompt */
10623 { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK },
10625 /* Imagic flag set on an inode when filesystem doesn't support it */
10627 N_("@i %i has imagic flag set. "),
10630 /* Immutable flag set on a device or socket inode */
10631 { PR_1_SET_IMMUTABLE,
10632 N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n"
10633 "or append-only flag set. "),
10634 PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK },
10636 /* Compression flag set on an inode when filesystem doesn't support it */
10638 N_("@i %i has @cion flag set on @f without @cion support. "),
10641 /* Non-zero size for device, fifo or socket inode */
10642 { PR_1_SET_NONZSIZE,
10643 "Special (@v/socket/fifo) @i %i has non-zero size. ",
10644 PROMPT_FIX, PR_PREEN_OK },
10646 /* Filesystem revision is 0, but feature flags are set */
10647 { PR_1_FS_REV_LEVEL,
10648 "@f has feature flag(s) set, but is a revision 0 @f. ",
10649 PROMPT_FIX, PR_PREEN_OK | PR_NO_OK },
10651 /* Journal inode is not in use, but contains data */
10652 { PR_1_JOURNAL_INODE_NOT_CLEAR,
10653 "@j @i is not in use, but contains data. ",
10654 PROMPT_CLEAR, PR_PREEN_OK },
10656 /* Journal has bad mode */
10657 { PR_1_JOURNAL_BAD_MODE,
10658 N_("@j is not regular file. "),
10659 PROMPT_FIX, PR_PREEN_OK },
10661 /* Deal with inodes that were part of orphan linked list */
10663 N_("@i %i was part of the orphaned @i list. "),
10664 PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 },
10666 /* Deal with inodes that were part of corrupted orphan linked
10667 list (latch question) */
10668 { PR_1_ORPHAN_LIST_REFUGEES,
10669 N_("@is that were part of a corrupted orphan linked list found. "),
10672 /* Error allocating refcount structure */
10673 { PR_1_ALLOCATE_REFCOUNT,
10674 "@A refcount structure (%N): %m\n",
10675 PROMPT_NONE, PR_FATAL },
10677 /* Error reading extended attribute block */
10678 { PR_1_READ_EA_BLOCK,
10679 N_("Error reading @a @b %b for @i %i. "),
10682 /* Invalid extended attribute block */
10683 { PR_1_BAD_EA_BLOCK,
10684 N_("@i %i has a bad @a @b %b. "),
10687 /* Error reading Extended Attribute block while fixing refcount */
10688 { PR_1_EXTATTR_READ_ABORT,
10689 N_("Error reading @a @b %b (%m). "),
10692 /* Extended attribute reference count incorrect */
10693 { PR_1_EXTATTR_REFCOUNT,
10694 N_("@a @b %b has reference count %B, should be %N. "),
10697 /* Error writing Extended Attribute block while fixing refcount */
10698 { PR_1_EXTATTR_WRITE,
10699 N_("Error writing @a @b %b (%m). "),
10702 /* Multiple EA blocks not supported */
10703 { PR_1_EA_MULTI_BLOCK,
10704 N_("@a @b %b has h_blocks > 1. "),
10707 /* Error allocating EA region allocation structure */
10708 { PR_1_EA_ALLOC_REGION,
10709 N_("Error allocating @a @b %b. "),
10712 /* Error EA allocation collision */
10713 { PR_1_EA_ALLOC_COLLISION,
10714 N_("@a @b %b is corrupt (allocation collision). "),
10717 /* Bad extended attribute name */
10718 { PR_1_EA_BAD_NAME,
10719 N_("@a @b %b is corrupt (invalid name). "),
10722 /* Bad extended attribute value */
10723 { PR_1_EA_BAD_VALUE,
10724 N_("@a @b %b is corrupt (invalid value). "),
10727 /* Inode too big (latch question) */
10728 { PR_1_INODE_TOOBIG,
10729 N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 },
10731 /* Directory too big */
10733 N_("@b #%B (%b) causes @d to be too big. "),
10734 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10736 /* Regular file too big */
10738 N_("@b #%B (%b) causes file to be too big. "),
10739 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10741 /* Symlink too big */
10742 { PR_1_TOOBIG_SYMLINK,
10743 N_("@b #%B (%b) causes symlink to be too big. "),
10744 PROMPT_CLEAR, PR_LATCH_TOOBIG },
10746 /* INDEX_FL flag set on a non-HTREE filesystem */
10748 N_("@i %i has INDEX_FL flag set on @f without htree support.\n"),
10749 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10751 /* INDEX_FL flag set on a non-directory */
10752 { PR_1_HTREE_NODIR,
10753 N_("@i %i has INDEX_FL flag set but is not a @d.\n"),
10754 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10756 /* Invalid root node in HTREE directory */
10757 { PR_1_HTREE_BADROOT,
10758 N_("@h %i has an invalid root node.\n"),
10759 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10761 /* Unsupported hash version in HTREE directory */
10762 { PR_1_HTREE_HASHV,
10763 N_("@h %i has an unsupported hash version (%N)\n"),
10764 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10766 /* Incompatible flag in HTREE root node */
10767 { PR_1_HTREE_INCOMPAT,
10768 N_("@h %i uses an incompatible htree root node flag.\n"),
10769 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10771 /* HTREE too deep */
10772 { PR_1_HTREE_DEPTH,
10773 N_("@h %i has a tree depth (%N) which is too big\n"),
10774 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
10776 /* Bad block has indirect block that conflicts with filesystem block */
10777 { PR_1_BB_FS_BLOCK,
10778 N_("Bad @b @i has an indirect @b (%b) that conflicts with\n"
10780 PROMPT_CLEAR, PR_LATCH_BBLOCK },
10782 /* Resize inode failed */
10783 { PR_1_RESIZE_INODE_CREATE,
10784 N_("Resize @i (re)creation failed: %m."),
10787 /* invalid inode->i_extra_isize */
10788 { PR_1_EXTRA_ISIZE,
10789 N_("@i %i has a extra size (%IS) which is invalid\n"),
10790 PROMPT_FIX, PR_PREEN_OK },
10792 /* invalid ea entry->e_name_len */
10793 { PR_1_ATTR_NAME_LEN,
10794 N_("@a in @i %i has a namelen (%N) which is invalid\n"),
10795 PROMPT_CLEAR, PR_PREEN_OK },
10797 /* invalid ea entry->e_value_size */
10798 { PR_1_ATTR_VALUE_SIZE,
10799 N_("@a in @i %i has a value size (%N) which is invalid\n"),
10800 PROMPT_CLEAR, PR_PREEN_OK },
10802 /* invalid ea entry->e_value_offs */
10803 { PR_1_ATTR_VALUE_OFFSET,
10804 N_("@a in @i %i has a value offset (%N) which is invalid\n"),
10805 PROMPT_CLEAR, PR_PREEN_OK },
10807 /* invalid ea entry->e_value_block */
10808 { PR_1_ATTR_VALUE_BLOCK,
10809 N_("@a in @i %i has a value block (%N) which is invalid (must be 0)\n"),
10810 PROMPT_CLEAR, PR_PREEN_OK },
10812 /* invalid ea entry->e_hash */
10814 N_("@a in @i %i has a hash (%N) which is invalid (must be 0)\n"),
10815 PROMPT_CLEAR, PR_PREEN_OK },
10817 /* Pass 1b errors */
10819 /* Pass 1B: Rescan for duplicate/bad blocks */
10820 { PR_1B_PASS_HEADER,
10821 N_("Duplicate @bs found... invoking duplicate @b passes.\n"
10822 "Pass 1B: Rescan for duplicate/bad @bs\n"),
10825 /* Duplicate/bad block(s) header */
10826 { PR_1B_DUP_BLOCK_HEADER,
10827 N_("Duplicate/bad @b(s) in @i %i:"),
10830 /* Duplicate/bad block(s) in inode */
10833 PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR },
10835 /* Duplicate/bad block(s) end */
10836 { PR_1B_DUP_BLOCK_END,
10838 PROMPT_NONE, PR_PREEN_NOHDR },
10840 /* Error while scanning inodes */
10841 { PR_1B_ISCAN_ERROR,
10842 N_("Error while scanning inodes (%i): %m\n"),
10843 PROMPT_NONE, PR_FATAL },
10845 /* Error allocating inode bitmap */
10846 { PR_1B_ALLOCATE_IBITMAP_ERROR,
10847 N_("@A @i @B (inode_dup_map): %m\n"),
10848 PROMPT_NONE, PR_FATAL },
10850 /* Error while iterating over blocks */
10851 { PR_1B_BLOCK_ITERATE,
10852 N_("Error while iterating over @bs in @i %i (%s): %m\n"),
10855 /* Error adjusting EA refcount */
10856 { PR_1B_ADJ_EA_REFCOUNT,
10857 N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"),
10861 /* Pass 1C: Scan directories for inodes with dup blocks. */
10862 { PR_1C_PASS_HEADER,
10863 N_("Pass 1C: Scan directories for @is with dup @bs.\n"),
10867 /* Pass 1D: Reconciling duplicate blocks */
10868 { PR_1D_PASS_HEADER,
10869 N_("Pass 1D: Reconciling duplicate @bs\n"),
10872 /* File has duplicate blocks */
10874 N_("File %Q (@i #%i, mod time %IM) \n"
10875 " has %B duplicate @b(s), shared with %N file(s):\n"),
10878 /* List of files sharing duplicate blocks */
10879 { PR_1D_DUP_FILE_LIST,
10880 N_("\t%Q (@i #%i, mod time %IM)\n"),
10883 /* File sharing blocks with filesystem metadata */
10884 { PR_1D_SHARE_METADATA,
10885 N_("\t<@f metadata>\n"),
10888 /* Report of how many duplicate/bad inodes */
10889 { PR_1D_NUM_DUP_INODES,
10890 N_("(There are %N @is containing duplicate/bad @bs.)\n\n"),
10893 /* Duplicated blocks already reassigned or cloned. */
10894 { PR_1D_DUP_BLOCKS_DEALT,
10895 N_("Duplicated @bs already reassigned or cloned.\n\n"),
10898 /* Clone duplicate/bad blocks? */
10899 { PR_1D_CLONE_QUESTION,
10900 "", PROMPT_CLONE, PR_NO_OK },
10903 { PR_1D_DELETE_QUESTION,
10904 "", PROMPT_DELETE, 0 },
10906 /* Couldn't clone file (error) */
10907 { PR_1D_CLONE_ERROR,
10908 N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 },
10910 /* Pass 2 errors */
10912 /* Pass 2: Checking directory structure */
10913 { PR_2_PASS_HEADER,
10914 N_("Pass 2: Checking @d structure\n"),
10917 /* Bad inode number for '.' */
10918 { PR_2_BAD_INODE_DOT,
10919 N_("Bad @i number for '.' in @d @i %i.\n"),
10922 /* Directory entry has bad inode number */
10924 N_("@E has bad @i #: %Di.\n"),
10927 /* Directory entry has deleted or unused inode */
10928 { PR_2_UNUSED_INODE,
10929 N_("@E has @D/unused @i %Di. "),
10930 PROMPT_CLEAR, PR_PREEN_OK },
10932 /* Directry entry is link to '.' */
10934 N_("@E @L to '.' "),
10937 /* Directory entry points to inode now located in a bad block */
10939 N_("@E points to @i (%Di) located in a bad @b.\n"),
10942 /* Directory entry contains a link to a directory */
10944 N_("@E @L to @d %P (%Di).\n"),
10947 /* Directory entry contains a link to the root directry */
10949 N_("@E @L to the @r.\n"),
10952 /* Directory entry has illegal characters in its name */
10954 N_("@E has illegal characters in its name.\n"),
10957 /* Missing '.' in directory inode */
10958 { PR_2_MISSING_DOT,
10959 N_("Missing '.' in @d @i %i.\n"),
10962 /* Missing '..' in directory inode */
10963 { PR_2_MISSING_DOT_DOT,
10964 N_("Missing '..' in @d @i %i.\n"),
10967 /* First entry in directory inode doesn't contain '.' */
10968 { PR_2_1ST_NOT_DOT,
10969 N_("First @e '%Dn' (inode=%Di) in @d @i %i (%p) @s '.'\n"),
10972 /* Second entry in directory inode doesn't contain '..' */
10973 { PR_2_2ND_NOT_DOT_DOT,
10974 N_("Second @e '%Dn' (inode=%Di) in @d @i %i @s '..'\n"),
10977 /* i_faddr should be zero */
10979 N_("i_faddr @F %IF, @s zero.\n"),
10982 /* i_file_acl should be zero */
10983 { PR_2_FILE_ACL_ZERO,
10984 N_("i_file_acl @F %If, @s zero.\n"),
10987 /* i_dir_acl should be zero */
10988 { PR_2_DIR_ACL_ZERO,
10989 N_("i_dir_acl @F %Id, @s zero.\n"),
10992 /* i_frag should be zero */
10994 N_("i_frag @F %N, @s zero.\n"),
10997 /* i_fsize should be zero */
10999 N_("i_fsize @F %N, @s zero.\n"),
11002 /* inode has bad mode */
11004 N_("@i %i (%Q) has a bad mode (%Im).\n"),
11007 /* directory corrupted */
11008 { PR_2_DIR_CORRUPTED,
11009 N_("@d @i %i, @b %B, offset %N: @d corrupted\n"),
11010 PROMPT_SALVAGE, 0 },
11012 /* filename too long */
11013 { PR_2_FILENAME_LONG,
11014 N_("@d @i %i, @b %B, offset %N: filename too long\n"),
11015 PROMPT_TRUNCATE, 0 },
11017 /* Directory inode has a missing block (hole) */
11018 { PR_2_DIRECTORY_HOLE,
11019 N_("@d @i %i has an unallocated @b #%B. "),
11020 PROMPT_ALLOCATE, 0 },
11022 /* '.' is not NULL terminated */
11023 { PR_2_DOT_NULL_TERM,
11024 N_("'.' @d @e in @d @i %i is not NULL terminated\n"),
11027 /* '..' is not NULL terminated */
11028 { PR_2_DOT_DOT_NULL_TERM,
11029 N_("'..' @d @e in @d @i %i is not NULL terminated\n"),
11032 /* Illegal character device inode */
11033 { PR_2_BAD_CHAR_DEV,
11034 N_("@i %i (%Q) is an @I character @v.\n"),
11037 /* Illegal block device inode */
11038 { PR_2_BAD_BLOCK_DEV,
11039 N_("@i %i (%Q) is an @I @b @v.\n"),
11042 /* Duplicate '.' entry */
11044 N_("@E is duplicate '.' @e.\n"),
11047 /* Duplicate '..' entry */
11048 { PR_2_DUP_DOT_DOT,
11049 N_("@E is duplicate '..' @e.\n"),
11052 /* Internal error: couldn't find dir_info */
11054 N_("Internal error: couldn't find dir_info for %i.\n"),
11055 PROMPT_NONE, PR_FATAL },
11057 /* Final rec_len is wrong */
11058 { PR_2_FINAL_RECLEN,
11059 N_("@E has rec_len of %Dr, should be %N.\n"),
11062 /* Error allocating icount structure */
11063 { PR_2_ALLOCATE_ICOUNT,
11064 N_("@A icount structure: %m\n"),
11065 PROMPT_NONE, PR_FATAL },
11067 /* Error iterating over directory blocks */
11068 { PR_2_DBLIST_ITERATE,
11069 N_("Error iterating over @d @bs: %m\n"),
11070 PROMPT_NONE, PR_FATAL },
11072 /* Error reading directory block */
11073 { PR_2_READ_DIRBLOCK,
11074 N_("Error reading @d @b %b (@i %i): %m\n"),
11075 PROMPT_CONTINUE, 0 },
11077 /* Error writing directory block */
11078 { PR_2_WRITE_DIRBLOCK,
11079 N_("Error writing @d @b %b (@i %i): %m\n"),
11080 PROMPT_CONTINUE, 0 },
11082 /* Error allocating new directory block */
11083 { PR_2_ALLOC_DIRBOCK,
11084 N_("@A new @d @b for @i %i (%s): %m\n"),
11087 /* Error deallocating inode */
11088 { PR_2_DEALLOC_INODE,
11089 N_("Error deallocating @i %i: %m\n"),
11090 PROMPT_NONE, PR_FATAL },
11092 /* Directory entry for '.' is big. Split? */
11094 N_("@d @e for '.' is big. "),
11095 PROMPT_SPLIT, PR_NO_OK },
11097 /* Illegal FIFO inode */
11099 N_("@i %i (%Q) is an @I FIFO.\n"),
11102 /* Illegal socket inode */
11104 N_("@i %i (%Q) is an @I socket.\n"),
11107 /* Directory filetype not set */
11108 { PR_2_SET_FILETYPE,
11109 N_("Setting filetype for @E to %N.\n"),
11110 PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG },
11112 /* Directory filetype incorrect */
11113 { PR_2_BAD_FILETYPE,
11114 N_("@E has an incorrect filetype (was %Dt, should be %N).\n"),
11117 /* Directory filetype set on filesystem */
11118 { PR_2_CLEAR_FILETYPE,
11119 N_("@E has filetype set.\n"),
11120 PROMPT_CLEAR, PR_PREEN_OK },
11122 /* Directory filename is null */
11124 N_("@E has a zero-length name.\n"),
11127 /* Invalid symlink */
11128 { PR_2_INVALID_SYMLINK,
11129 N_("Symlink %Q (@i #%i) is invalid.\n"),
11132 /* i_file_acl (extended attribute block) is bad */
11133 { PR_2_FILE_ACL_BAD,
11134 N_("@a @b @F invalid (%If).\n"),
11137 /* Filesystem contains large files, but has no such flag in sb */
11138 { PR_2_FEATURE_LARGE_FILES,
11139 N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"),
11142 /* Node in HTREE directory not referenced */
11143 { PR_2_HTREE_NOTREF,
11144 N_("@p @h %d: node (%B) not referenced\n"),
11147 /* Node in HTREE directory referenced twice */
11148 { PR_2_HTREE_DUPREF,
11149 N_("@p @h %d: node (%B) referenced twice\n"),
11152 /* Node in HTREE directory has bad min hash */
11153 { PR_2_HTREE_MIN_HASH,
11154 N_("@p @h %d: node (%B) has bad min hash\n"),
11157 /* Node in HTREE directory has bad max hash */
11158 { PR_2_HTREE_MAX_HASH,
11159 N_("@p @h %d: node (%B) has bad max hash\n"),
11162 /* Clear invalid HTREE directory */
11163 { PR_2_HTREE_CLEAR,
11164 N_("Invalid @h %d (%q). "), PROMPT_CLEAR, 0 },
11166 /* Bad block in htree interior node */
11167 { PR_2_HTREE_BADBLK,
11168 N_("@p @h %d (%q): bad @b number %b.\n"),
11169 PROMPT_CLEAR_HTREE, 0 },
11171 /* Error adjusting EA refcount */
11172 { PR_2_ADJ_EA_REFCOUNT,
11173 N_("Error addjusting refcount for @a @b %b (@i %i): %m\n"),
11174 PROMPT_NONE, PR_FATAL },
11176 /* Invalid HTREE root node */
11177 { PR_2_HTREE_BAD_ROOT,
11178 N_("@p @h %d: root node is invalid\n"),
11179 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11181 /* Invalid HTREE limit */
11182 { PR_2_HTREE_BAD_LIMIT,
11183 N_("@p @h %d: node (%B) has bad limit (%N)\n"),
11184 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11186 /* Invalid HTREE count */
11187 { PR_2_HTREE_BAD_COUNT,
11188 N_("@p @h %d: node (%B) has bad count (%N)\n"),
11189 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11191 /* HTREE interior node has out-of-order hashes in table */
11192 { PR_2_HTREE_HASH_ORDER,
11193 N_("@p @h %d: node (%B) has an unordered hash table\n"),
11194 PROMPT_CLEAR_HTREE, PR_PREEN_OK },
11196 /* Node in HTREE directory has bad depth */
11197 { PR_2_HTREE_BAD_DEPTH,
11198 N_("@p @h %d: node (%B) has bad depth\n"),
11201 /* Duplicate directory entry found */
11202 { PR_2_DUPLICATE_DIRENT,
11203 N_("Duplicate @E found. "),
11206 /* Non-unique filename found */
11207 { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */
11208 N_("@E has a non-unique filename.\nRename to %s"),
11211 /* Duplicate directory entry found */
11212 { PR_2_REPORT_DUP_DIRENT,
11213 N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"),
11216 /* Pass 3 errors */
11218 /* Pass 3: Checking directory connectivity */
11219 { PR_3_PASS_HEADER,
11220 N_("Pass 3: Checking @d connectivity\n"),
11223 /* Root inode not allocated */
11224 { PR_3_NO_ROOT_INODE,
11225 N_("@r not allocated. "),
11226 PROMPT_ALLOCATE, 0 },
11228 /* No room in lost+found */
11229 { PR_3_EXPAND_LF_DIR,
11230 N_("No room in @l @d. "),
11231 PROMPT_EXPAND, 0 },
11233 /* Unconnected directory inode */
11234 { PR_3_UNCONNECTED_DIR,
11235 N_("Unconnected @d @i %i (%p)\n"),
11236 PROMPT_CONNECT, 0 },
11238 /* /lost+found not found */
11240 N_("/@l not found. "),
11241 PROMPT_CREATE, PR_PREEN_OK },
11243 /* .. entry is incorrect */
11244 { PR_3_BAD_DOT_DOT,
11245 N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"),
11248 /* Bad or non-existent /lost+found. Cannot reconnect */
11250 N_("Bad or non-existent /@l. Cannot reconnect.\n"),
11253 /* Could not expand /lost+found */
11254 { PR_3_CANT_EXPAND_LPF,
11255 N_("Could not expand /@l: %m\n"),
11258 /* Could not reconnect inode */
11259 { PR_3_CANT_RECONNECT,
11260 N_("Could not reconnect %i: %m\n"),
11263 /* Error while trying to find /lost+found */
11264 { PR_3_ERR_FIND_LPF,
11265 N_("Error while trying to find /@l: %m\n"),
11268 /* Error in ext2fs_new_block while creating /lost+found */
11269 { PR_3_ERR_LPF_NEW_BLOCK,
11270 N_("ext2fs_new_@b: %m while trying to create /@l @d\n"),
11273 /* Error in ext2fs_new_inode while creating /lost+found */
11274 { PR_3_ERR_LPF_NEW_INODE,
11275 N_("ext2fs_new_@i: %m while trying to create /@l @d\n"),
11278 /* Error in ext2fs_new_dir_block while creating /lost+found */
11279 { PR_3_ERR_LPF_NEW_DIR_BLOCK,
11280 N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"),
11283 /* Error while writing directory block for /lost+found */
11284 { PR_3_ERR_LPF_WRITE_BLOCK,
11285 N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"),
11288 /* Error while adjusting inode count */
11289 { PR_3_ADJUST_INODE,
11290 N_("Error while adjusting @i count on @i %i\n"),
11293 /* Couldn't fix parent directory -- error */
11294 { PR_3_FIX_PARENT_ERR,
11295 N_("Couldn't fix parent of @i %i: %m\n\n"),
11298 /* Couldn't fix parent directory -- couldn't find it */
11299 { PR_3_FIX_PARENT_NOFIND,
11300 N_("Couldn't fix parent of @i %i: Couldn't find parent @d entry\n\n"),
11303 /* Error allocating inode bitmap */
11304 { PR_3_ALLOCATE_IBITMAP_ERROR,
11305 N_("@A @i @B (%N): %m\n"),
11306 PROMPT_NONE, PR_FATAL },
11308 /* Error creating root directory */
11309 { PR_3_CREATE_ROOT_ERROR,
11310 N_("Error creating root @d (%s): %m\n"),
11311 PROMPT_NONE, PR_FATAL },
11313 /* Error creating lost and found directory */
11314 { PR_3_CREATE_LPF_ERROR,
11315 N_("Error creating /@l @d (%s): %m\n"),
11316 PROMPT_NONE, PR_FATAL },
11318 /* Root inode is not directory; aborting */
11319 { PR_3_ROOT_NOT_DIR_ABORT,
11320 N_("@r is not a @d; aborting.\n"),
11321 PROMPT_NONE, PR_FATAL },
11323 /* Cannot proceed without a root inode. */
11324 { PR_3_NO_ROOT_INODE_ABORT,
11325 N_("Cannot proceed without a @r.\n"),
11326 PROMPT_NONE, PR_FATAL },
11328 /* Internal error: couldn't find dir_info */
11330 N_("Internal error: couldn't find dir_info for %i.\n"),
11331 PROMPT_NONE, PR_FATAL },
11333 /* Lost+found not a directory */
11335 N_("/@l is not a @d (ino=%i)\n"),
11336 PROMPT_UNLINK, 0 },
11338 /* Pass 3A Directory Optimization */
11340 /* Pass 3A: Optimizing directories */
11341 { PR_3A_PASS_HEADER,
11342 N_("Pass 3A: Optimizing directories\n"),
11343 PROMPT_NONE, PR_PREEN_NOMSG },
11345 /* Error iterating over directories */
11346 { PR_3A_OPTIMIZE_ITER,
11347 N_("Failed to create dirs_to_hash iterator: %m"),
11350 /* Error rehash directory */
11351 { PR_3A_OPTIMIZE_DIR_ERR,
11352 N_("Failed to optimize directory %q (%d): %m"),
11355 /* Rehashing dir header */
11356 { PR_3A_OPTIMIZE_DIR_HEADER,
11357 N_("Optimizing directories: "),
11358 PROMPT_NONE, PR_MSG_ONLY },
11360 /* Rehashing directory %d */
11361 { PR_3A_OPTIMIZE_DIR,
11363 PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR},
11365 /* Rehashing dir end */
11366 { PR_3A_OPTIMIZE_DIR_END,
11368 PROMPT_NONE, PR_PREEN_NOHDR },
11370 /* Pass 4 errors */
11372 /* Pass 4: Checking reference counts */
11373 { PR_4_PASS_HEADER,
11374 N_("Pass 4: Checking reference counts\n"),
11377 /* Unattached zero-length inode */
11378 { PR_4_ZERO_LEN_INODE,
11380 PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK },
11382 /* Unattached inode */
11383 { PR_4_UNATTACHED_INODE,
11385 PROMPT_CONNECT, 0 },
11387 /* Inode ref count wrong */
11388 { PR_4_BAD_REF_COUNT,
11389 N_("@i %i ref count is %Il, @s %N. "),
11390 PROMPT_FIX, PR_PREEN_OK },
11392 { PR_4_INCONSISTENT_COUNT,
11393 N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n"
11394 "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n"
11395 "@i_link_info[%i] is %N, @i.i_links_count is %Il. "
11396 "They should be the same!\n"),
11399 /* Pass 5 errors */
11401 /* Pass 5: Checking group summary information */
11402 { PR_5_PASS_HEADER,
11403 N_("Pass 5: Checking @g summary information\n"),
11406 /* Padding at end of inode bitmap is not set. */
11407 { PR_5_INODE_BMAP_PADDING,
11408 N_("Padding at end of @i @B is not set. "),
11409 PROMPT_FIX, PR_PREEN_OK },
11411 /* Padding at end of block bitmap is not set. */
11412 { PR_5_BLOCK_BMAP_PADDING,
11413 N_("Padding at end of @b @B is not set. "),
11414 PROMPT_FIX, PR_PREEN_OK },
11416 /* Block bitmap differences header */
11417 { PR_5_BLOCK_BITMAP_HEADER,
11418 N_("@b @B differences: "),
11419 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG},
11421 /* Block not used, but marked in bitmap */
11422 { PR_5_BLOCK_UNUSED,
11424 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11426 /* Block used, but not marked used in bitmap */
11429 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11431 /* Block bitmap differences end */
11432 { PR_5_BLOCK_BITMAP_END,
11434 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11436 /* Inode bitmap differences header */
11437 { PR_5_INODE_BITMAP_HEADER,
11438 N_("@i @B differences: "),
11439 PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG },
11441 /* Inode not used, but marked in bitmap */
11442 { PR_5_INODE_UNUSED,
11444 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11446 /* Inode used, but not marked used in bitmap */
11449 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11451 /* Inode bitmap differences end */
11452 { PR_5_INODE_BITMAP_END,
11454 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11456 /* Free inodes count for group wrong */
11457 { PR_5_FREE_INODE_COUNT_GROUP,
11458 N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"),
11459 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11461 /* Directories count for group wrong */
11462 { PR_5_FREE_DIR_COUNT_GROUP,
11463 N_("Directories count wrong for @g #%g (%i, counted=%j).\n"),
11464 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11466 /* Free inodes count wrong */
11467 { PR_5_FREE_INODE_COUNT,
11468 N_("Free @is count wrong (%i, counted=%j).\n"),
11469 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11471 /* Free blocks count for group wrong */
11472 { PR_5_FREE_BLOCK_COUNT_GROUP,
11473 N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"),
11474 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11476 /* Free blocks count wrong */
11477 { PR_5_FREE_BLOCK_COUNT,
11478 N_("Free @bs count wrong (%b, counted=%c).\n"),
11479 PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG },
11481 /* Programming error: bitmap endpoints don't match */
11482 { PR_5_BMAP_ENDPOINTS,
11483 N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't "
11484 "match calculated @B endpoints (%i, %j)\n"),
11485 PROMPT_NONE, PR_FATAL },
11487 /* Internal error: fudging end of bitmap */
11488 { PR_5_FUDGE_BITMAP_ERROR,
11489 N_("Internal error: fudging end of bitmap (%N)\n"),
11490 PROMPT_NONE, PR_FATAL },
11492 /* Error copying in replacement inode bitmap */
11493 { PR_5_COPY_IBITMAP_ERROR,
11494 "Error copying in replacement @i @B: %m\n",
11495 PROMPT_NONE, PR_FATAL },
11497 /* Error copying in replacement block bitmap */
11498 { PR_5_COPY_BBITMAP_ERROR,
11499 "Error copying in replacement @b @B: %m\n",
11500 PROMPT_NONE, PR_FATAL },
11502 /* Block range not used, but marked in bitmap */
11503 { PR_5_BLOCK_RANGE_UNUSED,
11505 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11507 /* Block range used, but not marked used in bitmap */
11508 { PR_5_BLOCK_RANGE_USED,
11510 PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11512 /* Inode range not used, but marked in bitmap */
11513 { PR_5_INODE_RANGE_UNUSED,
11515 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11517 /* Inode range used, but not marked used in bitmap */
11518 { PR_5_INODE_RANGE_USED,
11520 PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG },
11526 * This is the latch flags register. It allows several problems to be
11527 * "latched" together. This means that the user has to answer but one
11528 * question for the set of problems, and all of the associated
11529 * problems will be either fixed or not fixed.
11531 static struct latch_descr pr_latch_info[] = {
11532 { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 },
11533 { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 },
11534 { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END },
11535 { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END },
11536 { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 },
11537 { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END },
11538 { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 },
11539 { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 },
11540 { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END },
11544 static const struct e2fsck_problem *find_problem(problem_t code)
11548 for (i=0; problem_table[i].e2p_code; i++) {
11549 if (problem_table[i].e2p_code == code)
11550 return &problem_table[i];
11555 static struct latch_descr *find_latch(int code)
11559 for (i=0; pr_latch_info[i].latch_code >= 0; i++) {
11560 if (pr_latch_info[i].latch_code == code)
11561 return &pr_latch_info[i];
11566 int end_problem_latch(e2fsck_t ctx, int mask)
11568 struct latch_descr *ldesc;
11569 struct problem_context pctx;
11572 ldesc = find_latch(mask);
11573 if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) {
11574 clear_problem_context(&pctx);
11575 answer = fix_problem(ctx, ldesc->end_message, &pctx);
11577 ldesc->flags &= ~(PRL_VARIABLE);
11581 int set_latch_flags(int mask, int setflags, int clearflags)
11583 struct latch_descr *ldesc;
11585 ldesc = find_latch(mask);
11588 ldesc->flags |= setflags;
11589 ldesc->flags &= ~clearflags;
11593 void clear_problem_context(struct problem_context *ctx)
11595 memset(ctx, 0, sizeof(struct problem_context));
11596 ctx->blkcount = -1;
11600 int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
11602 ext2_filsys fs = ctx->fs;
11603 const struct e2fsck_problem *ptr;
11604 struct latch_descr *ldesc = 0;
11605 const char *message;
11606 int def_yn, answer, ans;
11607 int print_answer = 0;
11610 ptr = find_problem(code);
11612 printf(_("Unhandled error code (0x%x)!\n"), code);
11616 if ((ptr->flags & PR_NO_DEFAULT) ||
11617 ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) ||
11618 (ctx->options & E2F_OPT_NO))
11622 * Do special latch processing. This is where we ask the
11623 * latch question, if it exists
11625 if (ptr->flags & PR_LATCH_MASK) {
11626 ldesc = find_latch(ptr->flags & PR_LATCH_MASK);
11627 if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) {
11628 ans = fix_problem(ctx, ldesc->question, pctx);
11630 ldesc->flags |= PRL_YES;
11632 ldesc->flags |= PRL_NO;
11633 ldesc->flags |= PRL_LATCHED;
11635 if (ldesc->flags & PRL_SUPPRESS)
11638 if ((ptr->flags & PR_PREEN_NOMSG) &&
11639 (ctx->options & E2F_OPT_PREEN))
11641 if ((ptr->flags & PR_NO_NOMSG) &&
11642 (ctx->options & E2F_OPT_NO))
11645 message = ptr->e2p_description;
11646 if ((ctx->options & E2F_OPT_PREEN) &&
11647 !(ptr->flags & PR_PREEN_NOHDR)) {
11648 printf("%s: ", ctx->device_name ?
11649 ctx->device_name : ctx->filesystem_name);
11652 print_e2fsck_message(ctx, _(message), pctx, 1);
11654 if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE))
11657 if (ptr->flags & PR_FATAL)
11658 fatal_error(ctx, 0);
11660 if (ptr->prompt == PROMPT_NONE) {
11661 if (ptr->flags & PR_NOCOLLATE)
11666 if (ctx->options & E2F_OPT_PREEN) {
11668 if (!(ptr->flags & PR_PREEN_NOMSG))
11670 } else if ((ptr->flags & PR_LATCH_MASK) &&
11671 (ldesc->flags & (PRL_YES | PRL_NO))) {
11674 if (ldesc->flags & PRL_YES)
11679 answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn);
11680 if (!answer && !(ptr->flags & PR_NO_OK))
11681 ext2fs_unmark_valid(fs);
11684 printf("%s.\n", answer ?
11685 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
11689 if ((ptr->prompt == PROMPT_ABORT) && answer)
11690 fatal_error(ctx, 0);
11692 if (ptr->flags & PR_AFTER_CODE)
11693 answer = fix_problem(ctx, ptr->second_code, pctx);
11699 * linux/fs/recovery.c
11701 * Written by Stephen C. Tweedie <sct@redhat.com>, 1999
11705 * Maintain information about the progress of the recovery job, so that
11706 * the different passes can carry information between them.
11708 struct recovery_info
11710 tid_t start_transaction;
11711 tid_t end_transaction;
11715 int nr_revoke_hits;
11718 enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY};
11719 static int do_one_pass(journal_t *journal,
11720 struct recovery_info *info, enum passtype pass);
11721 static int scan_revoke_records(journal_t *, struct buffer_head *,
11722 tid_t, struct recovery_info *);
11725 * Read a block from the journal
11728 static int jread(struct buffer_head **bhp, journal_t *journal,
11729 unsigned int offset)
11732 unsigned long blocknr;
11733 struct buffer_head *bh;
11737 J_ASSERT (offset < journal->j_maxlen);
11739 err = journal_bmap(journal, offset, &blocknr);
11742 printk (KERN_ERR "JBD: bad block at offset %u\n",
11747 bh = getblk(journal->j_dev, blocknr, journal->j_blocksize);
11751 if (!buffer_uptodate(bh)) {
11752 /* If this is a brand new buffer, start readahead.
11753 Otherwise, we assume we are already reading it. */
11754 if (!buffer_req(bh))
11755 do_readahead(journal, offset);
11756 wait_on_buffer(bh);
11759 if (!buffer_uptodate(bh)) {
11760 printk (KERN_ERR "JBD: Failed to read block at offset %u\n",
11772 * Count the number of in-use tags in a journal descriptor block.
11775 static int count_tags(struct buffer_head *bh, int size)
11778 journal_block_tag_t * tag;
11781 tagp = &bh->b_data[sizeof(journal_header_t)];
11783 while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) {
11784 tag = (journal_block_tag_t *) tagp;
11787 tagp += sizeof(journal_block_tag_t);
11788 if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID)))
11791 if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG))
11799 /* Make sure we wrap around the log correctly! */
11800 #define wrap(journal, var) \
11802 if (var >= (journal)->j_last) \
11803 var -= ((journal)->j_last - (journal)->j_first); \
11807 * int journal_recover(journal_t *journal) - recovers a on-disk journal
11808 * @journal: the journal to recover
11810 * The primary function for recovering the log contents when mounting a
11811 * journaled device.
11813 * Recovery is done in three passes. In the first pass, we look for the
11814 * end of the log. In the second, we assemble the list of revoke
11815 * blocks. In the third and final pass, we replay any un-revoked blocks
11818 int journal_recover(journal_t *journal)
11821 journal_superblock_t * sb;
11823 struct recovery_info info;
11825 memset(&info, 0, sizeof(info));
11826 sb = journal->j_superblock;
11829 * The journal superblock's s_start field (the current log head)
11830 * is always zero if, and only if, the journal was cleanly
11834 if (!sb->s_start) {
11835 jbd_debug(1, "No recovery required, last transaction %d\n",
11836 ntohl(sb->s_sequence));
11837 journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1;
11841 err = do_one_pass(journal, &info, PASS_SCAN);
11843 err = do_one_pass(journal, &info, PASS_REVOKE);
11845 err = do_one_pass(journal, &info, PASS_REPLAY);
11847 jbd_debug(0, "JBD: recovery, exit status %d, "
11848 "recovered transactions %u to %u\n",
11849 err, info.start_transaction, info.end_transaction);
11850 jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n",
11851 info.nr_replays, info.nr_revoke_hits, info.nr_revokes);
11853 /* Restart the log at the next transaction ID, thus invalidating
11854 * any existing commit records in the log. */
11855 journal->j_transaction_sequence = ++info.end_transaction;
11857 journal_clear_revoke(journal);
11858 sync_blockdev(journal->j_fs_dev);
11862 static int do_one_pass(journal_t *journal,
11863 struct recovery_info *info, enum passtype pass)
11865 unsigned int first_commit_ID, next_commit_ID;
11866 unsigned long next_log_block;
11867 int err, success = 0;
11868 journal_superblock_t * sb;
11869 journal_header_t * tmp;
11870 struct buffer_head * bh;
11871 unsigned int sequence;
11874 /* Precompute the maximum metadata descriptors in a descriptor block */
11875 int MAX_BLOCKS_PER_DESC;
11876 MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t))
11877 / sizeof(journal_block_tag_t));
11880 * First thing is to establish what we expect to find in the log
11881 * (in terms of transaction IDs), and where (in terms of log
11882 * block offsets): query the superblock.
11885 sb = journal->j_superblock;
11886 next_commit_ID = ntohl(sb->s_sequence);
11887 next_log_block = ntohl(sb->s_start);
11889 first_commit_ID = next_commit_ID;
11890 if (pass == PASS_SCAN)
11891 info->start_transaction = first_commit_ID;
11893 jbd_debug(1, "Starting recovery pass %d\n", pass);
11896 * Now we walk through the log, transaction by transaction,
11897 * making sure that each transaction has a commit block in the
11898 * expected place. Each complete transaction gets replayed back
11899 * into the main filesystem.
11905 journal_block_tag_t * tag;
11906 struct buffer_head * obh;
11907 struct buffer_head * nbh;
11909 /* If we already know where to stop the log traversal,
11910 * check right now that we haven't gone past the end of
11913 if (pass != PASS_SCAN)
11914 if (tid_geq(next_commit_ID, info->end_transaction))
11917 jbd_debug(2, "Scanning for sequence ID %u at %lu/%lu\n",
11918 next_commit_ID, next_log_block, journal->j_last);
11920 /* Skip over each chunk of the transaction looking
11921 * either the next descriptor block or the final commit
11924 jbd_debug(3, "JBD: checking block %ld\n", next_log_block);
11925 err = jread(&bh, journal, next_log_block);
11930 wrap(journal, next_log_block);
11932 /* What kind of buffer is it?
11934 * If it is a descriptor block, check that it has the
11935 * expected sequence number. Otherwise, we're all done
11938 tmp = (journal_header_t *)bh->b_data;
11940 if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) {
11945 blocktype = ntohl(tmp->h_blocktype);
11946 sequence = ntohl(tmp->h_sequence);
11947 jbd_debug(3, "Found magic %d, sequence %d\n",
11948 blocktype, sequence);
11950 if (sequence != next_commit_ID) {
11955 /* OK, we have a valid descriptor block which matches
11956 * all of the sequence number checks. What are we going
11957 * to do with it? That depends on the pass... */
11959 switch(blocktype) {
11960 case JFS_DESCRIPTOR_BLOCK:
11961 /* If it is a valid descriptor block, replay it
11962 * in pass REPLAY; otherwise, just skip over the
11963 * blocks it describes. */
11964 if (pass != PASS_REPLAY) {
11966 count_tags(bh, journal->j_blocksize);
11967 wrap(journal, next_log_block);
11972 /* A descriptor block: we can now write all of
11973 * the data blocks. Yay, useful work is finally
11974 * getting done here! */
11976 tagp = &bh->b_data[sizeof(journal_header_t)];
11977 while ((tagp - bh->b_data +sizeof(journal_block_tag_t))
11978 <= journal->j_blocksize) {
11979 unsigned long io_block;
11981 tag = (journal_block_tag_t *) tagp;
11982 flags = ntohl(tag->t_flags);
11984 io_block = next_log_block++;
11985 wrap(journal, next_log_block);
11986 err = jread(&obh, journal, io_block);
11988 /* Recover what we can, but
11989 * report failure at the end. */
11992 "JBD: IO error %d recovering "
11993 "block %ld in log\n",
11996 unsigned long blocknr;
11998 J_ASSERT(obh != NULL);
11999 blocknr = ntohl(tag->t_blocknr);
12001 /* If the block has been
12002 * revoked, then we're all done
12004 if (journal_test_revoke
12008 ++info->nr_revoke_hits;
12012 /* Find a buffer for the new
12013 * data being restored */
12014 nbh = getblk(journal->j_fs_dev,
12016 journal->j_blocksize);
12019 "JBD: Out of memory "
12020 "during recovery.\n");
12028 memcpy(nbh->b_data, obh->b_data,
12029 journal->j_blocksize);
12030 if (flags & JFS_FLAG_ESCAPE) {
12031 *((unsigned int *)bh->b_data) =
12032 htonl(JFS_MAGIC_NUMBER);
12035 BUFFER_TRACE(nbh, "marking dirty");
12036 mark_buffer_uptodate(nbh, 1);
12037 mark_buffer_dirty(nbh);
12038 BUFFER_TRACE(nbh, "marking uptodate");
12039 ++info->nr_replays;
12040 /* ll_rw_block(WRITE, 1, &nbh); */
12041 unlock_buffer(nbh);
12047 tagp += sizeof(journal_block_tag_t);
12048 if (!(flags & JFS_FLAG_SAME_UUID))
12051 if (flags & JFS_FLAG_LAST_TAG)
12058 case JFS_COMMIT_BLOCK:
12059 /* Found an expected commit block: not much to
12060 * do other than move on to the next sequence
12066 case JFS_REVOKE_BLOCK:
12067 /* If we aren't in the REVOKE pass, then we can
12068 * just skip over this block. */
12069 if (pass != PASS_REVOKE) {
12074 err = scan_revoke_records(journal, bh,
12075 next_commit_ID, info);
12082 jbd_debug(3, "Unrecognised magic %d, end of scan.\n",
12090 * We broke out of the log scan loop: either we came to the
12091 * known end of the log or we found an unexpected block in the
12092 * log. If the latter happened, then we know that the "current"
12093 * transaction marks the end of the valid log.
12096 if (pass == PASS_SCAN)
12097 info->end_transaction = next_commit_ID;
12099 /* It's really bad news if different passes end up at
12100 * different places (but possible due to IO errors). */
12101 if (info->end_transaction != next_commit_ID) {
12102 printk (KERN_ERR "JBD: recovery pass %d ended at "
12103 "transaction %u, expected %u\n",
12104 pass, next_commit_ID, info->end_transaction);
12117 /* Scan a revoke record, marking all blocks mentioned as revoked. */
12119 static int scan_revoke_records(journal_t *journal, struct buffer_head *bh,
12120 tid_t sequence, struct recovery_info *info)
12122 journal_revoke_header_t *header;
12125 header = (journal_revoke_header_t *) bh->b_data;
12126 offset = sizeof(journal_revoke_header_t);
12127 max = ntohl(header->r_count);
12129 while (offset < max) {
12130 unsigned long blocknr;
12133 blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset)));
12135 err = journal_set_revoke(journal, blocknr, sequence);
12138 ++info->nr_revokes;
12145 * rehash.c --- rebuild hash tree directories
12147 * This algorithm is designed for simplicity of implementation and to
12148 * pack the directory as much as possible. It however requires twice
12149 * as much memory as the size of the directory. The maximum size
12150 * directory supported using a 4k blocksize is roughly a gigabyte, and
12151 * so there may very well be problems with machines that don't have
12152 * virtual memory, and obscenely large directories.
12154 * An alternate algorithm which is much more disk intensive could be
12155 * written, and probably will need to be written in the future. The
12156 * design goals of such an algorithm are: (a) use (roughly) constant
12157 * amounts of memory, no matter how large the directory, (b) the
12158 * directory must be safe at all times, even if e2fsck is interrupted
12159 * in the middle, (c) we must use minimal amounts of extra disk
12160 * blocks. This pretty much requires an incremental approach, where
12161 * we are reading from one part of the directory, and inserting into
12162 * the front half. So the algorithm will have to keep track of a
12163 * moving block boundary between the new tree and the old tree, and
12164 * files will need to be moved from the old directory and inserted
12165 * into the new tree. If the new directory requires space which isn't
12166 * yet available, blocks from the beginning part of the old directory
12167 * may need to be moved to the end of the directory to make room for
12170 * --------------------------------------------------------
12171 * | new tree | | old tree |
12172 * --------------------------------------------------------
12174 * tail new head old
12176 * This is going to be a pain in the tuckus to implement, and will
12177 * require a lot more disk accesses. So I'm going to skip it for now;
12178 * it's only really going to be an issue for really, really big
12179 * filesystems (when we reach the level of tens of millions of files
12180 * in a single directory). It will probably be easier to simply
12181 * require that e2fsck use VM first.
12184 struct fill_dir_struct {
12186 struct ext2_inode *inode;
12189 struct hash_entry *harray;
12190 int max_array, num_array;
12196 struct hash_entry {
12197 ext2_dirhash_t hash;
12198 ext2_dirhash_t minor_hash;
12199 struct ext2_dir_entry *dir;
12206 ext2_dirhash_t *hashes;
12209 static int fill_dir_block(ext2_filsys fs,
12211 e2_blkcnt_t blockcnt,
12212 blk_t ref_block FSCK_ATTR((unused)),
12213 int ref_offset FSCK_ATTR((unused)),
12216 struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data;
12217 struct hash_entry *new_array, *ent;
12218 struct ext2_dir_entry *dirent;
12220 unsigned int offset, dir_offset;
12225 offset = blockcnt * fs->blocksize;
12226 if (offset + fs->blocksize > fd->inode->i_size) {
12227 fd->err = EXT2_ET_DIR_CORRUPTED;
12228 return BLOCK_ABORT;
12230 dir = (fd->buf+offset);
12231 if (HOLE_BLKADDR(*block_nr)) {
12232 memset(dir, 0, fs->blocksize);
12233 dirent = (struct ext2_dir_entry *) dir;
12234 dirent->rec_len = fs->blocksize;
12236 fd->err = ext2fs_read_dir_block(fs, *block_nr, dir);
12238 return BLOCK_ABORT;
12240 /* While the directory block is "hot", index it. */
12242 while (dir_offset < fs->blocksize) {
12243 dirent = (struct ext2_dir_entry *) (dir + dir_offset);
12244 if (((dir_offset + dirent->rec_len) > fs->blocksize) ||
12245 (dirent->rec_len < 8) ||
12246 ((dirent->rec_len % 4) != 0) ||
12247 (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
12248 fd->err = EXT2_ET_DIR_CORRUPTED;
12249 return BLOCK_ABORT;
12251 dir_offset += dirent->rec_len;
12252 if (dirent->inode == 0)
12254 if (!fd->compress && ((dirent->name_len&0xFF) == 1) &&
12255 (dirent->name[0] == '.'))
12257 if (!fd->compress && ((dirent->name_len&0xFF) == 2) &&
12258 (dirent->name[0] == '.') && (dirent->name[1] == '.')) {
12259 fd->parent = dirent->inode;
12262 if (fd->num_array >= fd->max_array) {
12263 new_array = realloc(fd->harray,
12264 sizeof(struct hash_entry) * (fd->max_array+500));
12267 return BLOCK_ABORT;
12269 fd->harray = new_array;
12270 fd->max_array += 500;
12272 ent = fd->harray + fd->num_array++;
12274 fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
12276 ent->hash = ent->minor_hash = 0;
12278 fd->err = ext2fs_dirhash(fs->super->s_def_hash_version,
12280 dirent->name_len & 0xFF,
12281 fs->super->s_hash_seed,
12282 &ent->hash, &ent->minor_hash);
12284 return BLOCK_ABORT;
12291 /* Used for sorting the hash entry */
12292 static EXT2_QSORT_TYPE name_cmp(const void *a, const void *b)
12294 const struct hash_entry *he_a = (const struct hash_entry *) a;
12295 const struct hash_entry *he_b = (const struct hash_entry *) b;
12299 min_len = he_a->dir->name_len;
12300 if (min_len > he_b->dir->name_len)
12301 min_len = he_b->dir->name_len;
12303 ret = strncmp(he_a->dir->name, he_b->dir->name, min_len);
12305 if (he_a->dir->name_len > he_b->dir->name_len)
12307 else if (he_a->dir->name_len < he_b->dir->name_len)
12310 ret = he_b->dir->inode - he_a->dir->inode;
12315 /* Used for sorting the hash entry */
12316 static EXT2_QSORT_TYPE hash_cmp(const void *a, const void *b)
12318 const struct hash_entry *he_a = (const struct hash_entry *) a;
12319 const struct hash_entry *he_b = (const struct hash_entry *) b;
12322 if (he_a->hash > he_b->hash)
12324 else if (he_a->hash < he_b->hash)
12327 if (he_a->minor_hash > he_b->minor_hash)
12329 else if (he_a->minor_hash < he_b->minor_hash)
12332 ret = name_cmp(a, b);
12337 static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir,
12343 new_mem = realloc(outdir->buf, blocks * fs->blocksize);
12346 outdir->buf = new_mem;
12347 new_mem = realloc(outdir->hashes,
12348 blocks * sizeof(ext2_dirhash_t));
12351 outdir->hashes = new_mem;
12353 outdir->buf = malloc(blocks * fs->blocksize);
12354 outdir->hashes = malloc(blocks * sizeof(ext2_dirhash_t));
12357 outdir->max = blocks;
12361 static void free_out_dir(struct out_dir *outdir)
12365 if (outdir->hashes)
12366 free(outdir->hashes);
12371 static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir,
12376 if (outdir->num >= outdir->max) {
12377 retval = alloc_size_dir(fs, outdir, outdir->max + 50);
12381 *ret = outdir->buf + (outdir->num++ * fs->blocksize);
12382 memset(*ret, 0, fs->blocksize);
12387 * This function is used to make a unique filename. We do this by
12388 * appending ~0, and then incrementing the number. However, we cannot
12389 * expand the length of the filename beyond the padding available in
12390 * the directory entry.
12392 static void mutate_name(char *str, __u16 *len)
12395 __u16 l = *len & 0xFF, h = *len & 0xff00;
12398 * First check to see if it looks the name has been mutated
12401 for (i = l-1; i > 0; i--) {
12402 if (!isdigit(str[i]))
12405 if ((i == l-1) || (str[i] != '~')) {
12406 if (((l-1) & 3) < 2)
12415 for (i = l-1; i >= 0; i--) {
12416 if (isdigit(str[i])) {
12428 else if (str[0] == 'Z') {
12433 } else if (i > 0) {
12446 static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs,
12448 struct fill_dir_struct *fd)
12450 struct problem_context pctx;
12451 struct hash_entry *ent, *prev;
12454 char new_name[256];
12457 clear_problem_context(&pctx);
12460 for (i=1; i < fd->num_array; i++) {
12461 ent = fd->harray + i;
12463 if (!ent->dir->inode ||
12464 ((ent->dir->name_len & 0xFF) !=
12465 (prev->dir->name_len & 0xFF)) ||
12466 (strncmp(ent->dir->name, prev->dir->name,
12467 ent->dir->name_len & 0xFF)))
12469 pctx.dirent = ent->dir;
12470 if ((ent->dir->inode == prev->dir->inode) &&
12471 fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) {
12472 e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1);
12473 ent->dir->inode = 0;
12477 memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF);
12478 new_len = ent->dir->name_len;
12479 mutate_name(new_name, &new_len);
12480 for (j=0; j < fd->num_array; j++) {
12482 ((ent->dir->name_len & 0xFF) !=
12483 (fd->harray[j].dir->name_len & 0xFF)) ||
12484 (strncmp(new_name, fd->harray[j].dir->name,
12487 mutate_name(new_name, &new_len);
12491 new_name[new_len & 0xFF] = 0;
12492 pctx.str = new_name;
12493 if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) {
12494 memcpy(ent->dir->name, new_name, new_len & 0xFF);
12495 ent->dir->name_len = new_len;
12496 ext2fs_dirhash(fs->super->s_def_hash_version,
12498 ent->dir->name_len & 0xFF,
12499 fs->super->s_hash_seed,
12500 &ent->hash, &ent->minor_hash);
12508 static errcode_t copy_dir_entries(ext2_filsys fs,
12509 struct fill_dir_struct *fd,
12510 struct out_dir *outdir)
12514 struct hash_entry *ent;
12515 struct ext2_dir_entry *dirent;
12516 int i, rec_len, left;
12517 ext2_dirhash_t prev_hash;
12521 retval = alloc_size_dir(fs, outdir,
12522 (fd->dir_size / fs->blocksize) + 2);
12525 outdir->num = fd->compress ? 0 : 1;
12527 outdir->hashes[0] = 0;
12529 if ((retval = get_next_block(fs, outdir, &block_start)))
12531 dirent = (struct ext2_dir_entry *) block_start;
12532 left = fs->blocksize;
12533 for (i=0; i < fd->num_array; i++) {
12534 ent = fd->harray + i;
12535 if (ent->dir->inode == 0)
12537 rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF);
12538 if (rec_len > left) {
12540 dirent->rec_len += left;
12541 if ((retval = get_next_block(fs, outdir,
12546 left = fs->blocksize - offset;
12547 dirent = (struct ext2_dir_entry *) (block_start + offset);
12549 if (ent->hash == prev_hash)
12550 outdir->hashes[outdir->num-1] = ent->hash | 1;
12552 outdir->hashes[outdir->num-1] = ent->hash;
12554 dirent->inode = ent->dir->inode;
12555 dirent->name_len = ent->dir->name_len;
12556 dirent->rec_len = rec_len;
12557 memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF);
12561 dirent->rec_len += left;
12565 prev_hash = ent->hash;
12568 dirent->rec_len += left;
12574 static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf,
12575 ext2_ino_t ino, ext2_ino_t parent)
12577 struct ext2_dir_entry *dir;
12578 struct ext2_dx_root_info *root;
12579 struct ext2_dx_countlimit *limits;
12582 if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
12583 filetype = EXT2_FT_DIR << 8;
12585 memset(buf, 0, fs->blocksize);
12586 dir = (struct ext2_dir_entry *) buf;
12588 dir->name[0] = '.';
12589 dir->name_len = 1 | filetype;
12591 dir = (struct ext2_dir_entry *) (buf + 12);
12592 dir->inode = parent;
12593 dir->name[0] = '.';
12594 dir->name[1] = '.';
12595 dir->name_len = 2 | filetype;
12596 dir->rec_len = fs->blocksize - 12;
12598 root = (struct ext2_dx_root_info *) (buf+24);
12599 root->reserved_zero = 0;
12600 root->hash_version = fs->super->s_def_hash_version;
12601 root->info_length = 8;
12602 root->indirect_levels = 0;
12603 root->unused_flags = 0;
12605 limits = (struct ext2_dx_countlimit *) (buf+32);
12606 limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry);
12613 static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
12615 struct ext2_dir_entry *dir;
12616 struct ext2_dx_countlimit *limits;
12618 memset(buf, 0, fs->blocksize);
12619 dir = (struct ext2_dir_entry *) buf;
12621 dir->rec_len = fs->blocksize;
12623 limits = (struct ext2_dx_countlimit *) (buf+8);
12624 limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry);
12627 return (struct ext2_dx_entry *) limits;
12631 * This function takes the leaf nodes which have been written in
12632 * outdir, and populates the root node and any necessary interior nodes.
12634 static errcode_t calculate_tree(ext2_filsys fs,
12635 struct out_dir *outdir,
12639 struct ext2_dx_root_info *root_info;
12640 struct ext2_dx_entry *root, *dx_ent = 0;
12641 struct ext2_dx_countlimit *root_limit, *limit;
12643 char * block_start;
12644 int i, c1, c2, nblks;
12645 int limit_offset, root_offset;
12647 root_info = set_root_node(fs, outdir->buf, ino, parent);
12648 root_offset = limit_offset = ((char *) root_info - outdir->buf) +
12649 root_info->info_length;
12650 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
12651 c1 = root_limit->limit;
12652 nblks = outdir->num;
12654 /* Write out the pointer blocks */
12655 if (nblks-1 <= c1) {
12656 /* Just write out the root block, and we're done */
12657 root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
12658 for (i=1; i < nblks; i++) {
12659 root->block = ext2fs_cpu_to_le32(i);
12662 ext2fs_cpu_to_le32(outdir->hashes[i]);
12669 root_info->indirect_levels = 1;
12670 for (i=1; i < nblks; i++) {
12675 limit->limit = limit->count =
12676 ext2fs_cpu_to_le16(limit->limit);
12677 root = (struct ext2_dx_entry *)
12678 (outdir->buf + root_offset);
12679 root->block = ext2fs_cpu_to_le32(outdir->num);
12682 ext2fs_cpu_to_le32(outdir->hashes[i]);
12683 if ((retval = get_next_block(fs, outdir,
12686 dx_ent = set_int_node(fs, block_start);
12687 limit = (struct ext2_dx_countlimit *) dx_ent;
12689 root_offset += sizeof(struct ext2_dx_entry);
12692 dx_ent->block = ext2fs_cpu_to_le32(i);
12693 if (c2 != limit->limit)
12695 ext2fs_cpu_to_le32(outdir->hashes[i]);
12699 limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
12700 limit->limit = ext2fs_cpu_to_le16(limit->limit);
12702 root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
12703 root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
12704 root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit);
12709 struct write_dir_struct {
12710 struct out_dir *outdir;
12717 * Helper function which writes out a directory block.
12719 static int write_dir_block(ext2_filsys fs,
12721 e2_blkcnt_t blockcnt,
12722 blk_t ref_block FSCK_ATTR((unused)),
12723 int ref_offset FSCK_ATTR((unused)),
12726 struct write_dir_struct *wd = (struct write_dir_struct *) priv_data;
12730 if (*block_nr == 0)
12732 if (blockcnt >= wd->outdir->num) {
12733 e2fsck_read_bitmaps(wd->ctx);
12735 ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk);
12736 ext2fs_block_alloc_stats(fs, blk, -1);
12739 return BLOCK_CHANGED;
12744 dir = wd->outdir->buf + (blockcnt * fs->blocksize);
12745 wd->err = ext2fs_write_dir_block(fs, *block_nr, dir);
12747 return BLOCK_ABORT;
12751 static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs,
12752 struct out_dir *outdir,
12753 ext2_ino_t ino, int compress)
12755 struct write_dir_struct wd;
12757 struct ext2_inode inode;
12759 retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num);
12763 wd.outdir = outdir;
12768 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
12769 write_dir_block, &wd);
12775 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
12777 inode.i_flags &= ~EXT2_INDEX_FL;
12779 inode.i_flags |= EXT2_INDEX_FL;
12780 inode.i_size = outdir->num * fs->blocksize;
12781 inode.i_blocks -= (fs->blocksize / 512) * wd.cleared;
12782 e2fsck_write_inode(ctx, ino, &inode, "rehash_dir");
12787 static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino)
12789 ext2_filsys fs = ctx->fs;
12791 struct ext2_inode inode;
12793 struct fill_dir_struct fd;
12794 struct out_dir outdir;
12796 outdir.max = outdir.num = 0;
12799 e2fsck_read_inode(ctx, ino, &inode, "rehash_dir");
12803 dir_buf = malloc(inode.i_size);
12807 fd.max_array = inode.i_size / 32;
12809 fd.harray = malloc(fd.max_array * sizeof(struct hash_entry));
12819 if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
12820 (inode.i_size / fs->blocksize) < 2)
12824 /* Read in the entire directory into memory */
12825 retval = ext2fs_block_iterate2(fs, ino, 0, 0,
12826 fill_dir_block, &fd);
12833 printf("%d entries (%d bytes) found in inode %d\n",
12834 fd.num_array, fd.dir_size, ino);
12837 /* Sort the list */
12840 qsort(fd.harray+2, fd.num_array-2,
12841 sizeof(struct hash_entry), name_cmp);
12843 qsort(fd.harray, fd.num_array,
12844 sizeof(struct hash_entry), hash_cmp);
12847 * Look for duplicates
12849 if (duplicate_search_and_fix(ctx, fs, ino, &fd))
12852 if (ctx->options & E2F_OPT_NO) {
12858 * Copy the directory entries. In a htree directory these
12859 * will become the leaf nodes.
12861 retval = copy_dir_entries(fs, &fd, &outdir);
12865 free(dir_buf); dir_buf = 0;
12867 if (!fd.compress) {
12868 /* Calculate the interior nodes */
12869 retval = calculate_tree(fs, &outdir, ino, fd.parent);
12874 retval = write_directory(ctx, fs, &outdir, ino, fd.compress);
12884 free_out_dir(&outdir);
12888 void e2fsck_rehash_directories(e2fsck_t ctx)
12890 struct problem_context pctx;
12891 #ifdef RESOURCE_TRACK
12892 struct resource_track rtrack;
12894 struct dir_info *dir;
12895 ext2_u32_iterate iter;
12898 int i, cur, max, all_dirs, dir_index, first = 1;
12900 #ifdef RESOURCE_TRACK
12901 init_resource_track(&rtrack);
12904 all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS;
12906 if (!ctx->dirs_to_hash && !all_dirs)
12909 e2fsck_get_lost_and_found(ctx, 0);
12911 clear_problem_context(&pctx);
12913 dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX;
12917 max = e2fsck_get_num_dirinfo(ctx);
12919 retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash,
12922 pctx.errcode = retval;
12923 fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx);
12926 max = ext2fs_u32_list_count(ctx->dirs_to_hash);
12930 if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0)
12934 if (!ext2fs_u32_list_iterate(iter, &ino))
12937 if (ino == ctx->lost_and_found)
12941 fix_problem(ctx, PR_3A_PASS_HEADER, &pctx);
12945 fix_problem(ctx, PR_3A_OPTIMIZE_DIR, &pctx);
12947 pctx.errcode = e2fsck_rehash_dir(ctx, ino);
12948 if (pctx.errcode) {
12949 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
12950 fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx);
12952 if (ctx->progress && !ctx->progress_fd)
12953 e2fsck_simple_progress(ctx, "Rebuilding directory",
12954 100.0 * (float) (++cur) / (float) max, ino);
12956 end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR);
12958 ext2fs_u32_list_iterate_end(iter);
12960 if (ctx->dirs_to_hash)
12961 ext2fs_u32_list_free(ctx->dirs_to_hash);
12962 ctx->dirs_to_hash = 0;
12964 #ifdef RESOURCE_TRACK
12965 if (ctx->options & E2F_OPT_TIME2) {
12966 e2fsck_clear_progbar(ctx);
12967 print_resource_track("Pass 3A", &rtrack);
12973 * linux/fs/revoke.c
12975 * Journal revoke routines for the generic filesystem journaling code;
12976 * part of the ext2fs journaling system.
12978 * Revoke is the mechanism used to prevent old log records for deleted
12979 * metadata from being replayed on top of newer data using the same
12980 * blocks. The revoke mechanism is used in two separate places:
12982 * + Commit: during commit we write the entire list of the current
12983 * transaction's revoked blocks to the journal
12985 * + Recovery: during recovery we record the transaction ID of all
12986 * revoked blocks. If there are multiple revoke records in the log
12987 * for a single block, only the last one counts, and if there is a log
12988 * entry for a block beyond the last revoke, then that log entry still
12991 * We can get interactions between revokes and new log data within a
12992 * single transaction:
12994 * Block is revoked and then journaled:
12995 * The desired end result is the journaling of the new block, so we
12996 * cancel the revoke before the transaction commits.
12998 * Block is journaled and then revoked:
12999 * The revoke must take precedence over the write of the block, so we
13000 * need either to cancel the journal entry or to write the revoke
13001 * later in the log than the log block. In this case, we choose the
13002 * latter: journaling a block cancels any revoke record for that block
13003 * in the current transaction, so any revoke for that block in the
13004 * transaction must have happened after the block was journaled and so
13005 * the revoke must take precedence.
13007 * Block is revoked and then written as data:
13008 * The data write is allowed to succeed, but the revoke is _not_
13009 * cancelled. We still need to prevent old log records from
13010 * overwriting the new data. We don't even need to clear the revoke
13013 * Revoke information on buffers is a tri-state value:
13015 * RevokeValid clear: no cached revoke status, need to look it up
13016 * RevokeValid set, Revoked clear:
13017 * buffer has not been revoked, and cancel_revoke
13019 * RevokeValid set, Revoked set:
13020 * buffer has been revoked.
13023 static kmem_cache_t *revoke_record_cache;
13024 static kmem_cache_t *revoke_table_cache;
13026 /* Each revoke record represents one single revoked block. During
13027 journal replay, this involves recording the transaction ID of the
13028 last transaction to revoke this block. */
13030 struct jbd_revoke_record_s
13032 struct list_head hash;
13033 tid_t sequence; /* Used for recovery only */
13034 unsigned long blocknr;
13038 /* The revoke table is just a simple hash table of revoke records. */
13039 struct jbd_revoke_table_s
13041 /* It is conceivable that we might want a larger hash table
13042 * for recovery. Must be a power of two. */
13045 struct list_head *hash_table;
13049 /* Utility functions to maintain the revoke table */
13051 /* Borrowed from buffer.c: this is a tried and tested block hash function */
13052 static inline int hash(journal_t *journal, unsigned long block)
13054 struct jbd_revoke_table_s *table = journal->j_revoke;
13055 int hash_shift = table->hash_shift;
13057 return ((block << (hash_shift - 6)) ^
13059 (block << (hash_shift - 12))) & (table->hash_size - 1);
13062 static int insert_revoke_hash(journal_t *journal, unsigned long blocknr,
13065 struct list_head *hash_list;
13066 struct jbd_revoke_record_s *record;
13068 record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS);
13072 record->sequence = seq;
13073 record->blocknr = blocknr;
13074 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
13075 list_add(&record->hash, hash_list);
13082 /* Find a revoke record in the journal's hash table. */
13084 static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal,
13085 unsigned long blocknr)
13087 struct list_head *hash_list;
13088 struct jbd_revoke_record_s *record;
13090 hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
13092 record = (struct jbd_revoke_record_s *) hash_list->next;
13093 while (&(record->hash) != hash_list) {
13094 if (record->blocknr == blocknr)
13096 record = (struct jbd_revoke_record_s *) record->hash.next;
13101 int journal_init_revoke_caches(void)
13103 revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s));
13104 if (revoke_record_cache == 0)
13107 revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s));
13108 if (revoke_table_cache == 0) {
13109 do_cache_destroy(revoke_record_cache);
13110 revoke_record_cache = NULL;
13116 void journal_destroy_revoke_caches(void)
13118 do_cache_destroy(revoke_record_cache);
13119 revoke_record_cache = 0;
13120 do_cache_destroy(revoke_table_cache);
13121 revoke_table_cache = 0;
13124 /* Initialise the revoke table for a given journal to a given size. */
13126 int journal_init_revoke(journal_t *journal, int hash_size)
13130 J_ASSERT (journal->j_revoke == NULL);
13132 journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
13133 if (!journal->j_revoke)
13136 /* Check that the hash_size is a power of two */
13137 J_ASSERT ((hash_size & (hash_size-1)) == 0);
13139 journal->j_revoke->hash_size = hash_size;
13143 while((tmp >>= 1UL) != 0UL)
13145 journal->j_revoke->hash_shift = shift;
13147 journal->j_revoke->hash_table = malloc(hash_size * sizeof(struct list_head));
13148 if (!journal->j_revoke->hash_table) {
13149 free(journal->j_revoke);
13150 journal->j_revoke = NULL;
13154 for (tmp = 0; tmp < hash_size; tmp++)
13155 INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
13160 /* Destoy a journal's revoke table. The table must already be empty! */
13162 void journal_destroy_revoke(journal_t *journal)
13164 struct jbd_revoke_table_s *table;
13165 struct list_head *hash_list;
13168 table = journal->j_revoke;
13172 for (i=0; i<table->hash_size; i++) {
13173 hash_list = &table->hash_table[i];
13174 J_ASSERT (list_empty(hash_list));
13177 free(table->hash_table);
13179 journal->j_revoke = NULL;
13183 * Revoke support for recovery.
13185 * Recovery needs to be able to:
13187 * record all revoke records, including the tid of the latest instance
13188 * of each revoke in the journal
13190 * check whether a given block in a given transaction should be replayed
13191 * (ie. has not been revoked by a revoke record in that or a subsequent
13194 * empty the revoke table after recovery.
13198 * First, setting revoke records. We create a new revoke record for
13199 * every block ever revoked in the log as we scan it for recovery, and
13200 * we update the existing records if we find multiple revokes for a
13204 int journal_set_revoke(journal_t *journal, unsigned long blocknr,
13207 struct jbd_revoke_record_s *record;
13209 record = find_revoke_record(journal, blocknr);
13211 /* If we have multiple occurences, only record the
13212 * latest sequence number in the hashed record */
13213 if (tid_gt(sequence, record->sequence))
13214 record->sequence = sequence;
13217 return insert_revoke_hash(journal, blocknr, sequence);
13221 * Test revoke records. For a given block referenced in the log, has
13222 * that block been revoked? A revoke record with a given transaction
13223 * sequence number revokes all blocks in that transaction and earlier
13224 * ones, but later transactions still need replayed.
13227 int journal_test_revoke(journal_t *journal, unsigned long blocknr,
13230 struct jbd_revoke_record_s *record;
13232 record = find_revoke_record(journal, blocknr);
13235 if (tid_gt(sequence, record->sequence))
13241 * Finally, once recovery is over, we need to clear the revoke table so
13242 * that it can be reused by the running filesystem.
13245 void journal_clear_revoke(journal_t *journal)
13248 struct list_head *hash_list;
13249 struct jbd_revoke_record_s *record;
13250 struct jbd_revoke_table_s *revoke_var;
13252 revoke_var = journal->j_revoke;
13254 for (i = 0; i < revoke_var->hash_size; i++) {
13255 hash_list = &revoke_var->hash_table[i];
13256 while (!list_empty(hash_list)) {
13257 record = (struct jbd_revoke_record_s*) hash_list->next;
13258 list_del(&record->hash);
13265 * e2fsck.c - superblock checks
13268 #define MIN_CHECK 1
13269 #define MAX_CHECK 2
13271 static void check_super_value(e2fsck_t ctx, const char *descr,
13272 unsigned long value, int flags,
13273 unsigned long min_val, unsigned long max_val)
13275 struct problem_context pctx;
13277 if (((flags & MIN_CHECK) && (value < min_val)) ||
13278 ((flags & MAX_CHECK) && (value > max_val))) {
13279 clear_problem_context(&pctx);
13282 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
13283 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
13288 * This routine may get stubbed out in special compilations of the
13291 #ifndef EXT2_SPECIAL_DEVICE_SIZE
13292 static errcode_t e2fsck_get_device_size(e2fsck_t ctx)
13294 return (ext2fs_get_device_size(ctx->filesystem_name,
13295 EXT2_BLOCK_SIZE(ctx->fs->super),
13296 &ctx->num_blocks));
13301 * helper function to release an inode
13303 struct process_block_struct {
13306 struct problem_context *pctx;
13308 int truncate_offset;
13309 e2_blkcnt_t truncate_block;
13310 int truncated_blocks;
13315 static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
13316 e2_blkcnt_t blockcnt,
13317 blk_t ref_blk FSCK_ATTR((unused)),
13318 int ref_offset FSCK_ATTR((unused)),
13321 struct process_block_struct *pb;
13323 struct problem_context *pctx;
13324 blk_t blk = *block_nr;
13327 pb = (struct process_block_struct *) priv_data;
13332 pctx->blkcount = blockcnt;
13334 if (HOLE_BLKADDR(blk))
13337 if ((blk < fs->super->s_first_data_block) ||
13338 (blk >= fs->super->s_blocks_count)) {
13339 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
13342 return BLOCK_ABORT;
13345 if (!ext2fs_test_block_bitmap(fs->block_map, blk)) {
13346 fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx);
13351 * If we are deleting an orphan, then we leave the fields alone.
13352 * If we are truncating an orphan, then update the inode fields
13353 * and clean up any partial block data.
13355 if (pb->truncating) {
13357 * We only remove indirect blocks if they are
13358 * completely empty.
13360 if (blockcnt < 0) {
13364 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
13369 limit = fs->blocksize >> 2;
13370 for (i = 0, bp = (blk_t *) pb->buf;
13371 i < limit; i++, bp++)
13376 * We don't remove direct blocks until we've reached
13377 * the truncation block.
13379 if (blockcnt >= 0 && blockcnt < pb->truncate_block)
13382 * If part of the last block needs truncating, we do
13385 if ((blockcnt == pb->truncate_block) && pb->truncate_offset) {
13386 pb->errcode = io_channel_read_blk(fs->io, blk, 1,
13390 memset(pb->buf + pb->truncate_offset, 0,
13391 fs->blocksize - pb->truncate_offset);
13392 pb->errcode = io_channel_write_blk(fs->io, blk, 1,
13397 pb->truncated_blocks++;
13399 retval |= BLOCK_CHANGED;
13402 ext2fs_block_alloc_stats(fs, blk, -1);
13407 * This function releases an inode. Returns 1 if an inconsistency was
13408 * found. If the inode has a link count, then it is being truncated and
13411 static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino,
13412 struct ext2_inode *inode, char *block_buf,
13413 struct problem_context *pctx)
13415 struct process_block_struct pb;
13416 ext2_filsys fs = ctx->fs;
13420 if (!ext2fs_inode_has_valid_blocks(inode))
13423 pb.buf = block_buf + 3 * ctx->fs->blocksize;
13428 if (inode->i_links_count) {
13430 pb.truncate_block = (e2_blkcnt_t)
13431 ((((long long)inode->i_size_high << 32) +
13432 inode->i_size + fs->blocksize - 1) /
13434 pb.truncate_offset = inode->i_size % fs->blocksize;
13437 pb.truncate_block = 0;
13438 pb.truncate_offset = 0;
13440 pb.truncated_blocks = 0;
13441 retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE,
13442 block_buf, release_inode_block, &pb);
13444 com_err("release_inode_blocks", retval,
13445 _("while calling ext2fs_block_iterate for inode %d"),
13452 /* Refresh the inode since ext2fs_block_iterate may have changed it */
13453 e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks");
13455 if (pb.truncated_blocks)
13456 inode->i_blocks -= pb.truncated_blocks *
13457 (fs->blocksize / 512);
13459 if (inode->i_file_acl) {
13460 retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl,
13461 block_buf, -1, &count);
13462 if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) {
13467 com_err("release_inode_blocks", retval,
13468 _("while calling ext2fs_adjust_ea_refocunt for inode %d"),
13473 ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1);
13474 inode->i_file_acl = 0;
13480 * This function releases all of the orphan inodes. It returns 1 if
13481 * it hit some error, and 0 on success.
13483 static int release_orphan_inodes(e2fsck_t ctx)
13485 ext2_filsys fs = ctx->fs;
13486 ext2_ino_t ino, next_ino;
13487 struct ext2_inode inode;
13488 struct problem_context pctx;
13491 if ((ino = fs->super->s_last_orphan) == 0)
13495 * Win or lose, we won't be using the head of the orphan inode
13498 fs->super->s_last_orphan = 0;
13499 ext2fs_mark_super_dirty(fs);
13502 * If the filesystem contains errors, don't run the orphan
13503 * list, since the orphan list can't be trusted; and we're
13504 * going to be running a full e2fsck run anyway...
13506 if (fs->super->s_state & EXT2_ERROR_FS)
13509 if ((ino < EXT2_FIRST_INODE(fs->super)) ||
13510 (ino > fs->super->s_inodes_count)) {
13511 clear_problem_context(&pctx);
13513 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx);
13517 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
13518 "block iterate buffer");
13519 e2fsck_read_bitmaps(ctx);
13522 e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes");
13523 clear_problem_context(&pctx);
13525 pctx.inode = &inode;
13526 pctx.str = inode.i_links_count ? _("Truncating") :
13529 fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx);
13531 next_ino = inode.i_dtime;
13533 ((next_ino < EXT2_FIRST_INODE(fs->super)) ||
13534 (next_ino > fs->super->s_inodes_count))) {
13535 pctx.ino = next_ino;
13536 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx);
13540 if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx))
13543 if (!inode.i_links_count) {
13544 ext2fs_inode_alloc_stats2(fs, ino, -1,
13545 LINUX_S_ISDIR(inode.i_mode));
13546 inode.i_dtime = time(0);
13550 e2fsck_write_inode(ctx, ino, &inode, "delete_file");
13553 ext2fs_free_mem(&block_buf);
13556 ext2fs_free_mem(&block_buf);
13561 * Check the resize inode to make sure it is sane. We check both for
13562 * the case where on-line resizing is not enabled (in which case the
13563 * resize inode should be cleared) as well as the case where on-line
13564 * resizing is enabled.
13566 static void check_resize_inode(e2fsck_t ctx)
13568 ext2_filsys fs = ctx->fs;
13569 struct ext2_inode inode;
13570 struct problem_context pctx;
13571 int i, j, gdt_off, ind_off;
13572 blk_t blk, pblk, expect;
13573 __u32 *dind_buf = 0, *ind_buf;
13576 clear_problem_context(&pctx);
13579 * If the resize inode feature isn't set, then
13580 * s_reserved_gdt_blocks must be zero.
13582 if (!(fs->super->s_feature_compat &
13583 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
13584 if (fs->super->s_reserved_gdt_blocks) {
13585 pctx.num = fs->super->s_reserved_gdt_blocks;
13586 if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS,
13588 fs->super->s_reserved_gdt_blocks = 0;
13589 ext2fs_mark_super_dirty(fs);
13594 /* Read the resizde inode */
13595 pctx.ino = EXT2_RESIZE_INO;
13596 retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
13598 if (fs->super->s_feature_compat &
13599 EXT2_FEATURE_COMPAT_RESIZE_INODE)
13600 ctx->flags |= E2F_FLAG_RESIZE_INODE;
13605 * If the resize inode feature isn't set, check to make sure
13606 * the resize inode is cleared; then we're done.
13608 if (!(fs->super->s_feature_compat &
13609 EXT2_FEATURE_COMPAT_RESIZE_INODE)) {
13610 for (i=0; i < EXT2_N_BLOCKS; i++) {
13611 if (inode.i_block[i])
13614 if ((i < EXT2_N_BLOCKS) &&
13615 fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) {
13616 memset(&inode, 0, sizeof(inode));
13617 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
13624 * The resize inode feature is enabled; check to make sure the
13625 * only block in use is the double indirect block
13627 blk = inode.i_block[EXT2_DIND_BLOCK];
13628 for (i=0; i < EXT2_N_BLOCKS; i++) {
13629 if (i != EXT2_DIND_BLOCK && inode.i_block[i])
13632 if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count ||
13633 !(inode.i_mode & LINUX_S_IFREG) ||
13634 (blk < fs->super->s_first_data_block ||
13635 blk >= fs->super->s_blocks_count)) {
13636 resize_inode_invalid:
13637 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
13638 memset(&inode, 0, sizeof(inode));
13639 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
13641 ctx->flags |= E2F_FLAG_RESIZE_INODE;
13643 if (!(ctx->options & E2F_OPT_READONLY)) {
13644 fs->super->s_state &= ~EXT2_VALID_FS;
13645 ext2fs_mark_super_dirty(fs);
13649 dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2,
13650 "resize dind buffer");
13651 ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize);
13653 retval = ext2fs_read_ind_block(fs, blk, dind_buf);
13655 goto resize_inode_invalid;
13657 gdt_off = fs->desc_blocks;
13658 pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks;
13659 for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4;
13660 i++, gdt_off++, pblk++) {
13661 gdt_off %= fs->blocksize/4;
13662 if (dind_buf[gdt_off] != pblk)
13663 goto resize_inode_invalid;
13664 retval = ext2fs_read_ind_block(fs, pblk, ind_buf);
13666 goto resize_inode_invalid;
13668 for (j = 1; j < fs->group_desc_count; j++) {
13669 if (!ext2fs_bg_has_super(fs, j))
13671 expect = pblk + (j * fs->super->s_blocks_per_group);
13672 if (ind_buf[ind_off] != expect)
13673 goto resize_inode_invalid;
13680 ext2fs_free_mem(&dind_buf);
13684 static void check_super_block(e2fsck_t ctx)
13686 ext2_filsys fs = ctx->fs;
13687 blk_t first_block, last_block;
13688 struct ext2_super_block *sb = fs->super;
13689 struct ext2_group_desc *gd;
13690 blk_t blocks_per_group = fs->super->s_blocks_per_group;
13692 int inodes_per_block;
13697 struct problem_context pctx;
13698 __u32 free_blocks = 0, free_inodes = 0;
13700 inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super);
13701 ipg_max = inodes_per_block * (blocks_per_group - 4);
13702 if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb))
13703 ipg_max = EXT2_MAX_INODES_PER_GROUP(sb);
13704 bpg_max = 8 * EXT2_BLOCK_SIZE(sb);
13705 if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb))
13706 bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb);
13708 ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
13709 sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap");
13710 ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx,
13711 sizeof(int) * fs->group_desc_count, "invalid_block_bitmap");
13712 ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx,
13713 sizeof(int) * fs->group_desc_count, "invalid_inode_table");
13715 clear_problem_context(&pctx);
13718 * Verify the super block constants...
13720 check_super_value(ctx, "inodes_count", sb->s_inodes_count,
13722 check_super_value(ctx, "blocks_count", sb->s_blocks_count,
13724 check_super_value(ctx, "first_data_block", sb->s_first_data_block,
13725 MAX_CHECK, 0, sb->s_blocks_count);
13726 check_super_value(ctx, "log_block_size", sb->s_log_block_size,
13727 MIN_CHECK | MAX_CHECK, 0,
13728 EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE);
13729 check_super_value(ctx, "log_frag_size", sb->s_log_frag_size,
13730 MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size);
13731 check_super_value(ctx, "frags_per_group", sb->s_frags_per_group,
13732 MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group,
13734 check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group,
13735 MIN_CHECK | MAX_CHECK, 8, bpg_max);
13736 check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group,
13737 MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max);
13738 check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count,
13739 MAX_CHECK, 0, sb->s_blocks_count / 2);
13740 check_super_value(ctx, "reserved_gdt_blocks",
13741 sb->s_reserved_gdt_blocks, MAX_CHECK, 0,
13743 inode_size = EXT2_INODE_SIZE(sb);
13744 check_super_value(ctx, "inode_size",
13745 inode_size, MIN_CHECK | MAX_CHECK,
13746 EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize);
13747 if (inode_size & (inode_size - 1)) {
13748 pctx.num = inode_size;
13749 pctx.str = "inode_size";
13750 fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx);
13751 ctx->flags |= E2F_FLAG_ABORT; /* never get here! */
13755 if (!ctx->num_blocks) {
13756 pctx.errcode = e2fsck_get_device_size(ctx);
13757 if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) {
13758 fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx);
13759 ctx->flags |= E2F_FLAG_ABORT;
13762 if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) &&
13763 (ctx->num_blocks < sb->s_blocks_count)) {
13764 pctx.blk = sb->s_blocks_count;
13765 pctx.blk2 = ctx->num_blocks;
13766 if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) {
13767 ctx->flags |= E2F_FLAG_ABORT;
13773 if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) {
13774 pctx.blk = EXT2_BLOCK_SIZE(sb);
13775 pctx.blk2 = EXT2_FRAG_SIZE(sb);
13776 fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx);
13777 ctx->flags |= E2F_FLAG_ABORT;
13781 should_be = sb->s_frags_per_group >>
13782 (sb->s_log_block_size - sb->s_log_frag_size);
13783 if (sb->s_blocks_per_group != should_be) {
13784 pctx.blk = sb->s_blocks_per_group;
13785 pctx.blk2 = should_be;
13786 fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx);
13787 ctx->flags |= E2F_FLAG_ABORT;
13791 should_be = (sb->s_log_block_size == 0) ? 1 : 0;
13792 if (sb->s_first_data_block != should_be) {
13793 pctx.blk = sb->s_first_data_block;
13794 pctx.blk2 = should_be;
13795 fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx);
13796 ctx->flags |= E2F_FLAG_ABORT;
13800 should_be = sb->s_inodes_per_group * fs->group_desc_count;
13801 if (sb->s_inodes_count != should_be) {
13802 pctx.ino = sb->s_inodes_count;
13803 pctx.ino2 = should_be;
13804 if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) {
13805 sb->s_inodes_count = should_be;
13806 ext2fs_mark_super_dirty(fs);
13811 * Verify the group descriptors....
13813 first_block = sb->s_first_data_block;
13814 last_block = first_block + blocks_per_group;
13816 for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) {
13819 if (i == fs->group_desc_count - 1)
13820 last_block = sb->s_blocks_count;
13821 if ((gd->bg_block_bitmap < first_block) ||
13822 (gd->bg_block_bitmap >= last_block)) {
13823 pctx.blk = gd->bg_block_bitmap;
13824 if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx))
13825 gd->bg_block_bitmap = 0;
13827 if (gd->bg_block_bitmap == 0) {
13828 ctx->invalid_block_bitmap_flag[i]++;
13829 ctx->invalid_bitmaps++;
13831 if ((gd->bg_inode_bitmap < first_block) ||
13832 (gd->bg_inode_bitmap >= last_block)) {
13833 pctx.blk = gd->bg_inode_bitmap;
13834 if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx))
13835 gd->bg_inode_bitmap = 0;
13837 if (gd->bg_inode_bitmap == 0) {
13838 ctx->invalid_inode_bitmap_flag[i]++;
13839 ctx->invalid_bitmaps++;
13841 if ((gd->bg_inode_table < first_block) ||
13842 ((gd->bg_inode_table +
13843 fs->inode_blocks_per_group - 1) >= last_block)) {
13844 pctx.blk = gd->bg_inode_table;
13845 if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx))
13846 gd->bg_inode_table = 0;
13848 if (gd->bg_inode_table == 0) {
13849 ctx->invalid_inode_table_flag[i]++;
13850 ctx->invalid_bitmaps++;
13852 free_blocks += gd->bg_free_blocks_count;
13853 free_inodes += gd->bg_free_inodes_count;
13854 first_block += sb->s_blocks_per_group;
13855 last_block += sb->s_blocks_per_group;
13857 if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) ||
13858 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
13859 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
13860 ext2fs_unmark_valid(fs);
13865 * Update the global counts from the block group counts. This
13866 * is needed for an experimental patch which eliminates
13867 * locking the entire filesystem when allocating blocks or
13868 * inodes; if the filesystem is not unmounted cleanly, the
13869 * global counts may not be accurate.
13871 if ((free_blocks != sb->s_free_blocks_count) ||
13872 (free_inodes != sb->s_free_inodes_count)) {
13873 if (ctx->options & E2F_OPT_READONLY)
13874 ext2fs_unmark_valid(fs);
13876 sb->s_free_blocks_count = free_blocks;
13877 sb->s_free_inodes_count = free_inodes;
13878 ext2fs_mark_super_dirty(fs);
13882 if ((sb->s_free_blocks_count > sb->s_blocks_count) ||
13883 (sb->s_free_inodes_count > sb->s_inodes_count))
13884 ext2fs_unmark_valid(fs);
13888 * If we have invalid bitmaps, set the error state of the
13891 if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) {
13892 sb->s_state &= ~EXT2_VALID_FS;
13893 ext2fs_mark_super_dirty(fs);
13896 clear_problem_context(&pctx);
13898 #ifndef EXT2_SKIP_UUID
13900 * If the UUID field isn't assigned, assign it.
13902 if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) {
13903 if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) {
13904 uuid_generate(sb->s_uuid);
13905 ext2fs_mark_super_dirty(fs);
13906 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
13912 * For the Hurd, check to see if the filetype option is set,
13913 * since it doesn't support it.
13915 if (!(ctx->options & E2F_OPT_READONLY) &&
13916 fs->super->s_creator_os == EXT2_OS_HURD &&
13917 (fs->super->s_feature_incompat &
13918 EXT2_FEATURE_INCOMPAT_FILETYPE)) {
13919 if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) {
13920 fs->super->s_feature_incompat &=
13921 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
13922 ext2fs_mark_super_dirty(fs);
13928 * If we have any of the compatibility flags set, we need to have a
13929 * revision 1 filesystem. Most kernels will not check the flags on
13930 * a rev 0 filesystem and we may have corruption issues because of
13931 * the incompatible changes to the filesystem.
13933 if (!(ctx->options & E2F_OPT_READONLY) &&
13934 fs->super->s_rev_level == EXT2_GOOD_OLD_REV &&
13935 (fs->super->s_feature_compat ||
13936 fs->super->s_feature_ro_compat ||
13937 fs->super->s_feature_incompat) &&
13938 fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) {
13939 ext2fs_update_dynamic_rev(fs);
13940 ext2fs_mark_super_dirty(fs);
13943 check_resize_inode(ctx);
13946 * Clean up any orphan inodes, if present.
13948 if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) {
13949 fs->super->s_state &= ~EXT2_VALID_FS;
13950 ext2fs_mark_super_dirty(fs);
13954 * Move the ext3 journal file, if necessary.
13956 e2fsck_move_ext3_journal(ctx);
13961 * swapfs.c --- byte-swap an ext2 filesystem
13964 #ifdef ENABLE_SWAPFS
13966 struct swap_block_struct {
13971 struct ext2_inode *inode;
13975 * This is a helper function for block_iterate. We mark all of the
13976 * indirect and direct blocks as changed, so that block_iterate will
13979 static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt,
13984 struct swap_block_struct *sb = (struct swap_block_struct *) priv_data;
13986 if (sb->isdir && (blockcnt >= 0) && *block_nr) {
13987 retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf);
13989 sb->errcode = retval;
13990 return BLOCK_ABORT;
13992 retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf);
13994 sb->errcode = retval;
13995 return BLOCK_ABORT;
13998 if (blockcnt >= 0) {
13999 if (blockcnt < EXT2_NDIR_BLOCKS)
14001 return BLOCK_CHANGED;
14003 if (blockcnt == BLOCK_COUNT_IND) {
14004 if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK])
14006 return BLOCK_CHANGED;
14008 if (blockcnt == BLOCK_COUNT_DIND) {
14009 if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK])
14011 return BLOCK_CHANGED;
14013 if (blockcnt == BLOCK_COUNT_TIND) {
14014 if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK])
14016 return BLOCK_CHANGED;
14018 return BLOCK_CHANGED;
14022 * This function is responsible for byte-swapping all of the indirect,
14023 * block pointers. It is also responsible for byte-swapping directories.
14025 static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf,
14026 struct ext2_inode *inode)
14029 struct swap_block_struct sb;
14033 sb.dir_buf = block_buf + ctx->fs->blocksize*3;
14036 if (LINUX_S_ISDIR(inode->i_mode))
14039 retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf,
14042 com_err("swap_inode_blocks", retval,
14043 _("while calling ext2fs_block_iterate"));
14044 ctx->flags |= E2F_FLAG_ABORT;
14048 com_err("swap_inode_blocks", sb.errcode,
14049 _("while calling iterator function"));
14050 ctx->flags |= E2F_FLAG_ABORT;
14055 static void swap_inodes(e2fsck_t ctx)
14057 ext2_filsys fs = ctx->fs;
14060 ext2_ino_t ino = 1;
14061 char *buf, *block_buf;
14063 struct ext2_inode * inode;
14065 e2fsck_use_inode_shortcuts(ctx, 1);
14067 retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group,
14070 com_err("swap_inodes", retval,
14071 _("while allocating inode buffer"));
14072 ctx->flags |= E2F_FLAG_ABORT;
14075 block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4,
14076 "block interate buffer");
14077 for (group = 0; group < fs->group_desc_count; group++) {
14078 retval = io_channel_read_blk(fs->io,
14079 fs->group_desc[group].bg_inode_table,
14080 fs->inode_blocks_per_group, buf);
14082 com_err("swap_inodes", retval,
14083 _("while reading inode table (group %d)"),
14085 ctx->flags |= E2F_FLAG_ABORT;
14088 inode = (struct ext2_inode *) buf;
14089 for (i=0; i < fs->super->s_inodes_per_group;
14090 i++, ino++, inode++) {
14091 ctx->stashed_ino = ino;
14092 ctx->stashed_inode = inode;
14094 if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)
14095 ext2fs_swap_inode(fs, inode, inode, 0);
14098 * Skip deleted files.
14100 if (inode->i_links_count == 0)
14103 if (LINUX_S_ISDIR(inode->i_mode) ||
14104 ((inode->i_block[EXT2_IND_BLOCK] ||
14105 inode->i_block[EXT2_DIND_BLOCK] ||
14106 inode->i_block[EXT2_TIND_BLOCK]) &&
14107 ext2fs_inode_has_valid_blocks(inode)))
14108 swap_inode_blocks(ctx, ino, block_buf, inode);
14110 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14113 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
14114 ext2fs_swap_inode(fs, inode, inode, 1);
14116 retval = io_channel_write_blk(fs->io,
14117 fs->group_desc[group].bg_inode_table,
14118 fs->inode_blocks_per_group, buf);
14120 com_err("swap_inodes", retval,
14121 _("while writing inode table (group %d)"),
14123 ctx->flags |= E2F_FLAG_ABORT;
14127 ext2fs_free_mem(&buf);
14128 ext2fs_free_mem(&block_buf);
14129 e2fsck_use_inode_shortcuts(ctx, 0);
14130 ext2fs_flush_icache(fs);
14133 #if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
14135 * On the PowerPC, the big-endian variant of the ext2 filesystem
14136 * has its bitmaps stored as 32-bit words with bit 0 as the LSB
14137 * of each word. Thus a bitmap with only bit 0 set would be, as
14138 * a string of bytes, 00 00 00 01 00 ...
14139 * To cope with this, we byte-reverse each word of a bitmap if
14140 * we have a big-endian filesystem, that is, if we are *not*
14141 * byte-swapping other word-sized numbers.
14143 #define EXT2_BIG_ENDIAN_BITMAPS
14146 #ifdef EXT2_BIG_ENDIAN_BITMAPS
14147 static void ext2fs_swap_bitmap(ext2fs_generic_bitmap bmap)
14149 __u32 *p = (__u32 *) bmap->bitmap;
14150 int n, nbytes = (bmap->end - bmap->start + 7) / 8;
14152 for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
14153 *p = ext2fs_swab32(*p);
14158 #ifdef ENABLE_SWAPFS
14159 static void swap_filesys(e2fsck_t ctx)
14161 ext2_filsys fs = ctx->fs;
14162 #ifdef RESOURCE_TRACK
14163 struct resource_track rtrack;
14165 init_resource_track(&rtrack);
14168 if (!(ctx->options & E2F_OPT_PREEN))
14169 printf(_("Pass 0: Doing byte-swap of filesystem\n"));
14172 mtrace_print("Byte swap");
14175 if (fs->super->s_mnt_count) {
14176 fprintf(stderr, _("%s: the filesystem must be freshly "
14177 "checked using fsck\n"
14178 "and not mounted before trying to "
14179 "byte-swap it.\n"), ctx->device_name);
14180 ctx->flags |= E2F_FLAG_ABORT;
14183 if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
14184 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES|
14185 EXT2_FLAG_SWAP_BYTES_WRITE);
14186 fs->flags |= EXT2_FLAG_SWAP_BYTES_READ;
14188 fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ;
14189 fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE;
14192 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
14194 if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)
14195 fs->flags |= EXT2_FLAG_SWAP_BYTES;
14196 fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ|
14197 EXT2_FLAG_SWAP_BYTES_WRITE);
14199 #ifdef EXT2_BIG_ENDIAN_BITMAPS
14200 e2fsck_read_bitmaps(ctx);
14201 ext2fs_swap_bitmap(fs->inode_map);
14202 ext2fs_swap_bitmap(fs->block_map);
14203 fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
14205 fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
14207 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
14209 #ifdef RESOURCE_TRACK
14210 if (ctx->options & E2F_OPT_TIME2)
14211 print_resource_track(_("Byte swap"), &rtrack);
14214 #endif /* ENABLE_SWAPFS */
14219 * util.c --- miscellaneous utilities
14222 #ifdef HAVE_CONIO_H
14223 #undef HAVE_TERMIOS_H
14225 #define read_a_char() getch()
14227 #ifdef HAVE_TERMIOS_H
14228 #include <termios.h>
14233 void fatal_error(e2fsck_t ctx, const char *msg)
14236 fprintf (stderr, "e2fsck: %s\n", msg);
14237 if (ctx->fs && ctx->fs->io) {
14238 if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
14239 io_channel_flush(ctx->fs->io);
14241 fprintf(stderr, "e2fsck: io manager magic bad!\n");
14243 ctx->flags |= E2F_FLAG_ABORT;
14244 if (ctx->flags & E2F_FLAG_SETJMP_OK)
14245 longjmp(ctx->abort_loc, 1);
14250 void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
14251 const char *description)
14256 #ifdef DEBUG_ALLOCATE_MEMORY
14257 printf("Allocating %d bytes for %s...\n", size, description);
14259 ret = malloc(size);
14261 sprintf(buf, "Can't allocate %s\n", description);
14262 fatal_error(ctx, buf);
14264 memset(ret, 0, size);
14268 static char *string_copy(const char *str, int len)
14276 ret = malloc(len+1);
14278 strncpy(ret, str, len);
14284 #ifndef HAVE_CONIO_H
14285 static int read_a_char(void)
14292 if (e2fsck_global_ctx &&
14293 (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
14296 r = read(0, &c, 1);
14306 static int ask_yn(const char * string, int def)
14309 const char *defstr;
14310 static const char short_yes[] = "yY";
14311 static const char short_no[] = "nN";
14313 #ifdef HAVE_TERMIOS_H
14314 struct termios termios, tmp;
14316 tcgetattr (0, &termios);
14318 tmp.c_lflag &= ~(ICANON | ECHO);
14319 tmp.c_cc[VMIN] = 1;
14320 tmp.c_cc[VTIME] = 0;
14321 tcsetattr (0, TCSANOW, &tmp);
14330 printf("%s%s? ", string, defstr);
14333 if ((c = read_a_char()) == EOF)
14336 #ifdef HAVE_TERMIOS_H
14337 tcsetattr (0, TCSANOW, &termios);
14339 if (e2fsck_global_ctx &&
14340 e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
14342 longjmp(e2fsck_global_ctx->abort_loc, 1);
14344 puts(_("cancelled!\n"));
14347 if (strchr(short_yes, (char) c)) {
14351 else if (strchr(short_no, (char) c)) {
14355 else if ((c == ' ' || c == '\n') && (def != -1))
14362 #ifdef HAVE_TERMIOS_H
14363 tcsetattr (0, TCSANOW, &termios);
14368 int ask (e2fsck_t ctx, const char * string, int def)
14370 if (ctx->options & E2F_OPT_NO) {
14371 printf (_("%s? no\n\n"), string);
14374 if (ctx->options & E2F_OPT_YES) {
14375 printf (_("%s? yes\n\n"), string);
14378 if (ctx->options & E2F_OPT_PREEN) {
14379 printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
14382 return ask_yn(string, def);
14385 void e2fsck_read_bitmaps(e2fsck_t ctx)
14387 ext2_filsys fs = ctx->fs;
14390 if (ctx->invalid_bitmaps) {
14391 com_err(ctx->program_name, 0,
14392 _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
14394 fatal_error(ctx, 0);
14397 ehandler_operation(_("reading inode and block bitmaps"));
14398 retval = ext2fs_read_bitmaps(fs);
14399 ehandler_operation(0);
14401 com_err(ctx->program_name, retval,
14402 _("while retrying to read bitmaps for %s"),
14404 fatal_error(ctx, 0);
14408 static void e2fsck_write_bitmaps(e2fsck_t ctx)
14410 ext2_filsys fs = ctx->fs;
14413 if (ext2fs_test_bb_dirty(fs)) {
14414 ehandler_operation(_("writing block bitmaps"));
14415 retval = ext2fs_write_block_bitmap(fs);
14416 ehandler_operation(0);
14418 com_err(ctx->program_name, retval,
14419 _("while retrying to write block bitmaps for %s"),
14421 fatal_error(ctx, 0);
14425 if (ext2fs_test_ib_dirty(fs)) {
14426 ehandler_operation(_("writing inode bitmaps"));
14427 retval = ext2fs_write_inode_bitmap(fs);
14428 ehandler_operation(0);
14430 com_err(ctx->program_name, retval,
14431 _("while retrying to write inode bitmaps for %s"),
14433 fatal_error(ctx, 0);
14438 void preenhalt(e2fsck_t ctx)
14440 ext2_filsys fs = ctx->fs;
14442 if (!(ctx->options & E2F_OPT_PREEN))
14444 fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
14445 "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
14448 fs->super->s_state |= EXT2_ERROR_FS;
14449 ext2fs_mark_super_dirty(fs);
14452 exit(EXIT_UNCORRECTED);
14455 #ifdef RESOURCE_TRACK
14456 void init_resource_track(struct resource_track *track)
14458 #ifdef HAVE_GETRUSAGE
14462 track->brk_start = sbrk(0);
14463 gettimeofday(&track->time_start, 0);
14464 #ifdef HAVE_GETRUSAGE
14466 memset(&r, 0, sizeof(struct rusage));
14468 getrusage(RUSAGE_SELF, &r);
14469 track->user_start = r.ru_utime;
14470 track->system_start = r.ru_stime;
14472 track->user_start.tv_sec = track->user_start.tv_usec = 0;
14473 track->system_start.tv_sec = track->system_start.tv_usec = 0;
14477 static _INLINE_ float timeval_subtract(struct timeval *tv1,
14478 struct timeval *tv2)
14480 return ((tv1->tv_sec - tv2->tv_sec) +
14481 ((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
14484 void print_resource_track(const char *desc, struct resource_track *track)
14486 #ifdef HAVE_GETRUSAGE
14489 #ifdef HAVE_MALLINFO
14490 struct mallinfo malloc_info;
14492 struct timeval time_end;
14494 gettimeofday(&time_end, 0);
14497 printf("%s: ", desc);
14499 #ifdef HAVE_MALLINFO
14500 #define kbytes(x) (((x) + 1023) / 1024)
14502 malloc_info = mallinfo();
14503 printf(_("Memory used: %dk/%dk (%dk/%dk), "),
14504 kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd),
14505 kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks));
14507 printf(_("Memory used: %d, "),
14508 (int) (((char *) sbrk(0)) - ((char *) track->brk_start)));
14510 #ifdef HAVE_GETRUSAGE
14511 getrusage(RUSAGE_SELF, &r);
14513 printf(_("time: %5.2f/%5.2f/%5.2f\n"),
14514 timeval_subtract(&time_end, &track->time_start),
14515 timeval_subtract(&r.ru_utime, &track->user_start),
14516 timeval_subtract(&r.ru_stime, &track->system_start));
14518 printf(_("elapsed time: %6.3f\n"),
14519 timeval_subtract(&time_end, &track->time_start));
14522 #endif /* RESOURCE_TRACK */
14524 void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
14525 struct ext2_inode * inode, const char *proc)
14529 retval = ext2fs_read_inode(ctx->fs, ino, inode);
14531 com_err("ext2fs_read_inode", retval,
14532 _("while reading inode %ld in %s"), ino, proc);
14533 fatal_error(ctx, 0);
14537 extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
14538 struct ext2_inode * inode, int bufsize,
14543 retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
14545 com_err("ext2fs_write_inode", retval,
14546 _("while writing inode %ld in %s"), ino, proc);
14547 fatal_error(ctx, 0);
14551 extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
14552 struct ext2_inode * inode, const char *proc)
14556 retval = ext2fs_write_inode(ctx->fs, ino, inode);
14558 com_err("ext2fs_write_inode", retval,
14559 _("while writing inode %ld in %s"), ino, proc);
14560 fatal_error(ctx, 0);
14565 void mtrace_print(char *mesg)
14567 FILE *malloc_get_mallstream();
14568 FILE *f = malloc_get_mallstream();
14571 fprintf(f, "============= %s\n", mesg);
14575 blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
14576 io_manager manager)
14578 struct ext2_super_block *sb;
14579 io_channel io = NULL;
14582 blk_t superblock, ret_sb = 8193;
14584 if (fs && fs->super) {
14585 ret_sb = (fs->super->s_blocks_per_group +
14586 fs->super->s_first_data_block);
14588 ctx->superblock = ret_sb;
14589 ctx->blocksize = fs->blocksize;
14595 if (ctx->blocksize) {
14596 ret_sb = ctx->blocksize * 8;
14597 if (ctx->blocksize == 1024)
14599 ctx->superblock = ret_sb;
14602 ctx->superblock = ret_sb;
14603 ctx->blocksize = 1024;
14606 if (!name || !manager)
14609 if (manager->open(name, 0, &io) != 0)
14612 if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
14614 sb = (struct ext2_super_block *) buf;
14616 for (blocksize = EXT2_MIN_BLOCK_SIZE;
14617 blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
14618 superblock = blocksize*8;
14619 if (blocksize == 1024)
14621 io_channel_set_blksize(io, blocksize);
14622 if (io_channel_read_blk(io, superblock,
14623 -SUPERBLOCK_SIZE, buf))
14625 #ifdef EXT2FS_ENABLE_SWAPFS
14626 if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
14627 ext2fs_swap_super(sb);
14629 if (sb->s_magic == EXT2_SUPER_MAGIC) {
14630 ret_sb = superblock;
14632 ctx->superblock = superblock;
14633 ctx->blocksize = blocksize;
14641 io_channel_close(io);
14643 ext2fs_free_mem(&buf);
14649 * This function runs through the e2fsck passes and calls them all,
14650 * returning restart, abort, or cancel as necessary...
14652 typedef void (*pass_t)(e2fsck_t ctx);
14654 static const pass_t e2fsck_passes[] = {
14655 e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4,
14658 #define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART)
14660 static int e2fsck_run(e2fsck_t ctx)
14663 pass_t e2fsck_pass;
14665 if (setjmp(ctx->abort_loc)) {
14666 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
14667 return (ctx->flags & E2F_FLAG_RUN_RETURN);
14669 ctx->flags |= E2F_FLAG_SETJMP_OK;
14671 for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) {
14672 if (ctx->flags & E2F_FLAG_RUN_RETURN)
14676 (void) (ctx->progress)(ctx, 0, 0, 0);
14678 ctx->flags &= ~E2F_FLAG_SETJMP_OK;
14680 if (ctx->flags & E2F_FLAG_RUN_RETURN)
14681 return (ctx->flags & E2F_FLAG_RUN_RETURN);
14687 * unix.c - The unix-specific code for e2fsck
14691 /* Command line options */
14693 #ifdef ENABLE_SWAPFS
14694 static int normalize_swapfs;
14696 static int cflag; /* check disk */
14697 static int show_version_only;
14698 static int verbose;
14700 static int replace_bad_blocks;
14701 static int keep_bad_blocks;
14702 static char *bad_blocks_file;
14704 #ifdef __CONFIG_JBD_DEBUG__E2FS /* Enabled by configure --enable-jfs-debug */
14705 int journal_enable_debug = -1;
14709 static void usage(e2fsck_t ctx)
14712 _("Usage: %s [-panyrcdfvstDFSV] [-b superblock] [-B blocksize]\n"
14713 "\t\t[-I inode_buffer_blocks] [-P process_inode_size]\n"
14714 "\t\t[-l|-L bad_blocks_file] [-C fd] [-j ext-journal]\n"
14715 "\t\t[-E extended-options] device\n"),
14716 ctx->program_name);
14718 fprintf(stderr, _("\nEmergency help:\n"
14719 " -p Automatic repair (no questions)\n"
14720 " -n Make no changes to the filesystem\n"
14721 " -y Assume \"yes\" to all questions\n"
14722 " -c Check for bad blocks and add them to the badblock list\n"
14723 " -f Force checking even if filesystem is marked clean\n"));
14724 fprintf(stderr, _(""
14726 " -b superblock Use alternative superblock\n"
14727 " -B blocksize Force blocksize when looking for superblock\n"
14728 " -j external-journal Set location of the external journal\n"
14729 " -l bad_blocks_file Add to badblocks list\n"
14730 " -L bad_blocks_file Set badblocks list\n"
14737 #define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural)
14739 static void show_stats(e2fsck_t ctx)
14741 ext2_filsys fs = ctx->fs;
14742 int inodes, inodes_used, blocks, blocks_used;
14744 int num_files, num_links;
14747 dir_links = 2 * ctx->fs_directory_count - 1;
14748 num_files = ctx->fs_total_count - dir_links;
14749 num_links = ctx->fs_links_count - dir_links;
14750 inodes = fs->super->s_inodes_count;
14751 inodes_used = (fs->super->s_inodes_count -
14752 fs->super->s_free_inodes_count);
14753 blocks = fs->super->s_blocks_count;
14754 blocks_used = (fs->super->s_blocks_count -
14755 fs->super->s_free_blocks_count);
14757 frag_percent = (10000 * ctx->fs_fragmented) / inodes_used;
14758 frag_percent = (frag_percent + 5) / 10;
14761 printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n",
14762 ctx->device_name, inodes_used, inodes,
14763 frag_percent / 10, frag_percent % 10,
14764 blocks_used, blocks);
14767 printf ("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used),
14768 100 * inodes_used / inodes);
14769 printf ("%8d non-contiguous inode%s (%0d.%d%%)\n",
14770 P_E2("", "s", ctx->fs_fragmented),
14771 frag_percent / 10, frag_percent % 10);
14772 printf (_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"),
14773 ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count);
14774 printf ("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used),
14775 (int) ((long long) 100 * blocks_used / blocks));
14776 printf ("%8d bad block%s\n", P_E2("", "s", ctx->fs_badblocks_count));
14777 printf ("%8d large file%s\n", P_E2("", "s", ctx->large_files));
14778 printf ("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count));
14779 printf ("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count));
14780 printf ("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count));
14781 printf ("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count));
14782 printf ("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count));
14783 printf ("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links));
14784 printf ("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count));
14785 printf (" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count));
14786 printf ("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count));
14787 printf ("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links));
14790 static void check_mount(e2fsck_t ctx)
14795 retval = ext2fs_check_if_mounted(ctx->filesystem_name,
14796 &ctx->mount_flags);
14798 com_err("ext2fs_check_if_mount", retval,
14799 _("while determining whether %s is mounted."),
14800 ctx->filesystem_name);
14805 * If the filesystem isn't mounted, or it's the root filesystem
14806 * and it's mounted read-only, then everything's fine.
14808 if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) ||
14809 ((ctx->mount_flags & EXT2_MF_ISROOT) &&
14810 (ctx->mount_flags & EXT2_MF_READONLY)))
14813 if (ctx->options & E2F_OPT_READONLY) {
14814 printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name);
14818 printf(_("%s is mounted. "), ctx->filesystem_name);
14819 if (!ctx->interactive)
14820 fatal_error(ctx, _("Cannot continue, aborting.\n\n"));
14821 printf(_("\n\n\007\007\007\007WARNING!!! "
14822 "Running e2fsck on a mounted filesystem may cause\n"
14823 "SEVERE filesystem damage.\007\007\007\n\n"));
14824 cont = ask_yn(_("Do you really want to continue"), -1);
14826 printf (_("check aborted.\n"));
14832 static int is_on_batt(void)
14836 char tmp[80], tmp2[80], fname[80];
14837 unsigned int acflag;
14840 f = fopen("/proc/apm", "r");
14842 if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4)
14845 return (acflag != 1);
14847 d = opendir("/proc/acpi/ac_adapter");
14849 while ((de=readdir(d)) != NULL) {
14850 if (!strncmp(".", de->d_name, 1))
14852 snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state",
14854 f = fopen(fname, "r");
14857 if (fscanf(f, "%s %s", tmp2, tmp) != 2)
14860 if (strncmp(tmp, "off-line", 8) == 0) {
14871 * This routine checks to see if a filesystem can be skipped; if so,
14872 * it will exit with EXIT_OK. Under some conditions it will print a
14873 * message explaining why a check is being forced.
14875 static void check_if_skip(e2fsck_t ctx)
14877 ext2_filsys fs = ctx->fs;
14878 const char *reason = NULL;
14879 unsigned int reason_arg = 0;
14881 int batt = is_on_batt();
14882 time_t now = time(0);
14884 if ((ctx->options & E2F_OPT_FORCE) || bad_blocks_file ||
14888 if ((fs->super->s_state & EXT2_ERROR_FS) ||
14889 !ext2fs_test_valid(fs))
14890 reason = _(" contains a file system with errors");
14891 else if ((fs->super->s_state & EXT2_VALID_FS) == 0)
14892 reason = _(" was not cleanly unmounted");
14893 else if ((fs->super->s_max_mnt_count > 0) &&
14894 (fs->super->s_mnt_count >=
14895 (unsigned) fs->super->s_max_mnt_count)) {
14896 reason = _(" has been mounted %u times without being checked");
14897 reason_arg = fs->super->s_mnt_count;
14898 if (batt && (fs->super->s_mnt_count <
14899 (unsigned) fs->super->s_max_mnt_count*2))
14901 } else if (fs->super->s_checkinterval &&
14902 ((now - fs->super->s_lastcheck) >=
14903 fs->super->s_checkinterval)) {
14904 reason = _(" has gone %u days without being checked");
14905 reason_arg = (now - fs->super->s_lastcheck)/(3600*24);
14906 if (batt && ((now - fs->super->s_lastcheck) <
14907 fs->super->s_checkinterval*2))
14911 fputs(ctx->device_name, stdout);
14912 printf(reason, reason_arg);
14913 fputs(_(", check forced.\n"), stdout);
14916 printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name,
14917 fs->super->s_inodes_count - fs->super->s_free_inodes_count,
14918 fs->super->s_inodes_count,
14919 fs->super->s_blocks_count - fs->super->s_free_blocks_count,
14920 fs->super->s_blocks_count);
14921 next_check = 100000;
14922 if (fs->super->s_max_mnt_count > 0) {
14923 next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count;
14924 if (next_check <= 0)
14927 if (fs->super->s_checkinterval &&
14928 ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval))
14930 if (next_check <= 5) {
14931 if (next_check == 1)
14932 fputs(_(" (check after next mount)"), stdout);
14934 printf(_(" (check in %ld mounts)"), next_check);
14936 fputc('\n', stdout);
14939 e2fsck_free_context(ctx);
14944 * For completion notice
14946 struct percent_tbl {
14950 static const struct percent_tbl e2fsck_tbl = {
14951 5, { 0, 70, 90, 92, 95, 100 }
14954 static char bar[128], spaces[128];
14956 static float calc_percent(const struct percent_tbl *tbl, int pass, int curr,
14963 if (pass > tbl->max_pass || max == 0)
14965 percent = ((float) curr) / ((float) max);
14966 return ((percent * (tbl->table[pass] - tbl->table[pass-1]))
14967 + tbl->table[pass-1]);
14970 extern void e2fsck_clear_progbar(e2fsck_t ctx)
14972 if (!(ctx->flags & E2F_FLAG_PROG_BAR))
14975 printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80),
14978 ctx->flags &= ~E2F_FLAG_PROG_BAR;
14981 int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent,
14982 unsigned int dpynum)
14984 static const char spinner[] = "\\|/-";
14991 if (ctx->flags & E2F_FLAG_PROG_SUPPRESS)
14995 * Calculate the new progress position. If the
14996 * percentage hasn't changed, then we skip out right
14999 fixed_percent = (int) ((10 * percent) + 0.5);
15000 if (ctx->progress_last_percent == fixed_percent)
15002 ctx->progress_last_percent = fixed_percent;
15005 * If we've already updated the spinner once within
15006 * the last 1/8th of a second, no point doing it
15009 gettimeofday(&tv, NULL);
15010 tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8));
15011 if ((tick == ctx->progress_last_time) &&
15012 (fixed_percent != 0) && (fixed_percent != 1000))
15014 ctx->progress_last_time = tick;
15017 * Advance the spinner, and note that the progress bar
15018 * will be on the screen
15020 ctx->progress_pos = (ctx->progress_pos+1) & 3;
15021 ctx->flags |= E2F_FLAG_PROG_BAR;
15023 dpywidth = 66 - strlen(label);
15024 dpywidth = 8 * (dpywidth / 8);
15028 i = ((percent * dpywidth) + 50) / 100;
15029 printf("%s%s: |%s%s", ctx->start_meta, label,
15030 bar + (sizeof(bar) - (i+1)),
15031 spaces + (sizeof(spaces) - (dpywidth - i + 1)));
15032 if (fixed_percent == 1000)
15033 fputc('|', stdout);
15035 fputc(spinner[ctx->progress_pos & 3], stdout);
15036 printf(" %4.1f%% ", percent);
15038 printf("%u\r", dpynum);
15040 fputs(" \r", stdout);
15041 fputs(ctx->stop_meta, stdout);
15043 if (fixed_percent == 1000)
15044 e2fsck_clear_progbar(ctx);
15050 static int e2fsck_update_progress(e2fsck_t ctx, int pass,
15051 unsigned long cur, unsigned long max)
15059 if (ctx->progress_fd) {
15060 sprintf(buf, "%d %lu %lu\n", pass, cur, max);
15061 write(ctx->progress_fd, buf, strlen(buf));
15063 percent = calc_percent(&e2fsck_tbl, pass, cur, max);
15064 e2fsck_simple_progress(ctx, ctx->device_name,
15070 static void reserve_stdio_fds(void)
15075 fd = open(bb_dev_null, O_RDWR);
15079 fprintf(stderr, _("ERROR: Couldn't open "
15080 "/dev/null (%s)\n"),
15088 static void signal_progress_on(int sig FSCK_ATTR((unused)))
15090 e2fsck_t ctx = e2fsck_global_ctx;
15095 ctx->progress = e2fsck_update_progress;
15096 ctx->progress_fd = 0;
15099 static void signal_progress_off(int sig FSCK_ATTR((unused)))
15101 e2fsck_t ctx = e2fsck_global_ctx;
15106 e2fsck_clear_progbar(ctx);
15110 static void signal_cancel(int sig FSCK_ATTR((unused)))
15112 e2fsck_t ctx = e2fsck_global_ctx;
15115 exit(FSCK_CANCELED);
15117 ctx->flags |= E2F_FLAG_CANCEL;
15120 static void parse_extended_opts(e2fsck_t ctx, const char *opts)
15122 char *buf, *token, *next, *p, *arg;
15124 int extended_usage = 0;
15126 buf = string_copy(opts, 0);
15127 for (token = buf; token && *token; token = next) {
15128 p = strchr(token, ',');
15134 arg = strchr(token, '=');
15139 if (strcmp(token, "ea_ver") == 0) {
15144 ea_ver = strtoul(arg, &p, 0);
15146 ((ea_ver != 1) && (ea_ver != 2))) {
15148 _("Invalid EA version.\n"));
15152 ctx->ext_attr_ver = ea_ver;
15156 if (extended_usage) {
15157 bb_error_msg_and_die(
15158 "Extended options are separated by commas, "
15159 "and may take an argument which\n"
15160 "is set off by an equals ('=') sign. "
15161 "Valid raid options are:\n"
15162 "\tea_ver=<ea_version (1 or 2)\n\n");
15167 static errcode_t PRS(int argc, char *argv[], e2fsck_t *ret_ctx)
15172 extern void *mallwatch;
15176 struct sigaction sa;
15177 char *extended_opts = 0;
15179 retval = e2fsck_allocate_context(&ctx);
15185 setvbuf(stdout, NULL, _IONBF, BUFSIZ);
15186 setvbuf(stderr, NULL, _IONBF, BUFSIZ);
15187 if (isatty(0) && isatty(1)) {
15188 ctx->interactive = 1;
15190 ctx->start_meta[0] = '\001';
15191 ctx->stop_meta[0] = '\002';
15193 memset(bar, '=', sizeof(bar)-1);
15194 memset(spaces, ' ', sizeof(spaces)-1);
15195 blkid_get_cache(&ctx->blkid, NULL);
15198 ctx->program_name = *argv;
15200 ctx->program_name = "e2fsck";
15201 while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF)
15204 ctx->progress = e2fsck_update_progress;
15205 ctx->progress_fd = atoi(optarg);
15206 if (!ctx->progress_fd)
15208 /* Validate the file descriptor to avoid disasters */
15209 fd = dup(ctx->progress_fd);
15212 _("Error validating file descriptor %d: %s\n"),
15214 error_message(errno));
15216 _("Invalid completion information file descriptor"));
15221 ctx->options |= E2F_OPT_COMPRESS_DIRS;
15224 extended_opts = optarg;
15228 if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) {
15231 _("Only one the options -p/-a, -n or -y may be specified."));
15233 ctx->options |= E2F_OPT_PREEN;
15236 if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN))
15238 ctx->options |= E2F_OPT_NO;
15241 if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO))
15243 ctx->options |= E2F_OPT_YES;
15246 #ifdef RESOURCE_TRACK
15247 if (ctx->options & E2F_OPT_TIME)
15248 ctx->options |= E2F_OPT_TIME2;
15250 ctx->options |= E2F_OPT_TIME;
15252 fprintf(stderr, _("The -t option is not "
15253 "supported on this version of e2fsck.\n"));
15258 ctx->options |= E2F_OPT_WRITECHECK;
15259 ctx->options |= E2F_OPT_CHECKBLOCKS;
15262 /* What we do by default, anyway! */
15265 ctx->use_superblock = atoi(optarg);
15266 ctx->flags |= E2F_FLAG_SB_SPECIFIED;
15269 ctx->blocksize = atoi(optarg);
15272 ctx->inode_buffer_blocks = atoi(optarg);
15275 ctx->journal_name = string_copy(optarg, 0);
15278 ctx->process_inode_size = atoi(optarg);
15281 replace_bad_blocks++;
15283 bad_blocks_file = string_copy(optarg, 0);
15286 ctx->options |= E2F_OPT_DEBUG;
15289 ctx->options |= E2F_OPT_FORCE;
15298 show_version_only = 1;
15302 mallwatch = (void *) strtol(optarg, NULL, 0);
15306 ctx->device_name = optarg;
15308 #ifdef ENABLE_SWAPFS
15310 normalize_swapfs = 1;
15317 fprintf(stderr, _("Byte-swapping filesystems "
15318 "not compiled in this version "
15328 if (show_version_only)
15330 if (optind != argc - 1)
15332 if ((ctx->options & E2F_OPT_NO) && !bad_blocks_file &&
15333 !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS))
15334 ctx->options |= E2F_OPT_READONLY;
15335 ctx->io_options = strchr(argv[optind], '?');
15336 if (ctx->io_options)
15337 *ctx->io_options++ = 0;
15338 ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0);
15339 if (!ctx->filesystem_name) {
15340 com_err(ctx->program_name, 0, _("Unable to resolve '%s'"),
15342 fatal_error(ctx, 0);
15345 parse_extended_opts(ctx, extended_opts);
15348 fd = open(ctx->filesystem_name, O_RDONLY, 0);
15350 com_err("open", errno,
15351 _("while opening %s for flushing"),
15352 ctx->filesystem_name);
15353 fatal_error(ctx, 0);
15355 if ((retval = ext2fs_sync_device(fd, 1))) {
15356 com_err("ext2fs_sync_device", retval,
15357 _("while trying to flush %s"),
15358 ctx->filesystem_name);
15359 fatal_error(ctx, 0);
15363 #ifdef ENABLE_SWAPFS
15365 if (cflag || bad_blocks_file) {
15366 fprintf(stderr, _("Incompatible options not "
15367 "allowed when byte-swapping.\n"));
15372 if (cflag && bad_blocks_file) {
15373 fprintf(stderr, _("The -c and the -l/-L options may "
15374 "not be both used at the same time.\n"));
15378 * Set up signal action
15380 memset(&sa, 0, sizeof(struct sigaction));
15381 sa.sa_handler = signal_cancel;
15382 sigaction(SIGINT, &sa, 0);
15383 sigaction(SIGTERM, &sa, 0);
15385 sa.sa_flags = SA_RESTART;
15387 e2fsck_global_ctx = ctx;
15388 sa.sa_handler = signal_progress_on;
15389 sigaction(SIGUSR1, &sa, 0);
15390 sa.sa_handler = signal_progress_off;
15391 sigaction(SIGUSR2, &sa, 0);
15393 /* Update our PATH to include /sbin if we need to run badblocks */
15395 e2fs_set_sbin_path();
15396 #ifdef __CONFIG_JBD_DEBUG__E2FS
15397 if (getenv("E2FSCK_JBD_DEBUG"))
15398 journal_enable_debug = atoi(getenv("E2FSCK_JBD_DEBUG"));
15403 static const char my_ver_string[] = E2FSPROGS_VERSION;
15404 static const char my_ver_date[] = E2FSPROGS_DATE;
15406 int e2fsck_main (int argc, char *argv[])
15409 int exit_value = EXIT_OK;
15410 ext2_filsys fs = 0;
15412 struct ext2_super_block *sb;
15413 const char *lib_ver_date;
15414 int my_ver, lib_ver;
15416 struct problem_context pctx;
15417 int flags, run_result;
15419 clear_problem_context(&pctx);
15427 setlocale(LC_MESSAGES, "");
15428 setlocale(LC_CTYPE, "");
15429 bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
15430 textdomain(NLS_CAT_NAME);
15432 my_ver = ext2fs_parse_version_string(my_ver_string);
15433 lib_ver = ext2fs_get_library_version(0, &lib_ver_date);
15434 if (my_ver > lib_ver) {
15435 fprintf( stderr, _("Error: ext2fs library version "
15436 "out of date!\n"));
15437 show_version_only++;
15440 retval = PRS(argc, argv, &ctx);
15442 com_err("e2fsck", retval,
15443 _("while trying to initialize program"));
15446 reserve_stdio_fds();
15448 #ifdef RESOURCE_TRACK
15449 init_resource_track(&ctx->global_rtrack);
15452 if (!(ctx->options & E2F_OPT_PREEN) || show_version_only)
15453 fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string,
15456 if (show_version_only) {
15457 fprintf(stderr, _("\tUsing %s, %s\n"),
15458 error_message(EXT2_ET_BASE), lib_ver_date);
15464 if (!(ctx->options & E2F_OPT_PREEN) &&
15465 !(ctx->options & E2F_OPT_NO) &&
15466 !(ctx->options & E2F_OPT_YES)) {
15467 if (!ctx->interactive)
15469 _("need terminal for interactive repairs"));
15471 ctx->superblock = ctx->use_superblock;
15473 #ifdef CONFIG_TESTIO_DEBUG
15474 io_ptr = test_io_manager;
15475 test_io_backing_manager = unix_io_manager;
15477 io_ptr = unix_io_manager;
15480 if ((ctx->options & E2F_OPT_READONLY) == 0)
15481 flags |= EXT2_FLAG_RW;
15483 if (ctx->superblock && ctx->blocksize) {
15484 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
15485 flags, ctx->superblock, ctx->blocksize,
15487 } else if (ctx->superblock) {
15489 for (blocksize = EXT2_MIN_BLOCK_SIZE;
15490 blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) {
15491 retval = ext2fs_open2(ctx->filesystem_name,
15492 ctx->io_options, flags,
15493 ctx->superblock, blocksize,
15499 retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options,
15500 flags, 0, 0, io_ptr, &fs);
15501 if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) &&
15502 !(ctx->flags & E2F_FLAG_SB_SPECIFIED) &&
15503 ((retval == EXT2_ET_BAD_MAGIC) ||
15504 ((retval == 0) && ext2fs_check_desc(fs)))) {
15505 if (!fs || (fs->group_desc_count > 1)) {
15506 printf(_("%s trying backup blocks...\n"),
15507 retval ? _("Couldn't find ext2 superblock,") :
15508 _("Group descriptors look bad..."));
15509 get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr);
15516 com_err(ctx->program_name, retval, _("while trying to open %s"),
15517 ctx->filesystem_name);
15518 if (retval == EXT2_ET_REV_TOO_HIGH) {
15519 printf(_("The filesystem revision is apparently "
15520 "too high for this version of e2fsck.\n"
15521 "(Or the filesystem superblock "
15522 "is corrupt)\n\n"));
15523 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
15524 } else if (retval == EXT2_ET_SHORT_READ)
15525 printf(_("Could this be a zero-length partition?\n"));
15526 else if ((retval == EPERM) || (retval == EACCES))
15527 printf(_("You must have %s access to the "
15528 "filesystem or be root\n"),
15529 (ctx->options & E2F_OPT_READONLY) ?
15531 else if (retval == ENXIO)
15532 printf(_("Possibly non-existent or swap device?\n"));
15534 else if (retval == EROFS)
15535 printf(_("Disk write-protected; use the -n option "
15536 "to do a read-only\n"
15537 "check of the device.\n"));
15540 fix_problem(ctx, PR_0_SB_CORRUPT, &pctx);
15541 fatal_error(ctx, 0);
15544 fs->priv_data = ctx;
15546 if (sb->s_rev_level > E2FSCK_CURRENT_REV) {
15547 com_err(ctx->program_name, EXT2_ET_REV_TOO_HIGH,
15548 _("while trying to open %s"),
15549 ctx->filesystem_name);
15551 fatal_error(ctx, _("Get a newer version of e2fsck!"));
15555 * Set the device name, which is used whenever we print error
15556 * or informational messages to the user.
15558 if (ctx->device_name == 0 &&
15559 (sb->s_volume_name[0] != 0)) {
15560 ctx->device_name = string_copy(sb->s_volume_name,
15561 sizeof(sb->s_volume_name));
15563 if (ctx->device_name == 0)
15564 ctx->device_name = ctx->filesystem_name;
15567 * Make sure the ext3 superblock fields are consistent.
15569 retval = e2fsck_check_ext3_journal(ctx);
15571 com_err(ctx->program_name, retval,
15572 _("while checking ext3 journal for %s"),
15574 fatal_error(ctx, 0);
15578 * Check to see if we need to do ext3-style recovery. If so,
15579 * do it, and then restart the fsck.
15581 if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
15582 if (ctx->options & E2F_OPT_READONLY) {
15583 printf(_("Warning: skipping journal recovery "
15584 "because doing a read-only filesystem "
15586 io_channel_flush(ctx->fs->io);
15588 if (ctx->flags & E2F_FLAG_RESTARTED) {
15590 * Whoops, we attempted to run the
15591 * journal twice. This should never
15592 * happen, unless the hardware or
15593 * device driver is being bogus.
15595 com_err(ctx->program_name, 0,
15596 _("unable to set superblock flags on %s\n"), ctx->device_name);
15597 fatal_error(ctx, 0);
15599 retval = e2fsck_run_ext3_journal(ctx);
15601 com_err(ctx->program_name, retval,
15602 _("while recovering ext3 journal of %s"),
15604 fatal_error(ctx, 0);
15606 ext2fs_close(ctx->fs);
15608 ctx->flags |= E2F_FLAG_RESTARTED;
15614 * Check for compatibility with the feature sets. We need to
15615 * be more stringent than ext2fs_open().
15617 if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) ||
15618 (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) {
15619 com_err(ctx->program_name, EXT2_ET_UNSUPP_FEATURE,
15620 "(%s)", ctx->device_name);
15623 if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
15624 com_err(ctx->program_name, EXT2_ET_RO_UNSUPP_FEATURE,
15625 "(%s)", ctx->device_name);
15628 #ifdef ENABLE_COMPRESSION
15629 if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION)
15630 com_err(ctx->program_name, 0,
15631 _("Warning: compression support is experimental.\n"));
15633 #ifndef ENABLE_HTREE
15634 if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) {
15635 com_err(ctx->program_name, 0,
15636 _("E2fsck not compiled with HTREE support,\n\t"
15637 "but filesystem %s has HTREE directories.\n"),
15644 * If the user specified a specific superblock, presumably the
15645 * master superblock has been trashed. So we mark the
15646 * superblock as dirty, so it can be written out.
15648 if (ctx->superblock &&
15649 !(ctx->options & E2F_OPT_READONLY))
15650 ext2fs_mark_super_dirty(fs);
15653 * We only update the master superblock because (a) paranoia;
15654 * we don't want to corrupt the backup superblocks, and (b) we
15655 * don't need to update the mount count and last checked
15656 * fields in the backup superblock (the kernel doesn't
15657 * update the backup superblocks anyway).
15659 fs->flags |= EXT2_FLAG_MASTER_SB_ONLY;
15661 ehandler_init(fs->io);
15663 if (ctx->superblock)
15664 set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0);
15665 ext2fs_mark_valid(fs);
15666 check_super_block(ctx);
15667 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
15668 fatal_error(ctx, 0);
15669 check_if_skip(ctx);
15670 if (bad_blocks_file)
15671 read_bad_blocks_file(ctx, bad_blocks_file, replace_bad_blocks);
15673 read_bad_blocks_file(ctx, 0, !keep_bad_blocks); /* Test disk */
15674 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
15675 fatal_error(ctx, 0);
15676 #ifdef ENABLE_SWAPFS
15677 if (normalize_swapfs) {
15678 if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ==
15679 ext2fs_native_flag()) {
15680 fprintf(stderr, _("%s: Filesystem byte order "
15681 "already normalized.\n"), ctx->device_name);
15682 fatal_error(ctx, 0);
15687 if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
15688 fatal_error(ctx, 0);
15693 * Mark the system as valid, 'til proven otherwise
15695 ext2fs_mark_valid(fs);
15697 retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
15699 com_err(ctx->program_name, retval,
15700 _("while reading bad blocks inode"));
15702 printf(_("This doesn't bode well,"
15703 " but we'll try to go on...\n"));
15706 run_result = e2fsck_run(ctx);
15707 e2fsck_clear_progbar(ctx);
15708 if (run_result == E2F_FLAG_RESTART) {
15709 printf(_("Restarting e2fsck from the beginning...\n"));
15710 retval = e2fsck_reset_context(ctx);
15712 com_err(ctx->program_name, retval,
15713 _("while resetting context"));
15714 fatal_error(ctx, 0);
15719 if (run_result & E2F_FLAG_CANCEL) {
15720 printf(_("%s: e2fsck canceled.\n"), ctx->device_name ?
15721 ctx->device_name : ctx->filesystem_name);
15722 exit_value |= FSCK_CANCELED;
15724 if (run_result & E2F_FLAG_ABORT)
15725 fatal_error(ctx, _("aborted"));
15728 mtrace_print("Cleanup");
15730 if (ext2fs_test_changed(fs)) {
15731 exit_value |= EXIT_NONDESTRUCT;
15732 if (!(ctx->options & E2F_OPT_PREEN))
15733 printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"),
15735 if (ctx->mount_flags & EXT2_MF_ISROOT) {
15736 printf(_("%s: ***** REBOOT LINUX *****\n"),
15738 exit_value |= EXIT_DESTRUCT;
15741 if (!ext2fs_test_valid(fs)) {
15742 printf(_("\n%s: ********** WARNING: Filesystem still has "
15743 "errors **********\n\n"), ctx->device_name);
15744 exit_value |= EXIT_UNCORRECTED;
15745 exit_value &= ~EXIT_NONDESTRUCT;
15747 if (exit_value & FSCK_CANCELED)
15748 exit_value &= ~EXIT_NONDESTRUCT;
15751 if (!(ctx->options & E2F_OPT_READONLY)) {
15752 if (ext2fs_test_valid(fs)) {
15753 if (!(sb->s_state & EXT2_VALID_FS))
15754 exit_value |= EXIT_NONDESTRUCT;
15755 sb->s_state = EXT2_VALID_FS;
15757 sb->s_state &= ~EXT2_VALID_FS;
15758 sb->s_mnt_count = 0;
15759 sb->s_lastcheck = time(NULL);
15760 ext2fs_mark_super_dirty(fs);
15764 e2fsck_write_bitmaps(ctx);
15768 free(ctx->filesystem_name);
15769 free(ctx->journal_name);
15770 e2fsck_free_context(ctx);
15772 #ifdef RESOURCE_TRACK
15773 if (ctx->options & E2F_OPT_TIME)
15774 print_resource_track(NULL, &ctx->global_rtrack);